diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 2589fd2c..00000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -octoprint_octorelay/_static_version.py export-subst diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 0baa6c2f..81424bfd 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -132,8 +132,8 @@ jobs: - name: Report the coverage working-directory: tests run: | - python -m coverage lcov --omit=test*,_version* - python -m coverage report --show-missing --omit=test*,_version* + python -m coverage lcov --omit=test* + python -m coverage report --show-missing --omit=test* - name: Coveralls uses: coverallsapp/github-action@v2 continue-on-error: true diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e1a98714..84e57dbf 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -47,12 +47,20 @@ jobs: path: ${{ steps.pipCache.outputs.dir }} key: ${{ runner.os }}-release-cache-pip - name: Install distribution dependencies - run: pip install --upgrade wheel setuptools pip + run: pip install build - name: Install OctoPrint run: pip install octoprint~=${{ env.OCTOPRINT_VERSION }}.0 ### Packing - name: Build distribution package - run: python setup.py sdist --formats=zip + run: python -m build --sdist + ## Required for backward compatibility, see UPDATES_CONFIG, todo: reconsider in v6 + - name: Repack as ZIP + run: | + mkdir -p repack + tar -xzf dist/octorelay-*.tar.gz -C repack + rm -rf dist/* + cd repack && zip -r ../dist/release.zip . + cd .. && rm -rf repack - name: Upload artifact uses: actions/upload-artifact@v7 with: @@ -111,7 +119,7 @@ jobs: # see https://community.octoprint.org/t/setuptools-error-while-installing-plugin-octoklipper-on-manual-op-installation/51387 run: pip install wheel - name: Install the distributed package - run: pip install dist/octorelay-*.zip + run: pip install dist/release.zip attach: name: Attaching asset to the release @@ -125,9 +133,7 @@ jobs: with: name: dist path: dist - - name: Rename to release.zip - run: cp dist/octorelay-*.zip release.zip - name: Attach the asset uses: softprops/action-gh-release@v2 with: - files: release.zip + files: dist/release.zip diff --git a/.pylintrc b/.pylintrc index 526ffa7e..d1b77d2c 100644 --- a/.pylintrc +++ b/.pylintrc @@ -58,8 +58,6 @@ ignore-paths= # The regex matches against base names, not paths. The default value ignores # Emacs file locks ignore-patterns=^\.#, - _static_version\.py, - _version\.py # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fdca0a2..dfbd4ab4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## Version 5 +### 5.4.0 + +- Modernized the build system: no longer use `setup.py`, now using `pyproject.toml` solely; +- Plugin versioning switched from `miniver` to `setuptools-scm`; +- Release file format remains `.zip` for automatic updates, but may be changed in the future v6; +- Explicitly enabled the plugin API protection: authentication required (`X-Api-Key`); +- Explicitly enabled template autoescaping to prevent potential XSS vulnerabilities. + ### 5.3.0 - Adds `pyproject.toml` file to the distribution: diff --git a/MANIFEST.in b/MANIFEST.in index 0d811e58..8998e231 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,3 +7,13 @@ recursive-include octoprint_octorelay/static * exclude octoprint_octorelay/static/js/.gitkeep exclude octoprint_octorelay/static/css/.gitkeep prune tests +prune ui +prune .github +prune .devcontainer +prune img +exclude .gitignore +exclude .pylintrc +exclude mypy.ini +exclude *.sh +exclude setup.cfg +exclude babel.cfg diff --git a/mypy.ini b/mypy.ini index 017369f8..90efedc4 100644 --- a/mypy.ini +++ b/mypy.ini @@ -9,6 +9,3 @@ ignore_missing_imports = True [mypy-flask.*] ignore_missing_imports = True - -[mypy-octoprint_octorelay._version] -ignore_errors = True diff --git a/octoprint_octorelay/__init__.py b/octoprint_octorelay/__init__.py index 25d517a3..184acd97 100755 --- a/octoprint_octorelay/__init__.py +++ b/octoprint_octorelay/__init__.py @@ -4,6 +4,7 @@ from functools import reduce import os import time +from importlib.metadata import version import flask import octoprint.plugin @@ -92,6 +93,14 @@ def get_api_commands(self): CANCEL_TASK_COMMAND: [ "subject", "target", "owner" ] } + def is_api_protected(self): + # https://docs.octoprint.org/en/main/plugins/mixins.html#octoprint.plugin.SimpleApiPlugin.is_api_protected + return True + + def is_template_autoescaped(self): + # https://docs.octoprint.org/en/main/plugins/mixins.html#octoprint.plugin.TemplatePlugin.is_template_autoescaped + return True + def get_additional_permissions(self, *args, **kwargs): return [ SWITCH_PERMISSION ] @@ -381,5 +390,4 @@ def input_polling(self): __plugin_implementation__.process_at_command } -# pylint: disable=wrong-import-position -from ._version import __version__ +__version__ = version("OctoRelay") diff --git a/octoprint_octorelay/_static_version.py b/octoprint_octorelay/_static_version.py deleted file mode 100644 index 5557f9b5..00000000 --- a/octoprint_octorelay/_static_version.py +++ /dev/null @@ -1,12 +0,0 @@ -# -*- coding: utf-8 -*- -# This file is part of 'miniver': https://github.com/jbweston/miniver -# -# This file will be overwritten by setup.py when a source or binary -# distribution is made. The magic value "__use_git__" is interpreted by -# version.py. - -version = "__use_git__" - -# These values are only set if the distribution was created with 'git archive' -refnames = "$Format:%D$" -git_hash = "$Format:%h$" diff --git a/octoprint_octorelay/_version.py b/octoprint_octorelay/_version.py deleted file mode 100644 index 4d5c1c05..00000000 --- a/octoprint_octorelay/_version.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*- coding: utf-8 -*- -# This file is part of 'miniver': https://github.com/jbweston/miniver -# -from collections import namedtuple -import os -import subprocess - -from setuptools.command.build_py import build_py as build_py_orig -from setuptools.command.sdist import sdist as sdist_orig - -Version = namedtuple("Version", ("release", "dev", "labels")) - -# No public API -__all__ = [] - -package_root = os.path.dirname(os.path.realpath(__file__)) -package_name = os.path.basename(package_root) - -STATIC_VERSION_FILE = "_static_version.py" - - -def get_version(version_file=STATIC_VERSION_FILE): - version_info = get_static_version_info(version_file) - version = version_info["version"] - if version == "__use_git__": - version = get_version_from_git() - if not version: - version = get_version_from_git_archive(version_info) - if not version: - # version = Version("unknown", None, None) - version = Version("0.0.0", None, None) - return pep440_format(version) - else: - return version - - -def get_static_version_info(version_file=STATIC_VERSION_FILE): - version_info = {} - with open(os.path.join(package_root, version_file), "rb") as f: - exec(f.read(), {}, version_info) - return version_info - - -def version_is_from_git(version_file=STATIC_VERSION_FILE): - return get_static_version_info(version_file)["version"] == "__use_git__" - - -def pep440_format(version_info): - release, dev, labels = version_info - - version_parts = [release] - if dev: - if release.endswith("-dev") or release.endswith(".dev"): - version_parts.append(dev) - else: # prefer PEP440 over strict adhesion to semver - version_parts.append(".dev{}".format(dev)) - - if labels: - version_parts.append("+") - version_parts.append(".".join(labels)) - - return "".join(version_parts) - - -def get_version_from_git(): - # git describe --first-parent does not take into account tags from branches - # that were merged-in. The '--long' flag gets us the 'dev' version and - # git hash, '--always' returns the git hash even if there are no tags. - for opts in [["--first-parent"], []]: - try: - p = subprocess.Popen( - # patched for non-annotated (lightweight) tags - # see https://raw.githubusercontent.com/jbweston/miniver/master/unannotated-tags.patch - ["git", "describe", "--long", "--always", "--tags"] + opts, - cwd=package_root, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - except OSError: - return - if p.wait() == 0: - break - else: - return - - description = ( - p.communicate()[0] - .decode() - .strip("v") # Tags can have a leading 'v', but the version should not - .rstrip("\n") - .rsplit("-", 2) # Split the latest tag, commits since tag, and hash - ) - - try: - release, dev, git = description - except ValueError: # No tags, only the git hash - # prepend 'g' to match with format returned by 'git describe' - git = "g{}".format(*description) - # release = "unknown" - release = "0.0.0" - dev = None - - labels = [] - if dev == "0": - dev = None - else: - labels.append(git) - - try: - p = subprocess.Popen(["git", "diff", "--quiet"], cwd=package_root) - except OSError: - labels.append("confused") # This should never happen. - # patched for no "-dirty", JavaScript is being compiled during the release workflow, not committed - # else: - # if p.wait() == 1: - # labels.append("dirty") - - return Version(release, dev, labels) - - -# TODO: change this logic when there is a git pretty-format -# that gives the same output as 'git describe'. -# Currently we can only tell the tag the current commit is -# pointing to, or its hash (with no version info) -# if it is not tagged. -def get_version_from_git_archive(version_info): - try: - refnames = version_info["refnames"] - git_hash = version_info["git_hash"] - except KeyError: - # These fields are not present if we are running from an sdist. - # Execution should never reach here, though - return None - - if git_hash.startswith("$Format") or refnames.startswith("$Format"): - # variables not expanded during 'git archive' - return None - - VTAG = "tag: v" - refs = set(r.strip() for r in refnames.split(",")) - version_tags = set(r[len(VTAG) :] for r in refs if r.startswith(VTAG)) - if version_tags: - release, *_ = sorted(version_tags) # prefer e.g. "2.0" over "2.0rc1" - return Version(release, dev=None, labels=None) - else: - # return Version("unknown", dev=None, labels=["g{}".format(git_hash)]) - return Version("0.0.0", dev=None, labels=["g{}".format(git_hash)]) - - -__version__ = get_version() - - -# The following section defines a 'get_cmdclass' function -# that can be used from setup.py. The '__version__' module -# global is used (but not modified). - - -def _write_version(fname): - # This could be a hard link, so try to delete it first. Is there any way - # to do this atomically together with opening? - try: - os.remove(fname) - except OSError: - pass - with open(fname, "w") as f: - f.write( - "# This file has been created by setup.py.\n" - "version = '{}'\n".format(__version__) - ) - - -def get_cmdclass(pkg_source_path): - class _build_py(build_py_orig): - def run(self): - super().run() - - src_marker = "".join(["src", os.path.sep]) - - if pkg_source_path.startswith(src_marker): - path = pkg_source_path[len(src_marker):] - else: - path = pkg_source_path - _write_version( - os.path.join( - self.build_lib, path, STATIC_VERSION_FILE - ) - ) - - class _sdist(sdist_orig): - def make_release_tree(self, base_dir, files): - super().make_release_tree(base_dir, files) - _write_version( - os.path.join(base_dir, pkg_source_path, STATIC_VERSION_FILE) - ) - - return dict(sdist=_sdist, build_py=_build_py) diff --git a/pyproject.toml b/pyproject.toml index f67359df..cb92132c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,47 @@ [build-system] requires = [ - "setuptools", - "wheel", - "octoprint", + "setuptools>=77", + "setuptools-scm>=8", ] build-backend = "setuptools.build_meta" + +[project] +name = "OctoRelay" +dynamic = ["version"] +description = "A plugin that adds buttons to the navbar for toggling GPIO on the RPi. It can be used for turning relays on and off." +authors = [ + { name = "Boris Burgstaller", email = "raspi@burgstaller.net" }, +] +requires-python = ">=3.9,<4" +dependencies = [ + "gpiozero", + "lgpio", + "RPi.GPIO", +] +license = "AGPL-3.0-or-later" + +[project.entry-points."octoprint.plugin"] +octorelay = "octoprint_octorelay" + +[project.urls] +Homepage = "https://github.com/borisbu/OctoRelay" + +[project.optional-dependencies] +develop = [ + "go-task-bin", +] + +[project.readme] +file = "README.md" +content-type = "text/markdown" + +[tool.setuptools] +include-package-data = true + +[tool.setuptools.packages.find] +include = [ + "octoprint_octorelay", + "octoprint_octorelay.*", +] + +[tool.setuptools_scm] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a1dc4637..00000000 --- a/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -### -# This file is only here to make sure that something like -# -# pip install -e . -# -# works as expected. Requirements can be found in setup.py. -### - -. diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 2a9acf13..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[bdist_wheel] -universal = 1 diff --git a/setup.py b/setup.py deleted file mode 100755 index d2e788e8..00000000 --- a/setup.py +++ /dev/null @@ -1,113 +0,0 @@ -# coding=utf-8 - -from setuptools import setup - -def get_version_and_cmdclass(pkg_path): - """Load version.py module without importing the whole package. - - Template code from miniver - """ - import os - from importlib.util import module_from_spec, spec_from_file_location - - spec = spec_from_file_location("version", os.path.join(pkg_path, "_version.py")) - module = module_from_spec(spec) - spec.loader.exec_module(module) - return module.__version__, module.get_cmdclass(pkg_path) - -miniver_version, cmdclass = get_version_and_cmdclass(r"octoprint_octorelay") - -######################################################################################################################## -# Do not forget to adjust the following variables to your own plugin. - -# The plugin's identifier, has to be unique -plugin_identifier = "octorelay" - -# The plugin's python package, should be "octoprint_", has to be unique -plugin_package = "octoprint_octorelay" - -# The plugin's human readable name. Can be overwritten within OctoPrint's internal data via __plugin_name__ in the -# plugin module -plugin_name = "OctoRelay" - -# The plugin's version. Can be overwritten within OctoPrint's internal data via __plugin_version__ in the plugin module -plugin_version = miniver_version - -# The plugin's description. Can be overwritten within OctoPrint's internal data via __plugin_description__ in the plugin -# module -plugin_description = """A plugin that adds buttons to the navbar for toggling GPIO on the RPi. It can be used for turning relays on and off.""" - -# The plugin's author. Can be overwritten within OctoPrint's internal data via __plugin_author__ in the plugin module -plugin_author = "Boris Burgstaller" - -# The plugin's author's mail address. -plugin_author_email = "raspi@burgstaller.net" - -# The plugin's homepage URL. Can be overwritten within OctoPrint's internal data via __plugin_url__ in the plugin module -plugin_url = "https://github.com/borisbu/OctoRelay" - -# The plugin's license. Can be overwritten within OctoPrint's internal data via __plugin_license__ in the plugin module -plugin_license = "AGPLv3" - -# Any additional requirements besides OctoPrint should be listed here -plugin_requires = ["gpiozero", "lgpio", "RPi.GPIO"] - -# -------------------------------------------------------------------------------------------------------------------- -# More advanced options that you usually shouldn't have to touch follow after this point -# -------------------------------------------------------------------------------------------------------------------- - -# Additional package data to install for this plugin. The subfolders "templates", "static" and "translations" will -# already be installed automatically if they exist. Note that if you add something here you'll also need to update -# MANIFEST.in to match to ensure that python setup.py sdist produces a source distribution that contains all your -# files. This is sadly due to how python's setup.py works, see also http://stackoverflow.com/a/14159430/2028598 -plugin_additional_data = [] - -# Any additional python packages you need to install with your plugin that are not contained in .* -plugin_additional_packages = [] - -# Any python packages within .* you do NOT want to install with your plugin -plugin_ignored_packages = [] - -# Additional parameters for the call to setuptools.setup. If your plugin wants to register additional entry points, -# define dependency links or other things like that, this is the place to go. Will be merged recursively with the -# default setup parameters as provided by octoprint_setuptools.create_plugin_setup_parameters using -# octoprint.util.dict_merge. -# -# Example: -# plugin_requires = ["someDependency==dev"] -# additional_setup_parameters = {"dependency_links": ["https://github.com/someUser/someRepo/archive/master.zip#egg=someDependency-dev"]} -additional_setup_parameters = { "python_requires": ">=3.9,<4" } # see also __init__.py - -######################################################################################################################## - - -try: - import octoprint_setuptools -except: - print("Could not import OctoPrint's setuptools, are you sure you are running that under " - "the same python installation that OctoPrint is installed under?") - import sys - sys.exit(-1) - -setup_parameters = octoprint_setuptools.create_plugin_setup_parameters( - identifier=plugin_identifier, - package=plugin_package, - name=plugin_name, - version=plugin_version, - cmdclass=cmdclass, # miniver feature - description=plugin_description, - author=plugin_author, - mail=plugin_author_email, - url=plugin_url, - license=plugin_license, - requires=plugin_requires, - additional_packages=plugin_additional_packages, - ignored_packages=plugin_ignored_packages, - additional_data=plugin_additional_data -) - -if len(additional_setup_parameters): - from octoprint.util import dict_merge - setup_parameters = dict_merge(setup_parameters, additional_setup_parameters) - -setup(**setup_parameters) diff --git a/tests/test_init.py b/tests/test_init.py index 6ab77ff9..6d81ee13 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -406,6 +406,14 @@ def test_get_api_commands(self): actual = self.plugin_instance.get_api_commands() self.assertEqual(actual, expected) + def test_is_api_protected(self): + # Should return True to enforce API key authentication for SimpleApi endpoints + self.assertTrue(self.plugin_instance.is_api_protected()) + + def test_is_template_autoescaped(self): + # Should return True to enable autoescaping for templates, preventing XSS + self.assertTrue(self.plugin_instance.is_template_autoescaped()) + def test_get_update_information(self): # Should return the update strategy configuration expected = { diff --git a/ui/package.json b/ui/package.json index 3bdd3189..98836d11 100644 --- a/ui/package.json +++ b/ui/package.json @@ -13,7 +13,7 @@ "lint": "eslint", "test": "tsc --noEmit && TZ=UTC vitest run --coverage --exclude qa*", "build": "pnpm build:js && pnpm build:styles && pnpm build:qa", - "build:js": "tsdown", + "build:js": "tsdown && git restore ../**/.gitkeep", "build:styles": "lessc styles/octorelay.less ../octoprint_octorelay/static/css/octorelay.css", "build:qa": "vitest run qa.spec.ts" }, @@ -24,7 +24,7 @@ "@types/jquery": "^3.5.34", "@types/lodash": "^3.10.9", "@types/node": "^25.6.0", - "@vitest/coverage-v8": "^4.1.4", + "@vitest/coverage-v8": "^4.1.5", "eslint": "^10.2.1", "eslint-config-prettier": "^10.1.8", "eslint-plugin-allowed-dependencies": "^2.1.0", @@ -33,10 +33,10 @@ "happy-dom": "^20.9.0", "less": "^4.6.4", "prettier": "3.8.3", - "tsdown": "^0.21.9", + "tsdown": "^0.21.10", "typescript": "^6.0.3", "typescript-eslint": "^8.58.2", - "vitest": "^4.1.4" + "vitest": "^4.1.5" }, "resolutions": { "lightningcss": "-" diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 2b886dab..a07f90f4 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -27,8 +27,8 @@ importers: specifier: ^25.6.0 version: 25.6.0 '@vitest/coverage-v8': - specifier: ^4.1.4 - version: 4.1.4(vitest@4.1.4) + specifier: ^4.1.5 + version: 4.1.5(vitest@4.1.5) eslint: specifier: ^10.2.1 version: 10.2.1 @@ -54,8 +54,8 @@ importers: specifier: 3.8.3 version: 3.8.3 tsdown: - specifier: ^0.21.9 - version: 0.21.9(synckit@0.11.12)(typescript@6.0.3) + specifier: ^0.21.10 + version: 0.21.10(synckit@0.11.12)(typescript@6.0.3) typescript: specifier: ^6.0.3 version: 6.0.3 @@ -63,8 +63,8 @@ importers: specifier: ^8.58.2 version: 8.58.2(eslint@10.2.1)(typescript@6.0.3) vitest: - specifier: ^4.1.4 - version: 4.1.4(@types/node@25.6.0)(@vitest/coverage-v8@4.1.4)(happy-dom@20.9.0)(vite@8.0.9(@types/node@25.6.0)(less@4.6.4)) + specifier: ^4.1.5 + version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(less@4.6.4)) packages: @@ -110,11 +110,11 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@emnapi/core@1.9.2': - resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - '@emnapi/runtime@1.9.2': - resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} @@ -193,8 +193,8 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - '@oxc-project/types@0.126.0': - resolution: {integrity: sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==} + '@oxc-project/types@0.127.0': + resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} '@pkgr/core@0.2.9': resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} @@ -203,103 +203,103 @@ packages: '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} - '@rolldown/binding-android-arm64@1.0.0-rc.16': - resolution: {integrity: sha512-rhY3k7Bsae9qQfOtph2Pm2jZEA+s8Gmjoz4hhmx70K9iMQ/ddeae+xhRQcM5IuVx5ry1+bGfkvMn7D6MJggVSA==} + '@rolldown/binding-android-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.16': - resolution: {integrity: sha512-rNz0yK078yrNn3DrdgN+PKiMOW8HfQ92jQiXxwX8yW899ayV00MLVdaCNeVBhG/TbH3ouYVObo8/yrkiectkcQ==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.16': - resolution: {integrity: sha512-r/OmdR00HmD4i79Z//xO06uEPOq5hRXdhw7nzkxQxwSavs3PSHa1ijntdpOiZ2mzOQ3fVVu8C1M19FoNM+dMUQ==} + '@rolldown/binding-darwin-x64@1.0.0-rc.17': + resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.16': - resolution: {integrity: sha512-KcRE5w8h0OnjUatG8pldyD14/CQ5Phs1oxfR+3pKDjboHRo9+MkqQaiIZlZRpsxC15paeXme/I127tUa9TXJ6g==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.16': - resolution: {integrity: sha512-bT0guA1bpxEJ/ZhTRniQf7rNF8ybvXOuWbNIeLABaV5NGjx4EtOWBTSRGWFU9ZWVkPOZ+HNFP8RMcBokBiZ0Kg==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.16': - resolution: {integrity: sha512-+tHktCHWV8BDQSjemUqm/Jl/TPk3QObCTIjmdDy/nlupcujZghmKK2962LYrqFpWu+ai01AN/REOH3NEpqvYQg==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.16': - resolution: {integrity: sha512-3fPzdREH806oRLxpTWW1Gt4tQHs0TitZFOECB2xzCFLPKnSOy90gwA7P29cksYilFO6XVRY1kzga0cL2nRjKPg==} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.16': - resolution: {integrity: sha512-EKwI1tSrLs7YVw+JPJT/G2dJQ1jl9qlTTTEG0V2Ok/RdOenRfBw2PQdLPyjhIu58ocdBfP7vIRN/pvMsPxs/AQ==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.16': - resolution: {integrity: sha512-Uknladnb3Sxqu6SEcqBldQyJUpk8NleooZEc0MbRBJ4inEhRYWZX0NJu12vNf2mqAq7gsofAxHrGghiUYjhaLQ==} + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.16': - resolution: {integrity: sha512-FIb8+uG49sZBtLTn+zt1AJ20TqVcqWeSIyoVt0or7uAWesgKaHbiBh6OpA/k9v0LTt+PTrb1Lao133kP4uVxkg==} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.16': - resolution: {integrity: sha512-RuERhF9/EgWxZEXYWCOaViUWHIboceK4/ivdtQ3R0T44NjLkIIlGIAVAuCddFxsZ7vnRHtNQUrt2vR2n2slB2w==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.16': - resolution: {integrity: sha512-mXcXnvd9GpazCxeUCCnZ2+YF7nut+ZOEbE4GtaiPtyY6AkhZWbK70y1KK3j+RDhjVq5+U8FySkKRb/+w0EeUwA==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.16': - resolution: {integrity: sha512-3Q2KQxnC8IJOLqXmUMoYwyIPZU9hzRbnHaoV3Euz+VVnjZKcY8ktnNP8T9R4/GGQtb27C/UYKABxesKWb8lsvQ==} + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.16': - resolution: {integrity: sha512-tj7XRemQcOcFwv7qhpUxMTBbI5mWMlE4c1Omhg5+h8GuLXzyj8HviYgR+bB2DMDgRqUE+jiDleqSCRjx4aYk/Q==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.16': - resolution: {integrity: sha512-PH5DRZT+F4f2PTXRXR8uJxnBq2po/xFtddyabTJVJs/ZYVHqXPEgNIr35IHTEa6bpa0Q8Awg+ymkTaGnKITw4g==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.16': - resolution: {integrity: sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA==} + '@rolldown/pluginutils@1.0.0-rc.17': + resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -405,20 +405,20 @@ packages: resolution: {integrity: sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/coverage-v8@4.1.4': - resolution: {integrity: sha512-x7FptB5oDruxNPDNY2+S8tCh0pcq7ymCe1gTHcsp733jYjrJl8V1gMUlVysuCD9Kz46Xz9t1akkv08dPcYDs1w==} + '@vitest/coverage-v8@4.1.5': + resolution: {integrity: sha512-38C0/Ddb7HcRG0Z4/DUem8x57d2p9jYgp18mkaYswEOQBGsI1CG4f/hjm0ZCeaJfWhSZ4k7jgs29V1Zom7Ki9A==} peerDependencies: - '@vitest/browser': 4.1.4 - vitest: 4.1.4 + '@vitest/browser': 4.1.5 + vitest: 4.1.5 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.4': - resolution: {integrity: sha512-iPBpra+VDuXmBFI3FMKHSFXp3Gx5HfmSCE8X67Dn+bwephCnQCaB7qWK2ldHa+8ncN8hJU8VTMcxjPpyMkUjww==} + '@vitest/expect@4.1.5': + resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==} - '@vitest/mocker@4.1.4': - resolution: {integrity: sha512-R9HTZBhW6yCSGbGQnDnH3QHfJxokKN4KB+Yvk9Q1le7eQNYwiCyKxmLmurSpFy6BzJanSLuEUDrD+j97Q+ZLPg==} + '@vitest/mocker@4.1.5': + resolution: {integrity: sha512-/x2EmFC4mT4NNzqvC3fmesuV97w5FC903KPmey4gsnJiMQ3Be1IlDKVaDaG8iqaLFHqJ2FVEkxZk5VmeLjIItw==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -428,20 +428,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.4': - resolution: {integrity: sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A==} + '@vitest/pretty-format@4.1.5': + resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==} - '@vitest/runner@4.1.4': - resolution: {integrity: sha512-xTp7VZ5aXP5ZJrn15UtJUWlx6qXLnGtF6jNxHepdPHpMfz/aVPx+htHtgcAL2mDXJgKhpoo2e9/hVJsIeFbytQ==} + '@vitest/runner@4.1.5': + resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==} - '@vitest/snapshot@4.1.4': - resolution: {integrity: sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw==} + '@vitest/snapshot@4.1.5': + resolution: {integrity: sha512-zypXEt4KH/XgKGPUz4eC2AvErYx0My5hfL8oDb1HzGFpEk1P62bxSohdyOmvz+d9UJwanI68MKwr2EquOaOgMQ==} - '@vitest/spy@4.1.4': - resolution: {integrity: sha512-XxNdAsKW7C+FLydqFJLb5KhJtl3PGCMmYwFRfhvIgxJvLSXhhVI1zM8f1qD3Zg7RCjTSzDVyct6sghs9UEgBEQ==} + '@vitest/spy@4.1.5': + resolution: {integrity: sha512-2lNOsh6+R2Idnf1TCZqSwYlKN2E/iDlD8sgU59kYVl+OMDmvldO1VDk39smRfpUNwYpNRVn3w4YfuC7KfbBnkQ==} - '@vitest/utils@4.1.4': - resolution: {integrity: sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==} + '@vitest/utils@4.1.5': + resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -800,8 +800,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -854,8 +854,8 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - postcss@8.5.10: - resolution: {integrity: sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==} + postcss@8.5.13: + resolution: {integrity: sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -906,8 +906,8 @@ packages: vue-tsc: optional: true - rolldown@1.0.0-rc.16: - resolution: {integrity: sha512-rzi5WqKzEZw3SooTt7cgm4eqIoujPIyGcJNGFL7iPEuajQw7vxMHUkXylu4/vhCkJGXsgRmxqMKXUpT6FEgl0g==} + rolldown@1.0.0-rc.17: + resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -984,14 +984,14 @@ packages: peerDependencies: typescript: '>=4.8.4' - tsdown@0.21.9: - resolution: {integrity: sha512-tZPv2zMaMnjj9H9h0SDqpSXa9YWVZWHlG46DnSgNTFX6aq001MSI8kuBzJumr/u099nWj+1v5S7rhbnHk5jCHA==} + tsdown@0.21.10: + resolution: {integrity: sha512-3wk73yBhZe/wX7REqSdivNQ84TDs1mJ+IlnzrrEREP70xlJ/AEIzqaI04l/TzMKVIdkTdC3CPaADn2Lk/0SkdA==} engines: {node: '>=20.19.0'} hasBin: true peerDependencies: '@arethetypeswrong/core': ^0.18.1 - '@tsdown/css': 0.21.9 - '@tsdown/exe': 0.21.9 + '@tsdown/css': 0.21.10 + '@tsdown/exe': 0.21.10 '@vitejs/devtools': '*' publint: ^0.3.0 typescript: ^5.0.0 || ^6.0.0 @@ -1037,8 +1037,8 @@ packages: undici-types@7.19.2: resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} - unrun@0.2.36: - resolution: {integrity: sha512-ICAGv44LHSKjCdI4B4rk99lJLHXBweutO4MUwu3cavMlYtXID0Tn5e1Kwe/Uj6BSAuHHXfi1JheFVCYhcXHfAg==} + unrun@0.2.37: + resolution: {integrity: sha512-AA7vDuYsgeSYVzJMm16UKA+aXFKhy7nFqW9z5l7q44K4ppFWZAMqYS58ePRZbugMLPH0fwwMzD5A8nP0avxwZQ==} engines: {node: '>=20.19.0'} hasBin: true peerDependencies: @@ -1050,8 +1050,8 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - vite@8.0.9: - resolution: {integrity: sha512-t7g7GVRpMXjNpa67HaVWI/8BWtdVIQPCL2WoozXXA7LBGEFK4AkkKkHx2hAQf5x1GZSlcmEDPkVLSGahxnEEZw==} + vite@8.0.10: + resolution: {integrity: sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -1093,20 +1093,20 @@ packages: yaml: optional: true - vitest@4.1.4: - resolution: {integrity: sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==} + vitest@4.1.5: + resolution: {integrity: sha512-9Xx1v3/ih3m9hN+SbfkUyy0JAs72ap3r7joc87XL6jwF0jGg6mFBvQ1SrwaX+h8BlkX6Hz9shdd1uo6AF+ZGpg==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.4 - '@vitest/browser-preview': 4.1.4 - '@vitest/browser-webdriverio': 4.1.4 - '@vitest/coverage-istanbul': 4.1.4 - '@vitest/coverage-v8': 4.1.4 - '@vitest/ui': 4.1.4 + '@vitest/browser-playwright': 4.1.5 + '@vitest/browser-preview': 4.1.5 + '@vitest/browser-webdriverio': 4.1.5 + '@vitest/coverage-istanbul': 4.1.5 + '@vitest/coverage-v8': 4.1.5 + '@vitest/ui': 4.1.5 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -1207,13 +1207,13 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@emnapi/core@1.9.2': + '@emnapi/core@1.10.0': dependencies: '@emnapi/wasi-threads': 1.2.1 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.2': + '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 optional: true @@ -1282,14 +1282,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 '@tybys/wasm-util': 0.10.1 optional: true - '@oxc-project/types@0.126.0': {} + '@oxc-project/types@0.127.0': {} '@pkgr/core@0.2.9': {} @@ -1297,56 +1297,56 @@ snapshots: dependencies: quansync: 1.0.0 - '@rolldown/binding-android-arm64@1.0.0-rc.16': + '@rolldown/binding-android-arm64@1.0.0-rc.17': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.16': + '@rolldown/binding-darwin-arm64@1.0.0-rc.17': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.16': + '@rolldown/binding-darwin-x64@1.0.0-rc.17': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.16': + '@rolldown/binding-freebsd-x64@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.16': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.16': + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.16': + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.16': + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.16': + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.16': + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.16': + '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.16': + '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.16': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.16': + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.16': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': optional: true - '@rolldown/pluginutils@1.0.0-rc.16': {} + '@rolldown/pluginutils@1.0.0-rc.17': {} '@standard-schema/spec@1.1.0': {} @@ -1481,10 +1481,10 @@ snapshots: '@typescript-eslint/types': 8.58.2 eslint-visitor-keys: 5.0.1 - '@vitest/coverage-v8@4.1.4(vitest@4.1.4)': + '@vitest/coverage-v8@4.1.5(vitest@4.1.5)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.4 + '@vitest/utils': 4.1.5 ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -1493,46 +1493,46 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.4(@types/node@25.6.0)(@vitest/coverage-v8@4.1.4)(happy-dom@20.9.0)(vite@8.0.9(@types/node@25.6.0)(less@4.6.4)) + vitest: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(less@4.6.4)) - '@vitest/expect@4.1.4': + '@vitest/expect@4.1.5': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.4 - '@vitest/utils': 4.1.4 + '@vitest/spy': 4.1.5 + '@vitest/utils': 4.1.5 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.4(vite@8.0.9(@types/node@25.6.0)(less@4.6.4))': + '@vitest/mocker@4.1.5(vite@8.0.10(@types/node@25.6.0)(less@4.6.4))': dependencies: - '@vitest/spy': 4.1.4 + '@vitest/spy': 4.1.5 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.9(@types/node@25.6.0)(less@4.6.4) + vite: 8.0.10(@types/node@25.6.0)(less@4.6.4) - '@vitest/pretty-format@4.1.4': + '@vitest/pretty-format@4.1.5': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.4': + '@vitest/runner@4.1.5': dependencies: - '@vitest/utils': 4.1.4 + '@vitest/utils': 4.1.5 pathe: 2.0.3 - '@vitest/snapshot@4.1.4': + '@vitest/snapshot@4.1.5': dependencies: - '@vitest/pretty-format': 4.1.4 - '@vitest/utils': 4.1.4 + '@vitest/pretty-format': 4.1.5 + '@vitest/utils': 4.1.5 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.4': {} + '@vitest/spy@4.1.5': {} - '@vitest/utils@4.1.4': + '@vitest/utils@4.1.5': dependencies: - '@vitest/pretty-format': 4.1.4 + '@vitest/pretty-format': 4.1.5 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -1867,7 +1867,7 @@ snapshots: ms@2.1.3: {} - nanoid@3.3.11: {} + nanoid@3.3.12: {} natural-compare@1.4.0: {} @@ -1911,9 +1911,9 @@ snapshots: pify@4.0.1: optional: true - postcss@8.5.10: + postcss@8.5.13: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -1936,7 +1936,7 @@ snapshots: resolve-pkg-maps@1.0.0: {} - rolldown-plugin-dts@0.23.2(rolldown@1.0.0-rc.16)(typescript@6.0.3): + rolldown-plugin-dts@0.23.2(rolldown@1.0.0-rc.17)(typescript@6.0.3): dependencies: '@babel/generator': 8.0.0-rc.3 '@babel/helper-validator-identifier': 8.0.0-rc.3 @@ -1948,32 +1948,32 @@ snapshots: get-tsconfig: 4.14.0 obug: 2.1.1 picomatch: 4.0.4 - rolldown: 1.0.0-rc.16 + rolldown: 1.0.0-rc.17 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - oxc-resolver - rolldown@1.0.0-rc.16: + rolldown@1.0.0-rc.17: dependencies: - '@oxc-project/types': 0.126.0 - '@rolldown/pluginutils': 1.0.0-rc.16 + '@oxc-project/types': 0.127.0 + '@rolldown/pluginutils': 1.0.0-rc.17 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.16 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.16 - '@rolldown/binding-darwin-x64': 1.0.0-rc.16 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.16 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.16 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.16 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.16 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.16 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.16 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.16 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.16 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.16 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.16 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.16 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.16 + '@rolldown/binding-android-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 + '@rolldown/binding-darwin-x64': 1.0.0-rc.17 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 safer-buffer@2.1.2: optional: true @@ -2028,7 +2028,7 @@ snapshots: dependencies: typescript: 6.0.3 - tsdown@0.21.9(synckit@0.11.12)(typescript@6.0.3): + tsdown@0.21.10(synckit@0.11.12)(typescript@6.0.3): dependencies: ansis: 4.2.0 cac: 7.0.0 @@ -2038,14 +2038,14 @@ snapshots: import-without-cache: 0.3.3 obug: 2.1.1 picomatch: 4.0.4 - rolldown: 1.0.0-rc.16 - rolldown-plugin-dts: 0.23.2(rolldown@1.0.0-rc.16)(typescript@6.0.3) + rolldown: 1.0.0-rc.17 + rolldown-plugin-dts: 0.23.2(rolldown@1.0.0-rc.17)(typescript@6.0.3) semver: 7.7.4 tinyexec: 1.1.1 tinyglobby: 0.2.16 tree-kill: 1.2.2 unconfig-core: 7.5.0 - unrun: 0.2.36(synckit@0.11.12) + unrun: 0.2.37(synckit@0.11.12) optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -2082,9 +2082,9 @@ snapshots: undici-types@7.19.2: {} - unrun@0.2.36(synckit@0.11.12): + unrun@0.2.37(synckit@0.11.12): dependencies: - rolldown: 1.0.0-rc.16 + rolldown: 1.0.0-rc.17 optionalDependencies: synckit: 0.11.12 @@ -2092,26 +2092,26 @@ snapshots: dependencies: punycode: 2.3.1 - vite@8.0.9(@types/node@25.6.0)(less@4.6.4): + vite@8.0.10(@types/node@25.6.0)(less@4.6.4): dependencies: picomatch: 4.0.4 - postcss: 8.5.10 - rolldown: 1.0.0-rc.16 + postcss: 8.5.13 + rolldown: 1.0.0-rc.17 tinyglobby: 0.2.16 optionalDependencies: '@types/node': 25.6.0 fsevents: 2.3.3 less: 4.6.4 - vitest@4.1.4(@types/node@25.6.0)(@vitest/coverage-v8@4.1.4)(happy-dom@20.9.0)(vite@8.0.9(@types/node@25.6.0)(less@4.6.4)): + vitest@4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5)(happy-dom@20.9.0)(vite@8.0.10(@types/node@25.6.0)(less@4.6.4)): dependencies: - '@vitest/expect': 4.1.4 - '@vitest/mocker': 4.1.4(vite@8.0.9(@types/node@25.6.0)(less@4.6.4)) - '@vitest/pretty-format': 4.1.4 - '@vitest/runner': 4.1.4 - '@vitest/snapshot': 4.1.4 - '@vitest/spy': 4.1.4 - '@vitest/utils': 4.1.4 + '@vitest/expect': 4.1.5 + '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@25.6.0)(less@4.6.4)) + '@vitest/pretty-format': 4.1.5 + '@vitest/runner': 4.1.5 + '@vitest/snapshot': 4.1.5 + '@vitest/spy': 4.1.5 + '@vitest/utils': 4.1.5 es-module-lexer: 2.0.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -2123,11 +2123,11 @@ snapshots: tinyexec: 1.1.1 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 8.0.9(@types/node@25.6.0)(less@4.6.4) + vite: 8.0.10(@types/node@25.6.0)(less@4.6.4) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.6.0 - '@vitest/coverage-v8': 4.1.4(vitest@4.1.4) + '@vitest/coverage-v8': 4.1.5(vitest@4.1.5) happy-dom: 20.9.0 transitivePeerDependencies: - msw