diff --git a/.github/actions/setup-bun/action.yml b/.github/actions/setup-bun/action.yml index f4d017f..4bae42a 100644 --- a/.github/actions/setup-bun/action.yml +++ b/.github/actions/setup-bun/action.yml @@ -6,8 +6,6 @@ runs: steps: - name: Setup Bun uses: oven-sh/setup-bun@v1 - with: - bun-version: '1.0.26' - name: Install Dependencies shell: bash diff --git a/.github/actions/setup-dfx/action.yml b/.github/actions/setup-dfx/action.yml index 7c02bf8..a74463a 100644 --- a/.github/actions/setup-dfx/action.yml +++ b/.github/actions/setup-dfx/action.yml @@ -4,11 +4,7 @@ description: Setup DFX runs: using: 'composite' steps: - - name: Get DFX version - shell: bash - run: echo "dfx_version=$(cat dfx.json | jq -r .dfx)" >> "$GITHUB_ENV" - - name: Setup DFX uses: dfinity/setup-dfx@main with: - dfx-version: ${{ env.dfx_version }} + dfx-version: 'auto' diff --git a/.github/actions/setup-nodejs/action.yml b/.github/actions/setup-nodejs/action.yml index b3b9352..8beea97 100644 --- a/.github/actions/setup-nodejs/action.yml +++ b/.github/actions/setup-nodejs/action.yml @@ -5,7 +5,7 @@ runs: using: 'composite' steps: - name: Install NodeJS - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 20 + node-version-file: '.node-version' registry-url: 'https://registry.npmjs.org' diff --git a/.github/actions/setup-pnpm/action.yml b/.github/actions/setup-pnpm/action.yml index cbcd150..5013b09 100644 --- a/.github/actions/setup-pnpm/action.yml +++ b/.github/actions/setup-pnpm/action.yml @@ -6,25 +6,23 @@ runs: steps: - uses: ./.github/actions/setup-nodejs - - uses: pnpm/action-setup@v2 + - uses: pnpm/action-setup@v3 name: Install pnpm id: pnpm-install with: run_install: false - name: Get pnpm store directory - id: pnpm-cache shell: bash - run: | - echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - uses: actions/cache@v3 + - uses: actions/cache@v4 name: Setup pnpm cache with: - path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + path: ${{ env.STORE_PATH }} key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | - ${{ runner.os }}-pnpm-store + ${{ runner.os }}-pnpm-store- - name: Install dependencies shell: bash diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 55bd760..4f0cfb7 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/release-beta.yml b/.github/workflows/release-beta.yml index 8a3c2fa..7855184 100644 --- a/.github/workflows/release-beta.yml +++ b/.github/workflows/release-beta.yml @@ -13,7 +13,7 @@ jobs: url: https://www.npmjs.com/package/@hadronous/pic steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/release-latest.yml b/.github/workflows/release-latest.yml index 0e3810f..fe978f5 100644 --- a/.github/workflows/release-latest.yml +++ b/.github/workflows/release-latest.yml @@ -65,7 +65,7 @@ jobs: needs: release_latest steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: ./.github/actions/setup-pnpm diff --git a/.github/workflows/test-bun.yml b/.github/workflows/test-bun.yml index 3a5e35b..dc224b4 100644 --- a/.github/workflows/test-bun.yml +++ b/.github/workflows/test-bun.yml @@ -17,7 +17,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: ./.github/actions/setup-bun diff --git a/.github/workflows/test-nodejs.yml b/.github/workflows/test-nodejs.yml index d463470..9b75a28 100644 --- a/.github/workflows/test-nodejs.yml +++ b/.github/workflows/test-nodejs.yml @@ -17,7 +17,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - uses: ./.github/actions/setup-pnpm diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index 7a7e633..d6808a9 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -13,7 +13,7 @@ jobs: contents: write steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/bun.lockb b/bun.lockb index f067fd7..12ed023 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/docs/docs/guides/01-getting-started.md b/docs/docs/guides/01-getting-started.md index 29bf967..683a64b 100644 --- a/docs/docs/guides/01-getting-started.md +++ b/docs/docs/guides/01-getting-started.md @@ -1,21 +1,35 @@ # Getting started +[PocketIC](https://github.com/dfinity/pocketic) is a deterministic, lightweight and versatile testing solution for [Internet Computer canisters](https://internetcomputer.org/how-it-works/canister-lifecycle/). + +PicJS provides bindings to interact with [PocketIC](https://github.com/dfinity/pocketic) from Typescript and JavaScript. + ## JavaScript runtime environment -Tests written with PicJS are executed in a JavaScript runtime environment, such as [NodeJS](https://nodejs.org/en). To get started with PicJS, you will need to have a JavaScript runtime environment installed on your system. +Tests written with PicJS are executed in a JavaScript runtime environment, such as [NodeJS](https://nodejs.org/en). -[Bun](https://bun.sh/) is an alternative JavaScript runtime environment that is compatible with PicJS. Bun has several features that make it a great choice for running PicJS tests, such as a built-in test runner and assertion library in addition to being much more performant than NodeJS. +To get started with PicJS, you will need to have a JavaScript runtime environment installed on your system. If you're new to JavaScript, then [NodeJS](https://nodejs.org/en) is the recommended choice. -[Deno](https://deno.com/) in theory should also work, but it is not officially supported and compatibility is not actively tested. If you choose Deno and run into issues, please open an issue on the [GitHub repository](https://github.com/hadronous/pic-js/issues). +[Bun](https://bun.sh/) is an alternative JavaScript runtime environment that is compatible with PicJS. Bun has several features that make it a great choice for running PicJS tests, such as a built-in test runner and assertion library in addition to being much more performant than [NodeJS](https://nodejs.org/en). Bun is not very widely used yet, so it is not recommended for beginners. + +[Deno](https://deno.com/) in theory should also work, but it is not officially supported and compatibility is not actively tested. If you choose Deno and run into issues, please open an issue on the [GitHub repository](https://github.com/hadronous/pic-js/issues). Deno is also not widely used, so it is not recommended for developers that are unfamiliar with it. ## Package manager PicJS is a JavaScript/TypeScript package distributed on [NPM](https://www.npmjs.com/package/@hadronous/pic). To install and manage NPM packages, you will need to have an NPM-compatible package manager. -- [npm](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) is the official package manager for NodeJS and comes pre-installed with NodeJS. -- [pnpm](https://pnpm.io/) is a fast, disk space-efficient package manager. -- [Yarn](https://yarnpkg.com/) is a package manager that doubles down as a project manager. -- [Bun](https://bun.sh/) also includes a built-in package manager. +- [npm](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) + - This is the official package manager for [NodeJS](https://nodejs.org/en) and comes pre-installed. + - Beginners should stick with this option. +- [pnpm](https://pnpm.io/) + - A fast, disk space-efficient package manager. + - A great alternative to [npm](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) for more experienced developers. +- [Yarn](https://yarnpkg.com/) + - A package manager that doubles down as a project manager. + - Another great alternative to [npm](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) for more experienced developers. +- [Bun](https://bun.sh/) + - Bun also includes a built-in package manager. + - This is convenient if you are already using Bun as your runtime environment or test runner. ## DFX @@ -30,3 +44,20 @@ sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)" You can also check out the official [DFX installation documentation](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) for more information. DFX version 0.16.0 or later is recommended when writing PicJS tests. If you are on an earlier version then make sure to check out the [Canister declarations guide](./canister-declarations) to see how declarations should be used with older versions with DFX. + +## Test runner + +PicJS tests can be run with any test runner that runs on [NodeJS](https://nodejs.org/en) or [Bun](https://bun.sh/) (in theory the same should be true for [Deno](https://deno.com/), but that is not actively tested). + +The following test runners are actively tested and officially supported: + +- [Jest](https://jestjs.io/) + - Recommended if you're new to JavaScript testing because it has the largest community and is the most widely used. + - See the [Jest guide](./using-jest) for details on getting started with Jest and PicJS. +- [Vitest](https://vitest.dev/) + - If you're already using [Vite](https://vitejs.dev/) and Vitest for your frontend, then this is a good choice to reduce your dev dependencies. + - See the [Vitest guide](./using-vitest) for details on getting started with Vitest and PicJS. +- [Bun](https://bun.sh/) + - If you're already using Bun, or want to try it out, then this is a good choice. + - This is not recommended for beginners because it is less widely used and still immature compared to the other options. + - See the [Bun guide](./using-bun) for details on getting started with Bun and PicJS. diff --git a/docs/docs/guides/02-using-jest.md b/docs/docs/guides/02-using-jest.md new file mode 100644 index 0000000..ceb037e --- /dev/null +++ b/docs/docs/guides/02-using-jest.md @@ -0,0 +1,208 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Using Jest + +[Jest](https://jestjs.io) is a JavaScript testing framework that is widely used in the JavaScript community. It is recommended for beginners because it has the largest community and is the most widely used. Jest is also the officially supported test runner for PicJS. + +## Setup + +To get started with [Jest](https://jestjs.io), install the relevant packages using your preferred package manager: + + + + ```shell + npm i -D jest @types/jest @types/node ts-jest + ``` + + + + ```shell + pnpm i -D jest @types/jest @types/node ts-jest + ``` + + + + ```shell + yarn add -D jest @types/jest @types/node ts-jest + ``` + + + + ```shell + bun add -d jest @types/jest @types/node ts-jest + ``` + + + +Create a `tsconfig.json` file: + +```json title="tsconfig.json" +{ + "compilerOptions": { + // enable latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "allowJs": true, // allow importing `.js` from `.ts` + "types": ["jest", "node"], + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags + "useUnknownInCatchVariables": true, + "noPropertyAccessFromIndexSignature": true + }, + "include": [ + "./src/**/*.ts", + "./global-setup.ts", + "./global-teardown.ts", + "./types.d.ts" + ] +} +``` + +Create a `jest.config.ts` file: + +```ts title="jest.config.ts" +import type { Config } from 'jest'; + +const config: Config = { + watch: false, + preset: 'ts-jest/presets/js-with-ts', + testEnvironment: 'node', + globalSetup: '/global-setup.ts', + globalTeardown: '/global-teardown.ts', +}; + +export default config; +``` + +You can also check out the official the [`ts-jest` documentation](https://kulshekhar.github.io/ts-jest/docs/) for more information on configuring this file. + +Then, add a `test` script to your `package.json`: + +```json title="package.json" +{ + "scripts": { + "test": "jest" + } +} +``` + +The PocketIC server needs to be started before running tests and stopped once they're finished running. This can be done by creating `global-setup.ts` and `global-teardown.ts` files in your project's root directory: + +```ts title="global-setup.ts" +import { PocketIcServer } from '@hadronous/pic'; + +module.exports = async function (): Promise { + const pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + process.env.PIC_URL = url; + global.__PIC__ = pic; +}; +``` + +```ts title="global-teardown.ts" +module.exports = async function () { + await global.__PIC__.stop(); +}; +``` + +To improve type-safety for `process.env.PIC_URL` and `global.__PIC__`, create a `types.d.ts` file: + +```ts title="types.d.ts" +import { PocketIcServer } from '@hadronous/pic'; + +declare global { + declare var __PIC__: PocketIcServer; + + namespace NodeJS { + interface ProcessEnv { + PIC_URL: string; + } + } +} +``` + +## Writing tests + +[Jest](https://jestjs.io) tests are very similar to tests written with [Jasmine](https://jasmine.github.io), or [Vitest](https://vitest.dev) so they will feel very familiar to developers who have used these frameworks before. + +The basic skeleton of all PicJS tests written with [Jest](https://jestjs.io) will look something like this: + +```ts title="tests/example.spec.ts" +// Import generated types for your canister +import { type _SERVICE } from '../../declarations/backend/backend.did'; + +// Define the path to your canister's WASM file +export const WASM_PATH = resolve( + import.meta.dir, + '..', + '..', + 'target', + 'wasm32-unknown-unknown', + 'release', + 'backend.wasm', +); + +// The `describe` function is used to group tests together +// and is completely optional. +describe('Test suite name', () => { + // Define variables to hold our PocketIC instance, canister ID, + // and an actor to interact with our canister. + let pic: PocketIc; + let canisterId: Principal; + let actor: Actor<_SERVICE>; + + // The `beforeEach` hook runs before each test. + // + // This can be replaced with a `beforeAll` hook to persist canister + // state between tests. + beforeEach(async () => { + // create a new PocketIC instance + pic = await PocketIc.create(process.env.PIC_URL); + + // Setup the canister and actor + const fixture = await pic.setupCanister<_SERVICE>({ + idlFactory, + wasm: WASM_PATH, + }); + + // Save the actor and canister ID for use in tests + actor = fixture.actor; + canisterId = fixture.canisterId; + }); + + // The `afterEach` hook runs after each test. + // + // This should be replaced with an `afterAll` hook if you use + // a `beforeAll` hook instead of a `beforeEach` hook. + afterEach(async () => { + // tear down the PocketIC instance + await pic.tearDown(); + }); + + // The `it` function is used to define individual tests + it('should do something cool', async () => { + const response = await actor.do_something_cool(); + + expect(response).toEqual('cool'); + }); +}); +``` + +You can also check out the official [Jest getting started documentation](https://jestjs.io/docs/getting-started) for more information on writing tests. diff --git a/docs/docs/guides/03-using-vitest.md b/docs/docs/guides/03-using-vitest.md new file mode 100644 index 0000000..52b8ad0 --- /dev/null +++ b/docs/docs/guides/03-using-vitest.md @@ -0,0 +1,184 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Using Vitest + +[Vitest](https://vitest.dev/) is a modern JavaScript testing framework that integrates with the [Vite](https://vitejs.dev/) bundler. It is recommended for developers that are already using [Vite](https://vitejs.dev/) or [Vitest](https://vitest.dev/) on their project. + +## Setup + +To get started with [Vitest](https://vitest.dev/), install the relevant packages using your preferred package manager: + + + + ```shell + npm i -D vitest @types/node + ``` + + + + ```shell + pnpm i -D vitest @types/node + ``` + + + + ```shell + yarn add -D vitest @types/node + ``` + + + + ```shell + bun add -d vitest @types/node + ``` + + + +Create a `tsconfig.json` file: + +```json title="tsconfig.json" +{ + "compilerOptions": { + // enable latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "allowJs": true, // allow importing `.js` from `.ts` + "types": ["node"], + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags + "useUnknownInCatchVariables": true, + "noPropertyAccessFromIndexSignature": true + }, + "include": ["./src/**/*.ts", "./global-setup.ts", "./types.d.ts"] +} +``` + +The PocketIC server needs to be started before running tests and stopped once they're finished running. This can be done by creating a `global-setup.ts` file in your project's root directory: + +```ts title="global-setup.ts" +import type { GlobalSetupContext } from 'vitest/node'; +import { PocketIcServer } from '@hadronous/pic'; + +let pic: PocketIcServer | undefined; + +export async function setup(ctx: GlobalSetupContext): Promise { + pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + ctx.provide('PIC_URL', url); +} + +export async function teardown(): Promise { + await pic?.stop(); +} +``` + +To improve type-safety for `ctx.provide('PIC_URL')` and (later) `inject('PIC_URL')`, create a `types.d.ts` file: + +```typescript title="types.d.ts" +export declare module 'vitest' { + export interface ProvidedContext { + PIC_URL: string; + } +} +``` + +Create a `vitest.config.ts` file: + +```typescript title="vitest.config.ts" +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + root: 'examples/counter/tests', + globalSetup: './global-setup.ts', + }, +}); +``` + +## Writing tests + +[Vitest](https://vitest.dev/) tests are very similar to tests written with [Jest](https://jestjs.io/) or [Jasmine](https://jasmine.github.io), so they will feel very familiar to developers who have used these frameworks before. + +The basic skeleton of all PicJS tests written with [Vitest](https://vitest.dev/) will look something like this: + +```typescript title="tests/example.spec.ts" +import { describe, beforeEach, afterEach, it, expect, inject } from 'vitest'; + +// Import generated types for your canister +import { type _SERVICE } from '../../declarations/backend/backend.did'; + +// Define the path to your canister's WASM file +export const WASM_PATH = resolve( + import.meta.dir, + '..', + '..', + 'target', + 'wasm32-unknown-unknown', + 'release', + 'backend.wasm', +); + +// The `describe` function is used to group tests together +// and is completely optional. +describe('Test suite name', () => { + // Define variables to hold our PocketIC instance, canister ID, + // and an actor to interact with our canister. + let pic: PocketIc; + let canisterId: Principal; + let actor: Actor<_SERVICE>; + + // The `beforeEach` hook runs before each test. + // + // This can be replaced with a `beforeAll` hook to persist canister + // state between tests. + beforeEach(async () => { + // create a new PocketIC instance + pic = await PocketIc.create(inject('PIC_URL')); + + // Setup the canister and actor + const fixture = await pic.setupCanister<_SERVICE>({ + idlFactory, + wasm: WASM_PATH, + }); + + // Save the actor and canister ID for use in tests + actor = fixture.actor; + canisterId = fixture.canisterId; + }); + + // The `afterEach` hook runs after each test. + // + // This should be replaced with an `afterAll` hook if you use + // a `beforeAll` hook instead of a `beforeEach` hook. + afterEach(async () => { + // tear down the PocketIC instance + await pic.tearDown(); + }); + + // The `it` function is used to define individual tests + it('should do something cool', async () => { + const response = await actor.do_something_cool(); + + expect(response).toEqual('cool'); + }); +}); +``` + +You can check out the official [Vitest documentation](https://vitest.dev/) for more information writing tests. diff --git a/docs/docs/guides/02-using-bun.md b/docs/docs/guides/04-using-bun.md similarity index 66% rename from docs/docs/guides/02-using-bun.md rename to docs/docs/guides/04-using-bun.md index c1b2f04..88d5c92 100644 --- a/docs/docs/guides/02-using-bun.md +++ b/docs/docs/guides/04-using-bun.md @@ -7,7 +7,7 @@ import TabItem from '@theme/TabItem'; ## Installing -Installing Bun is as simple as running: +Installing [Bun](https://bun.sh) is as simple as running: ```shell curl -fsSL https://bun.sh/install | bash @@ -17,16 +17,15 @@ You can also check out the official [Bun installation documentation](https://bun ## As a test runner -### TypeScript +### Installation -To get started with Bun as a test runner with TypeScript, install the `@types/bun` package using your preferred package manager: +To get started with [Bun](https://bun.sh) as a test runner, install the `@types/bun` package using your preferred package manager: ```shell npm i -D @types/bun ``` - @@ -50,9 +49,8 @@ To get started with Bun as a test runner with TypeScript, install the `@types/bu Create a `tsconfig.json` file: -```json +```json title="tsconfig.json" { - "include": ["./**/*.ts"], "compilerOptions": { // enable latest features "lib": ["ESNext"], @@ -77,13 +75,14 @@ Create a `tsconfig.json` file: // Some stricter flags "useUnknownInCatchVariables": true, "noPropertyAccessFromIndexSignature": true - } + }, + "include": ["./src/**/*.ts", "./global-setup.ts", "./types.d.ts"] } ``` Then, add a `test` script to your `package.json`: -```json +```json title="package.json" { "scripts": { "test": "tsc && bun test" @@ -93,29 +92,58 @@ Then, add a `test` script to your `package.json`: Running `tsc` is optional, but it is recommended to catch any TypeScript errors before running your tests. -And that's it! Bun will automatically detect the `tsconfig.json` file and use it to compile your TypeScript files. - You can also check out the official [Bun documentation for TypeScript](https://bun.sh/docs/typescript) for more information. -### JavaScript +### Global test setup -Add a `test` script to your `package.json`: +The PocketIC server needs to be started before running tests and stopped once they're finished running. This can be done by creating a `global-setup.ts` file in your project's root directory: -```json -{ - "scripts": { - "test": "bun test" +```ts title="global-setup.ts" +import { beforeAll, afterAll } from 'bun:test'; +import { PocketIcServer } from '@hadronous/pic'; + +let pic: PocketIcServer | undefined; + +beforeAll(async () => { + pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + process.env.PIC_URL = url; +}); + +afterAll(async () => { + await pic?.stop(); +}); +``` + +This file can be configured to run with `bun test` by creating a `bunfig.toml` file in your project's root directory: + +```toml title="bunfig.toml" +[test] +preload = ["./global-setup.ts"] +``` + +To improve the type-safety of using `process.env.PIC_URL`, add a `types.d.ts` file in your project's root directory: + +```ts title="types.d.ts" +declare global { + namespace NodeJS { + interface ProcessEnv { + PIC_URL: string; + } } } + +export {}; ``` ### Writing tests -Bun tests are very similar to tests written with [Jest](https://jestjs.io), [Jasmine](https://jasmine.github.io), or [Vitest](https://vitest.dev) so they will feel very familiar to developers who have used these frameworks before. +[Bun](https://bun.sh) tests are very similar to tests written with [Jest](https://jestjs.io), [Jasmine](https://jasmine.github.io), or [Vitest](https://vitest.dev) so they will feel very familiar to developers who have used these frameworks before. -The basic skeleton of all PicJS tests written with Bun will look something like this: +The basic skeleton of all PicJS tests written with [Bun](https://bun.sh) will look something like this: -```typescript +```ts title="tests/example.spec.ts" // Import Bun testing globals import { beforeEach, describe, expect, it } from 'bun:test'; @@ -148,7 +176,7 @@ describe('Test suite name', () => { // state between tests. beforeEach(async () => { // create a new PocketIC instance - pic = await PocketIc.create(); + pic = await PocketIc.create(process.env.PIC_URL); // Setup the canister and actor const fixture = await pic.setupCanister<_SERVICE>({ @@ -161,6 +189,15 @@ describe('Test suite name', () => { canisterId = fixture.canisterId; }); + // The `afterEach` hook runs after each test. + // + // This should be replaced with an `afterAll` hook if you use + // a `beforeAll` hook instead of a `beforeEach` hook. + afterEach(async () => { + // tear down the PocketIC instance + await pic.tearDown(); + }); + // The `it` function is used to define individual tests it('should do something cool', async () => { const response = await actor.do_something_cool(); @@ -176,7 +213,7 @@ You can also check out the official [Bun test runner documentation](https://bun. PicJS leverages a [`postinstall`](https://docs.npmjs.com/cli/v9/using-npm/scripts#npm-install) script to download the `pocket-ic` binary. This is done to avoid bundling the binary with the library. If you are using [bun](https://bun.sh) to manage your project's dependencies, then you will need to add `@hadronous/pic` as a [trusted dependency](https://bun.sh/docs/install/lifecycle#trusteddependencies) in your `package.json`: -```json +```json title="package.json" { "trustedDependencies": ["@hadronous/pic"] } diff --git a/docs/docs/guides/04-working-with-the-nns.md b/docs/docs/guides/05-working-with-the-nns.md similarity index 98% rename from docs/docs/guides/04-working-with-the-nns.md rename to docs/docs/guides/05-working-with-the-nns.md index 267cd30..1f80768 100644 --- a/docs/docs/guides/04-working-with-the-nns.md +++ b/docs/docs/guides/05-working-with-the-nns.md @@ -20,7 +20,7 @@ cd nns_state Add a local system network to the `dfx.json` file. This will create the appropriate network configuration for the NNS without affecting any other projects that are running on DFX: -```json +```json title="dfx.json" { // redacted... "networks": { @@ -170,7 +170,7 @@ tar -xvf path/to/tests/state/nns_state.tar.gz -C path/to/tests/state This could be done with an `npm` `postinstall` script, by adding the following to your `package.json`: -```json +```json title="package.json" { // redacted... "scripts": { @@ -185,14 +185,14 @@ This could be done with an `npm` `postinstall` script, by adding the following t You'll need the subnet Id that you recored earlier: -```typescript +```ts const NNS_SUBNET_ID = 'nt6ha-vabpm-j6nog-bkr62-vbgbt-swwzc-u54zn-odtoy-igwlu-ab7uj-4qe'; ``` And you'll need to reference the path to the NNS state: -```typescript +```ts const NNS_STATE_PATH = resolve( __dirname, '..', @@ -205,7 +205,7 @@ const NNS_STATE_PATH = resolve( Now you can setup your PocketIC instance to use the NNS state: -```typescript +```ts const pic = await PocketIc.create({ nns: { fromPath: NNS_STATE_PATH, @@ -216,7 +216,7 @@ const pic = await PocketIc.create({ After creating the instance, make sure to set the PocketIc time to be the same or greater than the time that you created the NNS state: -```typescript +```ts await pic.setTime(new Date(2024, 1, 30).getTime()); await pic.tick(); ``` diff --git a/docs/docs/guides/03-canister-declarations.md b/docs/docs/guides/06-canister-declarations.md similarity index 100% rename from docs/docs/guides/03-canister-declarations.md rename to docs/docs/guides/06-canister-declarations.md diff --git a/examples/clock/tests/global-setup.ts b/examples/clock/tests/global-setup.ts new file mode 100644 index 0000000..2781a92 --- /dev/null +++ b/examples/clock/tests/global-setup.ts @@ -0,0 +1,9 @@ +import { PocketIcServer } from '@hadronous/pic'; + +module.exports = async function (): Promise { + const pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + process.env.PIC_URL = url; + global.__PIC__ = pic; +}; diff --git a/examples/clock/tests/global-teardown.ts b/examples/clock/tests/global-teardown.ts new file mode 100644 index 0000000..487cdff --- /dev/null +++ b/examples/clock/tests/global-teardown.ts @@ -0,0 +1,3 @@ +module.exports = async function () { + await global.__PIC__.stop(); +}; diff --git a/examples/clock/tests/jest.config.ts b/examples/clock/tests/jest.config.ts index ba9ef6a..57850cf 100644 --- a/examples/clock/tests/jest.config.ts +++ b/examples/clock/tests/jest.config.ts @@ -4,6 +4,8 @@ const config: Config = { watch: false, preset: 'ts-jest/presets/js-with-ts', testEnvironment: 'node', + globalSetup: '/global-setup.ts', + globalTeardown: '/global-teardown.ts', }; export default config; diff --git a/examples/clock/tests/src/clock.spec.ts b/examples/clock/tests/src/clock.spec.ts index aede16c..853609b 100644 --- a/examples/clock/tests/src/clock.spec.ts +++ b/examples/clock/tests/src/clock.spec.ts @@ -1,6 +1,7 @@ import { resolve } from 'node:path'; import { Principal } from '@dfinity/principal'; import { Actor, PocketIc } from '@hadronous/pic'; + import { _SERVICE, idlFactory } from '../../declarations/clock.did'; const WASM_PATH = resolve( @@ -22,7 +23,7 @@ describe('Clock', () => { let canisterId: Principal; beforeEach(async () => { - pic = await PocketIc.create(); + pic = await PocketIc.create(process.env.PIC_URL); const fixture = await pic.setupCanister<_SERVICE>({ idlFactory: idlFactory, wasm: WASM_PATH, diff --git a/examples/clock/tests/tsconfig.json b/examples/clock/tests/tsconfig.json index e85fbe5..b09bcf8 100644 --- a/examples/clock/tests/tsconfig.json +++ b/examples/clock/tests/tsconfig.json @@ -4,5 +4,10 @@ "allowJs": true, "types": ["jest", "node"] }, - "include": ["./src/**/*.ts"] + "include": [ + "./src/**/*.ts", + "./global-setup.ts", + "./global-teardown.ts", + "./types.d.ts" + ] } diff --git a/examples/clock/tests/types.d.ts b/examples/clock/tests/types.d.ts new file mode 100644 index 0000000..b8adfa6 --- /dev/null +++ b/examples/clock/tests/types.d.ts @@ -0,0 +1,11 @@ +import { PocketIcServer } from '@hadronous/pic'; + +declare global { + declare var __PIC__: PocketIcServer; + + namespace NodeJS { + interface ProcessEnv { + PIC_URL: string; + } + } +} diff --git a/examples/counter/tests/global-setup.ts b/examples/counter/tests/global-setup.ts new file mode 100644 index 0000000..6b6744d --- /dev/null +++ b/examples/counter/tests/global-setup.ts @@ -0,0 +1,15 @@ +import type { GlobalSetupContext } from 'vitest/node'; +import { PocketIcServer } from '@hadronous/pic'; + +let pic: PocketIcServer | undefined; + +export async function setup(ctx: GlobalSetupContext): Promise { + pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + ctx.provide('PIC_URL', url); +} + +export async function teardown(): Promise { + await pic?.stop(); +} diff --git a/examples/counter/tests/jest.config.ts b/examples/counter/tests/jest.config.ts deleted file mode 100644 index ba9ef6a..0000000 --- a/examples/counter/tests/jest.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type { Config } from 'jest'; - -const config: Config = { - watch: false, - preset: 'ts-jest/presets/js-with-ts', - testEnvironment: 'node', -}; - -export default config; diff --git a/examples/counter/tests/package.json b/examples/counter/tests/package.json index 6c5f97a..bb68043 100644 --- a/examples/counter/tests/package.json +++ b/examples/counter/tests/package.json @@ -1,5 +1,6 @@ { "name": "counter-tests", + "type": "module", "devDependencies": { "@hadronous/pic": "workspace:*" } diff --git a/examples/counter/tests/src/counter.spec.ts b/examples/counter/tests/src/counter.spec.ts index 94f284f..e42a838 100644 --- a/examples/counter/tests/src/counter.spec.ts +++ b/examples/counter/tests/src/counter.spec.ts @@ -2,7 +2,9 @@ import { resolve } from 'node:path'; import { Principal } from '@dfinity/principal'; import { Actor, PocketIc } from '@hadronous/pic'; import { IDL } from '@dfinity/candid'; -import { _SERVICE, idlFactory, init } from '../../declarations/counter.did'; +import { describe, beforeEach, afterEach, it, expect, inject } from 'vitest'; + +import { _SERVICE, idlFactory, init } from '../../declarations/counter.did.js'; const WASM_PATH = resolve( __dirname, @@ -25,7 +27,7 @@ describe('Counter', () => { const countInitArg = 1n; beforeEach(async () => { - pic = await PocketIc.create(); + pic = await PocketIc.create(inject('PIC_URL')); const fixture = await pic.setupCanister<_SERVICE>({ idlFactory, wasm: WASM_PATH, diff --git a/examples/counter/tests/tsconfig.json b/examples/counter/tests/tsconfig.json index e85fbe5..29957a5 100644 --- a/examples/counter/tests/tsconfig.json +++ b/examples/counter/tests/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../../tsconfig.json", "compilerOptions": { "allowJs": true, - "types": ["jest", "node"] + "types": ["node"] }, - "include": ["./src/**/*.ts"] + "include": ["./src/**/*.ts", "./global-setup.ts", "types.d.ts"] } diff --git a/examples/counter/tests/types.d.ts b/examples/counter/tests/types.d.ts new file mode 100644 index 0000000..8b8ef52 --- /dev/null +++ b/examples/counter/tests/types.d.ts @@ -0,0 +1,5 @@ +export declare module 'vitest' { + export interface ProvidedContext { + PIC_URL: string; + } +} diff --git a/examples/counter/tests/vitest.config.ts b/examples/counter/tests/vitest.config.ts new file mode 100644 index 0000000..5611772 --- /dev/null +++ b/examples/counter/tests/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + root: 'examples/counter/tests', + globalSetup: './global-setup.ts', + }, +}); diff --git a/examples/multicanister/tests/global-setup.ts b/examples/multicanister/tests/global-setup.ts new file mode 100644 index 0000000..2781a92 --- /dev/null +++ b/examples/multicanister/tests/global-setup.ts @@ -0,0 +1,9 @@ +import { PocketIcServer } from '@hadronous/pic'; + +module.exports = async function (): Promise { + const pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + process.env.PIC_URL = url; + global.__PIC__ = pic; +}; diff --git a/examples/multicanister/tests/global-teardown.ts b/examples/multicanister/tests/global-teardown.ts new file mode 100644 index 0000000..487cdff --- /dev/null +++ b/examples/multicanister/tests/global-teardown.ts @@ -0,0 +1,3 @@ +module.exports = async function () { + await global.__PIC__.stop(); +}; diff --git a/examples/multicanister/tests/jest.config.ts b/examples/multicanister/tests/jest.config.ts index ba9ef6a..57850cf 100644 --- a/examples/multicanister/tests/jest.config.ts +++ b/examples/multicanister/tests/jest.config.ts @@ -4,6 +4,8 @@ const config: Config = { watch: false, preset: 'ts-jest/presets/js-with-ts', testEnvironment: 'node', + globalSetup: '/global-setup.ts', + globalTeardown: '/global-teardown.ts', }; export default config; diff --git a/examples/multicanister/tests/src/multicanister.spec.ts b/examples/multicanister/tests/src/multicanister.spec.ts index bdd4562..1385485 100644 --- a/examples/multicanister/tests/src/multicanister.spec.ts +++ b/examples/multicanister/tests/src/multicanister.spec.ts @@ -1,5 +1,7 @@ import { resolve } from 'path'; import { Actor, PocketIc } from '@hadronous/pic'; +import { IDL } from '@dfinity/candid'; + import { PhoneBookEntry, SuperHero, @@ -7,7 +9,6 @@ import { idlFactory, init, } from '../../declarations/multicanister/multicanister.did'; -import { IDL } from '@dfinity/candid'; const MAIN_WASM_PATH = resolve( __dirname, @@ -53,7 +54,7 @@ describe('Multicanister', () => { let actor: Actor<_SERVICE>; beforeEach(async () => { - pic = await PocketIc.create({ application: 2 }); + pic = await PocketIc.create(process.env.PIC_URL, { application: 2 }); const applicationSubnets = pic.getApplicationSubnets(); const mainSubnet = applicationSubnets[0]; diff --git a/examples/multicanister/tests/tsconfig.json b/examples/multicanister/tests/tsconfig.json index e85fbe5..b09bcf8 100644 --- a/examples/multicanister/tests/tsconfig.json +++ b/examples/multicanister/tests/tsconfig.json @@ -4,5 +4,10 @@ "allowJs": true, "types": ["jest", "node"] }, - "include": ["./src/**/*.ts"] + "include": [ + "./src/**/*.ts", + "./global-setup.ts", + "./global-teardown.ts", + "./types.d.ts" + ] } diff --git a/examples/multicanister/tests/types.d.ts b/examples/multicanister/tests/types.d.ts new file mode 100644 index 0000000..b8adfa6 --- /dev/null +++ b/examples/multicanister/tests/types.d.ts @@ -0,0 +1,11 @@ +import { PocketIcServer } from '@hadronous/pic'; + +declare global { + declare var __PIC__: PocketIcServer; + + namespace NodeJS { + interface ProcessEnv { + PIC_URL: string; + } + } +} diff --git a/examples/nns_proxy/tests/global-setup.ts b/examples/nns_proxy/tests/global-setup.ts new file mode 100644 index 0000000..2781a92 --- /dev/null +++ b/examples/nns_proxy/tests/global-setup.ts @@ -0,0 +1,9 @@ +import { PocketIcServer } from '@hadronous/pic'; + +module.exports = async function (): Promise { + const pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + process.env.PIC_URL = url; + global.__PIC__ = pic; +}; diff --git a/examples/nns_proxy/tests/global-teardown.ts b/examples/nns_proxy/tests/global-teardown.ts new file mode 100644 index 0000000..487cdff --- /dev/null +++ b/examples/nns_proxy/tests/global-teardown.ts @@ -0,0 +1,3 @@ +module.exports = async function () { + await global.__PIC__.stop(); +}; diff --git a/examples/nns_proxy/tests/jest.config.ts b/examples/nns_proxy/tests/jest.config.ts index ba9ef6a..57850cf 100644 --- a/examples/nns_proxy/tests/jest.config.ts +++ b/examples/nns_proxy/tests/jest.config.ts @@ -4,6 +4,8 @@ const config: Config = { watch: false, preset: 'ts-jest/presets/js-with-ts', testEnvironment: 'node', + globalSetup: '/global-setup.ts', + globalTeardown: '/global-teardown.ts', }; export default config; diff --git a/examples/nns_proxy/tests/src/nns-proxy.spec.ts b/examples/nns_proxy/tests/src/nns-proxy.spec.ts index 434d137..709dfc3 100644 --- a/examples/nns_proxy/tests/src/nns-proxy.spec.ts +++ b/examples/nns_proxy/tests/src/nns-proxy.spec.ts @@ -38,7 +38,7 @@ describe('NNS Proxy', () => { const proposerIdentity = generateRandomIdentity(); beforeEach(async () => { - pic = await PocketIc.create({ + pic = await PocketIc.create(process.env.PIC_URL, { nns: { fromPath: NNS_STATE_PATH, subnetId: Principal.fromText(NNS_SUBNET_ID), diff --git a/examples/nns_proxy/tests/tsconfig.json b/examples/nns_proxy/tests/tsconfig.json index e85fbe5..b09bcf8 100644 --- a/examples/nns_proxy/tests/tsconfig.json +++ b/examples/nns_proxy/tests/tsconfig.json @@ -4,5 +4,10 @@ "allowJs": true, "types": ["jest", "node"] }, - "include": ["./src/**/*.ts"] + "include": [ + "./src/**/*.ts", + "./global-setup.ts", + "./global-teardown.ts", + "./types.d.ts" + ] } diff --git a/examples/nns_proxy/tests/types.d.ts b/examples/nns_proxy/tests/types.d.ts new file mode 100644 index 0000000..b8adfa6 --- /dev/null +++ b/examples/nns_proxy/tests/types.d.ts @@ -0,0 +1,11 @@ +import { PocketIcServer } from '@hadronous/pic'; + +declare global { + declare var __PIC__: PocketIcServer; + + namespace NodeJS { + interface ProcessEnv { + PIC_URL: string; + } + } +} diff --git a/examples/todo/tests/global-setup.ts b/examples/todo/tests/global-setup.ts new file mode 100644 index 0000000..2781a92 --- /dev/null +++ b/examples/todo/tests/global-setup.ts @@ -0,0 +1,9 @@ +import { PocketIcServer } from '@hadronous/pic'; + +module.exports = async function (): Promise { + const pic = await PocketIcServer.start(); + const url = pic.getUrl(); + + process.env.PIC_URL = url; + global.__PIC__ = pic; +}; diff --git a/examples/todo/tests/global-teardown.ts b/examples/todo/tests/global-teardown.ts new file mode 100644 index 0000000..487cdff --- /dev/null +++ b/examples/todo/tests/global-teardown.ts @@ -0,0 +1,3 @@ +module.exports = async function () { + await global.__PIC__.stop(); +}; diff --git a/examples/todo/tests/jest.config.ts b/examples/todo/tests/jest.config.ts index ba9ef6a..57850cf 100644 --- a/examples/todo/tests/jest.config.ts +++ b/examples/todo/tests/jest.config.ts @@ -4,6 +4,8 @@ const config: Config = { watch: false, preset: 'ts-jest/presets/js-with-ts', testEnvironment: 'node', + globalSetup: '/global-setup.ts', + globalTeardown: '/global-teardown.ts', }; export default config; diff --git a/examples/todo/tests/src/todo.spec.ts b/examples/todo/tests/src/todo.spec.ts index 40bcf80..4c34def 100644 --- a/examples/todo/tests/src/todo.spec.ts +++ b/examples/todo/tests/src/todo.spec.ts @@ -26,7 +26,7 @@ describe('Todo', () => { const bob = createIdentity('superSecretBobPassword'); beforeEach(async () => { - pic = await PocketIc.create(); + pic = await PocketIc.create(process.env.PIC_URL); const fixture = await pic.setupCanister<_SERVICE>({ idlFactory, wasm: WASM_PATH, diff --git a/examples/todo/tests/tsconfig.json b/examples/todo/tests/tsconfig.json index e85fbe5..b09bcf8 100644 --- a/examples/todo/tests/tsconfig.json +++ b/examples/todo/tests/tsconfig.json @@ -4,5 +4,10 @@ "allowJs": true, "types": ["jest", "node"] }, - "include": ["./src/**/*.ts"] + "include": [ + "./src/**/*.ts", + "./global-setup.ts", + "./global-teardown.ts", + "./types.d.ts" + ] } diff --git a/examples/todo/tests/types.d.ts b/examples/todo/tests/types.d.ts new file mode 100644 index 0000000..b8adfa6 --- /dev/null +++ b/examples/todo/tests/types.d.ts @@ -0,0 +1,11 @@ +import { PocketIcServer } from '@hadronous/pic'; + +declare global { + declare var __PIC__: PocketIcServer; + + namespace NodeJS { + interface ProcessEnv { + PIC_URL: string; + } + } +} diff --git a/package.json b/package.json index 67002e9..7fa46ed 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "build:examples": "dfx generate phonebook && dfx generate superheroes && dfx generate && dfx build --all --check", "test:examples": "run-p test:counter test:clock test:todo test:multicanister test:nns-proxy", "build:counter": "dfx generate counter && dfx build counter --check", - "test:counter": "jest -c ./examples/counter/tests/jest.config.ts", + "test:counter": "vitest run -c ./examples/counter/tests/vitest.config.ts", "build:clock": "dfx generate clock && dfx build clock --check", "test:clock": "jest -c ./examples/clock/tests/jest.config.ts", "build:todo": "dfx generate todo && dfx build todo --check", @@ -40,6 +40,7 @@ "prettier": "3.1.0", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", - "typescript": "^5.3.3" + "typescript": "^5.3.3", + "vitest": "^1.5.0" } } diff --git a/packages/pic/src/index.ts b/packages/pic/src/index.ts index 46e7f61..8d369f6 100644 --- a/packages/pic/src/index.ts +++ b/packages/pic/src/index.ts @@ -10,3 +10,4 @@ export type { SetupCanisterOptions, UpgradeCanisterOptions, } from './pocket-ic-types'; +export { PocketIcServer } from './pocket-ic-server'; diff --git a/packages/pic/src/pocket-ic-server.ts b/packages/pic/src/pocket-ic-server.ts index 451d27e..e7a4268 100644 --- a/packages/pic/src/pocket-ic-server.ts +++ b/packages/pic/src/pocket-ic-server.ts @@ -65,8 +65,18 @@ export class PocketIcServer { return this.url; } - public stop(): void { - this.serverProcess.unref(); + public async stop(): Promise { + return new Promise((resolve, reject) => { + this.serverProcess.on('exit', () => { + resolve(); + }); + + this.serverProcess.on('error', error => { + reject(error); + }); + + this.serverProcess.kill(); + }); } private static getBinPath(): string { diff --git a/packages/pic/src/pocket-ic.ts b/packages/pic/src/pocket-ic.ts index 9eb20cd..e5e67cc 100644 --- a/packages/pic/src/pocket-ic.ts +++ b/packages/pic/src/pocket-ic.ts @@ -1,7 +1,6 @@ import { Principal } from '@dfinity/principal'; import { IDL } from '@dfinity/candid'; import { optional, readFileAsBytes } from './util'; -import { PocketIcServer } from './pocket-ic-server'; import { PocketIcClient } from './pocket-ic-client'; import { ActorInterface, Actor, createActorClass } from './pocket-ic-actor'; import { @@ -71,14 +70,12 @@ import { * ``` */ export class PocketIc { - private constructor( - private readonly client: PocketIcClient, - private readonly server?: PocketIcServer, - ) {} + private constructor(private readonly client: PocketIcClient) {} /** - * Starts the PocketIC server and creates a PocketIC instance. + * Creates a PocketIC instance. * + * @param url The URL of an existing PocketIC server to connect to. * @param options Options for creating the PocketIC instance see {@link CreateInstanceOptions}. * @returns A new PocketIC instance. * @@ -86,33 +83,11 @@ export class PocketIc { * ```ts * import { PocketIc } from '@hadronous/pic'; * + * const url = 'http://localhost:8080'; * const pic = await PocketIc.create(); * ``` */ public static async create( - options?: CreateInstanceOptions, - ): Promise { - const server = await PocketIcServer.start(); - const client = await PocketIcClient.create(server.getUrl(), options); - - return new PocketIc(client, server); - } - - /** - * Creates a PocketIC instance that connects to an existing PocketIC server. - * - * @param url The URL of an existing PocketIC server to connect to. - * @returns A new PocketIC instance. - * - * @example - * ```ts - * import { PocketIc } from '@hadronous/pic'; - * - * const url = 'http://localhost:8080'; - * const pic = await PocketIc.createFromUrl(url); - * ``` - */ - public static async createFromUrl( url: string, options?: CreateInstanceOptions, ): Promise { @@ -663,7 +638,7 @@ export class PocketIc { } /** - * Deletes the PocketIC instance and disconnects from the server. + * Deletes the PocketIC instance. * * @example * ```ts @@ -675,7 +650,6 @@ export class PocketIc { */ public async tearDown(): Promise { await this.client.deleteInstance(); - this.server?.stop(); } /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ffb1e6..05ca39d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: typescript: specifier: ^5.3.3 version: 5.3.3 + vitest: + specifier: ^1.5.0 + version: 1.5.0(@types/node@20.11.5) docs: dependencies: @@ -2442,6 +2445,213 @@ packages: - webpack-cli dev: false + /@esbuild/aix-ppc64@0.20.2: + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.20.2: + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.20.2: + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.20.2: + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.20.2: + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.20.2: + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.20.2: + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.20.2: + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.20.2: + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.20.2: + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.20.2: + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.20.2: + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.20.2: + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.20.2: + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.20.2: + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.20.2: + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.20.2: + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.20.2: + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.20.2: + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.20.2: + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.20.2: + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.20.2: + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.20.2: + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@hapi/hoek@9.3.0: resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -2839,6 +3049,134 @@ packages: resolution: {integrity: sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==} dev: false + /@rollup/rollup-android-arm-eabi@4.15.0: + resolution: {integrity: sha512-O63bJ7p909pRRQfOJ0k/Jp8gNFMud+ZzLLG5EBWquylHxmRT2k18M2ifg8WyjCgFVdpA7+rI0YZ8EkAtg6dSUw==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.15.0: + resolution: {integrity: sha512-5UywPdmC9jiVOShjQx4uuIcnTQOf85iA4jgg8bkFoH5NYWFfAfrJpv5eeokmTdSmYwUTT5IrcrBCJNkowhrZDA==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.15.0: + resolution: {integrity: sha512-hNkt75uFfWpRxHItCBmbS0ba70WnibJh6yz60WShSWITLlVRbkvAu1E/c7RlliPY4ajhqJd0UPZz//gNalTd4g==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.15.0: + resolution: {integrity: sha512-HnC5bTP7qdfO9nUw/mBhNcjOEZfbS8NwV+nFegiMhYOn1ATAGZF4kfAxR9BuZevBrebWCxMmxm8NCU1CUoz+wQ==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.15.0: + resolution: {integrity: sha512-QGOIQIJZeIIqMsc4BUGe8TnV4dkXhSW2EhaQ1G4LqMUNpkyeLztvlDlOoNHn7SR7a4dBANdcEbPkkEzz3rzjzA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-musleabihf@4.15.0: + resolution: {integrity: sha512-PS/Cp8CinYgoysQ8i4UXYH/TZl06fXszvY/RDkyBYgUB1+tKyOMS925/4FZhfrhkl3XQEKjMc3BKtsxpB9Tz9Q==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.15.0: + resolution: {integrity: sha512-XzOsnD6lGDP+k+vGgTYAryVGu8N89qpjMN5BVFUj75dGVFP3FzIVAufJAraxirpDwEQZA7Gjs0Vo5p4UmnnjsA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.15.0: + resolution: {integrity: sha512-+ScJA4Epbx/ZQGjDnbvTAcb8ZD06b+TlIka2UkujbKf1I/A+yrvEcJwG3/27zMmvcWMQyeCJhbL9TlSjzL0B7Q==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-powerpc64le-gnu@4.15.0: + resolution: {integrity: sha512-1cUSvYgnyTakM4FDyf/GxUCDcqmj/hUh1NOizEOJU7+D5xEfFGCxgcNOs3hYBeRMUCcGmGkt01EhD3ILgKpGHQ==} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.15.0: + resolution: {integrity: sha512-3A1FbHDbBUvpJXFAZwVsiROIcstVHP9AX/cwnyIhAp+xyQ1cBCxywKtuzmw0Av1MDNNg/y/9dDHtNypfRa8bdw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-s390x-gnu@4.15.0: + resolution: {integrity: sha512-hYPbhg9ow6/mXIkojc8LOeiip2sCTuw1taWyoOXTOWk9vawIXz8x7B4KkgWUAtvAElssxhSyEXr2EZycH/FGzQ==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.15.0: + resolution: {integrity: sha512-511qln5mPSUKwv7HI28S1jCD1FK+2WbX5THM9A9annr3c1kzmfnf8Oe3ZakubEjob3IV6OPnNNcesfy+adIrmw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.15.0: + resolution: {integrity: sha512-4qKKGTDIv2bQZ+afhPWqPL+94+dLtk4lw1iwbcylKlLNqQ/Yyjof2CFYBxf6npiDzPV+zf4EWRiHb26/4Vsm9w==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.15.0: + resolution: {integrity: sha512-nEtaFBHp1OnbOf+tz66DtID579sNRHGgMC23to8HUyVuOCpCMD0CvRNqiDGLErLNnwApWIUtUl1VvuovCWUxwg==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.15.0: + resolution: {integrity: sha512-5O49NykwSgX6iT2HgZ6cAoGHt6T/FqNMB5OqFOGxU/y1GyFSHquox1sK2OqApQc0ANxiHFQEMNDLNVCL7AUDnQ==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.15.0: + resolution: {integrity: sha512-YA0hTwCunmKNeTOFWdJuKhdXse9jBqgo34FDo+9aS0spfCkp+wj0o1bCcOOTu+0P48O95GTfkLTAaVonwNuIdQ==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@sideway/address@4.1.5: resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} dependencies: @@ -3392,6 +3730,45 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: false + /@vitest/expect@1.5.0: + resolution: {integrity: sha512-0pzuCI6KYi2SIC3LQezmxujU9RK/vwC1U9R0rLuGlNGcOuDWxqWKu6nUdFsX9tH1WU0SXtAxToOsEjeUn1s3hA==} + dependencies: + '@vitest/spy': 1.5.0 + '@vitest/utils': 1.5.0 + chai: 4.4.1 + dev: true + + /@vitest/runner@1.5.0: + resolution: {integrity: sha512-7HWwdxXP5yDoe7DTpbif9l6ZmDwCzcSIK38kTSIt6CFEpMjX4EpCgT6wUmS0xTXqMI6E/ONmfgRKmaujpabjZQ==} + dependencies: + '@vitest/utils': 1.5.0 + p-limit: 5.0.0 + pathe: 1.1.2 + dev: true + + /@vitest/snapshot@1.5.0: + resolution: {integrity: sha512-qpv3fSEuNrhAO3FpH6YYRdaECnnRjg9VxbhdtPwPRnzSfHVXnNzzrpX4cJxqiwgRMo7uRMWDFBlsBq4Cr+rO3A==} + dependencies: + magic-string: 0.30.10 + pathe: 1.1.2 + pretty-format: 29.7.0 + dev: true + + /@vitest/spy@1.5.0: + resolution: {integrity: sha512-vu6vi6ew5N5MMHJjD5PoakMRKYdmIrNJmyfkhRpQt5d9Ewhw9nZ5Aqynbi3N61bvk9UvZ5UysMT6ayIrZ8GA9w==} + dependencies: + tinyspy: 2.2.1 + dev: true + + /@vitest/utils@1.5.0: + resolution: {integrity: sha512-BDU0GNL8MWkRkSRdNFvCUCAVOeHaUlVJ9Tx0TYBZyXaaOTmGtUFObzchCivIBrIwKzvZA7A9sCejVhXM2aY98A==} + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + dev: true + /@webassemblyjs/ast@1.11.6: resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} dependencies: @@ -3721,6 +4098,10 @@ packages: pvutils: 1.1.3 tslib: 2.6.2 + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + /astring@1.8.6: resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} hasBin: true @@ -4051,6 +4432,11 @@ packages: engines: {node: '>= 0.8'} dev: false + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + /cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} @@ -4117,6 +4503,19 @@ packages: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} dev: false + /chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -4157,6 +4556,12 @@ packages: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} dev: false + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + /cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} dependencies: @@ -4354,6 +4759,10 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + /confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + dev: true + /config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} dependencies: @@ -4775,6 +5184,13 @@ packages: optional: true dev: true + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -5124,6 +5540,37 @@ packages: is-symbol: 1.0.4 dev: true + /esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + dev: true + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -5228,7 +5675,6 @@ packages: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: '@types/estree': 1.0.5 - dev: false /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} @@ -5275,6 +5721,21 @@ packages: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + /exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} @@ -5606,6 +6067,10 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + dev: true + /get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: @@ -5627,6 +6092,11 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -6118,6 +6588,11 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -6460,6 +6935,11 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -7019,6 +7499,10 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + /js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + dev: true + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -7151,6 +7635,14 @@ packages: engines: {node: '>= 12.13.0'} dev: false + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + dependencies: + mlly: 1.6.1 + pkg-types: 1.1.0 + dev: true + /locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} @@ -7205,6 +7697,12 @@ packages: dependencies: js-tokens: 4.0.0 + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + dependencies: + get-func-name: 2.0.2 + dev: true + /lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} dependencies: @@ -7231,6 +7729,12 @@ packages: resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} dev: true + /magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} @@ -7940,6 +8444,11 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -7981,6 +8490,15 @@ packages: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: false + /mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.0 + ufo: 1.5.3 + dev: true + /mrmime@2.0.0: resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} engines: {node: '>=10'} @@ -8009,7 +8527,6 @@ packages: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: false /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -8106,6 +8623,13 @@ packages: dependencies: path-key: 3.1.1 + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + /nprogress@0.2.0: resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} dev: false @@ -8163,6 +8687,13 @@ packages: dependencies: mimic-fn: 2.1.0 + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + /open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -8201,6 +8732,13 @@ packages: yocto-queue: 1.0.0 dev: false + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + dependencies: + yocto-queue: 1.0.0 + dev: true + /p-locate@3.0.0: resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} engines: {node: '>=6'} @@ -8362,6 +8900,11 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -8391,6 +8934,14 @@ packages: engines: {node: '>=8'} dev: false + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + /periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} dependencies: @@ -8436,6 +8987,14 @@ packages: find-up: 6.3.0 dev: false + /pkg-types@1.1.0: + resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} + dependencies: + confbox: 0.1.7 + mlly: 1.6.1 + pathe: 1.1.2 + dev: true + /pkg-up@3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} @@ -8853,6 +9412,15 @@ packages: source-map-js: 1.0.2 dev: false + /postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + dev: true + /prettier@3.1.0: resolution: {integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==} engines: {node: '>=14'} @@ -9478,6 +10046,32 @@ packages: glob: 7.2.3 dev: false + /rollup@4.15.0: + resolution: {integrity: sha512-i0ir57IMF5o7YvNYyUNeIGG+IZaaucnGZAOsSctO2tPLXlCEaZzyBa+QhpHNSgtpyLMoDev2DyN6a7J1dQA8Tw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.15.0 + '@rollup/rollup-android-arm64': 4.15.0 + '@rollup/rollup-darwin-arm64': 4.15.0 + '@rollup/rollup-darwin-x64': 4.15.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.15.0 + '@rollup/rollup-linux-arm-musleabihf': 4.15.0 + '@rollup/rollup-linux-arm64-gnu': 4.15.0 + '@rollup/rollup-linux-arm64-musl': 4.15.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.15.0 + '@rollup/rollup-linux-riscv64-gnu': 4.15.0 + '@rollup/rollup-linux-s390x-gnu': 4.15.0 + '@rollup/rollup-linux-x64-gnu': 4.15.0 + '@rollup/rollup-linux-x64-musl': 4.15.0 + '@rollup/rollup-win32-arm64-msvc': 4.15.0 + '@rollup/rollup-win32-ia32-msvc': 4.15.0 + '@rollup/rollup-win32-x64-msvc': 4.15.0 + fsevents: 2.3.3 + dev: true + /rtl-detect@1.1.2: resolution: {integrity: sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==} dev: false @@ -9764,9 +10358,18 @@ packages: get-intrinsic: 1.2.2 object-inspect: 1.13.1 + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + /simple-cbor@0.4.1: resolution: {integrity: sha512-rijcxtwx2b4Bje3sqeIqw5EeW7UlOIC4YfOdwqIKacpvRQ/D78bWg/4/0m5e0U91oKvlGh7LlJuZCu07ISCC7w==} @@ -9827,6 +10430,11 @@ packages: engines: {node: '>=0.10.0'} dev: false + /source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + dev: true + /source-map-support@0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} dependencies: @@ -9921,6 +10529,10 @@ packages: escape-string-regexp: 2.0.0 dev: true + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + /statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -9933,7 +10545,6 @@ packages: /std-env@3.7.0: resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - dev: false /string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} @@ -10053,6 +10664,11 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + dev: true + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} @@ -10062,6 +10678,12 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + /strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + dependencies: + js-tokens: 9.0.0 + dev: true + /style-to-object@0.4.4: resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} dependencies: @@ -10192,6 +10814,20 @@ packages: resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} dev: false + /tinybench@2.7.0: + resolution: {integrity: sha512-Qgayeb106x2o4hNzNjsZEfFziw8IbKqtbXBjVh7VIZfBxfD5M4gWtpyx5+YTae2gJ6Y6Dz/KLepiv16RFeQWNA==} + dev: true + + /tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + dev: true + /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} dev: true @@ -10391,6 +11027,10 @@ packages: engines: {node: '>=14.17'} hasBin: true + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + dev: true + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -10630,6 +11270,119 @@ packages: vfile-message: 4.0.2 dev: false + /vite-node@1.5.0(@types/node@20.11.5): + resolution: {integrity: sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.2.10(@types/node@20.11.5) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite@5.2.10(@types/node@20.11.5): + resolution: {integrity: sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.11.5 + esbuild: 0.20.2 + postcss: 8.4.38 + rollup: 4.15.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vitest@1.5.0(@types/node@20.11.5): + resolution: {integrity: sha512-d8UKgR0m2kjdxDWX6911uwxout6GHS0XaGH1cksSIVVG8kRlE7G7aBw7myKQCvDI5dT4j7ZMa+l706BIORMDLw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.5.0 + '@vitest/ui': 1.5.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/node': 20.11.5 + '@vitest/expect': 1.5.0 + '@vitest/runner': 1.5.0 + '@vitest/snapshot': 1.5.0 + '@vitest/spy': 1.5.0 + '@vitest/utils': 1.5.0 + acorn-walk: 8.3.2 + chai: 4.4.1 + debug: 4.3.4 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 + pathe: 1.1.2 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.7.0 + tinypool: 0.8.4 + vite: 5.2.10(@types/node@20.11.5) + vite-node: 1.5.0(@types/node@20.11.5) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vscode-oniguruma@1.7.0: resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} dev: true @@ -10870,6 +11623,15 @@ packages: dependencies: isexe: 2.0.0 + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + /widest-line@4.0.1: resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} engines: {node: '>=12'} @@ -11002,7 +11764,6 @@ packages: /yocto-queue@1.0.0: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} engines: {node: '>=12.20'} - dev: false /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}