diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..455f0ad --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# see http://editorconfig.org + +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +max_line_length = 110 +trim_trailing_whitespace = true +insert_final_newline = true + +[{*.json,*.yml}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..f51849f --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,38 @@ +name: Run tests & upload coverage + +on: + workflow_dispatch: + push: + pull_request: + +permissions: + contents: read + pull-requests: read + +jobs: + validate: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PNPM + uses: pnpm/action-setup@v4 + + - name: Setup node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "pnpm" + + - name: Install dependencies + run: pnpm install + + - name: Run Unit Tests & compute coverage + run: pnpm run validate + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.npmignore b/.npmignore index 113bc51..edb3948 100644 --- a/.npmignore +++ b/.npmignore @@ -1,7 +1,8 @@ node_modules coverage +.github src/__tests__ pnpm-lock.yaml tsconfig.json tsup.config.ts -vitest.config.ts \ No newline at end of file +vitest.config.ts diff --git a/README.md b/README.md index f3304a9..bd370a1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,12 @@

SuppleJS Testing Library

Simple and complete Solid DOM testing utilities that encourage good testing practices.

-> Inspired completely by [solid-testing-library](https://github.com/solidjs/solid-testing-library) +> Inspired completely by [solid-testing-library](https://github.com/solidjs/solid-testing-library) and [preact-testing-library](https://github.com/testing-library/preact-testing-library) + +[![NPM Version](https://img.shields.io/npm/v/supplejs-testing-library.svg)](https://www.npmjs.com/package/supplejs-testing-library) +[![GitHub License](https://img.shields.io/github/license/delph123/supplejs-testing-library)](https://github.com/delph123/supplejs-testing-library/blob/main/LICENSE) +[![Build Status](https://img.shields.io/github/actions/workflow/status/delph123/supplejs-testing-library/validate.yml?branch=main&logo=github)](https://github.com/delph123/supplejs-testing-library/actions/workflows/validate.yml) +[![codecov](https://codecov.io/gh/delph123/supplejs-testing-library/graph/badge.svg?token=AJNU0N5YI7)](https://codecov.io/gh/delph123/supplejs-testing-library) @@ -10,12 +15,12 @@ ## Table of Contents -- [The Problem](#the-problem) -- [The Solution](#the-solution) -- [Installation](#installation) -- [Docs](#docs) -- [Issues](#issues) -- [Acknowledgement](#acknowledgment) +- [The Problem](#the-problem) +- [The Solution](#the-solution) +- [Installation](#installation) +- [Docs](#docs) +- [Issues](#issues) +- [Acknowledgement](#acknowledgment) --- @@ -31,8 +36,7 @@ The Solid Testing Library is a very lightweight solution for testing Solid compo ## Installation -This module is distributed via npm which is bundled with node and should be installed -as one of your project's `devDependencies`: +This module is distributed via npm which is bundled with node and should be installed as one of your project's `devDependencies`: ```sh npm install --save-dev supplejs-testing-library @@ -43,23 +47,33 @@ npm install --save-dev supplejs-testing-library ## Integration with Vite -A working Vite template setup with `supplejs-testing-library` and TypeScript support can be found [here](https://github.com/solidjs/templates/tree/main/ts-vitest). +A working Vite template setup with `supplejs-testing-library` and TypeScript support can be found [here](https://github.com/delph123/supplejs-templates/tree/main/ts-vitest). ## Docs -See the [docs](https://testing-library.com/docs/preact-testing-library/intro) over at the Testing Library website. +See the [docs for `preact-testing-library`](https://testing-library.com/docs/preact-testing-library/intro) over at the Testing Library website. `supplejs-testing-library` is pretty similar. There are several key differences, though: +#### `render` + ⚠️ The `render` function takes in a function that returns a SuppleJS Component, rather than simply the component itself. ```tsx +// With @testing-library/preact +const results = render(, options); +``` + +```tsx +// With supplejs-testing-library const results = render(() => , options); ``` -⚠️ SuppleJS does _not_ re-render, it merely executes side effects triggered by reactive state that change the DOM, therefore there is no `rerender` method. You can use global signals to manipulate your test component in a way that causes it to update. +⚠️ SuppleJS does _not_ re-render, it merely executes side effects triggered by reactive states that change the DOM, therefore there is no `rerender` method. You can use global signals to manipulate your test component in a way that causes it to update. + +SuppleJS reactive changes are pretty instantaneous, so there is rarely need to use `waitFor(…)`, `await findByRole(…)` and other asynchronous queries to test the rendered result, except for suspense, resources, lazy loaded components, some effects (createEffect, createDeferred, onMount) and error boundaries. -SuppleJS reactive changes are pretty instantaneous, so there is rarely need to use `waitFor(…)`, `await findByRole(…)` and other asynchronous queries to test the rendered result, except for transitions, suspense, resources and effects. +#### `renderHook` ⚠️ SuppleJS external reactive state does not require any DOM elements to run in, so our `renderHook` call to test hooks in the context of a component (if your hook does not require the context of a component, `createRoot` should suffice to test the reactive behavior; for convenience, we also have `testEffect`, which is described later) has no `container`, `baseElement` or queries in its options or return value. Instead, it has an `owner` to be used with `runWithOwner` if required. It also exposes a `cleanup` function, though this is already automatically called after the test is finished. @@ -86,6 +100,8 @@ expect(result).toBe(true); If you are using a `wrapper` with `renderHook`, make sure it will **always** return `props.children` - especially if you are using a context with asynchronous code together with ``, because this is required to get the value from the hook and it is only obtained synchronously once and you will otherwise only get `undefined` and wonder why this is the case. +#### `testEffect` + SuppleJS manages side effects with different variants of `createEffect`. While you can use `waitFor` to test asynchronous effects, it uses polling instead of allowing Solid's reactivity to trigger the next step. In order to simplify testing those asynchronous effects, we have a `testEffect` helper that complements the hooks for directives and hooks: ```ts @@ -93,22 +109,46 @@ testEffect(fn: (done: (result: T) => void) => void, owner?: Owner): Promise // use it like this: test("testEffect allows testing an effect asynchronously", () => { - const [value, setValue] = createSignal(0); - return testEffect(done => createEffect((run: number = 0) => { - if (run === 0) { - expect(value()).toBe(0); - setValue(1); - } else if (run === 1) { - expect(value()).toBe(1); - done(); - } - return run + 1; - })); + const [v, setValue] = createSignal(0); + const value = createDeferred(v); + return testEffect((done) => + createEffect((run: number = 0) => { + if (run === 0) { + expect(value()).toBe(0); + setValue(1); + } else if (run === 1) { + expect(value()).toBe(1); + done(); + } + return run + 1; + }) + ); }); ``` It allows running the effect inside a defined owner that is received as an optional second argument. This can be useful in combination with `renderHook`, which gives you an owner field in its result. The return value is a Promise with the value given to the `done()` callback. You can either await the result for further assertions or return it to your test runner. +#### `cleanup` + +The `cleanup` function cleans-up any rendered context. It is installed automatically when afterEach is globally available (as is the case when using option `globals: true` in vitest config). + +If you don't want to set `globals: true`, it is possible to manually install the cleanup function in a setup file. + +```ts +// vitest-setup.ts +import { afterEach } from "vitest"; +import { cleanup } from "supplejs-testing-library"; + +afterEach(() => cleanup()); + +// vite.config.ts +export default defineConfig({ + test: { + setupFiles: ["vitest-setup.ts"], + }, +}); +``` + ## Acknowledgement Thanks goes to [Kent C. Dodds](https://kentcdodds.com/) and his colleagues for creating testing-library and to the creators of [solid-testing-library](https://github.com/solidjs/solid-testing-library). diff --git a/package.json b/package.json index 58ebb88..cc8a531 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "supplejs-testing-library", - "version": "1.0.0", + "version": "1.1.0", "description": "Simple and complete SuppleJS testing utilities that encourage good testing practices.", "type": "module", "main": "./dist/index.cjs", @@ -18,6 +18,7 @@ "require": "./dist/pure.cjs" } }, + "packageManager": "pnpm@9.4.0", "license": "MIT", "author": "Delphin Barraud", "homepage": "https://github.com/delph123/supplejs-testing-library", @@ -41,32 +42,31 @@ "e2e" ], "scripts": { - "prepublishOnly": "npm run build", + "prepublishOnly": "pnpm run build", "build": "tsup", "typecheck": "tsc --noEmit && tsc --noEmit --project src/__tests__/tsconfig.json", "test": "vitest", "test:watch": "vitest --watch", - "test:coverage": "vitest --coverage", + "coverage": "vitest --coverage", "setup": "pnpm install && pnpm run validate", - "validate": "pnpm run typecheck && pnpm run test:coverage && pnpm run build" + "validate": "pnpm run typecheck && pnpm run coverage && pnpm run build" }, "dependencies": { - "@testing-library/dom": "^10.3.1" + "@testing-library/dom": "^10.3.2" }, "devDependencies": { "@testing-library/jest-dom": "^6.4.6", "@testing-library/user-event": "^14.5.2", - "@types/node": "^20.14.9", - "@vitest/coverage-v8": "^1.6.0", + "@vitest/coverage-v8": "^2.0.3", "jsdom": "^24.1.0", - "prettier": "^3.3.2", + "prettier": "^3.3.3", "pretty-format": "^29.7.0", - "supplejs": "1.2.1", - "tsup": "8.1.0", + "supplejs": "^1.3.0", + "tsup": "^8.2.0", "typescript": "^5.5.3", - "vitest": "^1.6.0" + "vitest": "^2.0.3" }, "peerDependencies": { - "supplejs": "1.2.1" + "supplejs": "^1.3.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37f11a4..35aad1d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,42 +9,39 @@ importers: .: dependencies: '@testing-library/dom': - specifier: ^10.3.1 - version: 10.3.1 + specifier: ^10.3.2 + version: 10.3.2 devDependencies: '@testing-library/jest-dom': specifier: ^6.4.6 - version: 6.4.6(vitest@1.6.0(@types/node@20.14.9)(jsdom@24.1.0)) + version: 6.4.6(vitest@2.0.3(@types/node@20.14.11)(jsdom@24.1.0)) '@testing-library/user-event': specifier: ^14.5.2 - version: 14.5.2(@testing-library/dom@10.3.1) - '@types/node': - specifier: ^20.14.9 - version: 20.14.9 + version: 14.5.2(@testing-library/dom@10.3.2) '@vitest/coverage-v8': - specifier: ^1.6.0 - version: 1.6.0(vitest@1.6.0(@types/node@20.14.9)(jsdom@24.1.0)) + specifier: ^2.0.3 + version: 2.0.3(vitest@2.0.3(@types/node@20.14.11)(jsdom@24.1.0)) jsdom: specifier: ^24.1.0 version: 24.1.0 prettier: - specifier: ^3.3.2 - version: 3.3.2 + specifier: ^3.3.3 + version: 3.3.3 pretty-format: specifier: ^29.7.0 version: 29.7.0 supplejs: - specifier: 1.2.1 - version: 1.2.1 + specifier: ^1.3.0 + version: 1.3.0 tsup: - specifier: 8.1.0 - version: 8.1.0(postcss@8.4.39)(typescript@5.5.3) + specifier: ^8.2.0 + version: 8.2.0(postcss@8.4.39)(typescript@5.5.3)(yaml@2.4.5) typescript: specifier: ^5.5.3 version: 5.5.3 vitest: - specifier: ^1.6.0 - version: 1.6.0(@types/node@20.14.9)(jsdom@24.1.0) + specifier: ^2.0.3 + version: 2.0.3(@types/node@20.14.11)(jsdom@24.1.0) packages: @@ -59,8 +56,8 @@ packages: resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.24.7': - resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} '@babel/helper-validator-identifier@7.24.7': @@ -71,17 +68,17 @@ packages: resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.24.7': - resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + '@babel/parser@7.24.8': + resolution: {integrity: sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/runtime@7.24.7': - resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} + '@babel/runtime@7.24.8': + resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==} engines: {node: '>=6.9.0'} - '@babel/types@7.24.7': - resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + '@babel/types@7.24.9': + resolution: {integrity: sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -93,138 +90,282 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.23.0': + resolution: {integrity: sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.23.0': + resolution: {integrity: sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.23.0': + resolution: {integrity: sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.23.0': + resolution: {integrity: sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.23.0': + resolution: {integrity: sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.23.0': + resolution: {integrity: sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.23.0': + resolution: {integrity: sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.23.0': + resolution: {integrity: sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.23.0': + resolution: {integrity: sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.23.0': + resolution: {integrity: sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.23.0': + resolution: {integrity: sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.23.0': + resolution: {integrity: sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.23.0': + resolution: {integrity: sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.23.0': + resolution: {integrity: sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.23.0': + resolution: {integrity: sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.23.0': + resolution: {integrity: sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.23.0': + resolution: {integrity: sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.23.0': + resolution: {integrity: sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.0': + resolution: {integrity: sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.23.0': + resolution: {integrity: sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.23.0': + resolution: {integrity: sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.23.0': + resolution: {integrity: sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.23.0': + resolution: {integrity: sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.23.0': + resolution: {integrity: sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -249,8 +390,8 @@ packages: resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -271,91 +412,91 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@rollup/rollup-android-arm-eabi@4.18.0': - resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} + '@rollup/rollup-android-arm-eabi@4.18.1': + resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.18.0': - resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} + '@rollup/rollup-android-arm64@4.18.1': + resolution: {integrity: sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.18.0': - resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} + '@rollup/rollup-darwin-arm64@4.18.1': + resolution: {integrity: sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.18.0': - resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} + '@rollup/rollup-darwin-x64@4.18.1': + resolution: {integrity: sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.18.0': - resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': + resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.18.0': - resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} + '@rollup/rollup-linux-arm-musleabihf@4.18.1': + resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.18.0': - resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} + '@rollup/rollup-linux-arm64-gnu@4.18.1': + resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.18.0': - resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} + '@rollup/rollup-linux-arm64-musl@4.18.1': + resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': - resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': + resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.18.0': - resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} + '@rollup/rollup-linux-riscv64-gnu@4.18.1': + resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.18.0': - resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} + '@rollup/rollup-linux-s390x-gnu@4.18.1': + resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.18.0': - resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} + '@rollup/rollup-linux-x64-gnu@4.18.1': + resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.18.0': - resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} + '@rollup/rollup-linux-x64-musl@4.18.1': + resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.18.0': - resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} + '@rollup/rollup-win32-arm64-msvc@4.18.1': + resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.18.0': - resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} + '@rollup/rollup-win32-ia32-msvc@4.18.1': + resolution: {integrity: sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.18.0': - resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} + '@rollup/rollup-win32-x64-msvc@4.18.1': + resolution: {integrity: sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==} cpu: [x64] os: [win32] '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - '@testing-library/dom@10.3.1': - resolution: {integrity: sha512-q/WL+vlXMpC0uXDyfsMtc1rmotzLV8Y0gq6q1gfrrDjQeHoeLrqHbxdPvPNAh1i+xuJl7+BezywcXArz7vLqKQ==} + '@testing-library/dom@10.3.2': + resolution: {integrity: sha512-0bxIdP9mmPiOJ6wHLj8bdJRq+51oddObeCGdEf6PNEhYd93ZYAN+lPRnEOVFtheVwDM7+p+tza3LAQgp0PTudg==} engines: {node: '>=18'} '@testing-library/jest-dom@6.4.6': @@ -391,37 +532,31 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - '@types/node@20.14.9': - resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==} + '@types/node@20.14.11': + resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==} - '@vitest/coverage-v8@1.6.0': - resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==} + '@vitest/coverage-v8@2.0.3': + resolution: {integrity: sha512-53d+6jXFdYbasXBmsL6qaGIfcY5eBQq0sP57AjdasOcSiGNj4qxkkpDKIitUNfjxcfAfUfQ8BD0OR2fSey64+g==} peerDependencies: - vitest: 1.6.0 + vitest: 2.0.3 - '@vitest/expect@1.6.0': - resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + '@vitest/expect@2.0.3': + resolution: {integrity: sha512-X6AepoOYePM0lDNUPsGXTxgXZAl3EXd0GYe/MZyVE4HzkUqyUVC6S3PrY5mClDJ6/7/7vALLMV3+xD/Ko60Hqg==} - '@vitest/runner@1.6.0': - resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + '@vitest/pretty-format@2.0.3': + resolution: {integrity: sha512-URM4GLsB2xD37nnTyvf6kfObFafxmycCL8un3OC9gaCs5cti2u+5rJdIflZ2fUJUen4NbvF6jCufwViAFLvz1g==} - '@vitest/snapshot@1.6.0': - resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + '@vitest/runner@2.0.3': + resolution: {integrity: sha512-EmSP4mcjYhAcuBWwqgpjR3FYVeiA4ROzRunqKltWjBfLNs1tnMLtF+qtgd5ClTwkDP6/DGlKJTNa6WxNK0bNYQ==} - '@vitest/spy@1.6.0': - resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + '@vitest/snapshot@2.0.3': + resolution: {integrity: sha512-6OyA6v65Oe3tTzoSuRPcU6kh9m+mPL1vQ2jDlPdn9IQoUxl8rXhBnfICNOC+vwxWY684Vt5UPgtcA2aPFBb6wg==} - '@vitest/utils@1.6.0': - resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + '@vitest/spy@2.0.3': + resolution: {integrity: sha512-sfqyAw/ypOXlaj4S+w8689qKM1OyPOqnonqOc9T91DsoHbfN5mU7FdifWWv3MtQFf0lEUstEwR9L/q/M390C+A==} - acorn-walk@8.3.3: - resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} - engines: {node: '>=0.4.0'} - - acorn@8.12.1: - resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} - engines: {node: '>=0.4.0'} - hasBin: true + '@vitest/utils@2.0.3': + resolution: {integrity: sha512-c/UdELMuHitQbbc/EVctlBaxoYAwQPQdSNwv7z/vHyBKy2edYZaFgptE27BRueZB7eW8po+cllotMNTDpL3HWg==} agent-base@7.1.1: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} @@ -465,8 +600,9 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -478,9 +614,6 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} @@ -488,19 +621,19 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - bundle-require@4.2.1: - resolution: {integrity: sha512-7Q/6vkyYAwOmQNRw75x+4yRtZCZJXUDmHHlFdkiV0wgv/reNjtJwpu1jPJ0w2kbEpIM0uoKI3S4/f39dU7AjSA==} + bundle-require@5.0.0: + resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} peerDependencies: - esbuild: '>=0.17' + esbuild: '>=0.18' cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -514,8 +647,9 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} @@ -542,11 +676,9 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} @@ -578,8 +710,8 @@ packages: decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} delayed-stream@1.0.0: @@ -590,10 +722,6 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -622,6 +750,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.23.0: + resolution: {integrity: sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==} + engines: {node: '>=18'} + hasBin: true + escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} @@ -656,9 +789,6 @@ packages: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -679,15 +809,10 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob@10.4.2: - resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==} - engines: {node: '>=16 || 14 >=14.18'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} @@ -735,13 +860,6 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -792,9 +910,8 @@ packages: resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} - jackspeak@3.4.0: - resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} - engines: {node: '>=14'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} @@ -826,22 +943,17 @@ packages: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} - lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.1.1: + resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} - lru-cache@10.3.0: - resolution: {integrity: sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==} - engines: {node: 14 || >=16.14} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} @@ -888,9 +1000,6 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -899,9 +1008,6 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} - mlly@1.7.1: - resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} - ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -925,16 +1031,13 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - nwsapi@2.2.10: - resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} + nwsapi@2.2.12: + resolution: {integrity: sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -943,20 +1046,12 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} - p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} - package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -976,8 +1071,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} @@ -990,27 +1086,30 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - pkg-types@1.1.3: - resolution: {integrity: sha512-+JrgthZG6m3ckicaOB74TwQ+tBWsFl3qVQg7mN8ulwSOElJ7gBhKzj2VkCPnZ4NlF6kEquYU+RIYNVAvzd54UA==} - - postcss-load-config@4.0.2: - resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} - engines: {node: '>= 14'} + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} peerDependencies: + jiti: '>=1.21.0' postcss: '>=8.0.9' - ts-node: '>=9.0.0' + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: + jiti: + optional: true postcss: optional: true - ts-node: + tsx: + optional: true + yaml: optional: true postcss@8.4.39: resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} engines: {node: ^10 || ^12 || >=14} - prettier@3.3.2: - resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true @@ -1063,8 +1162,8 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.18.0: - resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} + rollup@4.18.1: + resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1084,8 +1183,8 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true @@ -1161,8 +1260,8 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true - supplejs@1.2.1: - resolution: {integrity: sha512-bgnAJ8jTT78CgMbvcsZr38UtdKrsL2Xj7NPnBS7OAblDa5KKWUPPXOlijWKhB7j07oYtcda+I9dyBnQftz7O+g==} + supplejs@1.3.0: + resolution: {integrity: sha512-obpFoULp3honoAOJIzAm5j9lgOHAQgACi92yBYj64l0PpQGqMOZmsY4rzn20VSzNOKxIJpBgkgsipaRH4vjKig==} supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -1175,9 +1274,9 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} @@ -1189,12 +1288,16 @@ packages: tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} - tinypool@0.8.4: - resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + tinypool@1.0.0: + resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} engines: {node: '>=14.0.0'} - tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + tinyspy@3.0.0: + resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} engines: {node: '>=14.0.0'} to-fast-properties@2.0.0: @@ -1223,8 +1326,8 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - tsup@8.1.0: - resolution: {integrity: sha512-UFdfCAXukax+U6KzeTNO2kAARHcWxmKsnvSPXUcfA1D+kU05XDccCrkffCQpFaWDsZfV0jMyTsxU39VfCp6EOg==} + tsup@8.2.0: + resolution: {integrity: sha512-XoarnVlfXxbv8ODHtxUq8D2XPc9luX+pamnp1kHSKLknKCDcX0Rkc21NHdbpugH6hKoNiETXypKKVgVu46vVRg==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -1242,18 +1345,11 @@ packages: typescript: optional: true - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - typescript@5.5.3: resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} engines: {node: '>=14.17'} hasBin: true - ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -1264,13 +1360,13 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - vite-node@1.6.0: - resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + vite-node@2.0.3: + resolution: {integrity: sha512-14jzwMx7XTcMB+9BhGQyoEAmSl0eOr3nrnn+Z12WNERtOvLN+d2scbRUvyni05rT3997Bg+rZb47NyP4IQPKXg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true - vite@5.3.3: - resolution: {integrity: sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==} + vite@5.3.4: + resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1297,15 +1393,15 @@ packages: terser: optional: true - vitest@1.6.0: - resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + vitest@2.0.3: + resolution: {integrity: sha512-o3HRvU93q6qZK4rI2JrhKyZMMuxg/JRt30E6qeQs6ueaiz5hr1cPj+Sk2kATgQzMMqsa2DiNI0TIK++1ULx8Jw==} 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.6.0 - '@vitest/ui': 1.6.0 + '@vitest/browser': 2.0.3 + '@vitest/ui': 2.0.3 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -1353,8 +1449,8 @@ packages: engines: {node: '>= 8'} hasBin: true - why-is-node-running@2.2.2: - resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true @@ -1366,9 +1462,6 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -1393,10 +1486,6 @@ packages: engines: {node: '>= 14'} hasBin: true - yocto-queue@1.1.1: - resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} - engines: {node: '>=12.20'} - snapshots: '@adobe/css-tools@4.4.0': {} @@ -1411,7 +1500,7 @@ snapshots: '@babel/highlight': 7.24.7 picocolors: 1.0.1 - '@babel/helper-string-parser@7.24.7': {} + '@babel/helper-string-parser@7.24.8': {} '@babel/helper-validator-identifier@7.24.7': {} @@ -1422,17 +1511,17 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.0.1 - '@babel/parser@7.24.7': + '@babel/parser@7.24.8': dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.24.9 - '@babel/runtime@7.24.7': + '@babel/runtime@7.24.8': dependencies: regenerator-runtime: 0.14.1 - '@babel/types@7.24.7': + '@babel/types@7.24.9': dependencies: - '@babel/helper-string-parser': 7.24.7 + '@babel/helper-string-parser': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 @@ -1441,72 +1530,144 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true + '@esbuild/aix-ppc64@0.23.0': + optional: true + '@esbuild/android-arm64@0.21.5': optional: true + '@esbuild/android-arm64@0.23.0': + optional: true + '@esbuild/android-arm@0.21.5': optional: true + '@esbuild/android-arm@0.23.0': + optional: true + '@esbuild/android-x64@0.21.5': optional: true + '@esbuild/android-x64@0.23.0': + optional: true + '@esbuild/darwin-arm64@0.21.5': optional: true + '@esbuild/darwin-arm64@0.23.0': + optional: true + '@esbuild/darwin-x64@0.21.5': optional: true + '@esbuild/darwin-x64@0.23.0': + optional: true + '@esbuild/freebsd-arm64@0.21.5': optional: true + '@esbuild/freebsd-arm64@0.23.0': + optional: true + '@esbuild/freebsd-x64@0.21.5': optional: true + '@esbuild/freebsd-x64@0.23.0': + optional: true + '@esbuild/linux-arm64@0.21.5': optional: true + '@esbuild/linux-arm64@0.23.0': + optional: true + '@esbuild/linux-arm@0.21.5': optional: true + '@esbuild/linux-arm@0.23.0': + optional: true + '@esbuild/linux-ia32@0.21.5': optional: true + '@esbuild/linux-ia32@0.23.0': + optional: true + '@esbuild/linux-loong64@0.21.5': optional: true + '@esbuild/linux-loong64@0.23.0': + optional: true + '@esbuild/linux-mips64el@0.21.5': optional: true + '@esbuild/linux-mips64el@0.23.0': + optional: true + '@esbuild/linux-ppc64@0.21.5': optional: true + '@esbuild/linux-ppc64@0.23.0': + optional: true + '@esbuild/linux-riscv64@0.21.5': optional: true + '@esbuild/linux-riscv64@0.23.0': + optional: true + '@esbuild/linux-s390x@0.21.5': optional: true + '@esbuild/linux-s390x@0.23.0': + optional: true + '@esbuild/linux-x64@0.21.5': optional: true + '@esbuild/linux-x64@0.23.0': + optional: true + '@esbuild/netbsd-x64@0.21.5': optional: true + '@esbuild/netbsd-x64@0.23.0': + optional: true + + '@esbuild/openbsd-arm64@0.23.0': + optional: true + '@esbuild/openbsd-x64@0.21.5': optional: true + '@esbuild/openbsd-x64@0.23.0': + optional: true + '@esbuild/sunos-x64@0.21.5': optional: true + '@esbuild/sunos-x64@0.23.0': + optional: true + '@esbuild/win32-arm64@0.21.5': optional: true + '@esbuild/win32-arm64@0.23.0': + optional: true + '@esbuild/win32-ia32@0.21.5': optional: true + '@esbuild/win32-ia32@0.23.0': + optional: true + '@esbuild/win32-x64@0.21.5': optional: true + '@esbuild/win32-x64@0.23.0': + optional: true + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -1525,19 +1686,19 @@ snapshots: '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/set-array@1.2.1': {} - '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -1554,60 +1715,60 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@rollup/rollup-android-arm-eabi@4.18.0': + '@rollup/rollup-android-arm-eabi@4.18.1': optional: true - '@rollup/rollup-android-arm64@4.18.0': + '@rollup/rollup-android-arm64@4.18.1': optional: true - '@rollup/rollup-darwin-arm64@4.18.0': + '@rollup/rollup-darwin-arm64@4.18.1': optional: true - '@rollup/rollup-darwin-x64@4.18.0': + '@rollup/rollup-darwin-x64@4.18.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + '@rollup/rollup-linux-arm-gnueabihf@4.18.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.18.0': + '@rollup/rollup-linux-arm-musleabihf@4.18.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.18.0': + '@rollup/rollup-linux-arm64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.18.0': + '@rollup/rollup-linux-arm64-musl@4.18.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.18.0': + '@rollup/rollup-linux-riscv64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.18.0': + '@rollup/rollup-linux-s390x-gnu@4.18.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.18.0': + '@rollup/rollup-linux-x64-gnu@4.18.1': optional: true - '@rollup/rollup-linux-x64-musl@4.18.0': + '@rollup/rollup-linux-x64-musl@4.18.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.18.0': + '@rollup/rollup-win32-arm64-msvc@4.18.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.18.0': + '@rollup/rollup-win32-ia32-msvc@4.18.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.18.0': + '@rollup/rollup-win32-x64-msvc@4.18.1': optional: true '@sinclair/typebox@0.27.8': {} - '@testing-library/dom@10.3.1': + '@testing-library/dom@10.3.2': dependencies: '@babel/code-frame': 7.24.7 - '@babel/runtime': 7.24.7 + '@babel/runtime': 7.24.8 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -1615,10 +1776,10 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.6(vitest@1.6.0(@types/node@20.14.9)(jsdom@24.1.0))': + '@testing-library/jest-dom@6.4.6(vitest@2.0.3(@types/node@20.14.11)(jsdom@24.1.0))': dependencies: '@adobe/css-tools': 4.4.0 - '@babel/runtime': 7.24.7 + '@babel/runtime': 7.24.8 aria-query: 5.3.0 chalk: 3.0.0 css.escape: 1.5.1 @@ -1626,21 +1787,22 @@ snapshots: lodash: 4.17.21 redent: 3.0.0 optionalDependencies: - vitest: 1.6.0(@types/node@20.14.9)(jsdom@24.1.0) + vitest: 2.0.3(@types/node@20.14.11)(jsdom@24.1.0) - '@testing-library/user-event@14.5.2(@testing-library/dom@10.3.1)': + '@testing-library/user-event@14.5.2(@testing-library/dom@10.3.2)': dependencies: - '@testing-library/dom': 10.3.1 + '@testing-library/dom': 10.3.2 '@types/aria-query@5.0.4': {} '@types/estree@1.0.5': {} - '@types/node@20.14.9': + '@types/node@20.14.11': dependencies: undici-types: 5.26.5 + optional: true - '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.9)(jsdom@24.1.0))': + '@vitest/coverage-v8@2.0.3(vitest@2.0.3(@types/node@20.14.11)(jsdom@24.1.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -1651,48 +1813,46 @@ snapshots: istanbul-reports: 3.1.7 magic-string: 0.30.10 magicast: 0.3.4 - picocolors: 1.0.1 std-env: 3.7.0 strip-literal: 2.1.0 - test-exclude: 6.0.0 - vitest: 1.6.0(@types/node@20.14.9)(jsdom@24.1.0) + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.0.3(@types/node@20.14.11)(jsdom@24.1.0) transitivePeerDependencies: - supports-color - '@vitest/expect@1.6.0': + '@vitest/expect@2.0.3': + dependencies: + '@vitest/spy': 2.0.3 + '@vitest/utils': 2.0.3 + chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.0.3': dependencies: - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - chai: 4.4.1 + tinyrainbow: 1.2.0 - '@vitest/runner@1.6.0': + '@vitest/runner@2.0.3': dependencies: - '@vitest/utils': 1.6.0 - p-limit: 5.0.0 + '@vitest/utils': 2.0.3 pathe: 1.1.2 - '@vitest/snapshot@1.6.0': + '@vitest/snapshot@2.0.3': dependencies: + '@vitest/pretty-format': 2.0.3 magic-string: 0.30.10 pathe: 1.1.2 - pretty-format: 29.7.0 - '@vitest/spy@1.6.0': + '@vitest/spy@2.0.3': dependencies: - tinyspy: 2.2.1 + tinyspy: 3.0.0 - '@vitest/utils@1.6.0': + '@vitest/utils@2.0.3': dependencies: - diff-sequences: 29.6.3 + '@vitest/pretty-format': 2.0.3 estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 - - acorn-walk@8.3.3: - dependencies: - acorn: 8.12.1 - - acorn@8.12.1: {} + loupe: 3.1.1 + tinyrainbow: 1.2.0 agent-base@7.1.1: dependencies: @@ -1729,7 +1889,7 @@ snapshots: array-union@2.1.0: {} - assertion-error@1.1.0: {} + assertion-error@2.0.1: {} asynckit@0.4.0: {} @@ -1737,11 +1897,6 @@ snapshots: binary-extensions@2.3.0: {} - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 @@ -1750,22 +1905,20 @@ snapshots: dependencies: fill-range: 7.1.1 - bundle-require@4.2.1(esbuild@0.21.5): + bundle-require@5.0.0(esbuild@0.23.0): dependencies: - esbuild: 0.21.5 + esbuild: 0.23.0 load-tsconfig: 0.2.5 cac@6.7.14: {} - chai@4.4.1: + chai@5.1.1: dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.4 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.1 + pathval: 2.0.0 chalk@2.4.2: dependencies: @@ -1783,9 +1936,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 + check-error@2.1.1: {} chokidar@3.6.0: dependencies: @@ -1817,9 +1968,7 @@ snapshots: commander@4.1.1: {} - concat-map@0.0.1: {} - - confbox@0.1.7: {} + consola@3.2.3: {} cross-spawn@7.0.3: dependencies: @@ -1846,16 +1995,12 @@ snapshots: decimal.js@10.4.3: {} - deep-eql@4.1.4: - dependencies: - type-detect: 4.0.8 + deep-eql@5.0.2: {} delayed-stream@1.0.0: {} dequal@2.0.3: {} - diff-sequences@29.6.3: {} - dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -1898,6 +2043,33 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + esbuild@0.23.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.0 + '@esbuild/android-arm': 0.23.0 + '@esbuild/android-arm64': 0.23.0 + '@esbuild/android-x64': 0.23.0 + '@esbuild/darwin-arm64': 0.23.0 + '@esbuild/darwin-x64': 0.23.0 + '@esbuild/freebsd-arm64': 0.23.0 + '@esbuild/freebsd-x64': 0.23.0 + '@esbuild/linux-arm': 0.23.0 + '@esbuild/linux-arm64': 0.23.0 + '@esbuild/linux-ia32': 0.23.0 + '@esbuild/linux-loong64': 0.23.0 + '@esbuild/linux-mips64el': 0.23.0 + '@esbuild/linux-ppc64': 0.23.0 + '@esbuild/linux-riscv64': 0.23.0 + '@esbuild/linux-s390x': 0.23.0 + '@esbuild/linux-x64': 0.23.0 + '@esbuild/netbsd-x64': 0.23.0 + '@esbuild/openbsd-arm64': 0.23.0 + '@esbuild/openbsd-x64': 0.23.0 + '@esbuild/sunos-x64': 0.23.0 + '@esbuild/win32-arm64': 0.23.0 + '@esbuild/win32-ia32': 0.23.0 + '@esbuild/win32-x64': 0.23.0 + escape-string-regexp@1.0.5: {} estree-walker@3.0.3: @@ -1955,8 +2127,6 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 - fs.realpath@1.0.0: {} - fsevents@2.3.3: optional: true @@ -1970,24 +2140,15 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.4.2: + glob@10.4.5: dependencies: foreground-child: 3.2.1 - jackspeak: 3.4.0 + jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 package-json-from-dist: 1.0.0 path-scurry: 1.11.1 - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - globby@11.1.0: dependencies: array-union: 2.1.0 @@ -2033,13 +2194,6 @@ snapshots: indent-string@4.0.0: {} - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -2083,7 +2237,7 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - jackspeak@3.4.0: + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: @@ -2105,7 +2259,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.5 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.10 + nwsapi: 2.2.12 parse5: 7.1.2 rrweb-cssom: 0.7.1 saxes: 6.0.0 @@ -2129,36 +2283,31 @@ snapshots: load-tsconfig@0.2.5: {} - local-pkg@0.5.0: - dependencies: - mlly: 1.7.1 - pkg-types: 1.1.3 - lodash.sortby@4.7.0: {} lodash@4.17.21: {} - loupe@2.3.7: + loupe@3.1.1: dependencies: get-func-name: 2.0.2 - lru-cache@10.3.0: {} + lru-cache@10.4.3: {} lz-string@1.5.0: {} magic-string@0.30.10: dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 magicast@0.3.4: dependencies: - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 + '@babel/parser': 7.24.8 + '@babel/types': 7.24.9 source-map-js: 1.2.0 make-dir@4.0.0: dependencies: - semver: 7.6.2 + semver: 7.6.3 merge-stream@2.0.0: {} @@ -2181,23 +2330,12 @@ snapshots: min-indent@1.0.1: {} - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 minipass@7.1.2: {} - mlly@1.7.1: - dependencies: - acorn: 8.12.1 - pathe: 1.1.2 - pkg-types: 1.1.3 - ufo: 1.5.3 - ms@2.1.2: {} mz@2.7.0: @@ -2218,14 +2356,10 @@ snapshots: dependencies: path-key: 4.0.0 - nwsapi@2.2.10: {} + nwsapi@2.2.12: {} object-assign@4.1.1: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 - onetime@5.1.2: dependencies: mimic-fn: 2.1.0 @@ -2234,32 +2368,26 @@ snapshots: dependencies: mimic-fn: 4.0.0 - p-limit@5.0.0: - dependencies: - yocto-queue: 1.1.1 - package-json-from-dist@1.0.0: {} parse5@7.1.2: dependencies: entities: 4.5.0 - path-is-absolute@1.0.1: {} - path-key@3.1.1: {} path-key@4.0.0: {} path-scurry@1.11.1: dependencies: - lru-cache: 10.3.0 + lru-cache: 10.4.3 minipass: 7.1.2 path-type@4.0.0: {} pathe@1.1.2: {} - pathval@1.1.1: {} + pathval@2.0.0: {} picocolors@1.0.1: {} @@ -2267,18 +2395,12 @@ snapshots: pirates@4.0.6: {} - pkg-types@1.1.3: - dependencies: - confbox: 0.1.7 - mlly: 1.7.1 - pathe: 1.1.2 - - postcss-load-config@4.0.2(postcss@8.4.39): + postcss-load-config@6.0.1(postcss@8.4.39)(yaml@2.4.5): dependencies: lilconfig: 3.1.2 - yaml: 2.4.5 optionalDependencies: postcss: 8.4.39 + yaml: 2.4.5 postcss@8.4.39: dependencies: @@ -2286,7 +2408,7 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 - prettier@3.3.2: {} + prettier@3.3.3: {} pretty-format@27.5.1: dependencies: @@ -2329,26 +2451,26 @@ snapshots: reusify@1.0.4: {} - rollup@4.18.0: + rollup@4.18.1: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.18.0 - '@rollup/rollup-android-arm64': 4.18.0 - '@rollup/rollup-darwin-arm64': 4.18.0 - '@rollup/rollup-darwin-x64': 4.18.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 - '@rollup/rollup-linux-arm-musleabihf': 4.18.0 - '@rollup/rollup-linux-arm64-gnu': 4.18.0 - '@rollup/rollup-linux-arm64-musl': 4.18.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 - '@rollup/rollup-linux-riscv64-gnu': 4.18.0 - '@rollup/rollup-linux-s390x-gnu': 4.18.0 - '@rollup/rollup-linux-x64-gnu': 4.18.0 - '@rollup/rollup-linux-x64-musl': 4.18.0 - '@rollup/rollup-win32-arm64-msvc': 4.18.0 - '@rollup/rollup-win32-ia32-msvc': 4.18.0 - '@rollup/rollup-win32-x64-msvc': 4.18.0 + '@rollup/rollup-android-arm-eabi': 4.18.1 + '@rollup/rollup-android-arm64': 4.18.1 + '@rollup/rollup-darwin-arm64': 4.18.1 + '@rollup/rollup-darwin-x64': 4.18.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.1 + '@rollup/rollup-linux-arm-musleabihf': 4.18.1 + '@rollup/rollup-linux-arm64-gnu': 4.18.1 + '@rollup/rollup-linux-arm64-musl': 4.18.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.1 + '@rollup/rollup-linux-riscv64-gnu': 4.18.1 + '@rollup/rollup-linux-s390x-gnu': 4.18.1 + '@rollup/rollup-linux-x64-gnu': 4.18.1 + '@rollup/rollup-linux-x64-musl': 4.18.1 + '@rollup/rollup-win32-arm64-msvc': 4.18.1 + '@rollup/rollup-win32-ia32-msvc': 4.18.1 + '@rollup/rollup-win32-x64-msvc': 4.18.1 fsevents: 2.3.3 rrweb-cssom@0.6.0: {} @@ -2365,7 +2487,7 @@ snapshots: dependencies: xmlchars: 2.2.0 - semver@7.6.2: {} + semver@7.6.3: {} shebang-command@2.0.0: dependencies: @@ -2427,13 +2549,13 @@ snapshots: dependencies: '@jridgewell/gen-mapping': 0.3.5 commander: 4.1.1 - glob: 10.4.2 + glob: 10.4.5 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.6 ts-interface-checker: 0.1.13 - supplejs@1.2.1: + supplejs@1.3.0: dependencies: csstype: 3.1.3 @@ -2447,11 +2569,11 @@ snapshots: symbol-tree@3.2.4: {} - test-exclude@6.0.0: + test-exclude@7.0.1: dependencies: '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 + glob: 10.4.5 + minimatch: 9.0.5 thenify-all@1.6.0: dependencies: @@ -2463,9 +2585,11 @@ snapshots: tinybench@2.8.0: {} - tinypool@0.8.4: {} + tinypool@1.0.0: {} + + tinyrainbow@1.2.0: {} - tinyspy@2.2.1: {} + tinyspy@3.0.0: {} to-fast-properties@2.0.0: {} @@ -2492,19 +2616,20 @@ snapshots: ts-interface-checker@0.1.13: {} - tsup@8.1.0(postcss@8.4.39)(typescript@5.5.3): + tsup@8.2.0(postcss@8.4.39)(typescript@5.5.3)(yaml@2.4.5): dependencies: - bundle-require: 4.2.1(esbuild@0.21.5) + bundle-require: 5.0.0(esbuild@0.23.0) cac: 6.7.14 chokidar: 3.6.0 + consola: 3.2.3 debug: 4.3.5 - esbuild: 0.21.5 + esbuild: 0.23.0 execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.4.39) + postcss-load-config: 6.0.1(postcss@8.4.39)(yaml@2.4.5) resolve-from: 5.0.0 - rollup: 4.18.0 + rollup: 4.18.1 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 @@ -2512,16 +2637,15 @@ snapshots: postcss: 8.4.39 typescript: 5.5.3 transitivePeerDependencies: + - jiti - supports-color - - ts-node - - type-detect@4.0.8: {} + - tsx + - yaml typescript@5.5.3: {} - ufo@1.5.3: {} - - undici-types@5.26.5: {} + undici-types@5.26.5: + optional: true universalify@0.2.0: {} @@ -2530,13 +2654,13 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - vite-node@1.6.0(@types/node@20.14.9): + vite-node@2.0.3(@types/node@20.14.11): dependencies: cac: 6.7.14 debug: 4.3.5 pathe: 1.1.2 - picocolors: 1.0.1 - vite: 5.3.3(@types/node@20.14.9) + tinyrainbow: 1.2.0 + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - '@types/node' - less @@ -2547,39 +2671,38 @@ snapshots: - supports-color - terser - vite@5.3.3(@types/node@20.14.9): + vite@5.3.4(@types/node@20.14.11): dependencies: esbuild: 0.21.5 postcss: 8.4.39 - rollup: 4.18.0 + rollup: 4.18.1 optionalDependencies: - '@types/node': 20.14.9 + '@types/node': 20.14.11 fsevents: 2.3.3 - vitest@1.6.0(@types/node@20.14.9)(jsdom@24.1.0): + vitest@2.0.3(@types/node@20.14.11)(jsdom@24.1.0): dependencies: - '@vitest/expect': 1.6.0 - '@vitest/runner': 1.6.0 - '@vitest/snapshot': 1.6.0 - '@vitest/spy': 1.6.0 - '@vitest/utils': 1.6.0 - acorn-walk: 8.3.3 - chai: 4.4.1 + '@ampproject/remapping': 2.3.0 + '@vitest/expect': 2.0.3 + '@vitest/pretty-format': 2.0.3 + '@vitest/runner': 2.0.3 + '@vitest/snapshot': 2.0.3 + '@vitest/spy': 2.0.3 + '@vitest/utils': 2.0.3 + chai: 5.1.1 debug: 4.3.5 execa: 8.0.1 - local-pkg: 0.5.0 magic-string: 0.30.10 pathe: 1.1.2 - picocolors: 1.0.1 std-env: 3.7.0 - strip-literal: 2.1.0 tinybench: 2.8.0 - tinypool: 0.8.4 - vite: 5.3.3(@types/node@20.14.9) - vite-node: 1.6.0(@types/node@20.14.9) - why-is-node-running: 2.2.2 + tinypool: 1.0.0 + tinyrainbow: 1.2.0 + vite: 5.3.4(@types/node@20.14.11) + vite-node: 2.0.3(@types/node@20.14.11) + why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.14.9 + '@types/node': 20.14.11 jsdom: 24.1.0 transitivePeerDependencies: - less @@ -2619,7 +2742,7 @@ snapshots: dependencies: isexe: 2.0.0 - why-is-node-running@2.2.2: + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 stackback: 0.0.2 @@ -2636,14 +2759,11 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 - wrappy@1.0.2: {} - ws@8.18.0: {} xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} - yaml@2.4.5: {} - - yocto-queue@1.1.1: {} + yaml@2.4.5: + optional: true diff --git a/src/__tests__/auto-cleanup.tsx b/src/__tests__/auto-cleanup.tsx index 087367e..9a837d8 100644 --- a/src/__tests__/auto-cleanup.tsx +++ b/src/__tests__/auto-cleanup.tsx @@ -4,9 +4,9 @@ import { render } from ".."; // environment which supports afterEach (like jest) // we'll get automatic cleanup between tests. test("first", () => { - render(() =>
hi
); + render(() =>
hi
); }); test("second", () => { - expect(document.body.innerHTML).toEqual(""); + expect(document.body.innerHTML).toEqual(""); }); diff --git a/src/__tests__/basic.tsx b/src/__tests__/basic.tsx index 18a753e..31b5f8f 100644 --- a/src/__tests__/basic.tsx +++ b/src/__tests__/basic.tsx @@ -1,153 +1,149 @@ import "@testing-library/jest-dom/vitest"; import { - createSignal, - createEffect, - createContext, - useContext, - getOwner, - createRoot, - createDeferred, - For, - createComputed, - createRef, - SuppleNode, - createMemo, + createSignal, + createEffect, + createContext, + useContext, + getOwner, + createRoot, + createDeferred, + For, + createComputed, + createRef, + SuppleNode, + createMemo, } from "supplejs"; import { render, renderHook, screen, testEffect } from ".."; import userEvent from "@testing-library/user-event"; test("render calls createComputed immediately", () => { - const cb = vi.fn(); + const cb = vi.fn(); - function Comp() { - createComputed(cb); - return () => null; - } + function Comp() { + createComputed(cb); + return () => null; + } - render(() => ); + render(() => ); - expect(cb).toHaveBeenCalledTimes(1); + expect(cb).toHaveBeenCalledTimes(1); }); test("findByTestId returns the element", async () => { - let ref = createRef(); + let ref = createRef(); - render(() =>
); + render(() =>
); - expect(await screen.findByTestId("foo")).toBe(ref.current); + expect(await screen.findByTestId("foo")).toBe(ref.current); }); test("userEvent triggers createEffect calls", async () => { - const cb = vi.fn(); + const cb = vi.fn(); - function Counter() { - const [count, setCount] = createSignal(0); + function Counter() { + const [count, setCount] = createSignal(0); - createComputed(() => { - count(); - cb(); - }); + createComputed(() => { + count(); + cb(); + }); - return () => ; - } + return () => ; + } - const { - container: { firstChild: buttonNode }, - } = render(() => ); + const { + container: { firstChild: buttonNode }, + } = render(() => ); - cb.mockClear(); - await userEvent.click(buttonNode! as Element); - expect(buttonNode).toHaveTextContent("1"); - expect(cb).toHaveBeenCalledTimes(1); + cb.mockClear(); + await userEvent.click(buttonNode! as Element); + expect(buttonNode).toHaveTextContent("1"); + expect(cb).toHaveBeenCalledTimes(1); }); -// test("calls to hydrate will run createEffects", () => { -// const cb = vi.fn(); - -// function Comp() { -// createEffect(cb); -// return null; -// } - -// render(() => , { hydrate: true }); - -// expect(cb).toHaveBeenCalledTimes(1); -// }); - test("queries should not return elements outside of the container", () => { - const { container, getAllByText } = render(() =>
Some text...
); - const falseContainer = document.createElement("p"); - falseContainer.textContent = "Some text..."; - container.parentNode!.insertBefore( - falseContainer, - getAllByText("Some text...")[0].parentNode - ); - expect(getAllByText("Some text...")[0] === container.childNodes[0]).toBe( - true - ); + const { container, getAllByText } = render(() =>
Some text...
); + const falseContainer = document.createElement("p"); + falseContainer.textContent = "Some text..."; + container.parentNode!.insertBefore(falseContainer, getAllByText("Some text...")[0].parentNode); + expect(getAllByText("Some text...")[0] === container.childNodes[0]).toBe(true); }); test("wrapper option works correctly", () => { - const { asFragment } = render(() =>
Component
, { - wrapper: (props) => () =>
Wrapper {props.children}
, - }); - expect(asFragment()).toBe("
Wrapper
Component
"); + const { asFragment } = render(() =>
Component
, { + wrapper: (props) => () =>
Wrapper {props.children}
, + }); + expect(asFragment()).toBe("
Wrapper
Component
"); +}); + +test("wrapper option works with wrapper returning JSX directly", () => { + const { asFragment } = render(() => Component, { + wrapper: (props) =>
Wrapper {props.children}
, + }); + expect(asFragment()).toBe("
Wrapper Component
"); }); test("wrapper option includes context", async () => { - const context = createContext("test"); - const Wrapper = (props: { children: SuppleNode }) => () => ( - {props.children} - ); - const { asFragment } = render(() =>
{useContext(context)}
, { - wrapper: Wrapper, - }); - expect(asFragment()).toBe("
works
"); + const context = createContext("test"); + const Wrapper = (props: { children: SuppleNode }) => () => ( + {props.children} + ); + const { asFragment } = render(() =>
{useContext(context)}
, { + wrapper: Wrapper, + }); + expect(asFragment()).toBe("
works
"); }); test("For does not need a parent wrapper", () => { - const { getByText } = render(() => ( - ["a", "b", "c"]}>{(i) => {i}} - )); - expect(getByText("b")).toBeInTheDocument(); + const { getByText } = render(() => ["a", "b", "c"]}>{(i) => {i}}); + expect(getByText("b")).toBeInTheDocument(); }); test("renderHook works correctly", () => { - const createDate = () => { - const [date, setDate] = createSignal(new Date()); - return [date, (d: Date) => (d ? setDate(d) : setDate(new Date()))] as const; - }; - const { - result: [date, setDate], - } = renderHook(createDate); - expect(date()).toBeInstanceOf(Date); - const newDate = new Date(); - setDate(newDate); - expect(date()).toBe(newDate); + const createDate = () => { + const [date, setDate] = createSignal(new Date()); + return [date, (d: Date) => (d ? setDate(d) : setDate(new Date()))] as const; + }; + const { + result: [date, setDate], + } = renderHook(createDate); + expect(date()).toBeInstanceOf(Date); + const newDate = new Date(); + setDate(newDate); + expect(date()).toBe(newDate); }); test("renderHook accepts hook props as array parameter", () => { - const { result } = renderHook((opts) => opts, ["option value"]); - expect(result).toBe("option value"); + const { result } = renderHook((opts) => opts, ["option value"]); + expect(result).toBe("option value"); }); test("renderHook accepts hook props as option value", () => { - const { result } = renderHook((opts) => opts, { - initialProps: ["option value"], - }); - expect(result).toBe("option value"); + const { result } = renderHook((opts) => opts, { + initialProps: ["option value"], + }); + expect(result).toBe("option value"); }); test("wrapper context is available in renderHook", () => { - const context = createContext("initial value"); - const testHook = () => useContext(context); - const Wrapper = (props: { children: SuppleNode }) => () => ( - {props.children} - ); - const { result } = renderHook(testHook, { wrapper: Wrapper }); - expect(result).toBe("context value"); + const context = createContext("initial value"); + const testHook = () => useContext(context); + const Wrapper = (props: { children: SuppleNode }) => () => ( + {props.children} + ); + const { result } = renderHook(testHook, { wrapper: Wrapper }); + expect(result).toBe("context value"); }); +test("wrapper context is available in renderHook with wrapper returning JSX directly", () => { + const context = createContext("initial value"); + const testHook = () => useContext(context); + const Wrapper = (props: { children: SuppleNode }) => ( + {props.children} + ); + const { result } = renderHook(testHook, { wrapper: Wrapper }); + expect(result).toBe("context value"); +}); // declare module "solid-js" { // namespace JSX { // interface Directives { @@ -211,52 +207,49 @@ test("wrapper context is available in renderHook", () => { // }); test("testEffect allows testing an effect asynchronously", () => { - const [v, setValue] = createSignal(0); - const value = createDeferred(v); - return testEffect((done) => - createEffect((run: number = 0) => { - if (run === 0) { - expect(value()).toBe(0); - setValue(1); - } else if (run === 1) { - expect(value()).toBe(1); - done(); - } - return run + 1; - }) - ); + const [v, setValue] = createSignal(0); + const value = createDeferred(v); + return testEffect((done) => + createEffect((run: number = 0) => { + if (run === 0) { + expect(value()).toBe(0); + setValue(1); + } else if (run === 1) { + expect(value()).toBe(1); + done(); + } + return run + 1; + }), + ); }); test("testEffect catches errors", () => { - const [value, setValue] = createSignal<{ error: string } | null>({ - error: "not yet", - }); - return testEffect((done) => - createEffect((run: number = 0) => { - value()!.error; - if (run === 0) { - setValue(null); - } - if (run === 1) { - done(); - } - return run + 1; - }) - ) - .then(() => { - throw new Error("Error swallowed by testEffect!"); - }) - .catch((e: Error) => expect(e.name).toBe("TypeError")); + const [value, setValue] = createSignal<{ error: string } | null>({ + error: "not yet", + }); + return testEffect((done) => + createEffect((run: number = 0) => { + value()!.error; + if (run === 0) { + setValue(null); + } + if (run === 1) { + done(); + } + return run + 1; + }), + ) + .then(() => { + throw new Error("Error swallowed by testEffect!"); + }) + .catch((e: Error) => expect(e.name).toBe("TypeError")); }); test("testEffect runs with owner", () => { - const [owner, dispose] = createRoot((dispose) => [ - createMemo(() => getOwner())(), - dispose, - ]); - return testEffect((done) => { - expect(getOwner()).toBe(owner); - dispose(); - done(); - }, owner!); + const [owner, dispose] = createRoot((dispose) => [createMemo(() => getOwner())(), dispose]); + return testEffect((done) => { + expect(getOwner()).toBe(owner); + dispose(); + done(); + }, owner!); }); diff --git a/src/__tests__/broken-cleanup.tsx b/src/__tests__/broken-cleanup.tsx index d2a6bdd..9c95270 100644 --- a/src/__tests__/broken-cleanup.tsx +++ b/src/__tests__/broken-cleanup.tsx @@ -1,16 +1,15 @@ -vi.mock('solid-js', () => ({ hydrate: () => {}, render: () => {} })); -import { render } from '..'; +vi.mock("solid-js", () => ({ hydrate: () => {}, render: () => {} })); +import { render } from ".."; const errors: Event[] = []; const handler = (ev: Event) => errors.push(ev); -globalThis.addEventListener('error', handler); +globalThis.addEventListener("error", handler); -test('trigger auto-cleanup', () => { - render(() =>
Hi
); +test("trigger auto-cleanup", () => { + render(() =>
Hi
); }); -test('check if auto-cleanup threw an error', () => { - expect(errors).toEqual([]); - globalThis.removeEventListener('error', handler); +test("check if auto-cleanup threw an error", () => { + expect(errors).toEqual([]); + globalThis.removeEventListener("error", handler); }); - diff --git a/src/__tests__/cleanup.tsx b/src/__tests__/cleanup.tsx index 7f9f165..18fab80 100644 --- a/src/__tests__/cleanup.tsx +++ b/src/__tests__/cleanup.tsx @@ -3,24 +3,24 @@ import { onCleanup } from "supplejs"; import { cleanup, render } from ".."; test("cleans up the document", () => { - const spy = vi.fn(); - const divId = "my-div"; + const spy = vi.fn(); + const divId = "my-div"; - function Test() { - onCleanup(() => { - // expect(document.getElementById(divId)).toBeInTheDocument(); - spy(); - }); - return () =>
; - } + function Test() { + onCleanup(() => { + // expect(document.getElementById(divId)).toBeInTheDocument(); + spy(); + }); + return () =>
; + } - render(() => ); - cleanup(); - expect(document.body.innerHTML).toBe(""); - expect(spy).toHaveBeenCalledTimes(1); + render(() => ); + cleanup(); + expect(document.body.innerHTML).toBe(""); + expect(spy).toHaveBeenCalledTimes(1); }); test("cleanup does not error when an element is not a child", () => { - render(() =>
, { container: document.createElement("div") }); - cleanup(); + render(() =>
, { container: document.createElement("div") }); + cleanup(); }); diff --git a/src/__tests__/debug.tsx b/src/__tests__/debug.tsx index 6c7b129..30f4285 100644 --- a/src/__tests__/debug.tsx +++ b/src/__tests__/debug.tsx @@ -2,51 +2,47 @@ import "@testing-library/jest-dom/vitest"; import { screen, render } from ".."; beforeEach(() => { - vi.spyOn(console, "log").mockImplementation(() => {}); + vi.spyOn(console, "log").mockImplementation(() => {}); }); afterEach(() => { - // @ts-ignore - console.log.mockRestore(); + // @ts-ignore + console.log.mockRestore(); }); test("debug pretty prints the container", () => { - const HelloWorld = () => () =>

Hello World

; + const HelloWorld = () => () =>

Hello World

; - render(() => ); + render(() => ); - screen.debug(); + screen.debug(); - expect(console.log).toHaveBeenCalledTimes(1); - expect(console.log).toHaveBeenCalledWith( - expect.stringContaining("Hello World") - ); + expect(console.log).toHaveBeenCalledTimes(1); + expect(console.log).toHaveBeenCalledWith(expect.stringContaining("Hello World")); }); test("debug pretty prints multiple containers", () => { - const HelloWorld = () => () => ( - <> -

Hello World

-

Hello World

- - ); - - const { debug, getAllByTestId } = render(() => ); - const multipleElements = getAllByTestId("testId"); - debug(multipleElements); - expect(console.log).toHaveBeenCalledTimes(2); - expect(console.log).toHaveBeenCalledWith( - expect.stringContaining("Hello World") - ); + const HelloWorld = () => () => ( + <> +

Hello World

+

Hello World

+ + ); + + const { debug, getAllByTestId } = render(() => ); + const multipleElements = getAllByTestId("testId"); + debug(multipleElements); + expect(console.log).toHaveBeenCalledTimes(2); + expect(console.log).toHaveBeenCalledWith(expect.stringContaining("Hello World")); }); test("allows same arguments as prettyDOM", () => { - const HelloWorld = () => () =>

Hello World

; - const { debug, container } = render(() => ); - debug(container, 6, { highlight: false }); - expect(console.log).toHaveBeenCalledTimes(1); - // @ts-ignore - expect(console.log.mock.calls[0]).toMatchInlineSnapshot(` + const HelloWorld = () => () =>

Hello World

; + const { debug, container } = render(() => ); + debug(container, 6, { highlight: false }); + expect(console.log).toHaveBeenCalledTimes(1); + // @ts-ignore + expect(console.log.mock.calls[0]).toMatchInlineSnapshot(` [ "
...", diff --git a/src/__tests__/end-to-end.tsx b/src/__tests__/end-to-end.tsx index c56dde7..6b3c44d 100644 --- a/src/__tests__/end-to-end.tsx +++ b/src/__tests__/end-to-end.tsx @@ -3,30 +3,28 @@ import { createResource, Show } from "supplejs"; import { screen, render, waitForElementToBeRemoved } from ".."; const fetchAMessage = () => - new Promise<{ returnedMessage: string }>((resolve) => { - // we are using random timeout here to simulate a real-time example - // of an async operation calling a callback at a non-deterministic time - const randomTimeout = Math.floor(Math.random() * 100); + new Promise<{ returnedMessage: string }>((resolve) => { + // we are using random timeout here to simulate a real-time example + // of an async operation calling a callback at a non-deterministic time + const randomTimeout = Math.floor(Math.random() * 100); - setTimeout(() => { - resolve({ returnedMessage: "Hello World" }); - }, randomTimeout); - }); + setTimeout(() => { + resolve({ returnedMessage: "Hello World" }); + }, randomTimeout); + }); function ComponentWithLoader() { - const [data] = createResource("data", fetchAMessage); - return () => ( - data.state === "ready"} fallback={
Loading...
}> -
- Loaded this message: {() => data()!.returnedMessage}! -
-
- ); + const [data] = createResource("data", fetchAMessage); + return () => ( + data.state === "ready"} fallback={
Loading...
}> +
Loaded this message: {() => data()!.returnedMessage}!
+
+ ); } test("it waits for the data to be loaded", async () => { - render(() => ); - const loading = () => screen.getByText("Loading..."); - await waitForElementToBeRemoved(loading); - expect(screen.getByTestId("message")).toHaveTextContent(/Hello World/); + render(() => ); + const loading = () => screen.getByText("Loading..."); + await waitForElementToBeRemoved(loading); + expect(screen.getByTestId("message")).toHaveTextContent(/Hello World/); }); diff --git a/src/__tests__/events.tsx b/src/__tests__/events.tsx index 4adb26d..75d40fe 100644 --- a/src/__tests__/events.tsx +++ b/src/__tests__/events.tsx @@ -4,182 +4,182 @@ import userEvent from "@testing-library/user-event"; import type { Mock } from "vitest"; const eventTypes = [ - { - type: "Clipboard", - events: ["copy", "paste"], - elementType: "input", - }, - { - type: "Composition", - events: ["compositionEnd", "compositionStart", "compositionUpdate"], - elementType: "input", - }, - { - type: "Keyboard", - events: ["keyDown", "keyPress", "keyUp"], - elementType: "input", - init: { keyCode: 13 }, - }, - { - type: "Focus", - events: ["focus", "blur"], - elementType: "input", - }, - { - type: "Form", - events: ["focus", "blur"], - elementType: "input", - }, - { - type: "Focus", - events: ["input", "invalid"], - elementType: "input", - }, - { - type: "Focus", - events: ["submit"], - elementType: "form", - }, - { - type: "Mouse", - events: [ - "click", - "contextMenu", - "dblClick", - "drag", - "dragEnd", - "dragEnter", - "dragExit", - "dragLeave", - "dragOver", - "dragStart", - "drop", - "mouseDown", - "mouseEnter", - "mouseLeave", - "mouseMove", - "mouseOut", - "mouseOver", - "mouseUp", - ], - elementType: "button", - }, - { - type: "Selection", - events: ["select"], - elementType: "input", - }, - { - type: "Touch", - events: ["touchCancel", "touchEnd", "touchMove", "touchStart"], - elementType: "button", - }, - { - type: "UI", - events: ["scroll"], - elementType: "div", - }, - { - type: "Wheel", - events: ["wheel"], - elementType: "div", - }, - { - type: "Media", - events: [ - "abort", - "canPlay", - "canPlayThrough", - "durationChange", - "emptied", - "encrypted", - "ended", - "error", - "loadedData", - "loadedMetadata", - "loadStart", - "pause", - "play", - "playing", - "progress", - "rateChange", - "seeked", - "seeking", - "stalled", - "suspend", - "timeUpdate", - "volumeChange", - "waiting", - ], - elementType: "video", - }, - { - type: "Image", - events: ["load", "error"], - elementType: "img", - }, - { - type: "Animation", - events: ["animationStart", "animationEnd", "animationIteration"], - elementType: "div", - }, - { - type: "Transition", - events: ["transitionEnd"], - elementType: "div", - }, + { + type: "Clipboard", + events: ["copy", "paste"], + elementType: "input", + }, + { + type: "Composition", + events: ["compositionEnd", "compositionStart", "compositionUpdate"], + elementType: "input", + }, + { + type: "Keyboard", + events: ["keyDown", "keyPress", "keyUp"], + elementType: "input", + init: { keyCode: 13 }, + }, + { + type: "Focus", + events: ["focus", "blur"], + elementType: "input", + }, + { + type: "Form", + events: ["focus", "blur"], + elementType: "input", + }, + { + type: "Focus", + events: ["input", "invalid"], + elementType: "input", + }, + { + type: "Focus", + events: ["submit"], + elementType: "form", + }, + { + type: "Mouse", + events: [ + "click", + "contextMenu", + "dblClick", + "drag", + "dragEnd", + "dragEnter", + "dragExit", + "dragLeave", + "dragOver", + "dragStart", + "drop", + "mouseDown", + "mouseEnter", + "mouseLeave", + "mouseMove", + "mouseOut", + "mouseOver", + "mouseUp", + ], + elementType: "button", + }, + { + type: "Selection", + events: ["select"], + elementType: "input", + }, + { + type: "Touch", + events: ["touchCancel", "touchEnd", "touchMove", "touchStart"], + elementType: "button", + }, + { + type: "UI", + events: ["scroll"], + elementType: "div", + }, + { + type: "Wheel", + events: ["wheel"], + elementType: "div", + }, + { + type: "Media", + events: [ + "abort", + "canPlay", + "canPlayThrough", + "durationChange", + "emptied", + "encrypted", + "ended", + "error", + "loadedData", + "loadedMetadata", + "loadStart", + "pause", + "play", + "playing", + "progress", + "rateChange", + "seeked", + "seeking", + "stalled", + "suspend", + "timeUpdate", + "volumeChange", + "waiting", + ], + elementType: "video", + }, + { + type: "Image", + events: ["load", "error"], + elementType: "img", + }, + { + type: "Animation", + events: ["animationStart", "animationEnd", "animationIteration"], + elementType: "div", + }, + { + type: "Transition", + events: ["transitionEnd"], + elementType: "div", + }, ]; function event(el: HTMLElement, name: string, spy: Mock) { - el.addEventListener(name, spy); + el.addEventListener(name, spy); } eventTypes.forEach(({ type, events, elementType, init }) => { - describe(`${type} Events`, () => { - events.forEach((eventName) => { - const eventProp = eventName.toLowerCase(); + describe(`${type} Events`, () => { + events.forEach((eventName) => { + const eventProp = eventName.toLowerCase(); - it(`triggers ${eventProp}`, () => { - let ref = createRef(); - const spy = vi.fn(); + it(`triggers ${eventProp}`, () => { + let ref = createRef(); + const spy = vi.fn(); - render(() => ); - event(ref.current, eventProp, spy); + render(() => ); + event(ref.current, eventProp, spy); - // @ts-ignore - fireEvent[eventName](ref.current, init); + // @ts-ignore + fireEvent[eventName](ref.current, init); - expect(spy).toHaveBeenCalledTimes(1); - }); + expect(spy).toHaveBeenCalledTimes(1); + }); + }); }); - }); }); test("onInput works", async () => { - const handler = vi.fn(); + const handler = vi.fn(); - const { - container: { firstChild: input }, - } = render(() => ); + const { + container: { firstChild: input }, + } = render(() => ); - await userEvent.type(input! as Element, "a"); + await userEvent.type(input! as Element, "a"); - expect(handler).toHaveBeenCalledTimes(1); + expect(handler).toHaveBeenCalledTimes(1); }); test("calling `fireEvent` directly works too", () => { - const handleEvent = vi.fn(); + const handleEvent = vi.fn(); - const { - container: { firstChild: button }, - } = render(() => - -
- ); + const [lapse, setLapse] = createSignal(0); + const [running, setRunning] = createSignal(false); + let timer: ReturnType; + + const handleRunClick = () => { + if (running()) { + clearInterval(timer); + } else { + const startTime = Date.now() - lapse(); + timer = setInterval(() => setLapse(Date.now() - startTime)); + } + return setRunning(!running()); + }; + + const handleClearClick = () => { + clearInterval(timer); + setLapse(0); + setRunning(false); + }; + + onCleanup(() => clearInterval(timer)); + + return ( +
+ {lapse}ms + + +
+ ); } -const wait = (time: number) => - new Promise((resolve) => setTimeout(resolve, time)); +const wait = (time: number) => new Promise((resolve) => setTimeout(resolve, time)); test("unmounts a component", async () => { - vi.spyOn(console, "error").mockImplementation(() => {}); + vi.spyOn(console, "error").mockImplementation(() => {}); - const { unmount, container } = render(() => ); + const { unmount, container } = render(() => ); - userEvent.click(screen.getByText("Start") as Element); + userEvent.click(screen.getByText("Start") as Element); - unmount(); + unmount(); - // Hey there reader! You don't need to have an assertion like this one - // this is just me making sure that the unmount function works. - // You don't need to do this in your apps. Just rely on the fact that this works. - expect(container.innerHTML).toBe(""); + // Hey there reader! You don't need to have an assertion like this one + // this is just me making sure that the unmount function works. + // You don't need to do this in your apps. Just rely on the fact that this works. + expect(container.innerHTML).toBe(""); - // Just wait to see if the interval is cleared or not. - // If it's not, then we'll call setState on an unmounted component and get an error. - await wait((() => expect(console.error).not.toHaveBeenCalled()) as any); + // Just wait to see if the interval is cleared or not. + // If it's not, then we'll call setState on an unmounted component and get an error. + await wait((() => expect(console.error).not.toHaveBeenCalled()) as any); }); diff --git a/src/index.ts b/src/index.ts index 3d2f873..6a20670 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,18 +5,18 @@ import { cleanup } from "./pure"; // this ensures that tests run in isolation from each other. // If you don't like this then either import the `pure` module // or set the STL_SKIP_AUTO_CLEANUP env variable to 'true'. +// @ts-ignore if (typeof process === "undefined" || !process.env.STL_SKIP_AUTO_CLEANUP) { - //@ts-ignore - if (typeof afterEach === "function") { - //@ts-ignore - afterEach(() => { - cleanup(); - }); - //@ts-ignore - } else if (typeof teardown === "function") { - //@ts-ignore - teardown(cleanup); - } + // @ts-ignore + if (typeof afterEach === "function") { + // @ts-ignore + afterEach(cleanup); + /* v8 ignore next 5 */ + // @ts-ignore + } else if (typeof teardown === "function") { + // @ts-ignore + teardown(cleanup); + } } export { render, renderHook, testEffect, cleanup } from "./pure"; diff --git a/src/pure.ts b/src/pure.ts index 54be86d..d7434f2 100644 --- a/src/pure.ts +++ b/src/pure.ts @@ -1,23 +1,17 @@ import { getQueriesForElement, prettyDOM } from "@testing-library/dom"; import { - SuppleNodeEffect, - TrackingContext, - createRoot, - getOwner, - h, - catchError, - runWithOwner, - render as core_render, - createRenderEffect, + SuppleNodeEffect, + TrackingContext, + createRoot, + getOwner, + h, + catchError, + runWithOwner, + render as core_render, + createRenderEffect, } from "supplejs"; -import type { - Result, - Options, - Ref, - RenderHookResult, - RenderHookOptions, -} from "./types"; +import type { Result, Options, Ref, RenderHookResult, RenderHookOptions } from "./types"; const mountedContainers = new Set(); @@ -45,52 +39,49 @@ const mountedContainers = new Set(); * - `result.unmount()` - unmounts the component, usually automatically called in cleanup * - `result.`[queries] - testing library queries, see https://testing-library.com/docs/queries/about) */ -export function render( - renderEffect: SuppleNodeEffect, - options: Options = {} -): Result { - let { container, baseElement = container } = options; - let transientContainer: HTMLElement | undefined = undefined; - - if (!baseElement) { - // Default to document.body instead of documentElement to avoid output of potentially-large - // head elements (such as JSS style blocks) in debug output. - baseElement = document.body; - } - - if (!container) { - transientContainer = document.createElement("div"); - container = baseElement.appendChild(transientContainer); - } - - const wrappedUi: SuppleNodeEffect = - typeof options.wrapper === "function" - ? () => - h(options.wrapper!, { - children: [renderEffect], - }) - : renderEffect; - - const dispose = core_render(wrappedUi, container); - - // We'll add it to the mounted components regardless of whether it's actually - // added to document.body so the cleanup method works regardless of whether - // they're passing us a custom container or not. - mountedContainers.add({ container: transientContainer, dispose }); - - const queryHelpers = getQueriesForElement(container, options.queries); - - return { - asFragment: () => container?.innerHTML, - container, - baseElement, - debug: (el = baseElement, maxLength?, options?) => - Array.isArray(el) - ? el.forEach((e) => console.log(prettyDOM(e, maxLength, options))) - : console.log(prettyDOM(el, maxLength, options)), - unmount: dispose, - ...queryHelpers, - } as Result; +export function render(renderEffect: SuppleNodeEffect, options: Options = {}): Result { + let { container, baseElement = container } = options; + let transientContainer: HTMLElement | undefined = undefined; + + if (!baseElement) { + // Default to document.body instead of documentElement to avoid output of potentially-large + // head elements (such as JSS style blocks) in debug output. + baseElement = document.body; + } + + if (!container) { + transientContainer = document.createElement("div"); + container = baseElement.appendChild(transientContainer); + } + + const wrappedUi: SuppleNodeEffect = + typeof options.wrapper === "function" + ? () => + h(options.wrapper!, { + children: [renderEffect], + }) + : renderEffect; + + const dispose = core_render(wrappedUi, container); + + // We'll add it to the mounted components regardless of whether it's actually + // added to document.body so the cleanup method works regardless of whether + // they're passing us a custom container or not. + mountedContainers.add({ container: transientContainer, dispose }); + + const queryHelpers = getQueriesForElement(container, options.queries); + + return { + asFragment: () => container?.innerHTML, + container, + baseElement, + debug: (el = baseElement, maxLength?, options?) => + Array.isArray(el) + ? el.forEach((e) => console.log(prettyDOM(e, maxLength, options))) + : console.log(prettyDOM(el, maxLength, options)), + unmount: dispose, + ...queryHelpers, + } as Result; } /** @@ -113,92 +104,82 @@ export function render( * - `result.cleanup()` - calls the cleanup function of the hook/primitive */ export function renderHook( - hook: (...args: A) => R, - options?: RenderHookOptions + hook: (...args: A) => R, + options?: RenderHookOptions, ): RenderHookResult { - const initialProps: A | [] = Array.isArray(options) - ? options - : options?.initialProps ?? []; - const [dispose, owner, result] = createRoot((dispose) => { - if ( - typeof options === "object" && - "wrapper" in options && - typeof options.wrapper === "function" - ) { - let result: ReturnType; - createRenderEffect( - options.wrapper({ - children: [ - () => { - result = hook(...(initialProps as A)); - return null; - }, - ], - }) - ); - return [dispose, getOwner(), result!]; - } - return [dispose, getOwner(), hook(...(initialProps as A))]; - }); - - mountedContainers.add({ dispose }); - - return { result, cleanup: dispose, owner }; + const initialProps: A | [] = Array.isArray(options) ? options : (options?.initialProps ?? []); + const [dispose, owner, result] = createRoot((dispose) => { + if (typeof options === "object" && "wrapper" in options && typeof options.wrapper === "function") { + let result: ReturnType; + createRenderEffect(() => + h(options.wrapper!, undefined, () => { + result = hook(...(initialProps as A)); + return null; + }), + ); + return [dispose, getOwner(), result!]; + } + return [dispose, getOwner(), hook(...(initialProps as A))]; + }); + + mountedContainers.add({ dispose }); + + return { result, cleanup: dispose, owner }; } export function testEffect( - fn: (done: (result: T) => void) => void, - owner?: TrackingContext + fn: (done: (result: T) => void) => void, + owner?: TrackingContext, ): Promise { - const context: { - promise?: Promise; - done?: (result: T) => void; - fail?: (error: any) => void; - } = {}; - context.promise = new Promise((resolve, reject) => { - context.done = resolve; - context.fail = reject; - }); - createRoot((dispose) => { - catchError( - () => { - const f = owner - ? (done: (result: T) => void) => { - const h = () => { - fn(done); - }; - runWithOwner(owner, h); - } - : fn; - - f((result) => { - context.done?.(result); - dispose(); - }); - }, - (err) => context.fail?.(err) - ); - }); - return context.promise; + const context: { + promise?: Promise; + done?: (result: T) => void; + fail?: (error: any) => void; + } = {}; + context.promise = new Promise((resolve, reject) => { + context.done = resolve; + context.fail = reject; + }); + createRoot((dispose) => { + catchError( + () => { + const f = owner + ? (done: (result: T) => void) => { + const h = () => { + fn(done); + }; + runWithOwner(owner, h); + } + : fn; + + f((result) => { + context.done?.(result); + dispose(); + }); + }, + (err) => context.fail?.(err), + ); + }); + return context.promise; } function cleanupAtContainer(ref: Ref) { - const { container, dispose } = ref; - try { - dispose(); - } catch (e) { - // consume & ignore error - } - - if (container?.parentNode != null) { - container.parentNode.removeChild(container); - } - - mountedContainers.delete(ref); + const { container, dispose } = ref; + try { + dispose(); + } catch (e) { + // consume & ignore error + } + + if (container?.parentNode != null) { + container.parentNode.removeChild(container); + } + + mountedContainers.delete(ref); } export function cleanup() { - mountedContainers.forEach(cleanupAtContainer); + mountedContainers.forEach(cleanupAtContainer); } export * from "@testing-library/dom"; diff --git a/tsconfig.json b/tsconfig.json index 0ae666d..65e62be 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,8 +11,7 @@ "jsx": "react-jsx", "jsxImportSource": "supplejs", "outDir": "./dist", - "module": "ESNext", - "types": ["@types/node"] + "module": "ESNext" }, "include": ["src/index.ts", "src/types.ts"] } diff --git a/tsup.config.ts b/tsup.config.ts index 0ce4269..a2d2f11 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -1,9 +1,9 @@ import { defineConfig } from "tsup"; export default defineConfig({ - entry: ["src/index.ts", "src/pure.ts"], - format: ["esm", "cjs"], - splitting: false, - dts: true, - clean: true, + entry: ["src/index.ts", "src/pure.ts"], + format: ["esm", "cjs"], + splitting: false, + dts: true, + clean: true, }); diff --git a/vitest.config.ts b/vitest.config.ts index dd601ad..ff40f6a 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,15 +1,15 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ - test: { - coverage: { - provider: "v8", - include: ["src/*.ts"], + test: { + coverage: { + provider: "v8", + include: ["src/*.ts"], + }, + environment: "jsdom", + watch: false, + globals: true, + clearMocks: true, + include: ["src/__tests__/*.tsx"], }, - environment: "jsdom", - watch: false, - globals: true, - clearMocks: true, - include: ["src/__tests__/*.tsx"], - }, });