diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 7b9f2f59..b8e5fa7f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -57,6 +57,7 @@ jobs: - name: Run E2E tests for ${{ matrix.library }} env: DOCKER_DEFAULT_PLATFORM: linux/amd64 + TUSK_USE_RUST_CORE: "1" TUSK_CLI_VERSION: ${{ steps.tusk-version.outputs.version }} # Required for Firestore e2e tests FIREBASE_PROJECT_ID: ${{ vars.FIREBASE_PROJECT_ID }} diff --git a/.gitignore b/.gitignore index 1ed296e9..e04ee093 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ Thumbs.db **/e2e-tests/**/.tusk/traces/ .direnv +experimental/ +benchmarks/results/ \ No newline at end of file diff --git a/docs/rust-core-bindings.md b/docs/rust-core-bindings.md new file mode 100644 index 00000000..d06629b7 --- /dev/null +++ b/docs/rust-core-bindings.md @@ -0,0 +1,62 @@ +# Rust Core Bindings + +This document explains how Rust acceleration works in the Node SDK, how to enable it, and what fallback behavior to expect. + +## Overview + +The SDK can offload selected hot-path logic to Rust via Node bindings (`@use-tusk/drift-core-node`), defined in the [`drift-core`](https://github.com/Use-Tusk/drift-core) repository. This is controlled by an environment flag and is designed to fail open. + +At a high level: + +- Node SDK logic remains the source of truth. +- Rust paths are opportunistic optimizations. +- If Rust is unavailable or fails at runtime, SDK behavior falls back to JavaScript equivalents. + +## Enablement + +Set: + +```bash +TUSK_USE_RUST_CORE=1 +``` + +Truthy values are `1` and `true` (case-insensitive). Any other value is treated as disabled. + +## Installation Requirements + +The Node SDK currently includes `@use-tusk/drift-core-node` as a regular dependency. + +Notes: + +- There is no Node equivalent of Python extras like `[rust]`. +- Rust acceleration is still runtime-gated by `TUSK_USE_RUST_CORE`. +- If the native binding cannot be loaded on a machine, the SDK continues on JavaScript code paths. + +## Platform Coverage and Native Binary Concerns + +Node native bindings depend on OS/arch/libc compatibility of published prebuilt artifacts. + +Practical implications: + +- Some platforms may not have a matching native artifact. +- On such platforms, direct use of `@use-tusk/drift-core-node` can fail at runtime. +- Within `drift-node-sdk`, Rust helper loading is guarded and fails open to non-Rust paths. + +Unlike Python wheels, this concern appears as Node native addon compatibility rather than wheel tag compatibility. + +## Fallback Behavior + +The bridge module is fail-open: + +- Rust calls are guarded behind a binding loader. +- If `TUSK_USE_RUST_CORE` is unset/falsey, Rust is skipped. +- If loading or a Rust call fails, helper functions return `null`. +- Calling code then uses the existing JavaScript implementation. + +This means users do not need Rust installed to run the SDK when Rust acceleration is disabled or unavailable. + +## Practical Guidance + +- Default production-safe posture: keep Rust disabled unless your deployment matrix is tested. +- Performance posture: enable Rust and benchmark on your workloads before broad rollout. +- Reliability posture: keep parity/smoke tests in CI to detect drift between JS and Rust paths. diff --git a/package-lock.json b/package-lock.json index 2f67fbe4..13f8c1a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.30", "license": "Apache-2.0", "dependencies": { + "@use-tusk/drift-core-node": "0.1.6", "import-in-the-middle": "^1.14.4", "js-yaml": "^4.1.0", "jsonpath": "^1.1.1", @@ -67,14 +68,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -115,13 +116,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -131,9 +132,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -145,9 +146,9 @@ } }, "node_modules/@bufbuild/buf": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.59.0.tgz", - "integrity": "sha512-VdLuGnFp1OKJaiMevlLow6Jcvv9omOyM02Qa1zexl8dBB4Ac2ggz6bpT3Zb06tmCnqd8tFrI/Im1fbom3CznlQ==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf/-/buf-1.65.0.tgz", + "integrity": "sha512-IQmIBB2CGbJAwx1NkuAWMuj4QGPnZ8mujbf4ckx9t6KI9EzfUzql1OyKi9qPrxlLAciI+kBIyPDQ2MIvXTxWUg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -160,19 +161,19 @@ "node": ">=12" }, "optionalDependencies": { - "@bufbuild/buf-darwin-arm64": "1.59.0", - "@bufbuild/buf-darwin-x64": "1.59.0", - "@bufbuild/buf-linux-aarch64": "1.59.0", - "@bufbuild/buf-linux-armv7": "1.59.0", - "@bufbuild/buf-linux-x64": "1.59.0", - "@bufbuild/buf-win32-arm64": "1.59.0", - "@bufbuild/buf-win32-x64": "1.59.0" + "@bufbuild/buf-darwin-arm64": "1.65.0", + "@bufbuild/buf-darwin-x64": "1.65.0", + "@bufbuild/buf-linux-aarch64": "1.65.0", + "@bufbuild/buf-linux-armv7": "1.65.0", + "@bufbuild/buf-linux-x64": "1.65.0", + "@bufbuild/buf-win32-arm64": "1.65.0", + "@bufbuild/buf-win32-x64": "1.65.0" } }, "node_modules/@bufbuild/buf-darwin-arm64": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.59.0.tgz", - "integrity": "sha512-d3JTxBCibC+C94JU0jwLMgo/WBhaAHBIRzZXaZ3Y8KREjTj3jhzAlelGZmCtQJyyE0l6DFSm3lQgMblJ5qlq/w==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-arm64/-/buf-darwin-arm64-1.65.0.tgz", + "integrity": "sha512-2U8CHjW1ysINYKwIPcc4WAiQPxe91RIjNtjpg+RC9rP0aZ7TpGm5MTMY5l3sN4drtmKdb9rBs3bMQsMNhSc90A==", "cpu": [ "arm64" ], @@ -187,9 +188,9 @@ } }, "node_modules/@bufbuild/buf-darwin-x64": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.59.0.tgz", - "integrity": "sha512-eFnFB96GM6KjP5S8QFqjufjlMF41CVnXjkR8cIfR5jUXdwl1vf5S82Zv+cK1+Uogqhmt7AVBntd5Z+xmz4NKaw==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-darwin-x64/-/buf-darwin-x64-1.65.0.tgz", + "integrity": "sha512-aMqfc6pQC4L9dZpSD61XCEpPWKEtb1rXDPkK0/tzrfTWodnbaJ/elNoxsCGzbZVSMFeAdomUpXmSMrk8ALfWWw==", "cpu": [ "x64" ], @@ -204,9 +205,9 @@ } }, "node_modules/@bufbuild/buf-linux-aarch64": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.59.0.tgz", - "integrity": "sha512-g6DxTcJM29SBvqe42ll7HpkmTfecuG+PZYTysaxON9Y59fwtflhuLDpNqGhxWehHMkH11bFfpNeCGKjpGbVvkw==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-aarch64/-/buf-linux-aarch64-1.65.0.tgz", + "integrity": "sha512-gzqvY4PLRQ7g0+RlE9g+OL/6yPd5szG7e3Wd5bgjJzfKaQerNiQWaGyPLdcRsIM/WxJhT5e5lG8OrrWHwgQ9Ig==", "cpu": [ "arm64" ], @@ -221,9 +222,9 @@ } }, "node_modules/@bufbuild/buf-linux-armv7": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-armv7/-/buf-linux-armv7-1.59.0.tgz", - "integrity": "sha512-C92s+gmKnAyCzN7MdbtukRXOiW7e0hkeQrOie17vF6qWXPk2r9ix0WXZvg5gZr9R4zD8pOYwRVwYiB9zFXZOaA==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-armv7/-/buf-linux-armv7-1.65.0.tgz", + "integrity": "sha512-RpYFuPr9MKniD+WNfDgCclyvMu+/w9kK41OWr9sNnbS2BorujskwPiY0iTf5j+8+n/MeAnLIGlyC36+vUB/wIw==", "cpu": [ "arm" ], @@ -238,9 +239,9 @@ } }, "node_modules/@bufbuild/buf-linux-x64": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.59.0.tgz", - "integrity": "sha512-Pzc3TFm1t2fZ5uT7jkYBjyuLNKo5ji/wRl/lLLvOlTFRyqsSZBkFNQcJGHoHSej1yDWau16VMrAh0GN1rZfvAg==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-linux-x64/-/buf-linux-x64-1.65.0.tgz", + "integrity": "sha512-0j06h1uKCXlOtrlNcTBkURazT+AwMNvuVxgJsYeUDnSliN05QS7LnBzPOwKg76ariSqlLo+QXk9eNtdhgVjYOg==", "cpu": [ "x64" ], @@ -255,9 +256,9 @@ } }, "node_modules/@bufbuild/buf-win32-arm64": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.59.0.tgz", - "integrity": "sha512-hS5VThgYNqbMFgY9SibDA/RXBdegw12jgrT2H+Tzaa2rvlSADck9ZAq9rwf2H0IvFJOqtR75Lejb+5Fx2rThpQ==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-arm64/-/buf-win32-arm64-1.65.0.tgz", + "integrity": "sha512-KBFsQ3iEityUuLTUCoXAO6ZTGUXWljSjK4upqofsYCb4OJeSeVguD7b09efkQt9ymKsXBt5wQicsRdkMJy/VEA==", "cpu": [ "arm64" ], @@ -272,9 +273,9 @@ } }, "node_modules/@bufbuild/buf-win32-x64": { - "version": "1.59.0", - "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.59.0.tgz", - "integrity": "sha512-JAGSF3oaKC2L/TelqvjB1N7oB5pTiviVr8mxiaxHyv4HpvcxCVdiO+iw0goRhZb4QHhYYswk2gLMezWHBxtR/g==", + "version": "1.65.0", + "resolved": "https://registry.npmjs.org/@bufbuild/buf-win32-x64/-/buf-win32-x64-1.65.0.tgz", + "integrity": "sha512-vJYzHjncSLdy4sPDW8kLqUldHh6Vucg6KabAflm7CDj29lU/HydV8T+nOVsXkoRMUf4+H/qy8WjnSMEtRkaogA==", "cpu": [ "x64" ], @@ -302,9 +303,9 @@ } }, "node_modules/@emnapi/core": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.0.tgz", - "integrity": "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", "dev": true, "license": "MIT", "optional": true, @@ -314,9 +315,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.0.tgz", - "integrity": "sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", "dev": true, "license": "MIT", "optional": true, @@ -336,9 +337,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", "cpu": [ "ppc64" ], @@ -353,9 +354,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", "cpu": [ "arm" ], @@ -370,9 +371,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", "cpu": [ "arm64" ], @@ -387,9 +388,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", "cpu": [ "x64" ], @@ -404,9 +405,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", "cpu": [ "arm64" ], @@ -421,9 +422,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", "cpu": [ "x64" ], @@ -438,9 +439,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", "cpu": [ "arm64" ], @@ -455,9 +456,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", "cpu": [ "x64" ], @@ -472,9 +473,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", "cpu": [ "arm" ], @@ -489,9 +490,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", "cpu": [ "arm64" ], @@ -506,9 +507,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", "cpu": [ "ia32" ], @@ -523,9 +524,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", "cpu": [ "loong64" ], @@ -540,9 +541,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", "cpu": [ "mips64el" ], @@ -557,9 +558,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", "cpu": [ "ppc64" ], @@ -574,9 +575,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", "cpu": [ "riscv64" ], @@ -591,9 +592,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", "cpu": [ "s390x" ], @@ -608,9 +609,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", "cpu": [ "x64" ], @@ -625,9 +626,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", "cpu": [ "arm64" ], @@ -642,9 +643,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", "cpu": [ "x64" ], @@ -659,9 +660,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", "cpu": [ "arm64" ], @@ -676,9 +677,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", "cpu": [ "x64" ], @@ -693,9 +694,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", "cpu": [ "arm64" ], @@ -710,9 +711,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", "cpu": [ "x64" ], @@ -727,9 +728,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", "cpu": [ "arm64" ], @@ -744,9 +745,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", "cpu": [ "ia32" ], @@ -761,9 +762,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", "cpu": [ "x64" ], @@ -778,9 +779,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -875,9 +876,9 @@ } }, "node_modules/@grpc/grpc-js": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.1.tgz", - "integrity": "sha512-sPxgEWtPUR3EnRJCEtbGZG2iX8LQDUls2wUS3o27jg07KqJFMq6YDeWvMo1wfpmy3rqRdS0rivpLwhqQtEyCuQ==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", + "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1480,9 +1481,9 @@ } }, "node_modules/@ioredis/commands": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.4.0.tgz", - "integrity": "sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz", + "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==", "dev": true, "license": "MIT" }, @@ -1604,9 +1605,9 @@ } }, "node_modules/@mapbox/node-pre-gyp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.0.tgz", - "integrity": "sha512-llMXd39jtP0HpQLVI37Bf1m2ADlEb35GYSh1SDSLsBhR+5iCxiNGlT31yqbNtVHygHAtMy6dWFERpU2JgufhPg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-2.0.3.tgz", + "integrity": "sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -1626,9 +1627,9 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.2.tgz", - "integrity": "sha512-QgA5AySqB27cGTXBFmnpifAi7HxoGUeezwo6p9dI03MuDB6Pp33zgclqVb6oVK3j6I9Vesg0+oojW2XxB59SGg==", + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.6.tgz", + "integrity": "sha512-y+x3H1xBZd38n10NZF/rEBlvDOOMQ6LKUTHqr8R9VkJ+mmQOYtJFxIlkkK8fZrtOiL6VixbOBWMbZGBdal3Z1g==", "dev": true, "license": "MIT", "dependencies": { @@ -1636,29 +1637,33 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", - "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.5.0", - "@emnapi/runtime": "^1.5.0", + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" } }, "node_modules/@next/env": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.6.tgz", - "integrity": "sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.12.tgz", + "integrity": "sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg==", "dev": true, "license": "MIT" }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.6.tgz", - "integrity": "sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.12.tgz", + "integrity": "sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg==", "cpu": [ "arm64" ], @@ -1673,9 +1678,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.6.tgz", - "integrity": "sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.12.tgz", + "integrity": "sha512-nqa9/7iQlboF1EFtNhWxQA0rQstmYRSBGxSM6g3GxvxHxcoeqVXfGNr9stJOme674m2V7r4E3+jEhhGvSQhJRA==", "cpu": [ "x64" ], @@ -1690,9 +1695,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.6.tgz", - "integrity": "sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.12.tgz", + "integrity": "sha512-dCzAjqhDHwmoB2M4eYfVKqXs99QdQxNQVpftvP1eGVppamXh/OkDAwV737Zr0KPXEqRUMN4uCjh6mjO+XtF3Mw==", "cpu": [ "arm64" ], @@ -1707,9 +1712,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.6.tgz", - "integrity": "sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.12.tgz", + "integrity": "sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==", "cpu": [ "arm64" ], @@ -1724,9 +1729,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.6.tgz", - "integrity": "sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.12.tgz", + "integrity": "sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==", "cpu": [ "x64" ], @@ -1741,9 +1746,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.6.tgz", - "integrity": "sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.12.tgz", + "integrity": "sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==", "cpu": [ "x64" ], @@ -1758,9 +1763,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.6.tgz", - "integrity": "sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.12.tgz", + "integrity": "sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==", "cpu": [ "arm64" ], @@ -1775,9 +1780,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.6.tgz", - "integrity": "sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.12.tgz", + "integrity": "sha512-Z1Dh6lhFkxvBDH1FoW6OU/L6prYwPSlwjLiZkExIAh8fbP6iI/M7iGTQAJPYJ9YFlWobCZ1PHbchFhFYb2ADkw==", "cpu": [ "x64" ], @@ -2000,9 +2005,9 @@ } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.38.0.tgz", - "integrity": "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2143,13 +2148,13 @@ "license": "BSD-3-Clause" }, "node_modules/@quansync/fs": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-0.1.5.tgz", - "integrity": "sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz", + "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==", "dev": true, "license": "MIT", "dependencies": { - "quansync": "^0.2.11" + "quansync": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/sxzz" @@ -2275,9 +2280,9 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0-beta.48", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.48.tgz", - "integrity": "sha512-dhhk6yq8VWoC9bEPqYbsZL09mHSwfI9VuTW5V0AKiE91R0FhcJyIPsOaDcvd1FXPZL6miTqlILwM2kRpGdEr2w==", + "version": "1.0.0-rc.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.5.tgz", + "integrity": "sha512-CUlplTujmbDWp2gamvrqVKi2Or8lmngXT1WxsizJfts7JrvfGhZObciaY/+CbdbS9qNnskvwMZNEhTPrn7b+WA==", "cpu": [ "x64" ], @@ -2446,9 +2451,9 @@ } }, "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", "dev": true, "license": "MIT" }, @@ -2533,9 +2538,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", + "version": "4.19.8", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", + "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", "dev": true, "license": "MIT", "dependencies": { @@ -2613,9 +2618,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz", - "integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==", + "version": "20.19.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", + "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==", "dev": true, "license": "MIT", "dependencies": { @@ -2623,9 +2628,9 @@ } }, "node_modules/@types/pg": { - "version": "8.15.6", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", - "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.16.0.tgz", + "integrity": "sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2934,10 +2939,15 @@ "dev": true, "license": "ISC" }, + "node_modules/@use-tusk/drift-core-node": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@use-tusk/drift-core-node/-/drift-core-node-0.1.6.tgz", + "integrity": "sha512-xFvaZAbyykIoqVIEBfmuYWYquyC7C8QlWQyseQTfBK1l97YkXSZZEN3re9cgsIiqd/SNrrMZld/L9eIYmSOktg==" + }, "node_modules/@use-tusk/drift-schemas": { - "version": "0.1.24", - "resolved": "https://registry.npmjs.org/@use-tusk/drift-schemas/-/drift-schemas-0.1.24.tgz", - "integrity": "sha512-Y+xQfpseJdP4S2mcpOxxwn9oFvnhVlZ/6wvmaMxl1oAA9nraO8oN9e2inx9ft/MhwA1gwZ9mJAotfc1/MSFg0g==", + "version": "0.1.30", + "resolved": "https://registry.npmjs.org/@use-tusk/drift-schemas/-/drift-schemas-0.1.30.tgz", + "integrity": "sha512-gNU6JHqvI+BT0TvGvHjmFfPz+y4Q8vJAUdRG5mnqE6/wu+tfZla5J8nG27hd2DrpZJ3TK5kCjoG5LXlV3ftWEA==", "dev": true, "dependencies": { "@protobuf-ts/runtime": "^2.11.0", @@ -3003,9 +3013,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -3034,9 +3044,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", "dev": true, "license": "MIT", "dependencies": { @@ -3361,14 +3371,14 @@ } }, "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "dev": true, "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -3403,9 +3413,9 @@ } }, "node_modules/birpc": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.8.0.tgz", - "integrity": "sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", + "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", "dev": true, "license": "MIT", "funding": { @@ -3420,24 +3430,28 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", - "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "dev": true, "license": "MIT", "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", - "debug": "^4.4.0", + "debug": "^4.4.3", "http-errors": "^2.0.0", - "iconv-lite": "^0.6.3", + "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.0", - "type-is": "^2.0.0" + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/brace-expansion": { @@ -3564,9 +3578,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001754", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", - "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "version": "1.0.30001770", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", + "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", "dev": true, "funding": [ { @@ -3666,9 +3680,9 @@ "license": "MIT" }, "node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -3943,16 +3957,17 @@ } }, "node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", "dev": true, "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { @@ -4081,6 +4096,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, "license": "MIT" }, "node_modules/define-data-property": { @@ -4160,9 +4176,9 @@ } }, "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -4345,9 +4361,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -4358,32 +4374,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" } }, "node_modules/escalade": { @@ -4417,22 +4433,21 @@ } }, "node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" + "estraverse": "^5.2.0", + "esutils": "^2.0.2" }, "bin": { "escodegen": "bin/escodegen.js", "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">=4.0" + "node": ">=6.0" }, "optionalDependencies": { "source-map": "~0.6.1" @@ -4451,65 +4466,6 @@ "node": ">=4" } }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/eslint": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", @@ -4696,9 +4652,9 @@ } }, "node_modules/esprima": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz", - "integrity": "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz", + "integrity": "sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -4708,9 +4664,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -4737,7 +4693,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -4770,19 +4725,20 @@ } }, "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "dev": true, "license": "MIT", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.2.0", + "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", + "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", @@ -4867,6 +4823,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, "license": "MIT" }, "node_modules/fast-safe-stringify": { @@ -4877,9 +4834,9 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "dev": true, "license": "ISC", "dependencies": { @@ -4954,9 +4911,9 @@ } }, "node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "dev": true, "license": "MIT", "dependencies": { @@ -4968,7 +4925,11 @@ "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/find-up": { @@ -5072,9 +5033,9 @@ } }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "dev": true, "license": "MIT", "dependencies": { @@ -5216,9 +5177,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", "dev": true, "license": "MIT", "engines": { @@ -5268,9 +5229,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", "dev": true, "license": "MIT", "dependencies": { @@ -5281,9 +5242,10 @@ } }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -5506,30 +5468,24 @@ "license": "MIT" }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/https-proxy-agent": { @@ -5547,9 +5503,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, "license": "MIT", "dependencies": { @@ -5557,6 +5513,10 @@ }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/ignore": { @@ -5661,13 +5621,13 @@ "license": "ISC" }, "node_modules/ioredis": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.8.2.tgz", - "integrity": "sha512-C6uC+kleiIMmjViJINWk80sOQw5lEzse1ZmvD+S/s8p8CWapftSaC+kocGTx6xrbrJ4WmYQGC08ffHLr6ToR6Q==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.9.3.tgz", + "integrity": "sha512-VI5tMCdeoxZWU5vjHWsiE/Su76JGhBvWF1MJnV9ZtGltHk9BmD48oDq8Tj8haZ85aceXZMxLNDQZRVo5QKNgXA==", "dev": true, "license": "MIT", "dependencies": { - "@ioredis/commands": "1.4.0", + "@ioredis/commands": "1.5.0", "cluster-key-slot": "^1.1.0", "debug": "^4.3.4", "denque": "^2.1.0", @@ -5906,9 +5866,9 @@ } }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -5995,24 +5955,24 @@ } }, "node_modules/jsonpath": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.1.1.tgz", - "integrity": "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.2.1.tgz", + "integrity": "sha512-Jl6Jhk0jG+kP3yk59SSeGq7LFPR4JQz1DU0K+kXTysUhMostbhU3qh5mjTuf0PqFcXpAT7kvmMt9WxV10NyIgQ==", "license": "MIT", "dependencies": { - "esprima": "1.2.2", - "static-eval": "2.0.2", - "underscore": "1.12.1" + "esprima": "1.2.5", + "static-eval": "2.1.1", + "underscore": "1.13.6" } }, "node_modules/jsonwebtoken": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", - "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", "dev": true, "license": "MIT", "dependencies": { - "jws": "^3.2.2", + "jws": "^4.0.1", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -6029,9 +5989,9 @@ } }, "node_modules/jwa": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", - "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "dev": true, "license": "MIT", "dependencies": { @@ -6041,13 +6001,13 @@ } }, "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", "dev": true, "license": "MIT", "dependencies": { - "jwa": "^1.4.1", + "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, @@ -6115,9 +6075,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, @@ -6206,19 +6166,16 @@ "license": "Apache-2.0" }, "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } + "license": "ISC" }, "node_modules/lru.min": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.2.tgz", - "integrity": "sha512-Nv9KddBcQSlQopmBHXSsZVY5xsdlZkdH/Iey0BlcBYggMd4two7cZnKOK9vmy3nY0O5RGH99z1PCeTpPqszUYg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz", + "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==", "dev": true, "license": "MIT", "engines": { @@ -6417,16 +6374,20 @@ } }, "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/mimic-function": { @@ -6469,11 +6430,11 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -6498,9 +6459,9 @@ "license": "MIT" }, "node_modules/mongodb": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.20.0.tgz", - "integrity": "sha512-Tl6MEIU3K4Rq3TSHd+sZQqRBoGlFsOgNrH5ltAcFBV62Re3Fd+FcaVf8uSEQFOJ51SDowDVttBTONMfoYWrWlQ==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.21.0.tgz", + "integrity": "sha512-URyb/VXMjJ4da46OeSXg+puO39XH9DeQpWCslifrRn9JWugy0D+DvvBvkm2WxmHe61O/H19JM66p1z7RHVkZ6A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -6576,54 +6537,36 @@ } }, "node_modules/mysql2": { - "version": "3.15.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.15.3.tgz", - "integrity": "sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==", + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.17.3.tgz", + "integrity": "sha512-uCLmQMe1l96Sb6J3Ii8YJTOWJkhRmxlLJFdOfhD68jPpGTzK2fxEkFMpf5gewyHgUB0FJKzuAuPhYS+oPB0/vA==", "dev": true, "license": "MIT", "dependencies": { - "aws-ssl-profiles": "^1.1.1", + "aws-ssl-profiles": "^1.1.2", "denque": "^2.1.0", "generate-function": "^2.3.1", - "iconv-lite": "^0.7.0", - "long": "^5.2.1", - "lru.min": "^1.0.0", - "named-placeholders": "^1.1.3", - "seq-queue": "^0.0.5", - "sqlstring": "^2.3.2" + "iconv-lite": "^0.7.2", + "long": "^5.3.2", + "lru.min": "^1.1.4", + "named-placeholders": "^1.1.6", + "sql-escaper": "^1.3.3" }, "engines": { "node": ">= 8.0" } }, - "node_modules/mysql2/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/named-placeholders": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", - "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.6.tgz", + "integrity": "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==", "dev": true, "license": "MIT", "dependencies": { - "lru-cache": "^7.14.1" + "lru.min": "^1.1.0" }, "engines": { - "node": ">=12.0.0" + "node": ">=8.0.0" } }, "node_modules/nanoid": { @@ -6663,13 +6606,13 @@ } }, "node_modules/next": { - "version": "15.5.6", - "resolved": "https://registry.npmjs.org/next/-/next-15.5.6.tgz", - "integrity": "sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==", + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz", + "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==", "dev": true, "license": "MIT", "dependencies": { - "@next/env": "15.5.6", + "@next/env": "15.5.12", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", @@ -6682,14 +6625,14 @@ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.6", - "@next/swc-darwin-x64": "15.5.6", - "@next/swc-linux-arm64-gnu": "15.5.6", - "@next/swc-linux-arm64-musl": "15.5.6", - "@next/swc-linux-x64-gnu": "15.5.6", - "@next/swc-linux-x64-musl": "15.5.6", - "@next/swc-win32-arm64-msvc": "15.5.6", - "@next/swc-win32-x64-msvc": "15.5.6", + "@next/swc-darwin-arm64": "15.5.12", + "@next/swc-darwin-x64": "15.5.12", + "@next/swc-linux-arm64-gnu": "15.5.12", + "@next/swc-linux-arm64-musl": "15.5.12", + "@next/swc-linux-x64-gnu": "15.5.12", + "@next/swc-linux-x64-musl": "15.5.12", + "@next/swc-win32-arm64-msvc": "15.5.12", + "@next/swc-win32-x64-msvc": "15.5.12", "sharp": "^0.34.3" }, "peerDependencies": { @@ -6832,6 +6775,17 @@ "node": ">= 0.4" } }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -6923,9 +6877,9 @@ } }, "node_modules/p-map": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", - "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "dev": true, "license": "MIT", "engines": { @@ -7147,13 +7101,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, "node_modules/path-to-regexp": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", @@ -7183,15 +7130,15 @@ "license": "MIT" }, "node_modules/pg": { - "version": "8.16.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", - "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.18.0.tgz", + "integrity": "sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==", "dev": true, "license": "MIT", "dependencies": { - "pg-connection-string": "^2.9.1", - "pg-pool": "^3.10.1", - "pg-protocol": "^1.10.3", + "pg-connection-string": "^2.11.0", + "pg-pool": "^3.11.0", + "pg-protocol": "^1.11.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, @@ -7199,7 +7146,7 @@ "node": ">= 16.0.0" }, "optionalDependencies": { - "pg-cloudflare": "^1.2.7" + "pg-cloudflare": "^1.3.0" }, "peerDependencies": { "pg-native": ">=3.0.1" @@ -7211,17 +7158,17 @@ } }, "node_modules/pg-cloudflare": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", - "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", "dev": true, "license": "MIT", "optional": true }, "node_modules/pg-connection-string": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", - "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.11.0.tgz", + "integrity": "sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==", "dev": true, "license": "MIT" }, @@ -7236,9 +7183,9 @@ } }, "node_modules/pg-pool": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", - "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz", + "integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -7246,9 +7193,9 @@ } }, "node_modules/pg-protocol": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", - "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", + "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", "dev": true, "license": "MIT" }, @@ -7358,9 +7305,9 @@ } }, "node_modules/postgres": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.7.tgz", - "integrity": "sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==", + "version": "3.4.8", + "resolved": "https://registry.npmjs.org/postgres/-/postgres-3.4.8.tgz", + "integrity": "sha512-d+JFcLM17njZaOLkv6SCev7uoLaBtfK86vMUXhW1Z4glPWh4jozno9APvW/XKFJ3CCxVoC7OL38BqRydtu5nGg==", "dev": true, "license": "Unlicense", "engines": { @@ -7382,9 +7329,9 @@ } }, "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", "dev": true, "license": "MIT", "engines": { @@ -7425,9 +7372,9 @@ } }, "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", "bin": { @@ -7513,9 +7460,9 @@ } }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -7529,9 +7476,9 @@ } }, "node_modules/quansync": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", - "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz", + "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==", "dev": true, "funding": [ { @@ -7587,42 +7534,25 @@ } }, "node_modules/raw-body": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz", - "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "dev": true, "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.7.0", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.10" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/react": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", - "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "dev": true, "license": "MIT", "peer": true, @@ -7631,9 +7561,9 @@ } }, "node_modules/react-dom": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", - "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "dev": true, "license": "MIT", "peer": true, @@ -7641,7 +7571,7 @@ "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.0" + "react": "^19.2.4" } }, "node_modules/readdirp": { @@ -7813,7 +7743,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { @@ -7878,9 +7808,9 @@ } }, "node_modules/rolldown-plugin-dts": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.17.5.tgz", - "integrity": "sha512-dYzjLdhgsSIPmOCPJdDXiD6AUotAHVkGLNlSMdi3VmvTqk7O9H7uGzG2WGzgnDxZq6kZh31vZUbp9ZFoOhpySA==", + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.17.8.tgz", + "integrity": "sha512-76EEBlhF00yeY6M7VpMkWKI4r9WjuoMiOGey7j4D6zf3m0BR+ZrrY9hvSXdueJ3ljxSLq4DJBKFpX/X9+L7EKw==", "dev": true, "license": "MIT", "dependencies": { @@ -7889,13 +7819,13 @@ "@babel/types": "^7.28.5", "ast-kit": "^2.2.0", "birpc": "^2.8.0", - "debug": "^4.4.3", "dts-resolver": "^2.1.3", "get-tsconfig": "^4.13.0", - "magic-string": "^0.30.21" + "magic-string": "^0.30.21", + "obug": "^2.0.0" }, "engines": { - "node": ">=20.18.0" + "node": ">=20.19.0" }, "funding": { "url": "https://github.com/sponsors/sxzz" @@ -8017,9 +7947,9 @@ "peer": true }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8029,34 +7959,32 @@ } }, "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.3.5", + "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "mime-types": "^3.0.1", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", - "statuses": "^2.0.1" + "statuses": "^2.0.2" }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/seq-queue": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", - "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==", - "dev": true - }, "node_modules/serialize-error": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", @@ -8087,9 +8015,9 @@ } }, "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "dev": true, "license": "MIT", "dependencies": { @@ -8100,6 +8028,10 @@ }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/set-function-length": { @@ -8359,14 +8291,20 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/sqlstring": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", - "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "node_modules/sql-escaper": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/sql-escaper/-/sql-escaper-1.3.3.tgz", + "integrity": "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.6" + "bun": ">=1.0.0", + "deno": ">=2.0.0", + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/mysqljs/sql-escaper?sponsor=1" } }, "node_modules/stack-utils": { @@ -8400,12 +8338,12 @@ "license": "MIT" }, "node_modules/static-eval": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz", - "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.1.tgz", + "integrity": "sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==", "license": "MIT", "dependencies": { - "escodegen": "^1.8.1" + "escodegen": "^2.1.0" } }, "node_modules/statuses": { @@ -8570,9 +8508,9 @@ } }, "node_modules/superagent": { - "version": "10.2.3", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.3.tgz", - "integrity": "sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", + "integrity": "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8580,11 +8518,11 @@ "cookiejar": "^2.1.4", "debug": "^4.3.7", "fast-safe-stringify": "^2.1.1", - "form-data": "^4.0.4", + "form-data": "^4.0.5", "formidable": "^3.5.4", "methods": "^1.1.2", "mime": "2.6.0", - "qs": "^6.11.2" + "qs": "^6.14.1" }, "engines": { "node": ">=14.18.0" @@ -8631,9 +8569,9 @@ } }, "node_modules/supertap/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -8645,14 +8583,15 @@ } }, "node_modules/supertest": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.4.tgz", - "integrity": "sha512-tjLPs7dVyqgItVFirHYqe2T+MfWc2VOBQ8QFKKbWTA3PU7liZR8zoSpAi/C1k1ilm9RsXIKYf197oap9wXGVYg==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.2.2.tgz", + "integrity": "sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==", "dev": true, "license": "MIT", "dependencies": { + "cookie-signature": "^1.2.2", "methods": "^1.1.2", - "superagent": "^10.2.3" + "superagent": "^10.3.0" }, "engines": { "node": ">=14.18.0" @@ -8684,9 +8623,9 @@ } }, "node_modules/tar": { - "version": "7.5.2", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", - "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz", + "integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -8976,9 +8915,9 @@ } }, "node_modules/tsdown/node_modules/diff": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", - "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -9007,13 +8946,13 @@ "license": "0BSD" }, "node_modules/tsx": { - "version": "4.20.6", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.6.tgz", - "integrity": "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.25.0", + "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -9082,40 +9021,40 @@ } }, "node_modules/unconfig": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.4.0.tgz", - "integrity": "sha512-KM0SrvIvwQXJnbiSzur1Y+5jHSLVPhS31H5qzgjDQxGqS3PWrH6X7TxYX/JTuTlItarHkZ9ePK9t01Q6wu1c4Q==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.5.0.tgz", + "integrity": "sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==", "dev": true, "license": "MIT", "dependencies": { - "@quansync/fs": "^0.1.5", + "@quansync/fs": "^1.0.0", "defu": "^6.1.4", "jiti": "^2.6.1", - "quansync": "^0.2.11", - "unconfig-core": "7.4.0" + "quansync": "^1.0.0", + "unconfig-core": "7.5.0" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/unconfig-core": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.4.0.tgz", - "integrity": "sha512-3ew7rvES5x2LCZ/QRKV3nQQpq7eFYuszQuvZrhTHxDPKc34QFjRXI17XGiZI+WQTVIXKYeBti4v3LS39NWmhmg==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz", + "integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==", "dev": true, "license": "MIT", "dependencies": { - "@quansync/fs": "^0.1.5", - "quansync": "^0.2.11" + "@quansync/fs": "^1.0.0", + "quansync": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, "node_modules/underscore": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", - "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "license": "MIT" }, "node_modules/undici-types": { @@ -9239,6 +9178,7 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9429,9 +9369,9 @@ } }, "node_modules/yaml": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "dev": true, "license": "ISC", "bin": { @@ -9439,6 +9379,9 @@ }, "engines": { "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { diff --git a/package.json b/package.json index b98471bb..c1172969 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "typescript": "^5.0.0" }, "dependencies": { + "@use-tusk/drift-core-node": "0.1.6", "import-in-the-middle": "^1.14.4", "js-yaml": "^4.1.0", "jsonpath": "^1.1.1", diff --git a/src/core/rustCoreBinding.ts b/src/core/rustCoreBinding.ts new file mode 100644 index 00000000..b82c47a2 --- /dev/null +++ b/src/core/rustCoreBinding.ts @@ -0,0 +1,225 @@ +import type { + BuildSpanProtoBytesInput as RustBuildSpanProtoBytesInput, +} from "@use-tusk/drift-core-node"; + +type RustCoreNodeBinding = Pick< + typeof import("@use-tusk/drift-core-node"), + "processExportPayload" | "buildSpanProtoBytes" | "buildExportSpansRequestBytes" +>; + +export type ProcessExportPayloadResult = { + normalizedValue: unknown; + decodedValueHash: string; + decodedSchema: unknown; + decodedSchemaHash: string; +}; + +export type BuildSpanProtoBytesInput = { + traceId: string; + spanId: string; + parentSpanId: string; + name: string; + packageName: string; + instrumentationName: string; + submoduleName: string; + packageType: number; + environment?: string; + kind: number; + inputSchema: unknown; + outputSchema: unknown; + inputSchemaHash: string; + outputSchemaHash: string; + inputValueHash: string; + outputValueHash: string; + statusCode: number; + statusMessage: string; + isPreAppStart: boolean; + isRootSpan: boolean; + timestampSeconds: number; + timestampNanos: number; + durationSeconds: number; + durationNanos: number; + metadata?: unknown; + inputValue?: unknown; + outputValue?: unknown; + inputValueProtoStructBytes?: Buffer; + outputValueProtoStructBytes?: Buffer; +}; + +let bindingLoadAttempted = false; +let binding: RustCoreNodeBinding | null = null; + +function isRustCoreEnabled(): boolean { + const raw = process.env.TUSK_USE_RUST_CORE; + if (!raw) { + return false; + } + return raw === "1" || raw.toLowerCase() === "true"; +} + +function loadBinding(): RustCoreNodeBinding | null { + if (bindingLoadAttempted) { + return binding; + } + bindingLoadAttempted = true; + + if (!isRustCoreEnabled()) { + return null; + } + + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + binding = require("@use-tusk/drift-core-node") as RustCoreNodeBinding; + } catch { + binding = null; + } + return binding; +} + +function toRustSchemaMerges(schemaMerges?: Record): Record | undefined { + if (!schemaMerges) { + return undefined; + } + const out: Record = {}; + for (const [key, value] of Object.entries(schemaMerges)) { + out[key] = { + ...(value.encoding !== undefined ? { encoding: value.encoding } : {}), + ...(value.decodedType !== undefined ? { decoded_type: value.decodedType } : {}), + ...(value.matchImportance !== undefined ? { match_importance: value.matchImportance } : {}), + }; + } + return out; +} + +function normalizeSchemaKeys(value: any): any { + if (Array.isArray(value)) { + return value.map(normalizeSchemaKeys); + } + if (!value || typeof value !== "object") { + return value; + } + const out: Record = {}; + for (const [k, v] of Object.entries(value)) { + if (k === "decoded_type") { + out.decodedType = normalizeSchemaKeys(v); + } else if (k === "match_importance") { + out.matchImportance = normalizeSchemaKeys(v); + } else { + out[k] = normalizeSchemaKeys(v); + } + } + return out; +} + +function denormalizeSchemaKeys(value: any): any { + if (Array.isArray(value)) { + return value.map(denormalizeSchemaKeys); + } + if (!value || typeof value !== "object") { + return value; + } + const out: Record = {}; + for (const [k, v] of Object.entries(value)) { + if (k === "decodedType") { + out.decoded_type = denormalizeSchemaKeys(v); + } else if (k === "matchImportance") { + out.match_importance = denormalizeSchemaKeys(v); + } else { + out[k] = denormalizeSchemaKeys(v); + } + } + return out; +} + +export function processExportPayloadJsonable( + payload: unknown, + schemaMerges?: Record, +): ProcessExportPayloadResult | null { + const loaded = loadBinding(); + if (!loaded) { + return null; + } + + try { + const payloadJson = JSON.stringify(payload); + const rustSchemaMerges = toRustSchemaMerges(schemaMerges); + const schemaMergesJson = rustSchemaMerges ? JSON.stringify(rustSchemaMerges) : undefined; + const result = loaded.processExportPayload(payloadJson, schemaMergesJson); + + return { + normalizedValue: JSON.parse(result.normalizedJson), + decodedValueHash: result.decodedValueHash, + decodedSchema: normalizeSchemaKeys(JSON.parse(result.decodedSchemaJson)), + decodedSchemaHash: result.decodedSchemaHash, + }; + } catch { + return null; + } +} + +export function buildSpanProtoBytes(input: BuildSpanProtoBytesInput): Buffer | null { + const loaded = loadBinding(); + if (!loaded) { + return null; + } + try { + const rustInput: RustBuildSpanProtoBytesInput = { + traceId: input.traceId, + spanId: input.spanId, + parentSpanId: input.parentSpanId, + name: input.name, + packageName: input.packageName, + instrumentationName: input.instrumentationName, + submoduleName: input.submoduleName, + packageType: input.packageType, + environment: input.environment, + kind: input.kind, + inputSchemaJson: JSON.stringify(denormalizeSchemaKeys(input.inputSchema)), + outputSchemaJson: JSON.stringify(denormalizeSchemaKeys(input.outputSchema)), + inputSchemaHash: input.inputSchemaHash, + outputSchemaHash: input.outputSchemaHash, + inputValueHash: input.inputValueHash, + outputValueHash: input.outputValueHash, + statusCode: input.statusCode, + statusMessage: input.statusMessage, + isPreAppStart: input.isPreAppStart, + isRootSpan: input.isRootSpan, + timestampSeconds: input.timestampSeconds, + timestampNanos: input.timestampNanos, + durationSeconds: input.durationSeconds, + durationNanos: input.durationNanos, + metadataJson: input.metadata === undefined ? undefined : JSON.stringify(input.metadata), + inputValueJson: input.inputValue === undefined ? undefined : JSON.stringify(input.inputValue), + outputValueJson: input.outputValue === undefined ? undefined : JSON.stringify(input.outputValue), + inputValueProtoStructBytes: input.inputValueProtoStructBytes, + outputValueProtoStructBytes: input.outputValueProtoStructBytes, + }; + return loaded.buildSpanProtoBytes(rustInput); + } catch { + return null; + } +} + +export function buildExportSpansRequestBytes( + observableServiceId: string, + environment: string, + sdkVersion: string, + sdkInstanceId: string, + spanProtoBytesList: Buffer[], +): Buffer | null { + const loaded = loadBinding(); + if (!loaded) { + return null; + } + try { + return loaded.buildExportSpansRequestBytes( + observableServiceId, + environment, + sdkVersion, + sdkInstanceId, + spanProtoBytesList, + ); + } catch { + return null; + } +} diff --git a/src/core/tracing/SpanTransformer.ts b/src/core/tracing/SpanTransformer.ts index d09bc8ee..dd1ecea3 100644 --- a/src/core/tracing/SpanTransformer.ts +++ b/src/core/tracing/SpanTransformer.ts @@ -1,14 +1,46 @@ import { ReadableSpan } from "@opentelemetry/sdk-trace-base"; import { SpanKind as OtSpanKind } from "@opentelemetry/api"; -import { JsonSchemaHelper, JsonSchemaType, JsonSchema } from "./JsonSchemaHelper"; +import { JsonSchemaHelper, JsonSchemaType, JsonSchema, SchemaMerges } from "./JsonSchemaHelper"; import { CleanSpanData, TdSpanAttributes } from "../types"; import { PackageType, StatusCode } from "@use-tusk/drift-schemas/core/span"; import { logger } from "../utils"; +import { buildSpanProtoBytes, processExportPayloadJsonable } from "../rustCoreBinding"; /** * Utility class for transforming OpenTelemetry spans to CleanSpanData */ export class SpanTransformer { + private static processPayload( + data: unknown, + schemaMerges?: SchemaMerges, + ): { + normalizedValue: unknown; + schema: JsonSchema; + decodedValueHash: string; + decodedSchemaHash: string; + } { + const rustResult = processExportPayloadJsonable(data, schemaMerges); + if (rustResult) { + return { + normalizedValue: rustResult.normalizedValue, + schema: rustResult.decodedSchema as JsonSchema, + decodedValueHash: rustResult.decodedValueHash, + decodedSchemaHash: rustResult.decodedSchemaHash, + }; + } + + const { schema, decodedValueHash, decodedSchemaHash } = JsonSchemaHelper.generateSchemaAndHash( + data, + schemaMerges, + ); + return { + normalizedValue: data, + schema, + decodedValueHash, + decodedSchemaHash, + }; + } + /** * Transform OpenTelemetry span to clean JSON format with compile-time type safety * Return type is derived from protobuf schema but uses clean JSON. @@ -34,10 +66,11 @@ export class SpanTransformer { : undefined; const { + normalizedValue: normalizedInputData, schema: inputSchema, decodedValueHash: inputValueHash, decodedSchemaHash: inputSchemaHash, - } = JsonSchemaHelper.generateSchemaAndHash(inputData, inputSchemaMerges); + } = SpanTransformer.processPayload(inputData, inputSchemaMerges); // Process output data let outputData: unknown = {}; @@ -56,16 +89,18 @@ export class SpanTransformer { : undefined; ({ + normalizedValue: outputData, schema: outputSchema, decodedValueHash: outputValueHash, decodedSchemaHash: outputSchemaHash, - } = JsonSchemaHelper.generateSchemaAndHash(outputData, outputSchemaMerges)); + } = SpanTransformer.processPayload(outputData, outputSchemaMerges)); } else { ({ + normalizedValue: outputData, schema: outputSchema, decodedValueHash: outputValueHash, decodedSchemaHash: outputSchemaHash, - } = JsonSchemaHelper.generateSchemaAndHash(outputData)); + } = SpanTransformer.processPayload(outputData)); } let metadata: Record | undefined = undefined; @@ -85,6 +120,36 @@ export class SpanTransformer { } } + const protoSpanBytes = buildSpanProtoBytes({ + traceId: span.spanContext().traceId, + spanId: span.spanContext().spanId, + parentSpanId: span.parentSpanId || "", + name: (attributes[TdSpanAttributes.NAME] as string) || "", + packageName, + instrumentationName, + submoduleName: submoduleName || "", + packageType: ((attributes[TdSpanAttributes.PACKAGE_TYPE] as PackageType) || PackageType.UNSPECIFIED) as number, + environment, + kind: span.kind as number, + inputSchema, + outputSchema, + inputSchemaHash, + outputSchemaHash, + inputValueHash, + outputValueHash, + statusCode: span.status.code === 1 ? StatusCode.OK : StatusCode.ERROR, + statusMessage: span.status.message || "", + isPreAppStart: attributes[TdSpanAttributes.IS_PRE_APP_START] === true, + isRootSpan, + timestampSeconds: span.startTime[0], + timestampNanos: span.startTime[1], + durationSeconds: span.duration[0], + durationNanos: span.duration[1], + metadata, + inputValue: normalizedInputData, + outputValue: outputData, + }); + return { traceId: span.spanContext().traceId, spanId: span.spanContext().spanId, @@ -99,7 +164,7 @@ export class SpanTransformer { packageType: (attributes[TdSpanAttributes.PACKAGE_TYPE] as PackageType) ?? undefined, environment, - inputValue: inputData, + inputValue: normalizedInputData, outputValue: outputData, inputSchema, outputSchema, @@ -130,6 +195,7 @@ export class SpanTransformer { isRootSpan, metadata, transformMetadata, + protoSpanBytes: protoSpanBytes ?? undefined, } satisfies CleanSpanData; } diff --git a/src/core/tracing/adapters/ApiSpanAdapter.ts b/src/core/tracing/adapters/ApiSpanAdapter.ts index 570793c2..7d516fe0 100644 --- a/src/core/tracing/adapters/ApiSpanAdapter.ts +++ b/src/core/tracing/adapters/ApiSpanAdapter.ts @@ -2,12 +2,13 @@ import { ExportResult, ExportResultCode } from "@opentelemetry/core"; import type { SpanExportAdapter } from "../TdSpanExporter"; import { CleanSpanData } from "../../types"; import { SpanExportServiceClient } from "@use-tusk/drift-schemas/backend/span_export_service.client"; -import { ExportSpansRequest } from "@use-tusk/drift-schemas/backend/span_export_service"; +import { ExportSpansRequest, ExportSpansResponse } from "@use-tusk/drift-schemas/backend/span_export_service"; import { TwirpFetchTransport } from "@protobuf-ts/twirp-transport"; import { Span, PackageType, SpanKind as DriftSpanKind } from "@use-tusk/drift-schemas/core/span"; import { SpanKind as OtelSpanKind } from "@opentelemetry/api"; import { toStruct } from "../../utils/protobufUtils"; import { logger } from "../../utils/logger"; +import { buildExportSpansRequestBytes } from "../../rustCoreBinding"; export interface ApiSpanAdapterConfig { apiKey: string; @@ -25,6 +26,8 @@ const DRIFT_API_PATH = "/api/drift"; */ export class ApiSpanAdapter implements SpanExportAdapter { readonly name = "api"; + private apiKey: string; + private tuskBackendBaseUrl: string; private spanExportClient: SpanExportServiceClient; private observableServiceId: string; private environment?: string; @@ -32,6 +35,8 @@ export class ApiSpanAdapter implements SpanExportAdapter { private sdkInstanceId: string; constructor(config: ApiSpanAdapterConfig) { + this.apiKey = config.apiKey; + this.tuskBackendBaseUrl = config.tuskBackendBaseUrl; this.observableServiceId = config.observableServiceId; this.environment = config.environment; this.sdkVersion = config.sdkVersion; @@ -51,6 +56,45 @@ export class ApiSpanAdapter implements SpanExportAdapter { async exportSpans(spans: CleanSpanData[]): Promise { try { + const rustRequestBytes = buildExportSpansRequestBytes( + this.observableServiceId, + this.environment || "", + this.sdkVersion, + this.sdkInstanceId, + spans + .map((s) => s.protoSpanBytes) + .filter((s): s is Buffer => Buffer.isBuffer(s)), + ); + const allSpansHavePrebuiltBytes = spans.length > 0 && spans.every((s) => Buffer.isBuffer(s.protoSpanBytes)); + + if (allSpansHavePrebuiltBytes && rustRequestBytes) { + const response = await fetch( + `${this.tuskBackendBaseUrl}${DRIFT_API_PATH}/tusk.drift.backend.v1.SpanExportService/ExportSpans`, + { + method: "POST", + headers: { + "x-api-key": this.apiKey, + "x-td-skip-instrumentation": "true", + "Content-Type": "application/protobuf", + }, + body: new Uint8Array(rustRequestBytes), + }, + ); + + if (!response.ok) { + throw new Error(`Remote export failed with status ${response.status}`); + } + + const responseBytes = new Uint8Array(await response.arrayBuffer()); + const parsed = ExportSpansResponse.fromBinary(responseBytes); + if (!parsed.success) { + throw new Error(`Remote export failed: ${parsed.message}`); + } + + logger.debug(`Successfully exported ${spans.length} spans to remote endpoint (rust binary path)`); + return { code: ExportResultCode.SUCCESS }; + } + // Transform spans to protobuf format const protoSpans: Span[] = spans.map((span) => this.transformSpanToProtobuf(span)); diff --git a/src/core/types.ts b/src/core/types.ts index d7e02676..aaca155b 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -107,6 +107,7 @@ export type CleanSpanData = { // sdk-specific isUsed?: boolean; stackTrace?: string; + protoSpanBytes?: Buffer; }; export type MockRequestData = { diff --git a/src/instrumentation/libraries/fetch/e2e-tests/cjs-fetch/run.sh b/src/instrumentation/libraries/fetch/e2e-tests/cjs-fetch/run.sh index 55cb5d5a..dd9ca100 100755 --- a/src/instrumentation/libraries/fetch/e2e-tests/cjs-fetch/run.sh +++ b/src/instrumentation/libraries/fetch/e2e-tests/cjs-fetch/run.sh @@ -34,7 +34,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/fetch/e2e-tests/esm-fetch/run.sh b/src/instrumentation/libraries/fetch/e2e-tests/esm-fetch/run.sh index 4cb7ab08..8795bfb0 100755 --- a/src/instrumentation/libraries/fetch/e2e-tests/esm-fetch/run.sh +++ b/src/instrumentation/libraries/fetch/e2e-tests/esm-fetch/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/firestore/e2e-tests/cjs-firestore/run.sh b/src/instrumentation/libraries/firestore/e2e-tests/cjs-firestore/run.sh index 45af8741..8fa4f0cb 100755 --- a/src/instrumentation/libraries/firestore/e2e-tests/cjs-firestore/run.sh +++ b/src/instrumentation/libraries/firestore/e2e-tests/cjs-firestore/run.sh @@ -44,7 +44,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/firestore/e2e-tests/esm-firestore/run.sh b/src/instrumentation/libraries/firestore/e2e-tests/esm-firestore/run.sh index 8c55980a..e74dfdb8 100755 --- a/src/instrumentation/libraries/firestore/e2e-tests/esm-firestore/run.sh +++ b/src/instrumentation/libraries/firestore/e2e-tests/esm-firestore/run.sh @@ -44,7 +44,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/grpc/e2e-tests/cjs-grpc/run.sh b/src/instrumentation/libraries/grpc/e2e-tests/cjs-grpc/run.sh index c90b8a2a..4c0d9286 100755 --- a/src/instrumentation/libraries/grpc/e2e-tests/cjs-grpc/run.sh +++ b/src/instrumentation/libraries/grpc/e2e-tests/cjs-grpc/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/grpc/e2e-tests/esm-grpc/run.sh b/src/instrumentation/libraries/grpc/e2e-tests/esm-grpc/run.sh index 5bcbeca7..f113ea85 100755 --- a/src/instrumentation/libraries/grpc/e2e-tests/esm-grpc/run.sh +++ b/src/instrumentation/libraries/grpc/e2e-tests/esm-grpc/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/http/e2e-tests/cjs-http/run.sh b/src/instrumentation/libraries/http/e2e-tests/cjs-http/run.sh index 5e081718..b67bc91f 100755 --- a/src/instrumentation/libraries/http/e2e-tests/cjs-http/run.sh +++ b/src/instrumentation/libraries/http/e2e-tests/cjs-http/run.sh @@ -40,7 +40,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/http/e2e-tests/esm-http/run.sh b/src/instrumentation/libraries/http/e2e-tests/esm-http/run.sh index f7d0102e..847bf647 100755 --- a/src/instrumentation/libraries/http/e2e-tests/esm-http/run.sh +++ b/src/instrumentation/libraries/http/e2e-tests/esm-http/run.sh @@ -40,7 +40,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/ioredis/e2e-tests/cjs-ioredis/run.sh b/src/instrumentation/libraries/ioredis/e2e-tests/cjs-ioredis/run.sh index 89d5d240..9db922e9 100755 --- a/src/instrumentation/libraries/ioredis/e2e-tests/cjs-ioredis/run.sh +++ b/src/instrumentation/libraries/ioredis/e2e-tests/cjs-ioredis/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/ioredis/e2e-tests/esm-ioredis/run.sh b/src/instrumentation/libraries/ioredis/e2e-tests/esm-ioredis/run.sh index d10d67e7..5002f1d6 100755 --- a/src/instrumentation/libraries/ioredis/e2e-tests/esm-ioredis/run.sh +++ b/src/instrumentation/libraries/ioredis/e2e-tests/esm-ioredis/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/mysql/e2e-tests/cjs-mysql/run.sh b/src/instrumentation/libraries/mysql/e2e-tests/cjs-mysql/run.sh index f9b02f38..f656f6ee 100755 --- a/src/instrumentation/libraries/mysql/e2e-tests/cjs-mysql/run.sh +++ b/src/instrumentation/libraries/mysql/e2e-tests/cjs-mysql/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/mysql/e2e-tests/esm-mysql/run.sh b/src/instrumentation/libraries/mysql/e2e-tests/esm-mysql/run.sh index 09249948..396260ac 100755 --- a/src/instrumentation/libraries/mysql/e2e-tests/esm-mysql/run.sh +++ b/src/instrumentation/libraries/mysql/e2e-tests/esm-mysql/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/mysql2/Instrumentation.ts b/src/instrumentation/libraries/mysql2/Instrumentation.ts index 878e4990..e6796b66 100644 --- a/src/instrumentation/libraries/mysql2/Instrumentation.ts +++ b/src/instrumentation/libraries/mysql2/Instrumentation.ts @@ -32,6 +32,8 @@ const V3_11_5_TO_4_0 = ">=3.11.5 <4.0.0"; export class Mysql2Instrumentation extends TdInstrumentationBase { private readonly INSTRUMENTATION_NAME = "Mysql2Instrumentation"; + private readonly CONTEXT_BOUND_CONNECTION = Symbol("mysql2-context-bound-connection"); + private readonly CONTEXT_BOUND_PARENT_CONTEXT = Symbol("mysql2-bound-parent-context"); private mode: TuskDriftMode; private queryMock: TdMysql2QueryMock; @@ -373,7 +375,7 @@ export class Mysql2Instrumentation extends TdInstrumentationBase { } const inputValue: Mysql2InputValue = { - sql: queryConfig.sql, + sql: self.normalizeSqlForMockMatching(queryConfig.sql), values: queryConfig.values || [], clientType, }; @@ -484,7 +486,7 @@ export class Mysql2Instrumentation extends TdInstrumentationBase { } const inputValue: Mysql2InputValue = { - sql: queryConfig.sql, + sql: self.normalizeSqlForMockMatching(queryConfig.sql), values: queryConfig.values || [], clientType, }; @@ -1402,6 +1404,29 @@ export class Mysql2Instrumentation extends TdInstrumentationBase { return null; } + normalizeSqlForMockMatching(sql: string): string { + if (!sql) return sql; + + const trimmed = sql.trim(); + + // knex nested transactions: SAVEPOINT trx[;] + if (/^savepoint\s+trx\d+\s*;?$/i.test(trimmed)) { + return trimmed.replace(/^(savepoint\s+)trx\d+(\s*;?)$/i, "$1trx$2"); + } + + // knex savepoint release: RELEASE SAVEPOINT trx[;] + if (/^release\s+savepoint\s+trx\d+\s*;?$/i.test(trimmed)) { + return trimmed.replace(/^(release\s+savepoint\s+)trx\d+(\s*;?)$/i, "$1trx$2"); + } + + // knex rollback to savepoint: ROLLBACK TO SAVEPOINT trx[;] + if (/^rollback\s+to\s+savepoint\s+trx\d+\s*;?$/i.test(trimmed)) { + return trimmed.replace(/^(rollback\s+to\s+savepoint\s+)trx\d+(\s*;?)$/i, "$1trx$2"); + } + + return sql; + } + private _handleRecordQueryInSpan( spanInfo: SpanInfo, originalQuery: Function, @@ -1549,9 +1574,15 @@ export class Mysql2Instrumentation extends TdInstrumentationBase { callback: Function | undefined, context: Pool, ): any { + // Preserve request trace context across mysql2 callback/promise boundaries. + const parentContext = otelContext.active(); + if (callback) { // Callback-based getConnection const wrappedCallback = (error: Error | null, connection?: PoolConnection) => { + const scopedConnection = connection + ? this._bindConnectionMethodsToContext(connection, parentContext) + : connection; if (error) { logger.debug( `[Mysql2Instrumentation] MySQL2 Pool getConnection error: ${error.message} (${SpanUtils.getTraceInfo()})`, @@ -1572,7 +1603,7 @@ export class Mysql2Instrumentation extends TdInstrumentationBase { SpanUtils.addSpanAttributes(spanInfo.span, { outputValue: { connected: true, - hasConnection: !!connection, + hasConnection: !!scopedConnection, }, }); SpanUtils.endSpan(spanInfo.span, { code: SpanStatusCode.OK }); @@ -1580,55 +1611,92 @@ export class Mysql2Instrumentation extends TdInstrumentationBase { logger.error(`[Mysql2Instrumentation] error processing getConnection response:`, error); } } - return callback(error, connection); + return otelContext.with(parentContext, () => callback(error, scopedConnection)); }; - return originalGetConnection.call(context, wrappedCallback); + return otelContext.with(parentContext, () => originalGetConnection.call(context, wrappedCallback)); } else { // Promise-based getConnection - const promise = originalGetConnection.call(context); + const promise = otelContext.with(parentContext, () => originalGetConnection.call(context)); return promise .then((connection: PoolConnection) => { - logger.debug( - `[Mysql2Instrumentation] MySQL2 Pool getConnection completed successfully (${SpanUtils.getTraceInfo()})`, - ); - try { - SpanUtils.addSpanAttributes(spanInfo.span, { - outputValue: { - connected: true, - hasConnection: !!connection, - }, - }); - SpanUtils.endSpan(spanInfo.span, { code: SpanStatusCode.OK }); - } catch (error) { - logger.error(`[Mysql2Instrumentation] error processing getConnection response:`, error); - } - return connection; + const scopedConnection = this._bindConnectionMethodsToContext(connection, parentContext); + return otelContext.with(parentContext, () => { + logger.debug( + `[Mysql2Instrumentation] MySQL2 Pool getConnection completed successfully (${SpanUtils.getTraceInfo()})`, + ); + try { + SpanUtils.addSpanAttributes(spanInfo.span, { + outputValue: { + connected: true, + hasConnection: !!scopedConnection, + }, + }); + SpanUtils.endSpan(spanInfo.span, { code: SpanStatusCode.OK }); + } catch (error) { + logger.error(`[Mysql2Instrumentation] error processing getConnection response:`, error); + } + return scopedConnection; + }); }) .catch((error: Error) => { - logger.debug( - `[Mysql2Instrumentation] MySQL2 Pool getConnection error: ${error.message} (${SpanUtils.getTraceInfo()})`, - ); - try { - SpanUtils.endSpan(spanInfo.span, { - code: SpanStatusCode.ERROR, - message: error.message, - }); - } catch (error) { - logger.error(`[Mysql2Instrumentation] error ending span:`, error); - } - throw error; + return otelContext.with(parentContext, () => { + logger.debug( + `[Mysql2Instrumentation] MySQL2 Pool getConnection error: ${error.message} (${SpanUtils.getTraceInfo()})`, + ); + try { + SpanUtils.endSpan(spanInfo.span, { + code: SpanStatusCode.ERROR, + message: error.message, + }); + } catch (error) { + logger.error(`[Mysql2Instrumentation] error ending span:`, error); + } + throw error; + }); }); } } + private _bindConnectionMethodsToContext( + connection: PoolConnection, + parentContext: ReturnType, + ): PoolConnection { + const conn = connection as any; + if (!conn) { + return connection; + } + + // PoolConnection objects are reused by mysql2 pools. Always refresh the + // request context so wrappers use the current checkout context. + conn[this.CONTEXT_BOUND_PARENT_CONTEXT] = parentContext; + + if (conn[this.CONTEXT_BOUND_CONNECTION]) { + return connection; + } + + const methods = ["query", "execute", "beginTransaction", "commit", "rollback"]; + for (const method of methods) { + const original = conn[method]; + if (typeof original !== "function") continue; + conn[method] = (...args: any[]) => { + const boundContext = conn[this.CONTEXT_BOUND_PARENT_CONTEXT] ?? otelContext.active(); + return otelContext.with(boundContext, () => original.apply(conn, args)); + }; + } + + conn[this.CONTEXT_BOUND_CONNECTION] = true; + return connection; + } + private handleNoOpReplayGetConnection(callback?: Function): any { logger.debug( `[Mysql2Instrumentation] Background getConnection detected, returning mock connection`, ); - const mockConnection = new TdMysql2ConnectionMock(this, "pool"); + // PoolConnection extends Connection; match record-mode naming/hashes. + const mockConnection = new TdMysql2ConnectionMock(this, "connection"); if (callback) { process.nextTick(() => callback(null, mockConnection)); @@ -1641,7 +1709,8 @@ export class Mysql2Instrumentation extends TdInstrumentationBase { logger.debug(`[Mysql2Instrumentation] Replaying MySQL2 Pool getConnection`); // For pool getConnection operations, simulate returning a mock connection - const mockConnection = new TdMysql2ConnectionMock(this, "pool", spanInfo); + // PoolConnection extends Connection; match record-mode naming/hashes. + const mockConnection = new TdMysql2ConnectionMock(this, "connection", spanInfo); if (callback) { process.nextTick(() => callback(null, mockConnection)); diff --git a/src/instrumentation/libraries/mysql2/e2e-tests/cjs-mysql2/run.sh b/src/instrumentation/libraries/mysql2/e2e-tests/cjs-mysql2/run.sh index 6044dcb9..6bfd9ca0 100755 --- a/src/instrumentation/libraries/mysql2/e2e-tests/cjs-mysql2/run.sh +++ b/src/instrumentation/libraries/mysql2/e2e-tests/cjs-mysql2/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/mysql2/e2e-tests/esm-mysql2/run.sh b/src/instrumentation/libraries/mysql2/e2e-tests/esm-mysql2/run.sh index 7867e91c..10ceb41e 100755 --- a/src/instrumentation/libraries/mysql2/e2e-tests/esm-mysql2/run.sh +++ b/src/instrumentation/libraries/mysql2/e2e-tests/esm-mysql2/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/mysql2/mocks/TdMysql2ConnectionMock.ts b/src/instrumentation/libraries/mysql2/mocks/TdMysql2ConnectionMock.ts index ec774df9..a5483830 100644 --- a/src/instrumentation/libraries/mysql2/mocks/TdMysql2ConnectionMock.ts +++ b/src/instrumentation/libraries/mysql2/mocks/TdMysql2ConnectionMock.ts @@ -39,7 +39,8 @@ export class TdMysql2ConnectionMock extends EventEmitter { query(...args: any[]) { logger.debug(`[TdMysql2ConnectionMock] Mock connection query intercepted in REPLAY mode`); - const stackTrace = captureStackTrace(["TdMysql2ConnectionMock"]); + // Align replay stack traces with record path by removing both wrapper layers. + const stackTrace = captureStackTrace(["TdMysql2ConnectionMock", "Mysql2Instrumentation"]); // Parse query arguments similar to the main query patch const queryConfig = this.mysql2Instrumentation.parseQueryArgs(args); @@ -57,7 +58,7 @@ export class TdMysql2ConnectionMock extends EventEmitter { } const rawInputValue = { - sql: queryConfig.sql, + sql: this.mysql2Instrumentation.normalizeSqlForMockMatching(queryConfig.sql), values: queryConfig.values || [], clientType: this.clientType, // Use the stored clientType instead of hardcoded value }; @@ -69,6 +70,7 @@ export class TdMysql2ConnectionMock extends EventEmitter { queryConfig, inputValue, this.spanInfo, + "query", stackTrace, ); } else { @@ -81,7 +83,8 @@ export class TdMysql2ConnectionMock extends EventEmitter { execute(...args: any[]) { logger.debug(`[TdMysql2ConnectionMock] Mock connection execute intercepted in REPLAY mode`); - const stackTrace = captureStackTrace(["TdMysql2ConnectionMock"]); + // Align replay stack traces with record path by removing both wrapper layers. + const stackTrace = captureStackTrace(["TdMysql2ConnectionMock", "Mysql2Instrumentation"]); // Parse execute arguments similar to the main execute patch const queryConfig = this.mysql2Instrumentation.parseQueryArgs(args); @@ -99,7 +102,7 @@ export class TdMysql2ConnectionMock extends EventEmitter { } const rawInputValue = { - sql: queryConfig.sql, + sql: this.mysql2Instrumentation.normalizeSqlForMockMatching(queryConfig.sql), values: queryConfig.values || [], clientType: this.clientType, // Use the stored clientType instead of hardcoded value }; @@ -111,6 +114,7 @@ export class TdMysql2ConnectionMock extends EventEmitter { queryConfig, inputValue, this.spanInfo, + "execute", stackTrace, ); } else { diff --git a/src/instrumentation/libraries/mysql2/mocks/TdMysql2QueryMock.ts b/src/instrumentation/libraries/mysql2/mocks/TdMysql2QueryMock.ts index b26b41fa..44d9a11b 100644 --- a/src/instrumentation/libraries/mysql2/mocks/TdMysql2QueryMock.ts +++ b/src/instrumentation/libraries/mysql2/mocks/TdMysql2QueryMock.ts @@ -1,7 +1,7 @@ import { EventEmitter } from "events"; import { Readable } from "stream"; import { SpanKind } from "@opentelemetry/api"; -import { SpanInfo } from "../../../../core/tracing/SpanUtils"; +import { SpanInfo, SpanUtils } from "../../../../core/tracing/SpanUtils"; import { TuskDriftCore } from "../../../../core/TuskDrift"; import { findMockResponseAsync } from "../../../core/utils/mockResponseUtils"; import { logger } from "../../../../core/utils/logger"; diff --git a/src/instrumentation/libraries/nextjs/e2e-tests/cjs-nextjs/run.sh b/src/instrumentation/libraries/nextjs/e2e-tests/cjs-nextjs/run.sh index 424260bb..bedb39bc 100755 --- a/src/instrumentation/libraries/nextjs/e2e-tests/cjs-nextjs/run.sh +++ b/src/instrumentation/libraries/nextjs/e2e-tests/cjs-nextjs/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/nextjs/e2e-tests/esm-nextjs/run.sh b/src/instrumentation/libraries/nextjs/e2e-tests/esm-nextjs/run.sh index 78e9dc15..60f808e4 100755 --- a/src/instrumentation/libraries/nextjs/e2e-tests/esm-nextjs/run.sh +++ b/src/instrumentation/libraries/nextjs/e2e-tests/esm-nextjs/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/pg/e2e-tests/cjs-pg/run.sh b/src/instrumentation/libraries/pg/e2e-tests/cjs-pg/run.sh index 9b1805cb..05e8e2c0 100755 --- a/src/instrumentation/libraries/pg/e2e-tests/cjs-pg/run.sh +++ b/src/instrumentation/libraries/pg/e2e-tests/cjs-pg/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/pg/e2e-tests/esm-pg/run.sh b/src/instrumentation/libraries/pg/e2e-tests/esm-pg/run.sh index 643d9495..24b95e8d 100755 --- a/src/instrumentation/libraries/pg/e2e-tests/esm-pg/run.sh +++ b/src/instrumentation/libraries/pg/e2e-tests/esm-pg/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/run.sh b/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/run.sh index 33ee0467..a8f299d3 100755 --- a/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/run.sh +++ b/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/src/index.ts b/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/src/index.ts index e7469230..46e75e5e 100644 --- a/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/src/index.ts +++ b/src/instrumentation/libraries/postgres/e2e-tests/cjs-postgres/src/index.ts @@ -199,18 +199,29 @@ app.post("/cache/insert", async (req: Request, res: Response) => { const { key, value } = req.body; const timestamp = Date.now(); + const insertKey = key || `test_key_${timestamp}`; + const insertValue = value || `test_value_${timestamp}`; + const expiresAt = new Date(Date.now() + 86400000); // 1 day from now const result = await db .insert(cacheTable) .values({ - key: key || `test_key_${timestamp}`, - value: value || `test_value_${timestamp}`, - expiresAt: new Date(Date.now() + 86400000), // 1 day from now + key: insertKey, + value: insertValue, + expiresAt, + }) + .onConflictDoUpdate({ + target: cacheTable.key, + set: { + value: insertValue, + expiresAt, + updatedAt: new Date(), + }, }) .returning(); res.json({ - message: "Cache entry inserted", + message: "Cache entry inserted or updated", data: result, }); } catch (error: any) { diff --git a/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/run.sh b/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/run.sh index 7234fbc7..9658e7c3 100755 --- a/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/run.sh +++ b/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/src/index.ts b/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/src/index.ts index f5eb7317..bd0d75d2 100644 --- a/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/src/index.ts +++ b/src/instrumentation/libraries/postgres/e2e-tests/esm-postgres/src/index.ts @@ -214,20 +214,31 @@ app.post("/cache/insert", async (req: Request, res: Response) => { const { key, value } = req.body; const timestamp = Date.now(); + const insertKey = key || `test_key_${timestamp}`; + const insertValue = value || `test_value_${timestamp}`; + const expiresAt = new Date(Date.now() + 86400000); // 1 day from now const result = await db .insert(cacheTable) .values({ - key: key || `test_key_${timestamp}`, - value: value || `test_value_${timestamp}`, - expiresAt: new Date(Date.now() + 86400000), // 1 day from now + key: insertKey, + value: insertValue, + expiresAt, + }) + .onConflictDoUpdate({ + target: cacheTable.key, + set: { + value: insertValue, + expiresAt, + updatedAt: new Date(), + }, }) .returning(); console.log("Insert result:", result); res.json({ - message: "Cache entry inserted", + message: "Cache entry inserted or updated", data: result, }); } catch (error: any) { diff --git a/src/instrumentation/libraries/prisma/e2e-tests/cjs-prisma/run.sh b/src/instrumentation/libraries/prisma/e2e-tests/cjs-prisma/run.sh index 52700583..e731ce0b 100755 --- a/src/instrumentation/libraries/prisma/e2e-tests/cjs-prisma/run.sh +++ b/src/instrumentation/libraries/prisma/e2e-tests/cjs-prisma/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/prisma/e2e-tests/esm-prisma/run.sh b/src/instrumentation/libraries/prisma/e2e-tests/esm-prisma/run.sh index 8d2170c6..f361dc43 100755 --- a/src/instrumentation/libraries/prisma/e2e-tests/esm-prisma/run.sh +++ b/src/instrumentation/libraries/prisma/e2e-tests/esm-prisma/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/upstash-redis-js/e2e-tests/cjs-upstash-redis-js/run.sh b/src/instrumentation/libraries/upstash-redis-js/e2e-tests/cjs-upstash-redis-js/run.sh index 1d894f03..6d7fe44d 100755 --- a/src/instrumentation/libraries/upstash-redis-js/e2e-tests/cjs-upstash-redis-js/run.sh +++ b/src/instrumentation/libraries/upstash-redis-js/e2e-tests/cjs-upstash-redis-js/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e diff --git a/src/instrumentation/libraries/upstash-redis-js/e2e-tests/esm-upstash-redis-js/run.sh b/src/instrumentation/libraries/upstash-redis-js/e2e-tests/esm-upstash-redis-js/run.sh index b6939298..63a270cf 100755 --- a/src/instrumentation/libraries/upstash-redis-js/e2e-tests/esm-upstash-redis-js/run.sh +++ b/src/instrumentation/libraries/upstash-redis-js/e2e-tests/esm-upstash-redis-js/run.sh @@ -33,7 +33,7 @@ echo -e "${BLUE}Starting test...${NC}" echo "" set +e -docker compose -p "$PROJECT_NAME" run --rm app +docker compose -p "$PROJECT_NAME" run --rm -e TUSK_USE_RUST_CORE="${TUSK_USE_RUST_CORE:-}" app EXIT_CODE=$? set -e