diff --git a/package.json b/package.json index 1da41fad0..1798b9b22 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "typescript": "catalog:" }, "engines": { - "node": ">=22.14.0" + "node": ">=20.0.0" }, "pnpm": { "overrides": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6d4d8122..9d7cf0cf5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,6 +45,9 @@ catalogs: tsup: specifier: ^8.3.6 version: 8.3.6 + tsx: + specifier: ^4.19.4 + version: 4.20.3 typescript: specifier: ^5.7.3 version: 5.7.3 @@ -67,10 +70,10 @@ overrides: patchedDependencies: '@opentelemetry/api': - hash: 4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a + hash: izegmddoiqidmvapuxeha6lnw4 path: patches/@opentelemetry__api.patch '@opentelemetry/otlp-exporter-base': - hash: b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d + hash: brtaqazy64vzhaznf7q5df2byy path: patches/@opentelemetry__otlp-exporter-base.patch importers: @@ -88,7 +91,7 @@ importers: version: 2.28.1 tsup: specifier: 'catalog:' - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 @@ -184,7 +187,7 @@ importers: version: 0.476.0(react@18.3.1) next: specifier: 15.2.4 - version: 15.2.4(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 15.2.4(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -242,7 +245,7 @@ importers: version: 5.7.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) apps/ensindexer: dependencies: @@ -272,31 +275,31 @@ importers: version: 0.2.2(hono@4.7.8) '@opentelemetry/api': specifier: ^1.9.0 - version: 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + version: 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/core': specifier: ^2.0.1 - version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/exporter-metrics-otlp-proto': specifier: ^0.202.0 - version: 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/exporter-trace-otlp-proto': specifier: ^0.202.0 - version: 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/resources': specifier: ^2.0.1 - version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/sdk-metrics': specifier: ^2.0.1 - version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/sdk-node': specifier: ^0.202.0 - version: 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/sdk-trace-base': specifier: ^2.0.1 - version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/sdk-trace-node': specifier: ^2.0.1 - version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + version: 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/semantic-conventions': specifier: ^1.34.0 version: 1.34.0 @@ -317,7 +320,7 @@ importers: version: 2.9.0 ponder: specifier: 'catalog:' - version: 0.11.25(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7) + version: 0.11.25(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(postgres@3.4.7)(tsx@4.20.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7) ponder-enrich-gql-docs-middleware: specifier: ^0.1.3 version: 0.1.3(graphql@16.10.0)(hono@4.7.8) @@ -342,7 +345,7 @@ importers: version: 5.7.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) apps/ensrainbow: dependencies: @@ -391,7 +394,7 @@ importers: version: 17.0.33 '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0)) + version: 3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) tsx: specifier: ^4.19.3 version: 4.19.3 @@ -400,28 +403,28 @@ importers: version: 5.7.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) docs/ensnode.io: dependencies: '@astrojs/mdx': specifier: ^4.3.0 - version: 4.3.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) + version: 4.3.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) '@astrojs/react': specifier: 'catalog:' - version: 4.2.0(@types/node@22.15.3)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tsx@4.19.3)(yaml@2.7.0) + version: 4.2.0(@types/node@22.15.3)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tsx@4.20.3)(yaml@2.7.0) '@astrojs/sitemap': specifier: ^3.3.1 version: 3.3.1 '@astrojs/starlight': specifier: ^0.34.2 - version: 0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) + version: 0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) '@astrojs/starlight-tailwind': specifier: ^4.0.1 - version: 4.0.1(@astrojs/starlight@0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)))(tailwindcss@4.1.5) + version: 4.0.1(@astrojs/starlight@0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)))(tailwindcss@4.1.5) '@astrojs/tailwind': specifier: 'catalog:' - version: 6.0.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@4.1.5)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)) + version: 6.0.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@4.1.5)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)) '@fontsource/inter': specifier: ^5.2.5 version: 5.2.5 @@ -442,7 +445,7 @@ importers: version: 20.1.2 '@tailwindcss/vite': specifier: ^4.1.5 - version: 4.1.5(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + version: 4.1.5(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)) '@types/react': specifier: ^18.3.5 version: 18.3.18 @@ -451,7 +454,7 @@ importers: version: 18.3.5(@types/react@18.3.18) astro: specifier: ^5.7.11 - version: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) astro-font: specifier: 'catalog:' version: 1.0.0 @@ -481,10 +484,10 @@ importers: version: 0.33.5 starlight-llms-txt: specifier: ^0.5.0 - version: 0.5.0(@astrojs/starlight@0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)))(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) + version: 0.5.0(@astrojs/starlight@0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)))(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) starlight-sidebar-topics: specifier: ^0.4.1 - version: 0.4.1(@astrojs/starlight@0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))) + version: 0.4.1(@astrojs/starlight@0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))) tailwindcss: specifier: 4.1.5 version: 4.1.5 @@ -493,10 +496,10 @@ importers: dependencies: '@astrojs/react': specifier: 'catalog:' - version: 4.2.0(@types/node@22.15.3)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tsx@4.19.3)(yaml@2.7.0) + version: 4.2.0(@types/node@22.15.3)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tsx@4.20.3)(yaml@2.7.0) '@astrojs/tailwind': specifier: 'catalog:' - version: 6.0.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)))(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)) + version: 6.0.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)))(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)) '@heroicons/react': specifier: ^2.2.0 version: 2.2.0(react@18.3.1) @@ -514,7 +517,7 @@ importers: version: 18.3.5(@types/react@18.3.18) astro: specifier: ^5.3.1 - version: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) astro-font: specifier: 'catalog:' version: 1.0.0 @@ -554,7 +557,7 @@ importers: version: 22.15.3 tsup: specifier: 'catalog:' - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 @@ -579,13 +582,13 @@ importers: version: 5.67.1(react@18.3.1) '@testing-library/jest-dom': specifier: ^6.6.3 - version: 6.6.3 + version: 6.6.4 '@testing-library/react': specifier: ^16.1.0 - version: 16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@testing-library/user-event': specifier: ^14.5.2 - version: 14.6.1(@testing-library/dom@10.4.0) + version: 14.6.1(@testing-library/dom@10.4.1) '@types/node': specifier: 'catalog:' version: 22.15.3 @@ -594,7 +597,7 @@ importers: version: 18.3.18 '@vitest/coverage-v8': specifier: 'catalog:' - version: 3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0)) + version: 3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)) jsdom: specifier: ^26.0.0 version: 26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -606,19 +609,19 @@ importers: version: 18.3.1(react@18.3.1) tsup: specifier: ^8.3.6 - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) packages/ensnode-schema: dependencies: ponder: specifier: 'catalog:' - version: 0.11.25(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7) + version: 0.11.25(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(postgres@3.4.7)(tsx@4.20.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7) viem: specifier: 'catalog:' version: 2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7) @@ -631,7 +634,7 @@ importers: version: link:../shared-configs tsup: specifier: 'catalog:' - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 @@ -659,7 +662,7 @@ importers: version: 22.15.3 tsup: specifier: ^8.3.6 - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 @@ -668,7 +671,7 @@ importers: version: 2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7) vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) packages/ensrainbow-sdk: dependencies: @@ -687,13 +690,13 @@ importers: version: link:../shared-configs tsup: specifier: 'catalog:' - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) packages/ponder-metadata: dependencies: @@ -702,7 +705,7 @@ importers: version: link:../ensrainbow-sdk drizzle-orm: specifier: 'catalog:' - version: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3) + version: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3)(postgres@3.4.7) parse-prometheus-text-format: specifier: ^1.1.1 version: 1.1.1 @@ -724,16 +727,16 @@ importers: version: 4.7.8 ponder: specifier: 'catalog:' - version: 0.11.25(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7) + version: 0.11.25(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(postgres@3.4.7)(tsx@4.20.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7) tsup: specifier: 'catalog:' - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 vitest: specifier: 'catalog:' - version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) packages/ponder-subgraph: dependencies: @@ -751,7 +754,7 @@ importers: version: 2.2.3 drizzle-orm: specifier: 'catalog:' - version: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3) + version: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3)(postgres@3.4.7) graphql: specifier: ^16.10.0 version: 16.10.0 @@ -776,7 +779,7 @@ importers: version: 4.7.8 tsup: specifier: 'catalog:' - version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + version: 8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) typescript: specifier: 'catalog:' version: 5.7.3 @@ -790,10 +793,62 @@ importers: specifier: 'catalog:' version: 5.7.3 + tools/ensdb-compare: + dependencies: + '@ensnode/ensnode-schema': + specifier: workspace:* + version: link:../../packages/ensnode-schema + chalk: + specifier: ^5.3.0 + version: 5.4.1 + commander: + specifier: ^12.0.0 + version: 12.1.0 + drizzle-orm: + specifier: 'catalog:' + version: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3)(postgres@3.4.7) + fs-extra: + specifier: ^11.2.0 + version: 11.3.0 + ora: + specifier: ^8.0.1 + version: 8.2.0 + pg: + specifier: ^8.11.3 + version: 8.11.3 + postgres: + specifier: ^3.4.4 + version: 3.4.7 + table: + specifier: ^6.8.1 + version: 6.9.0 + devDependencies: + '@biomejs/biome': + specifier: 'catalog:' + version: 1.9.4 + '@ensnode/shared-configs': + specifier: workspace:* + version: link:../../packages/shared-configs + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/node': + specifier: 'catalog:' + version: 22.15.3 + '@types/pg': + specifier: ^8.10.9 + version: 8.15.4 + tsx: + specifier: 'catalog:' + version: 4.20.3 + typescript: + specifier: 'catalog:' + version: 5.7.3 + packages: - '@adobe/css-tools@4.4.3': - resolution: {integrity: sha512-VQKMkwriZbaOgVCby1UDY/LDk5fIjhQicCvVPFqfe+69fWaPWydbWJ3wRt59/YzIwda1I81loas3oCoHxnqvdA==} + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} '@adraffy/ens-normalize@1.10.0': resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==} @@ -836,15 +891,12 @@ packages: peerDependencies: typescript: ^5.0.0 - '@astrojs/compiler@2.12.2': - resolution: {integrity: sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw==} + '@astrojs/compiler@2.11.0': + resolution: {integrity: sha512-zZOO7i+JhojO8qmlyR/URui6LyfHJY6m+L9nwyX5GiKD78YoRaZ5tzz6X0fkl+5bD3uwlDHayf6Oe8Fu36RKNg==} '@astrojs/internal-helpers@0.6.1': resolution: {integrity: sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A==} - '@astrojs/internal-helpers@0.7.1': - resolution: {integrity: sha512-7dwEVigz9vUWDw3nRwLQ/yH/xYovlUA0ZD86xoeKEBmkz9O6iELG1yri67PgAPW6VLL/xInA4t7H0CK6VmtkKQ==} - '@astrojs/language-server@2.15.4': resolution: {integrity: sha512-JivzASqTPR2bao9BWsSc/woPHH7OGSGc9aMxXL4U6egVTqBycB3ZHdBJPuOCVtcGLrzdWTosAqVPz1BVoxE0+A==} hasBin: true @@ -863,9 +915,6 @@ packages: '@astrojs/markdown-remark@6.3.2': resolution: {integrity: sha512-bO35JbWpVvyKRl7cmSJD822e8YA8ThR/YbUsciWNA7yTcqpIAL2hJDToWP5KcZBWxGT6IOdOkHSXARSNZc4l/Q==} - '@astrojs/markdown-remark@6.3.5': - resolution: {integrity: sha512-MiR92CkE2BcyWf3b86cBBw/1dKiOH0qhLgXH2OXA6cScrrmmks1Rr4Tl0p/lFpvmgQQrP54Pd1uidJfmxGrpWQ==} - '@astrojs/mdx@4.3.0': resolution: {integrity: sha512-OGX2KvPeBzjSSKhkCqrUoDMyzFcjKt5nTE5SFw3RdoLf0nrhyCXBQcCyclzWy1+P+XpOamn+p+hm1EhpCRyPxw==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} @@ -909,9 +958,9 @@ packages: astro: ^3.0.0 || ^4.0.0 || ^5.0.0 tailwindcss: ^3.0.24 - '@astrojs/telemetry@3.3.0': - resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + '@astrojs/telemetry@3.2.1': + resolution: {integrity: sha512-SSVM820Jqc6wjsn7qYfV9qfeQvePtVc1nSofhyap7l0/iakUKywj3hfy3UJAOV4sGV4Q/u450RD4AaCaFvNPlg==} + engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} '@astrojs/yaml2ts@0.2.2': resolution: {integrity: sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ==} @@ -1056,15 +1105,6 @@ packages: cpu: [x64] os: [win32] - '@bundled-es-modules/cookie@2.0.1': - resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} - - '@bundled-es-modules/statuses@1.0.1': - resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} - - '@bundled-es-modules/tough-cookie@0.1.6': - resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} - '@capsizecss/unpack@2.4.0': resolution: {integrity: sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q==} @@ -1436,8 +1476,8 @@ packages: resolution: {integrity: sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} + '@eslint/core@0.15.1': + resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.2.0': @@ -1785,37 +1825,6 @@ packages: cpu: [x64] os: [win32] - '@inquirer/confirm@5.1.14': - resolution: {integrity: sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@10.1.15': - resolution: {integrity: sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@1.0.13': - resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} - engines: {node: '>=18'} - - '@inquirer/type@3.0.8': - resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1978,10 +1987,6 @@ packages: resolution: {integrity: sha512-z10PF9JV6SbjFq+/rYabM+8CVlMokgl8RFGvieSGNTmrkQanfHn+15XBrhG3BgUfvmTeSeyShfOHpG0i9zEdcg==} deprecated: Motion One for Vue is deprecated. Use Oku Motion instead https://oku-ui.com/motion - '@mswjs/interceptors@0.39.5': - resolution: {integrity: sha512-B9nHSJYtsv79uo7QdkZ/b/WoKm20IkVSmTc/WCKarmDtFwM0dRx2ouEniqwNkzCSLn3fydzKmnMzjtfdOWt3VQ==} - engines: {node: '>=18'} - '@n1ru4l/push-pull-async-iterable-iterator@3.2.0': resolution: {integrity: sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q==} engines: {node: '>=12'} @@ -2157,15 +2162,6 @@ packages: '@octokit/types@13.10.0': resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==} - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@opentelemetry/api-logs@0.202.0': resolution: {integrity: sha512-fTBjMqKCfotFWfLzaKyhjLvyEyq5vDKTTFfBmx21btv3gvy8Lq6N5Dh2OzqeuN4DjtpSvNT1uNVfg08eD2Rfxw==} engines: {node: '>=8.0.0'} @@ -3102,12 +3098,12 @@ packages: '@tanstack/virtual-core@3.13.6': resolution: {integrity: sha512-cnQUeWnhNP8tJ4WsGcYiX24Gjkc9ALstLbHcBj1t3E7EimN6n6kHH+DPV4PpDnuw00NApQp+ViojMj1GRdwYQg==} - '@testing-library/dom@10.4.0': - resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.6.3': - resolution: {integrity: sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==} + '@testing-library/jest-dom@6.6.4': + resolution: {integrity: sha512-xDXgLjVunjHqczScfkCJ9iyjdNOVHvvCdqHSSxwM9L0l/wHkTRum67SDc020uAlCoqktJplgO2AAQeLP1wgqDQ==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} '@testing-library/react@16.3.0': @@ -3174,9 +3170,6 @@ packages: '@types/codemirror@5.60.15': resolution: {integrity: sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==} - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/d3-color@3.1.3': resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} @@ -3210,8 +3203,8 @@ packages: '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} - '@types/fontkit@2.0.8': - resolution: {integrity: sha512-wN+8bYxIpJf+5oZdrdtaX04qUuWHcKxcDEgRS9Qm9ZClSHjzEn13SxUC+5eRM+4yXIeTYk8mTzLAWGF64847ew==} + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} @@ -3225,6 +3218,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -3278,18 +3274,12 @@ packages: '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - '@types/tar@6.1.13': resolution: {integrity: sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==} '@types/tern@0.23.9': resolution: {integrity: sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==} - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -3658,10 +3648,6 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - ansi-escapes@7.0.0: resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} engines: {node: '>=18'} @@ -3762,6 +3748,10 @@ packages: ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + astring@1.9.0: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true @@ -3780,9 +3770,9 @@ packages: astro-seo@0.8.4: resolution: {integrity: sha512-Ou1vzQSXAxa0K8rtNtXNvSpYqOGEgMhh0immMxJeXmbVZac3UKCNWAoXWyOQDFYsZvBugCRSg0N1phBqPMVgCw==} - astro@5.12.8: - resolution: {integrity: sha512-KkJ7FR+c2SyZYlpakm48XBiuQcRsrVtdjG5LN5an0givI/tLik+ePJ4/g3qrAVhYMjJOxBA2YgFQxANPiWB+Mw==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + astro@5.7.11: + resolution: {integrity: sha512-9qRVwp8pue3isddLBnTexJsmKFpmms9Fo7Ss+3yrC0aINvbHKpD7q6qf52BtfQEk2xJgyx3SQy3dUsuD90sEqQ==} + engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} hasBin: true async-function@1.0.0: @@ -3973,10 +3963,6 @@ packages: resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} engines: {node: '>=12'} - chalk@3.0.0: - resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} - engines: {node: '>=8'} - chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -4048,9 +4034,13 @@ packages: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} @@ -4149,10 +4139,6 @@ packages: cookie-es@1.2.2: resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - cookie@1.0.2: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} @@ -4975,6 +4961,14 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fdir@6.4.6: resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} peerDependencies: @@ -5027,9 +5021,6 @@ packages: debug: optional: true - fontace@0.3.0: - resolution: {integrity: sha512-czoqATrcnxgWb/nAkfyIrRp6Q8biYj7nGnL6zfhTcX+JKKpWHFBnb8uNMw/kZr7u++3Y3wYSYoZgHkCcsuBpBg==} - fontkit@2.0.4: resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} @@ -5068,6 +5059,10 @@ packages: framesync@6.0.1: resolution: {integrity: sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==} + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -5338,9 +5333,6 @@ packages: hastscript@9.0.0: resolution: {integrity: sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==} - headers-polyfill@4.0.3: - resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} - help-me@5.0.0: resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} @@ -5543,13 +5535,14 @@ packages: engines: {node: '>=14.16'} hasBin: true + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -5605,6 +5598,14 @@ packages: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -5752,6 +5753,9 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsx-ast-utils@3.3.5: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} @@ -5927,9 +5931,16 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} @@ -6199,6 +6210,10 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -6276,26 +6291,12 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.10.4: - resolution: {integrity: sha512-6R1or/qyele7q3RyPwNuvc0IxO8L8/Aim6Sz5ncXEgcWUNxSKE+udriTOWHtpMwmfkLYlacA2y7TIx4cL5lgHA==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - typescript: '>= 4.8.x' - peerDependenciesMeta: - typescript: - optional: true - muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} multiformats@9.9.0: resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} - mute-stream@2.0.0: - resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} - engines: {node: ^18.17.0 || >=20.5.0} - mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} @@ -6396,8 +6397,8 @@ packages: nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} - nwsapi@2.2.20: - resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==} + nwsapi@2.2.21: + resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} obj-multiplex@1.0.0: resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} @@ -6461,6 +6462,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + oniguruma-parser@0.12.1: resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} @@ -6471,12 +6476,13 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + ora@8.2.0: + resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} + engines: {node: '>=18'} + outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -6603,9 +6609,6 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -6837,6 +6840,10 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} + postgres@3.4.7: + resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} + engines: {node: '>=12'} + preact@10.26.4: resolution: {integrity: sha512-KJhO7LBFTjP71d83trW+Ilnjbo+ySsaAgCfXOXUlmGzJ4ygYPWmysm77yg4emwfmoz3b22yvH5IsVFHbhUaH5w==} @@ -6906,9 +6913,6 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -6932,9 +6936,6 @@ packages: resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} engines: {node: '>=6'} - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -7146,9 +7147,6 @@ packages: require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -7169,6 +7167,10 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + restructure@3.0.2: resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} @@ -7340,14 +7342,14 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + smol-toml@1.3.1: resolution: {integrity: sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==} engines: {node: '>= 18'} - smol-toml@1.4.1: - resolution: {integrity: sha512-CxdwHXyYTONGHThDbq5XdwbFsuY4wlClRGejfE2NtwUtiHYsP1QtNsHb/hnj31jKYSchztJsaA8pSQoVzkfCFg==} - engines: {node: '>= 18'} - socket.io-client@4.8.1: resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} engines: {node: '>=10.0.0'} @@ -7439,13 +7441,13 @@ packages: peerDependencies: '@astrojs/starlight': '>=0.32.0' - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - std-env@3.8.1: resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==} + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + stream-replace-string@2.0.0: resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} @@ -7456,9 +7458,6 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - strict-uri-encode@2.0.0: resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} engines: {node: '>=4'} @@ -7588,6 +7587,10 @@ packages: tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + tailwind-merge@3.0.2: resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} @@ -7657,6 +7660,10 @@ packages: tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + tinyglobby@0.2.14: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} @@ -7680,8 +7687,8 @@ packages: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tmp@0.2.4: - resolution: {integrity: sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ==} + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} to-regex-range@5.0.1: @@ -7691,10 +7698,6 @@ packages: toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - tough-cookie@5.1.2: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} @@ -7791,14 +7794,15 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tsx@4.20.3: + resolution: {integrity: sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==} + engines: {node: '>=18.0.0'} + hasBin: true + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} @@ -7933,9 +7937,9 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} unstorage@1.15.0: resolution: {integrity: sha512-m40eHdGY/gA6xAPqo8eaxqXgBuzQTlAKfmB1iF7oCKXE1HfwHwzDJBywK+qQGn52dta+bPlZluPF7++yR3p/bg==} @@ -8005,9 +8009,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - urlpattern-polyfill@10.0.0: resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} @@ -8121,6 +8122,46 @@ packages: vite: optional: true + vite@6.2.7: + resolution: {integrity: sha512-qg3LkeuinTrZoJHHF94coSaTfIPyBYoywp+ys4qu20oSJFbKMYoIJo0FWJT9q6Vp49l6z9IsJRbHdcGtiKbGoQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vite@6.3.5: resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -8544,10 +8585,6 @@ packages: resolution: {integrity: sha512-lHHxjh0bXaLgdJy3cNnVb/F9myx3CkhrvSOEVTkaUgNMXnYFa2xYPVhtGnqhh3jErY2gParBOHallCbc7NrlZQ==} engines: {node: '>=18.19'} - yoctocolors-cjs@2.1.2: - resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} - engines: {node: '>=18'} - yoctocolors@2.1.1: resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} engines: {node: '>=18'} @@ -8604,7 +8641,7 @@ packages: snapshots: - '@adobe/css-tools@4.4.3': {} + '@adobe/css-tools@4.4.4': {} '@adraffy/ens-normalize@1.10.0': {} @@ -8662,15 +8699,13 @@ snapshots: - prettier - prettier-plugin-astro - '@astrojs/compiler@2.12.2': {} + '@astrojs/compiler@2.11.0': {} '@astrojs/internal-helpers@0.6.1': {} - '@astrojs/internal-helpers@0.7.1': {} - '@astrojs/language-server@2.15.4(typescript@5.7.3)': dependencies: - '@astrojs/compiler': 2.12.2 + '@astrojs/compiler': 2.11.0 '@astrojs/yaml2ts': 0.2.2 '@jridgewell/sourcemap-codec': 1.5.0 '@volar/kit': 2.4.11(typescript@5.7.3) @@ -8743,38 +8778,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/markdown-remark@6.3.5': - dependencies: - '@astrojs/internal-helpers': 0.7.1 - '@astrojs/prism': 3.3.0 - github-slugger: 2.0.0 - hast-util-from-html: 2.0.3 - hast-util-to-text: 4.0.2 - import-meta-resolve: 4.1.0 - js-yaml: 4.1.0 - mdast-util-definitions: 6.0.0 - rehype-raw: 7.0.0 - rehype-stringify: 10.0.1 - remark-gfm: 4.0.1 - remark-parse: 11.0.0 - remark-rehype: 11.1.2 - remark-smartypants: 3.0.2 - shiki: 3.4.0 - smol-toml: 1.4.1 - unified: 11.0.5 - unist-util-remove-position: 5.0.0 - unist-util-visit: 5.0.0 - unist-util-visit-parents: 6.0.1 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@astrojs/mdx@4.3.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))': + '@astrojs/mdx@4.3.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))': dependencies: '@astrojs/markdown-remark': 6.3.2 '@mdx-js/mdx': 3.1.0(acorn@8.14.1) acorn: 8.14.1 - astro: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + astro: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) es-module-lexer: 1.6.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -8796,15 +8805,15 @@ snapshots: dependencies: prismjs: 1.30.0 - '@astrojs/react@4.2.0(@types/node@22.15.3)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tsx@4.19.3)(yaml@2.7.0)': + '@astrojs/react@4.2.0(@types/node@22.15.3)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(jiti@2.4.2)(lightningcss@1.29.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tsx@4.20.3)(yaml@2.7.0)': dependencies: '@types/react': 18.3.18 '@types/react-dom': 18.3.5(@types/react@18.3.18) - '@vitejs/plugin-react': 4.3.4(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + '@vitejs/plugin-react': 4.3.4(vite@6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) ultrahtml: 1.6.0 - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -8825,22 +8834,22 @@ snapshots: stream-replace-string: 2.0.0 zod: 3.25.7 - '@astrojs/starlight-tailwind@4.0.1(@astrojs/starlight@0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)))(tailwindcss@4.1.5)': + '@astrojs/starlight-tailwind@4.0.1(@astrojs/starlight@0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)))(tailwindcss@4.1.5)': dependencies: - '@astrojs/starlight': 0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) + '@astrojs/starlight': 0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) tailwindcss: 4.1.5 - '@astrojs/starlight@0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))': + '@astrojs/starlight@0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))': dependencies: '@astrojs/markdown-remark': 6.3.1 - '@astrojs/mdx': 4.3.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) + '@astrojs/mdx': 4.3.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) '@astrojs/sitemap': 3.3.1 '@pagefind/default-ui': 1.3.0 '@types/hast': 3.0.4 '@types/js-yaml': 4.0.9 '@types/mdast': 4.0.4 - astro: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) - astro-expressive-code: 0.41.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) + astro: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) + astro-expressive-code: 0.41.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) bcp-47: 2.1.0 hast-util-from-html: 2.0.3 hast-util-select: 6.0.3 @@ -8863,9 +8872,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/tailwind@6.0.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)))(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3))': + '@astrojs/tailwind@6.0.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@3.4.13(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)))(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3))': dependencies: - astro: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + astro: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) autoprefixer: 10.4.20(postcss@8.5.3) postcss: 8.5.3 postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)) @@ -8873,9 +8882,9 @@ snapshots: transitivePeerDependencies: - ts-node - '@astrojs/tailwind@6.0.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@4.1.5)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3))': + '@astrojs/tailwind@6.0.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))(tailwindcss@4.1.5)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3))': dependencies: - astro: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + astro: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) autoprefixer: 10.4.20(postcss@8.5.3) postcss: 8.5.3 postcss-load-config: 4.0.2(postcss@8.5.3)(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3)) @@ -8883,7 +8892,7 @@ snapshots: transitivePeerDependencies: - ts-node - '@astrojs/telemetry@3.3.0': + '@astrojs/telemetry@3.2.1': dependencies: ci-info: 4.2.0 debug: 4.4.0 @@ -9050,22 +9059,6 @@ snapshots: '@biomejs/cli-win32-x64@1.9.4': optional: true - '@bundled-es-modules/cookie@2.0.1': - dependencies: - cookie: 0.7.2 - optional: true - - '@bundled-es-modules/statuses@1.0.1': - dependencies: - statuses: 2.0.2 - optional: true - - '@bundled-es-modules/tough-cookie@0.1.6': - dependencies: - '@types/tough-cookie': 4.0.5 - tough-cookie: 4.1.4 - optional: true - '@capsizecss/unpack@2.4.0': dependencies: blob-to-buffer: 1.2.9 @@ -9521,7 +9514,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@0.15.2': + '@eslint/core@0.15.1': dependencies: '@types/json-schema': 7.0.15 @@ -9545,7 +9538,7 @@ snapshots: '@eslint/plugin-kit@0.3.4': dependencies: - '@eslint/core': 0.15.2 + '@eslint/core': 0.15.1 levn: 0.4.1 '@ethereumjs/common@3.2.0': @@ -9809,7 +9802,7 @@ snapshots: '@hono/otel@0.2.2(hono@4.7.8)': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/semantic-conventions': 1.34.0 hono: 4.7.8 @@ -9937,63 +9930,6 @@ snapshots: '@img/sharp-win32-x64@0.33.5': optional: true - '@inquirer/confirm@5.1.14(@types/node@20.17.14)': - dependencies: - '@inquirer/core': 10.1.15(@types/node@20.17.14) - '@inquirer/type': 3.0.8(@types/node@20.17.14) - optionalDependencies: - '@types/node': 20.17.14 - optional: true - - '@inquirer/confirm@5.1.14(@types/node@22.15.3)': - dependencies: - '@inquirer/core': 10.1.15(@types/node@22.15.3) - '@inquirer/type': 3.0.8(@types/node@22.15.3) - optionalDependencies: - '@types/node': 22.15.3 - optional: true - - '@inquirer/core@10.1.15(@types/node@20.17.14)': - dependencies: - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@20.17.14) - ansi-escapes: 4.3.2 - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 20.17.14 - optional: true - - '@inquirer/core@10.1.15(@types/node@22.15.3)': - dependencies: - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.15.3) - ansi-escapes: 4.3.2 - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 - optionalDependencies: - '@types/node': 22.15.3 - optional: true - - '@inquirer/figures@1.0.13': - optional: true - - '@inquirer/type@3.0.8(@types/node@20.17.14)': - optionalDependencies: - '@types/node': 20.17.14 - optional: true - - '@inquirer/type@3.0.8(@types/node@22.15.3)': - optionalDependencies: - '@types/node': 22.15.3 - optional: true - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -10308,16 +10244,6 @@ snapshots: '@motionone/dom': 10.18.0 tslib: 2.8.1 - '@mswjs/interceptors@0.39.5': - dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 - optional: true - '@n1ru4l/push-pull-async-iterable-iterator@3.2.0': {} '@namehash/ens-utils@1.19.0(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7)': @@ -10498,242 +10424,230 @@ snapshots: dependencies: '@octokit/openapi-types': 24.2.0 - '@open-draft/deferred-promise@2.2.0': - optional: true - - '@open-draft/logger@0.3.0': - dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - optional: true - - '@open-draft/until@2.1.0': - optional: true - '@opentelemetry/api-logs@0.202.0': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) - '@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)': {} + '@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)': {} - '@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) - '@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/semantic-conventions': 1.34.0 - '@opentelemetry/exporter-logs-otlp-grpc@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/exporter-logs-otlp-grpc@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: '@grpc/grpc-js': 1.13.4 - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-grpc-exporter-base': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-grpc-exporter-base': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/exporter-logs-otlp-http@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/exporter-logs-otlp-http@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/api-logs': 0.202.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/exporter-logs-otlp-proto@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/exporter-logs-otlp-proto@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/api-logs': 0.202.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/exporter-metrics-otlp-grpc@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/exporter-metrics-otlp-grpc@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: '@grpc/grpc-js': 1.13.4 - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-metrics-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-grpc-exporter-base': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - - '@opentelemetry/exporter-metrics-otlp-http@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': - dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - - '@opentelemetry/exporter-metrics-otlp-proto@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': - dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-metrics-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - - '@opentelemetry/exporter-prometheus@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': - dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - - '@opentelemetry/exporter-trace-otlp-grpc@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-metrics-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-grpc-exporter-base': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + + '@opentelemetry/exporter-metrics-otlp-http@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': + dependencies: + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + + '@opentelemetry/exporter-metrics-otlp-proto@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': + dependencies: + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-metrics-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + + '@opentelemetry/exporter-prometheus@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': + dependencies: + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + + '@opentelemetry/exporter-trace-otlp-grpc@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: '@grpc/grpc-js': 1.13.4 - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-grpc-exporter-base': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - - '@opentelemetry/exporter-trace-otlp-http@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': - dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - - '@opentelemetry/exporter-trace-otlp-proto@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': - dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - - '@opentelemetry/exporter-zipkin@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': - dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-grpc-exporter-base': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + + '@opentelemetry/exporter-trace-otlp-http@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': + dependencies: + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + + '@opentelemetry/exporter-trace-otlp-proto@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': + dependencies: + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + + '@opentelemetry/exporter-zipkin@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': + dependencies: + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/semantic-conventions': 1.34.0 - '@opentelemetry/instrumentation@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/instrumentation@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/api-logs': 0.202.0 import-in-the-middle: 1.14.2 require-in-the-middle: 7.5.2 transitivePeerDependencies: - supports-color - '@opentelemetry/otlp-exporter-base@0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/otlp-exporter-base@0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/otlp-grpc-exporter-base@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/otlp-grpc-exporter-base@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: '@grpc/grpc-js': 1.13.4 - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=b8c870e92957fbc0bd683ab4e2c0034dc892f663b22f2c8b30daeb8f321bbb8d)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-exporter-base': 0.202.0(patch_hash=brtaqazy64vzhaznf7q5df2byy)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/otlp-transformer': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/otlp-transformer@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/otlp-transformer@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/api-logs': 0.202.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) protobufjs: 7.5.3 - '@opentelemetry/propagator-b3@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/propagator-b3@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/propagator-jaeger@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/propagator-jaeger@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/semantic-conventions': 1.34.0 - '@opentelemetry/sdk-logs@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/sdk-logs@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/api-logs': 0.202.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/sdk-metrics@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/sdk-metrics@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) - '@opentelemetry/sdk-node@0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/sdk-node@0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@opentelemetry/api-logs': 0.202.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-logs-otlp-grpc': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-logs-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-logs-otlp-proto': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-metrics-otlp-grpc': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-metrics-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-metrics-otlp-proto': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-prometheus': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-trace-otlp-grpc': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-trace-otlp-proto': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/exporter-zipkin': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/instrumentation': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/propagator-b3': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/propagator-jaeger': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-logs-otlp-grpc': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-logs-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-logs-otlp-proto': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-metrics-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-metrics-otlp-proto': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-prometheus': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-trace-otlp-grpc': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-trace-otlp-proto': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/exporter-zipkin': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/instrumentation': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/propagator-b3': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/propagator-jaeger': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-logs': 0.202.0(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/semantic-conventions': 1.34.0 transitivePeerDependencies: - supports-color - '@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/semantic-conventions': 1.34.0 - '@opentelemetry/sdk-trace-node@2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))': + '@opentelemetry/sdk-trace-node@2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))': dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) - '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a)) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) + '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4)) '@opentelemetry/semantic-conventions@1.34.0': {} @@ -11431,12 +11345,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.5 '@tailwindcss/oxide-win32-x64-msvc': 4.1.5 - '@tailwindcss/vite@4.1.5(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0))': + '@tailwindcss/vite@4.1.5(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0))': dependencies: '@tailwindcss/node': 4.1.5 '@tailwindcss/oxide': 4.1.5 tailwindcss: 4.1.5 - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) '@tanstack/query-core@5.67.1': {} @@ -11453,40 +11367,40 @@ snapshots: '@tanstack/virtual-core@3.13.6': {} - '@testing-library/dom@10.4.0': + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.26.2 '@babel/runtime': 7.26.10 '@types/aria-query': 5.0.4 aria-query: 5.3.0 - chalk: 4.1.2 dom-accessibility-api: 0.5.16 lz-string: 1.5.0 + picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.6.3': + '@testing-library/jest-dom@6.6.4': dependencies: - '@adobe/css-tools': 4.4.3 + '@adobe/css-tools': 4.4.4 aria-query: 5.3.2 - chalk: 3.0.0 css.escape: 1.5.1 dom-accessibility-api: 0.6.3 lodash: 4.17.21 + picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/react@16.3.0(@testing-library/dom@10.4.0)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.26.10 - '@testing-library/dom': 10.4.0 + '@testing-library/dom': 10.4.1 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) optionalDependencies: '@types/react': 18.3.18 '@types/react-dom': 18.3.5(@types/react@18.3.18) - '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': dependencies: - '@testing-library/dom': 10.4.0 + '@testing-library/dom': 10.4.1 '@trysound/sax@0.2.0': {} @@ -11539,9 +11453,6 @@ snapshots: dependencies: '@types/tern': 0.23.9 - '@types/cookie@0.6.0': - optional: true - '@types/d3-color@3.1.3': {} '@types/d3-drag@3.0.7': @@ -11579,8 +11490,9 @@ snapshots: '@types/estree@1.0.7': {} - '@types/fontkit@2.0.8': + '@types/fs-extra@11.0.4': dependencies: + '@types/jsonfile': 6.1.4 '@types/node': 22.15.3 '@types/hast@3.0.4': @@ -11593,6 +11505,10 @@ snapshots: '@types/json5@0.0.29': {} + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 22.15.3 + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -11635,7 +11551,6 @@ snapshots: '@types/node': 22.15.3 pg-protocol: 1.7.0 pg-types: 2.2.0 - optional: true '@types/progress@2.0.7': dependencies: @@ -11656,9 +11571,6 @@ snapshots: dependencies: '@types/node': 22.15.3 - '@types/statuses@2.0.6': - optional: true - '@types/tar@6.1.13': dependencies: '@types/node': 22.15.3 @@ -11668,9 +11580,6 @@ snapshots: dependencies: '@types/estree': 1.0.7 - '@types/tough-cookie@4.0.5': - optional: true - '@types/trusted-types@2.0.7': {} '@types/unist@2.0.11': {} @@ -11767,18 +11676,18 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-react@4.3.4(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0))': + '@vitejs/plugin-react@4.3.4(vite@6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0))': dependencies: '@babel/core': 7.26.9 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.9) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0))': + '@vitest/coverage-v8@3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -11792,11 +11701,11 @@ snapshots: std-env: 3.8.1 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + vitest: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0))': + '@vitest/coverage-v8@3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -11810,7 +11719,7 @@ snapshots: std-env: 3.8.1 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0) + vitest: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) transitivePeerDependencies: - supports-color @@ -11821,23 +11730,21 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.1.1(msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3))(vite@6.3.5(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0))': + '@vitest/mocker@3.1.1(vite@6.2.7(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0))': dependencies: '@vitest/spy': 3.1.1 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - msw: 2.10.4(@types/node@20.17.14)(typescript@5.7.3) - vite: 6.3.5(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.2.7(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) - '@vitest/mocker@3.1.1(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0))': + '@vitest/mocker@3.1.1(vite@6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0))': dependencies: '@vitest/spy': 3.1.1 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - msw: 2.10.4(@types/node@22.15.3)(typescript@5.7.3) - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) '@vitest/pretty-format@3.1.1': dependencies: @@ -12462,11 +12369,6 @@ snapshots: ansi-colors@4.1.3: {} - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - optional: true - ansi-escapes@7.0.0: dependencies: environment: 1.1.0 @@ -12583,11 +12485,13 @@ snapshots: ast-types-flow@0.0.8: {} + astral-regex@2.0.0: {} + astring@1.9.0: {} - astro-expressive-code@0.41.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)): + astro-expressive-code@0.41.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)): dependencies: - astro: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + astro: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) rehype-expressive-code: 0.41.2 astro-font@1.0.0: {} @@ -12609,12 +12513,12 @@ snapshots: - prettier-plugin-astro - typescript - astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0): + astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0): dependencies: - '@astrojs/compiler': 2.12.2 - '@astrojs/internal-helpers': 0.7.1 - '@astrojs/markdown-remark': 6.3.5 - '@astrojs/telemetry': 3.3.0 + '@astrojs/compiler': 2.11.0 + '@astrojs/internal-helpers': 0.6.1 + '@astrojs/markdown-remark': 6.3.1 + '@astrojs/telemetry': 3.2.1 '@capsizecss/unpack': 2.4.0 '@oslojs/encoding': 1.1.0 '@rollup/pluginutils': 5.1.4(rollup@4.40.0) @@ -12637,11 +12541,9 @@ snapshots: esbuild: 0.25.0 estree-walker: 3.0.3 flattie: 1.1.1 - fontace: 0.3.0 github-slugger: 2.0.0 html-escaper: 3.0.3 http-cache-semantics: 4.1.1 - import-meta-resolve: 4.1.0 js-yaml: 4.1.0 kleur: 4.1.5 magic-string: 0.30.17 @@ -12656,17 +12558,16 @@ snapshots: rehype: 13.0.2 semver: 7.7.1 shiki: 3.4.0 - smol-toml: 1.4.1 tinyexec: 0.3.2 - tinyglobby: 0.2.14 + tinyglobby: 0.2.12 tsconfck: 3.1.5(typescript@5.7.3) ultrahtml: 1.6.0 unifont: 0.5.0 unist-util-visit: 5.0.0 unstorage: 1.15.0(idb-keyval@6.2.1) vfile: 6.0.3 - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) - vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) + vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)) xxhash-wasm: 1.1.0 yargs-parser: 21.1.1 yocto-spinner: 0.2.1 @@ -12891,11 +12792,6 @@ snapshots: loupe: 3.1.3 pathval: 2.0.0 - chalk@3.0.0: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -12978,8 +12874,11 @@ snapshots: cli-boxes@3.0.0: {} - cli-width@4.1.0: - optional: true + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@2.9.2: {} client-only@0.0.1: {} @@ -13068,9 +12967,6 @@ snapshots: cookie-es@1.2.2: {} - cookie@0.7.2: - optional: true - cookie@1.0.2: {} copy-anything@3.0.5: @@ -13372,13 +13268,14 @@ snapshots: dotenv@8.6.0: {} - drizzle-orm@0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3): + drizzle-orm@0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3)(postgres@3.4.7): optionalDependencies: '@electric-sql/pglite': 0.2.13 - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) '@types/pg': 8.15.4 kysely: 0.26.3 pg: 8.11.3 + postgres: 3.4.7 dset@3.1.4: {} @@ -13663,7 +13560,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@9.20.1(jiti@2.4.2)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@9.20.1(jiti@2.4.2)))(eslint@9.20.1(jiti@2.4.2)): dependencies: debug: 3.2.7 optionalDependencies: @@ -13685,7 +13582,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.20.1(jiti@2.4.2) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@9.20.1(jiti@2.4.2)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3(eslint-plugin-import@2.31.0)(eslint@9.20.1(jiti@2.4.2)))(eslint@9.20.1(jiti@2.4.2)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -13931,7 +13828,7 @@ snapshots: dependencies: chardet: 0.7.0 iconv-lite: 0.4.24 - tmp: 0.2.4 + tmp: 0.2.5 extract-zip@2.0.1: dependencies: @@ -13989,6 +13886,10 @@ snapshots: dependencies: pend: 1.2.0 + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + fdir@6.4.6(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -14029,11 +13930,6 @@ snapshots: follow-redirects@1.15.9: {} - fontace@0.3.0: - dependencies: - '@types/fontkit': 2.0.8 - fontkit: 2.0.4 - fontkit@2.0.4: dependencies: '@swc/helpers': 0.5.15 @@ -14093,6 +13989,12 @@ snapshots: dependencies: tslib: 2.8.1 + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -14540,9 +14442,6 @@ snapshots: property-information: 6.5.0 space-separated-tokens: 2.0.2 - headers-polyfill@4.0.3: - optional: true - help-me@5.0.0: {} hey-listen@1.0.8: {} @@ -14746,10 +14645,9 @@ snapshots: dependencies: is-docker: 3.0.0 - is-map@2.0.3: {} + is-interactive@2.0.0: {} - is-node-process@1.2.0: - optional: true + is-map@2.0.3: {} is-number-object@1.1.1: dependencies: @@ -14802,6 +14700,10 @@ snapshots: dependencies: which-typed-array: 1.1.18 + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} + is-weakmap@2.0.2: {} is-weakref@1.1.1: @@ -14899,7 +14801,7 @@ snapshots: http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 + nwsapi: 2.2.21 parse5: 7.2.1 rrweb-cssom: 0.8.0 saxes: 6.0.0 @@ -14950,6 +14852,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jsx-ast-utils@3.3.5: dependencies: array-includes: 3.1.8 @@ -15099,8 +15007,15 @@ snapshots: lodash.startcase@4.4.0: {} + lodash.truncate@4.4.2: {} + lodash@4.17.21: {} + log-symbols@6.0.0: + dependencies: + chalk: 5.4.1 + is-unicode-supported: 1.3.0 + long@5.3.2: {} longest-streak@3.1.0: {} @@ -15647,6 +15562,8 @@ snapshots: mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + min-indent@1.0.1: {} minimalistic-assert@1.0.1: {} @@ -15710,65 +15627,10 @@ snapshots: ms@2.1.3: {} - msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3): - dependencies: - '@bundled-es-modules/cookie': 2.0.1 - '@bundled-es-modules/statuses': 1.0.1 - '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.14(@types/node@20.17.14) - '@mswjs/interceptors': 0.39.5 - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/until': 2.1.0 - '@types/cookie': 0.6.0 - '@types/statuses': 2.0.6 - graphql: 16.10.0 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - strict-event-emitter: 0.5.1 - type-fest: 4.33.0 - yargs: 17.7.2 - optionalDependencies: - typescript: 5.7.3 - transitivePeerDependencies: - - '@types/node' - optional: true - - msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3): - dependencies: - '@bundled-es-modules/cookie': 2.0.1 - '@bundled-es-modules/statuses': 1.0.1 - '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.14(@types/node@22.15.3) - '@mswjs/interceptors': 0.39.5 - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/until': 2.1.0 - '@types/cookie': 0.6.0 - '@types/statuses': 2.0.6 - graphql: 16.10.0 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - strict-event-emitter: 0.5.1 - type-fest: 4.33.0 - yargs: 17.7.2 - optionalDependencies: - typescript: 5.7.3 - transitivePeerDependencies: - - '@types/node' - optional: true - muggle-string@0.4.1: {} multiformats@9.9.0: {} - mute-stream@2.0.0: - optional: true - mz@2.7.0: dependencies: any-promise: 1.3.0 @@ -15788,7 +15650,7 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - next@15.2.4(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@15.2.4(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 15.2.4 '@swc/counter': 0.1.3 @@ -15808,7 +15670,7 @@ snapshots: '@next/swc-linux-x64-musl': 15.2.4 '@next/swc-win32-arm64-msvc': 15.2.4 '@next/swc-win32-x64-msvc': 15.2.4 - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) sharp: 0.33.5 transitivePeerDependencies: - '@babel/core' @@ -15854,7 +15716,7 @@ snapshots: nullthrows@1.1.1: {} - nwsapi@2.2.20: {} + nwsapi@2.2.21: {} obj-multiplex@1.0.0: dependencies: @@ -15927,6 +15789,10 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + oniguruma-parser@0.12.1: {} oniguruma-to-es@4.3.3: @@ -15944,10 +15810,19 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - outdent@0.5.0: {} + ora@8.2.0: + dependencies: + chalk: 5.4.1 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.0 - outvariant@1.4.3: - optional: true + outdent@0.5.0: {} own-keys@1.0.1: dependencies: @@ -16087,9 +15962,6 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@6.3.0: - optional: true - path-type@4.0.0: {} pathe@1.1.2: {} @@ -16237,7 +16109,7 @@ snapshots: graphql: 16.10.0 hono: 4.7.8 - ponder@0.11.25(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7): + ponder@0.11.25(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/node@22.15.3)(@types/pg@8.15.4)(hono@4.7.8)(jiti@2.4.2)(lightningcss@1.29.2)(postgres@3.4.7)(tsx@4.20.3)(typescript@5.7.3)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7))(yaml@2.7.0)(zod@3.25.7): dependencies: '@babel/code-frame': 7.26.2 '@commander-js/extra-typings': 12.1.0(commander@12.1.0) @@ -16254,7 +16126,7 @@ snapshots: dataloader: 2.2.3 detect-package-manager: 3.0.2 dotenv: 16.4.7 - drizzle-orm: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3) + drizzle-orm: 0.41.0(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4))(@types/pg@8.15.4)(kysely@0.26.3)(pg@8.11.3)(postgres@3.4.7) glob: 10.4.5 graphql: 16.10.0 graphql-yoga: 5.10.10(graphql@16.10.0) @@ -16273,9 +16145,9 @@ snapshots: superjson: 2.2.2 terminal-size: 4.0.0 viem: 2.23.2(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.25.7) - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) - vite-node: 1.0.2(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) - vite-tsconfig-paths: 4.3.1(typescript@5.7.3)(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) + vite-node: 1.0.2(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) + vite-tsconfig-paths: 4.3.1(typescript@5.7.3)(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)) optionalDependencies: typescript: 5.7.3 transitivePeerDependencies: @@ -16350,13 +16222,13 @@ snapshots: postcss: 8.5.3 ts-node: 10.9.2(@types/node@22.15.3)(typescript@5.7.3) - postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(yaml@2.7.0): + postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(yaml@2.7.0): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 2.4.2 postcss: 8.5.3 - tsx: 4.19.3 + tsx: 4.20.3 yaml: 2.7.0 postcss-nested@6.2.0(postcss@8.5.3): @@ -16393,6 +16265,8 @@ snapshots: dependencies: xtend: 4.0.2 + postgres@3.4.7: {} + preact@10.26.4: {} prelude-ls@1.2.1: {} @@ -16422,7 +16296,7 @@ snapshots: prom-client@15.1.3: dependencies: - '@opentelemetry/api': 1.9.0(patch_hash=4b2adeefaf7c22f9987d0a125d69cab900719bec7ed7636648bea6947107033a) + '@opentelemetry/api': 1.9.0(patch_hash=izegmddoiqidmvapuxeha6lnw4) tdigest: 0.1.2 prompts@2.4.2: @@ -16459,11 +16333,6 @@ snapshots: proxy-from-env@1.1.0: {} - psl@1.15.0: - dependencies: - punycode: 2.3.1 - optional: true - pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -16489,9 +16358,6 @@ snapshots: split-on-first: 1.1.0 strict-uri-encode: 2.0.0 - querystringify@2.2.0: - optional: true - queue-microtask@1.2.3: {} quick-format-unescaped@4.0.4: {} @@ -16799,9 +16665,6 @@ snapshots: require-main-filename@2.0.0: {} - requires-port@1.0.0: - optional: true - resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -16820,6 +16683,11 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + restructure@3.0.2: {} retext-latin@4.0.0: @@ -17062,9 +16930,13 @@ snapshots: slash@3.0.0: {} - smol-toml@1.3.1: {} + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 - smol-toml@1.4.1: {} + smol-toml@1.3.1: {} socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: @@ -17147,13 +17019,13 @@ snapshots: dependencies: type-fest: 0.7.1 - starlight-llms-txt@0.5.0(@astrojs/starlight@0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)))(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)): + starlight-llms-txt@0.5.0(@astrojs/starlight@0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)))(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)): dependencies: - '@astrojs/mdx': 4.3.0(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) - '@astrojs/starlight': 0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) + '@astrojs/mdx': 4.3.0(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) + '@astrojs/starlight': 0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) '@types/hast': 3.0.4 '@types/micromatch': 4.0.9 - astro: 5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0) + astro: 5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0) github-slugger: 2.0.0 hast-util-select: 6.0.3 micromatch: 4.0.8 @@ -17166,24 +17038,20 @@ snapshots: transitivePeerDependencies: - supports-color - starlight-sidebar-topics@0.4.1(@astrojs/starlight@0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0))): + starlight-sidebar-topics@0.4.1(@astrojs/starlight@0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0))): dependencies: - '@astrojs/starlight': 0.34.2(astro@5.12.8(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0)) - - statuses@2.0.2: - optional: true + '@astrojs/starlight': 0.34.2(astro@5.7.11(@types/node@22.15.3)(idb-keyval@6.2.1)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.0)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0)) std-env@3.8.1: {} + stdin-discarder@0.2.2: {} + stream-replace-string@2.0.0: {} stream-shift@1.0.3: {} streamsearch@1.1.0: {} - strict-event-emitter@0.5.1: - optional: true - strict-uri-encode@2.0.0: {} string-width@4.2.3: @@ -17339,6 +17207,14 @@ snapshots: tabbable@6.2.0: {} + table@6.9.0: + dependencies: + ajv: 8.17.1 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + tailwind-merge@3.0.2: {} tailwindcss-animate@1.0.7(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.15.3)(typescript@5.7.3))): @@ -17450,6 +17326,11 @@ snapshots: tinyexec@1.0.1: {} + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + tinyglobby@0.2.14: dependencies: fdir: 6.4.6(picomatch@4.0.2) @@ -17467,7 +17348,7 @@ snapshots: dependencies: tldts-core: 6.1.86 - tmp@0.2.4: {} + tmp@0.2.5: {} to-regex-range@5.0.1: dependencies: @@ -17475,14 +17356,6 @@ snapshots: toggle-selection@1.0.6: {} - tough-cookie@4.1.4: - dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - optional: true - tough-cookie@5.1.2: dependencies: tldts: 6.1.86 @@ -17547,7 +17420,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(typescript@5.7.3)(yaml@2.7.0): + tsup@8.3.6(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(typescript@5.7.3)(yaml@2.7.0): dependencies: bundle-require: 5.1.0(esbuild@0.25.0) cac: 6.7.14 @@ -17557,7 +17430,7 @@ snapshots: esbuild: 0.25.0 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.5.3)(tsx@4.19.3)(yaml@2.7.0) + postcss-load-config: 6.0.1(jiti@2.4.2)(postcss@8.5.3)(tsx@4.20.3)(yaml@2.7.0) resolve-from: 5.0.0 rollup: 4.40.0 source-map: 0.8.0-beta.0 @@ -17581,13 +17454,17 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tsx@4.20.3: + dependencies: + esbuild: 0.25.0 + get-tsconfig: 4.10.0 + optionalDependencies: + fsevents: 2.3.3 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - type-fest@0.21.3: - optional: true - type-fest@0.7.1: {} type-fest@2.19.0: {} @@ -17751,8 +17628,7 @@ snapshots: universalify@0.1.2: {} - universalify@0.2.0: - optional: true + universalify@2.0.1: {} unstorage@1.15.0(idb-keyval@6.2.1): dependencies: @@ -17777,12 +17653,6 @@ snapshots: dependencies: punycode: 2.3.1 - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - optional: true - urlpattern-polyfill@10.0.0: {} use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1): @@ -17889,13 +17759,13 @@ snapshots: - utf-8-validate - zod - vite-node@1.0.2(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): + vite-node@1.0.2(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0): dependencies: cac: 6.7.14 debug: 4.4.0 pathe: 1.1.2 picocolors: 1.1.1 - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -17931,13 +17801,13 @@ snapshots: - tsx - yaml - vite-node@3.1.1(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): + vite-node@3.1.1(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) transitivePeerDependencies: - '@types/node' - jiti @@ -17952,17 +17822,43 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@4.3.1(typescript@5.7.3)(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)): + vite-tsconfig-paths@4.3.1(typescript@5.7.3)(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)): dependencies: debug: 4.4.0 globrex: 0.1.2 tsconfck: 3.1.5(typescript@5.7.3) optionalDependencies: - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) transitivePeerDependencies: - supports-color - typescript + vite@6.2.7(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): + dependencies: + esbuild: 0.25.0 + postcss: 8.5.3 + rollup: 4.40.0 + optionalDependencies: + '@types/node': 20.17.14 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.29.2 + tsx: 4.19.3 + yaml: 2.7.0 + + vite@6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0): + dependencies: + esbuild: 0.25.0 + postcss: 8.5.3 + rollup: 4.40.0 + optionalDependencies: + '@types/node': 22.15.3 + fsevents: 2.3.3 + jiti: 2.4.2 + lightningcss: 1.29.2 + tsx: 4.20.3 + yaml: 2.7.0 + vite@6.3.5(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): dependencies: esbuild: 0.25.0 @@ -17979,7 +17875,7 @@ snapshots: tsx: 4.19.3 yaml: 2.7.0 - vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): + vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0): dependencies: esbuild: 0.25.0 fdir: 6.4.6(picomatch@4.0.2) @@ -17992,17 +17888,17 @@ snapshots: fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.29.2 - tsx: 4.19.3 + tsx: 4.20.3 yaml: 2.7.0 - vitefu@1.0.6(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)): + vitefu@1.0.6(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)): optionalDependencies: - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) - vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0): + vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.14)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0): dependencies: '@vitest/expect': 3.1.1 - '@vitest/mocker': 3.1.1(msw@2.10.4(@types/node@20.17.14)(typescript@5.7.3))(vite@6.3.5(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + '@vitest/mocker': 3.1.1(vite@6.2.7(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) '@vitest/pretty-format': 3.1.1 '@vitest/runner': 3.1.1 '@vitest/snapshot': 3.1.1 @@ -18018,7 +17914,7 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.2.7(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) vite-node: 3.1.1(@types/node@20.17.14)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) why-is-node-running: 2.3.0 optionalDependencies: @@ -18039,10 +17935,10 @@ snapshots: - tsx - yaml - vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(tsx@4.19.3)(yaml@2.7.0): + vitest@3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0): dependencies: '@vitest/expect': 3.1.1 - '@vitest/mocker': 3.1.1(msw@2.10.4(@types/node@22.15.3)(typescript@5.7.3))(vite@6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + '@vitest/mocker': 3.1.1(vite@6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0)) '@vitest/pretty-format': 3.1.1 '@vitest/runner': 3.1.1 '@vitest/snapshot': 3.1.1 @@ -18058,8 +17954,8 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) - vite-node: 3.1.1(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + vite: 6.2.7(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) + vite-node: 3.1.1(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.20.3)(yaml@2.7.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -18459,9 +18355,6 @@ snapshots: dependencies: yoctocolors: 2.1.1 - yoctocolors-cjs@2.1.2: - optional: true - yoctocolors@2.1.1: {} zod-to-json-schema@3.24.5(zod@3.25.7): diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f6e4bcd36..1da86da09 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,6 +2,7 @@ packages: - apps/* - docs/* - packages/* + - tools/* catalog: "@biomejs/biome": ^1.9.4 @@ -21,3 +22,4 @@ catalog: "astro-font": ^1.0.0 "astro-seo": ^0.8.4 "@namehash/namekit-react": 0.12.0 + "tsx": ^4.19.4 diff --git a/tools/ensdb-compare/README.md b/tools/ensdb-compare/README.md new file mode 100644 index 000000000..95341fdb3 --- /dev/null +++ b/tools/ensdb-compare/README.md @@ -0,0 +1,234 @@ +# ENSDb Compare Tool + +A high-performance CLI tool for exporting and comparing ENS database contents using both Drizzle ORM and raw PostgreSQL approaches. + +## Overview + +This tool is designed to handle large ENS databases (100GB+) by providing: +- **Fast database exports** using PostgreSQL COPY commands and binary formats +- **Table-by-table processing** for memory efficiency +- **Compression support** (gzip, brotli) to reduce file sizes +- **Performance benchmarking** between Drizzle ORM and raw PostgreSQL +- **Database comparison** to identify differences between two ENS databases + +## Features + +### Export Formats +- **Binary** (fastest, PostgreSQL native format) +- **CSV** (human-readable, compressed) +- **JSON** (structured data, Drizzle only) + +### Compression Options +- **gzip** (good compression, fast) +- **brotli** (better compression, slower) +- **none** (fastest export, largest files) + +### Exporters +- **PostgreSQL** - Uses chunked SELECT queries for memory efficiency +- **Drizzle** - Uses Drizzle ORM with raw SQL fallback for custom schemas +- **Copy Stream** - Uses native PostgreSQL `COPY TO STDOUT` for maximum performance + +## Installation + +```bash +cd tools/ensdb-compare +npm install +npm run build +``` + +## Usage + +### 1. Export Database Tables + +Export all tables using PostgreSQL exporter with binary format: +```bash +ensdb-compare export \ + -c "postgresql://user:pass@host:port/dbname" \ + -o ./exports/db_a \ + -f binary \ + -z gzip \ + -e pgsql +``` + +Export specific tables using Drizzle with JSON format: +```bash +ensdb-compare export \ + -c "postgresql://user:pass@host:port/dbname" \ + -o ./exports/db_b \ + -f json \ + -z gzip \ + -e drizzle \ + -t "domains,accounts,resolvers" +``` + +### 2. Benchmark Performance + +Compare export performance between PostgreSQL and Drizzle: +```bash +ensdb-compare benchmark \ + -c "postgresql://user:pass@host:port/dbname" \ + -o ./benchmark \ + -t domains \ + -i 5 +``` + +### 3. Database Information + +Get database table statistics: +```bash +ensdb-compare info \ + -c "postgresql://user:pass@host:port/dbname" \ + -e pgsql +``` + +### 4. Compare Databases + +Compare two sets of exported database files: +```bash +ensdb-compare compare \ + -a ./exports/db_a \ + -b ./exports/db_b \ + -o comparison_report.json \ + -f json +``` + +Compare specific tables with custom primary keys: +```bash +ensdb-compare compare \ + -a ./exports/db_a \ + -b ./exports/db_b \ + -o comparison_report.html \ + -f html \ + -t "domains,accounts" \ + --primary-keys '{"domains":["id"],"accounts":["id"]}' +``` + +## Command Options + +### Export Command +- `-c, --connection ` - PostgreSQL connection string (required) +- `-o, --output ` - Output directory (required) +- `-f, --format ` - Export format: binary, csv, json (default: binary) +- `-z, --compression ` - Compression: gzip, brotli, none (default: gzip) +- `-e, --exporter ` - Exporter type: pgsql, drizzle, copy-stream (default: pgsql) +- `-t, --tables ` - Comma-separated list of tables (default: all) +- `--chunk-size ` - Chunk size for processing (default: 10000) + +### Benchmark Command +- `-c, --connection ` - PostgreSQL connection string (required) +- `-o, --output ` - Output directory (required) +- `-t, --table ` - Table to benchmark (default: domains) +- `-i, --iterations ` - Number of iterations (default: 3) +- `-f, --format ` - Export format for comparison (default: csv) + +### Compare Command +- `-a, --database-a ` - Path to database A export directory (required) +- `-b, --database-b ` - Path to database B export directory (required) +- `-o, --output ` - Output file for comparison report (required) +- `-f, --format ` - Report format: json, csv, html (default: json) +- `-t, --tables ` - Comma-separated list of tables to compare (default: all) +- `--primary-keys ` - JSON string defining custom primary keys per table + +## Performance Characteristics + +### Expected Performance (100GB Database) + +| Format | Exporter | Compression | Speed | File Size | +|--------|----------|-------------|-------|-----------| +| CSV | Copy Stream | gzip | **Fastest** | Small | +| CSV | Copy Stream | none | **Fastest** | Medium | +| CSV | PostgreSQL | gzip | Fast | Small | +| CSV | Drizzle | gzip | Fast | Small | +| JSON | Drizzle | gzip | Slower | Medium | + +### Recommendations for 100GB Databases + +1. **For maximum speed**: Use `csv` format with `copy-stream` exporter and `gzip` compression +2. **For human readability**: Use `csv` format with `pgsql` exporter and `gzip` compression +3. **For structured data**: Use `json` format with `drizzle` exporter and `gzip` compression +4. **For development/testing**: Use `csv` format with `drizzle` exporter + +## Tables Supported + +- `domains` - Core ENS domain data +- `accounts` - Account addresses +- `resolvers` - Resolver contracts and settings +- `registrations` - Domain registration data +- `resolver_address_records` - Address records by coin type +- `resolver_text_records` - Text records by key +- `ext_registration_referral` - Referral tracking data + +## Schema Compatibility + +This tool includes a "brute force" schema adapter that manually defines table schemas based on the `ensnode-schema` package, working around Ponder-specific functions to ensure compatibility with pure Drizzle ORM. + +## Connection String Format + +``` +postgresql://username:password@hostname:port/database_name +``` + +Example: +``` +postgresql://ensuser:password123@localhost:5432/ensdb +``` + +## Output Structure + +Exported files are organized by table: +``` +exports/ +├── domains.bin.gz +├── accounts.bin.gz +├── resolvers.bin.gz +├── registrations.bin.gz +├── resolver_address_records.bin.gz +├── resolver_text_records.bin.gz +└── ext_registration_referral.bin.gz +``` + +## Error Handling + +- Connection failures are reported immediately +- Failed table exports continue processing other tables +- Detailed error messages and export statistics +- Graceful handling of missing tables + +## Development + +```bash +# Install dependencies +npm install + +# Run in development mode +npm run dev export --help + +# Build for production +npm run build + +# Run linting +npm run lint +``` + +## Architecture + +The tool is built with a modular architecture: + +- `schema-adapter.ts` - Schema definitions and table registry +- `exporters/base-exporter.ts` - Abstract base class and interfaces +- `exporters/pgsql-exporter.ts` - Chunked SELECT implementation +- `exporters/drizzle-exporter.ts` - Drizzle ORM with raw SQL fallback +- `exporters/copy-stream-exporter.ts` - Native PostgreSQL COPY TO STDOUT streaming +- `cli.ts` - Command-line interface and orchestration + +## Future Enhancements + +- [x] File-based database comparison logic ✅ +- [ ] Parallel table exports +- [ ] Resume capability for interrupted exports +- [ ] Custom SQL query exports +- [ ] Delta/incremental export support +- [ ] Export validation and integrity checks +- [ ] Detailed diff views (field-by-field changes) +- [ ] Performance optimizations for very large datasets +- [ ] Binary file format comparison support diff --git a/tools/ensdb-compare/package.json b/tools/ensdb-compare/package.json new file mode 100644 index 000000000..e537915af --- /dev/null +++ b/tools/ensdb-compare/package.json @@ -0,0 +1,44 @@ +{ + "name": "@ensnode/ensdb-compare", + "version": "0.1.0", + "description": "CLI tool to compare ENSDb databases using Drizzle ORM", + "type": "module", + "main": "dist/index.js", + "bin": { + "ensdb-compare": "./dist/cli.js" + }, + "scripts": { + "build": "tsc", + "dev": "tsx src/cli.ts", + "start": "node dist/cli.js", + "lint": "biome check --write", + "lint:ci": "biome ci" + }, + "keywords": ["ENS", "database", "comparison", "drizzle", "CLI"], + "author": "ENSNode Team", + "license": "MIT", + "dependencies": { + "@ensnode/ensnode-schema": "workspace:*", + "drizzle-orm": "catalog:", + "postgres": "^3.4.4", + "pg": "^8.11.3", + "commander": "^12.0.0", + "chalk": "^5.3.0", + "ora": "^8.0.1", + "table": "^6.8.1", + "fs-extra": "^11.2.0" + }, + "devDependencies": { + "@biomejs/biome": "catalog:", + "@ensnode/shared-configs": "workspace:*", + "@types/node": "catalog:", + "@types/fs-extra": "^11.0.4", + "@types/pg": "^8.10.9", + "tsx": "catalog:", + "typescript": "catalog:" + }, + "files": [ + "dist", + "README.md" + ] +} diff --git a/tools/ensdb-compare/src/cli.ts b/tools/ensdb-compare/src/cli.ts new file mode 100644 index 000000000..8fccc77aa --- /dev/null +++ b/tools/ensdb-compare/src/cli.ts @@ -0,0 +1,541 @@ +#!/usr/bin/env node + +/** + * ENSDb Compare CLI Tool + * + * Commands: + * - export: Export database tables to files + * - compare: Compare two sets of exported files + * - benchmark: Benchmark export performance (Drizzle vs PostgreSQL) + */ + +import { Command } from 'commander'; +import chalk from 'chalk'; +import ora from 'ora'; +import { table } from 'table'; +import * as fs from 'fs-extra'; +import { promises as fsPromises } from 'fs'; +import path from 'path'; + +import { PostgreSQLExporter } from './exporters/pgsql-exporter.js'; +import { DrizzleExporter } from './exporters/drizzle-exporter.js'; +import { CopyStreamExporter } from './exporters/copy-stream-exporter.js'; +import { FileComparator } from './comparator/file-comparator.js'; +import { ComparisonConfig } from './comparator/base-comparator.js'; +import { ExportConfig } from './exporters/base-exporter.js'; +import { tableNames, TableName } from './schema-adapter.js'; + +const program = new Command(); + +program + .name('ensdb-compare') + .description('CLI tool to export and compare ENSDb databases') + .version('0.1.0'); + +// Export command +program + .command('export') + .description('Export database tables to files') + .requiredOption('-c, --connection ', 'PostgreSQL connection string') + .requiredOption('-o, --output ', 'Output directory') + .option('-s, --schema ', 'Database schema name (default: public)', 'public') + .option('-f, --format ', 'Export format: csv, json', 'csv') + .option('-z, --compression ', 'Compression: gzip, brotli, none', 'gzip') + .option('-e, --exporter ', 'Exporter type: pgsql, drizzle, copy-stream', 'pgsql') + .option('-t, --tables ', 'Comma-separated list of tables (default: all)') + .option('--chunk-size ', 'Chunk size for processing', '10000') + .action(async (options) => { + const spinner = ora('Starting export...').start(); + + try { + const config: ExportConfig = { + connectionString: options.connection, + outputDir: options.output, + format: options.format, + compression: options.compression === 'none' ? undefined : options.compression, + chunkSize: parseInt(options.chunkSize), + }; + + // Create exporter + let exporter; + switch (options.exporter) { + case 'drizzle': + exporter = new DrizzleExporter(config); + break; + case 'copy-stream': + exporter = new CopyStreamExporter(config); + break; + case 'pgsql': + default: + exporter = new PostgreSQLExporter(config); + break; + } + + // Test connection + spinner.text = 'Testing database connection...'; + const connected = await exporter.testConnection(); + if (!connected) { + spinner.fail('Failed to connect to database'); + process.exit(1); + } + + // Determine tables to export + const schemaName = options.schema; + let tablesToExport: string[]; + + if (options.tables) { + // User specified specific tables + tablesToExport = options.tables.split(',').map((t: string) => t.trim()); + } else { + // Auto-discover tables from the database + spinner.text = 'Discovering tables in database...'; + try { + tablesToExport = await exporter.getActualTables(schemaName); + + if (tablesToExport.length === 0) { + spinner.fail(`No tables found in schema "${schemaName}"`); + await exporter.close(); + process.exit(1); + } + + console.log(`\nDiscovered ${tablesToExport.length} tables in "${schemaName}":`); + tablesToExport.forEach(table => console.log(` - ${table}`)); + + } catch (error) { + spinner.fail('Failed to discover tables'); + console.error(chalk.red('Error:'), error instanceof Error ? error.message : error); + await exporter.close(); + process.exit(1); + } + } + + spinner.text = `Exporting ${tablesToExport.length} tables...`; + + // Export tables + for (const table of tablesToExport) { + try { + spinner.text = `Exporting table: ${table}`; + const result = await exporter.exportTable(schemaName, table); + + console.log(`✓ ${table}: ${result.stats.rowCount} rows, ${formatBytes(result.stats.fileSizeBytes)}, ${result.stats.exportTimeMs}ms`); + } catch (error) { + console.log(`✗ ${table}: ${error instanceof Error ? error.message : error}`); + } + } + + await exporter.close(); + spinner.succeed('Export completed!'); + + } catch (error) { + spinner.fail('Export failed'); + console.error(chalk.red('Error:'), error instanceof Error ? error.message : error); + process.exit(1); + } + }); + +// Benchmark command +program + .command('benchmark') + .description('Benchmark export performance (Drizzle vs PostgreSQL)') + .requiredOption('-c, --connection ', 'PostgreSQL connection string') + .requiredOption('-o, --output ', 'Output directory') + .option('-s, --schema ', 'Database schema name (default: public)', 'public') + .option('-t, --table ', 'Table to benchmark (default: domains)', 'domains') + .option('-i, --iterations ', 'Number of iterations', '3') + .option('-f, --format ', 'Export format for comparison', 'csv') + .action(async (options) => { + const spinner = ora('Starting benchmark...').start(); + + try { + const baseConfig: ExportConfig = { + connectionString: options.connection, + outputDir: options.output, + format: options.format, + compression: 'gzip', + }; + + const schemaName = options.schema; + const tableName = options.table; + const iterations = parseInt(options.iterations); + + console.log(`\nBenchmarking table: "${schemaName}"."${tableName}"`); + + // Let's check what tables actually exist in the database + spinner.text = 'Checking available tables in database...'; + const testExporter = new PostgreSQLExporter(baseConfig); + const connected = await testExporter.testConnection(); + + if (connected) { + try { + const actualTables = await testExporter.sql` + SELECT table_schema, table_name + FROM information_schema.tables + WHERE table_schema NOT IN ('information_schema', 'pg_catalog') + ORDER BY table_schema, table_name + `; + + console.log('\nActual tables in database:'); + actualTables.forEach((row: any) => { + const fullName = `"${row.table_schema}"."${row.table_name}"`; + console.log(` - ${fullName}`); + }); + + await testExporter.close(); + } catch (error) { + console.log('\nCould not list tables:', error instanceof Error ? error.message : error); + } + } + + // Create all three exporters + const pgsqlExporter = new PostgreSQLExporter(baseConfig); + const drizzleExporter = new DrizzleExporter(baseConfig); + const copyStreamExporter = new CopyStreamExporter(baseConfig); + + // Test connections + spinner.text = 'Testing connections...'; + const pgsqlConnected = await pgsqlExporter.testConnection(); + const drizzleConnected = await drizzleExporter.testConnection(); + const copyStreamConnected = await copyStreamExporter.testConnection(); + + if (!pgsqlConnected || !drizzleConnected || !copyStreamConnected) { + spinner.fail('Connection test failed'); + process.exit(1); + } + + // Get row count first to verify table exists and has data + spinner.text = 'Checking table row count...'; + try { + const tableRef = `"${schemaName}"."${tableName}"`; + const result = await pgsqlExporter.sql.unsafe(`SELECT COUNT(*) as count FROM ${tableRef}`); + const rowCount = parseInt(String(result[0].count)); + console.log(`\nTable "${schemaName}"."${tableName}" has ${rowCount.toLocaleString()} rows`); + + if (rowCount === 0) { + spinner.warn('Table is empty - benchmark results may not be meaningful'); + } + } catch (error) { + spinner.fail(`Failed to access table "${schemaName}"."${tableName}": ${error instanceof Error ? error.message : error}`); + await pgsqlExporter.close(); + await drizzleExporter.close(); + process.exit(1); + } + + // Benchmark PostgreSQL exporter + spinner.text = `Benchmarking PostgreSQL exporter (${iterations} iterations)...`; + const pgsqlBenchmark = await pgsqlExporter.benchmarkExport(schemaName, tableName, iterations); + + console.log('\nPostgreSQL results:'); + pgsqlBenchmark.results.forEach((result, i) => { + console.log(` Iteration ${i + 1}: ${result.success ? 'SUCCESS' : 'FAILED'} - ${result.stats.exportTimeMs}ms - ${result.stats.rowCount} rows`); + if (!result.success) { + console.log(` Error: ${result.error}`); + } + }); + + // Benchmark Drizzle exporter + spinner.text = `Benchmarking Drizzle exporter (${iterations} iterations)...`; + const drizzleBenchmark = await drizzleExporter.benchmarkExport(schemaName, tableName, iterations); + + console.log('\nDrizzle results:'); + drizzleBenchmark.results.forEach((result, i) => { + console.log(` Iteration ${i + 1}: ${result.success ? 'SUCCESS' : 'FAILED'} - ${result.stats.exportTimeMs}ms - ${result.stats.rowCount} rows`); + if (!result.success) { + console.log(` Error: ${result.error}`); + } + }); + + // Benchmark Copy Stream exporter + spinner.text = `Benchmarking Copy Stream exporter (${iterations} iterations)...`; + const copyStreamBenchmark = await copyStreamExporter.benchmarkExport(schemaName, tableName, iterations); + + console.log('\nCopy Stream results:'); + copyStreamBenchmark.results.forEach((result, i) => { + console.log(` Iteration ${i + 1}: ${result.success ? 'SUCCESS' : 'FAILED'} - ${result.stats.exportTimeMs}ms - ${result.stats.rowCount} rows`); + if (!result.success) { + console.log(` Error: ${result.error}`); + } + }); + + await pgsqlExporter.close(); + await drizzleExporter.close(); + await copyStreamExporter.close(); + + spinner.succeed('Benchmark completed!'); + + // Display results + console.log('\n' + chalk.bold('Benchmark Results:')); + + const benchmarkTable = [ + ['Exporter', 'Avg Time (ms)', 'Min Time (ms)', 'Max Time (ms)', 'Avg Rows/sec', 'Success Rate'], + [ + 'PostgreSQL', + pgsqlBenchmark.avgTimeMs.toFixed(2), + pgsqlBenchmark.minTimeMs.toString(), + pgsqlBenchmark.maxTimeMs.toString(), + pgsqlBenchmark.results[0]?.stats.rowCount && pgsqlBenchmark.results[0].success ? + ((pgsqlBenchmark.results[0].stats.rowCount / pgsqlBenchmark.avgTimeMs) * 1000).toFixed(0) : 'N/A', + `${pgsqlBenchmark.results.filter(r => r.success).length}/${pgsqlBenchmark.results.length}` + ], + [ + 'Drizzle', + drizzleBenchmark.avgTimeMs.toFixed(2), + drizzleBenchmark.minTimeMs.toString(), + drizzleBenchmark.maxTimeMs.toString(), + drizzleBenchmark.results[0]?.stats.rowCount && drizzleBenchmark.results[0].success ? + ((drizzleBenchmark.results[0].stats.rowCount / drizzleBenchmark.avgTimeMs) * 1000).toFixed(0) : 'N/A', + `${drizzleBenchmark.results.filter(r => r.success).length}/${drizzleBenchmark.results.length}` + ], + [ + 'Copy Stream', + copyStreamBenchmark.avgTimeMs.toFixed(2), + copyStreamBenchmark.minTimeMs.toString(), + copyStreamBenchmark.maxTimeMs.toString(), + copyStreamBenchmark.results[0]?.stats.rowCount && copyStreamBenchmark.results[0].success ? + ((copyStreamBenchmark.results[0].stats.rowCount / copyStreamBenchmark.avgTimeMs) * 1000).toFixed(0) : 'N/A', + `${copyStreamBenchmark.results.filter(r => r.success).length}/${copyStreamBenchmark.results.length}` + ] + ]; + + console.log(table(benchmarkTable)); + + // Only compare if both had successful results + const pgsqlSuccessful = pgsqlBenchmark.results.some(r => r.success); + const drizzleSuccessful = drizzleBenchmark.results.some(r => r.success); + + if (pgsqlSuccessful && drizzleSuccessful) { + const speedup = drizzleBenchmark.avgTimeMs / pgsqlBenchmark.avgTimeMs; + if (speedup > 1) { + console.log(chalk.green(`\nPostgreSQL is ${speedup.toFixed(2)}x faster than Drizzle`)); + } else { + console.log(chalk.yellow(`\nDrizzle is ${(1/speedup).toFixed(2)}x faster than PostgreSQL`)); + } + } else { + console.log(chalk.red('\nCannot compare - one or both exporters failed')); + if (pgsqlSuccessful && !drizzleSuccessful) { + console.log(chalk.blue('Note: Drizzle exporter doesn\'t support custom schemas. PostgreSQL exporter works fine.')); + } + } + + } catch (error) { + spinner.fail('Benchmark failed'); + console.error(chalk.red('Error:'), error instanceof Error ? error.message : error); + process.exit(1); + } + }); + +// Compare command +program + .command('compare') + .description('Compare two database exports and generate difference reports') + .requiredOption('-a, --database-a ', 'Path to database A export directory') + .requiredOption('-b, --database-b ', 'Path to database B export directory') + .requiredOption('-o, --output ', 'Output file for comparison report') + .option('-f, --format ', 'Report format: json, csv, html', 'json') + .option('-t, --tables ', 'Comma-separated list of tables to compare (default: all)') + .option('--primary-keys ', 'JSON string defining custom primary keys per table') + .action(async (options) => { + const spinner = ora('Starting database comparison...').start(); + + try { + // Parse custom primary keys if provided + let primaryKeys: Record | undefined; + if (options.primaryKeys) { + try { + primaryKeys = JSON.parse(options.primaryKeys); + } catch (error) { + spinner.fail('Invalid JSON format for primary keys'); + console.error(chalk.red('Error:'), 'Primary keys must be valid JSON, e.g. \'{"domains":["id"],"accounts":["id"]}\''); + process.exit(1); + } + } + + const config: ComparisonConfig = { + databaseA: options.databaseA, + databaseB: options.databaseB, + outputFile: options.output, + format: options.format, + tables: options.tables ? options.tables.split(',').map((t: string) => t.trim()) : undefined, + primaryKeys + }; + + // Validate directories exist + try { + await fsPromises.access(config.databaseA); + await fsPromises.access(config.databaseB); + } catch (error) { + spinner.fail('Export directories not found'); + console.error(chalk.red('Error:'), 'Both database export directories must exist'); + process.exit(1); + } + + spinner.text = 'Initializing comparator...'; + const comparator = new FileComparator(config); + + spinner.text = 'Comparing databases...'; + const report = await comparator.compareDatabase(); + + spinner.succeed('Database comparison completed!'); + + // Display summary + console.log(`\n${chalk.bold('Comparison Summary:')}`); + console.log(`${chalk.bold('Database A:')} ${report.databaseA}`); + console.log(`${chalk.bold('Database B:')} ${report.databaseB}`); + console.log(`${chalk.bold('Tables Compared:')} ${report.summary.tablesCompared}`); + console.log(`${chalk.bold('Total Differences:')} ${report.summary.totalDifferences}`); + console.log(`${chalk.bold('Comparison Time:')} ${report.summary.comparisonTimeMs}ms`); + + // Display table-by-table results + if (report.tableComparisons.length > 0) { + console.log(`\n${chalk.bold('Table Results:')}`); + const summaryTable = [ + ['Table', 'Total A', 'Total B', 'Identical', 'Different', 'Only A', 'Only B'], + ...report.tableComparisons.map(tc => [ + tc.tableName, + tc.totalRowsA.toString(), + tc.totalRowsB.toString(), + chalk.green(tc.identical.toString()), + tc.differentValues > 0 ? chalk.yellow(tc.differentValues.toString()) : '0', + tc.rowsInAOnly > 0 ? chalk.blue(tc.rowsInAOnly.toString()) : '0', + tc.rowsInBOnly > 0 ? chalk.cyan(tc.rowsInBOnly.toString()) : '0' + ]) + ]; + + console.log(table(summaryTable)); + } + + console.log(`\n${chalk.bold('Report saved to:')} ${config.outputFile}`); + + // Show warning if there are differences + if (report.summary.totalDifferences > 0) { + console.log(chalk.yellow(`\n⚠️ Found ${report.summary.totalDifferences} differences between databases`)); + } else { + console.log(chalk.green('\n✅ Databases are identical!')); + } + + } catch (error) { + spinner.fail('Database comparison failed'); + console.error(chalk.red('Error:'), error instanceof Error ? error.message : error); + process.exit(1); + } + }); + +// Info command +program + .command('info') + .description('Get database and table information') + .requiredOption('-c, --connection ', 'PostgreSQL connection string') + .option('-s, --schema ', 'Database schema name (default: public)', 'public') + .option('-t, --table ', 'Specific table to analyze') + .action(async (options) => { + const spinner = ora('Connecting to database...').start(); + + try { + const config: ExportConfig = { + connectionString: options.connection, + outputDir: './temp', + format: 'csv', + }; + + const exporter = new PostgreSQLExporter(config); + const connected = await exporter.testConnection(); + + if (!connected) { + spinner.fail('Connection failed'); + process.exit(1); + } + + const schemaName = options.schema; + + if (options.table) { + // Show specific table info + spinner.text = `Getting info for table ${schemaName}.${options.table}...`; + + try { + const tableInfo = await exporter.getTableInfo(schemaName, options.table); + + await exporter.close(); + spinner.succeed('Table information retrieved!'); + + console.log(`\n${chalk.bold('Table:')} "${schemaName}"."${options.table}"`); + console.log(`${chalk.bold('Rows:')} ${tableInfo.rowCount.toLocaleString()}`); + + console.log(`\n${chalk.bold('Columns:')}`); + const columnTable = [ + ['Name', 'Type', 'Nullable'], + ...tableInfo.columns.map(col => [col.name, col.type, col.nullable ? 'YES' : 'NO']) + ]; + console.log(table(columnTable)); + + if (tableInfo.indexes.length > 0) { + console.log(`\n${chalk.bold('Indexes:')}`); + const indexTable = [ + ['Name', 'Columns', 'Unique'], + ...tableInfo.indexes.map(idx => [idx.name, idx.columns.join(', '), idx.unique ? 'YES' : 'NO']) + ]; + console.log(table(indexTable)); + } + } catch (error) { + await exporter.close(); + spinner.fail('Failed to get table info'); + console.error(chalk.red('Error:'), error instanceof Error ? error.message : error); + process.exit(1); + } + } else { + // Show all tables + spinner.text = 'Getting database schema...'; + + try { + const allTables = await exporter.sql` + SELECT table_schema, table_name + FROM information_schema.tables + WHERE table_schema NOT IN ('information_schema', 'pg_catalog') + ORDER BY table_schema, table_name + `; + + await exporter.close(); + spinner.succeed('Database schema retrieved!'); + + console.log(`\n${chalk.bold('Available Tables:')}`); + + const schemaGroups: Record = {}; + allTables.forEach((row: any) => { + const schema = row.table_schema; + if (!schemaGroups[schema]) schemaGroups[schema] = []; + schemaGroups[schema].push(row.table_name); + }); + + Object.entries(schemaGroups).forEach(([schema, tables]) => { + console.log(`\n${chalk.yellow(schema)}:`); + tables.forEach(table => { + console.log(` - ${table}`); + }); + }); + + console.log(`\n${chalk.bold('Total tables:')} ${allTables.length}`); + console.log(`${chalk.bold('Schemas:')} ${Object.keys(schemaGroups).length}`); + } catch (error) { + await exporter.close(); + spinner.fail('Failed to get database info'); + console.error(chalk.red('Error:'), error instanceof Error ? error.message : error); + process.exit(1); + } + } + + } catch (error) { + spinner.fail('Info command failed'); + console.error(chalk.red('Error:'), error instanceof Error ? error.message : error); + process.exit(1); + } + }); + +// Utility function +function formatBytes(bytes: number): string { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} + +// Parse and execute +program.parse(); diff --git a/tools/ensdb-compare/src/comparator/base-comparator.ts b/tools/ensdb-compare/src/comparator/base-comparator.ts new file mode 100644 index 000000000..86e3541c5 --- /dev/null +++ b/tools/ensdb-compare/src/comparator/base-comparator.ts @@ -0,0 +1,176 @@ +/** + * Base comparator interfaces and types for database comparison + */ + +export interface ComparisonConfig { + databaseA: string; // Path to database A exports + databaseB: string; // Path to database B exports + outputFile: string; // Path for comparison report + format: 'json' | 'csv' | 'html'; // Report format + tables?: string[]; // Specific tables to compare (default: all) + primaryKeys?: Record; // Custom primary keys per table +} + +export interface TableComparison { + tableName: string; + rowsInAOnly: number; + rowsInBOnly: number; + differentValues: number; + identical: number; + totalRowsA: number; + totalRowsB: number; + comparisonTimeMs: number; +} + +export interface RecordDifference { + primaryKey: Record; + fieldsDifferent: string[]; + valuesA: Record; + valuesB: Record; +} + +export interface TableDifferences { + tableName: string; + onlyInA: Array>; + onlyInB: Array>; + different: RecordDifference[]; + summary: TableComparison; +} + +export interface ComparisonReport { + timestamp: string; + databaseA: string; + databaseB: string; + summary: { + tablesCompared: number; + totalDifferences: number; + comparisonTimeMs: number; + }; + tableComparisons: TableComparison[]; + details: TableDifferences[]; +} + +export interface FileInfo { + path: string; + format: 'csv' | 'json'; + compressed: boolean; + compressionType?: 'gzip' | 'brotli'; +} + +export abstract class BaseComparator { + protected config: ComparisonConfig; + + constructor(config: ComparisonConfig) { + this.config = config; + } + + abstract compareDatabase(): Promise; + abstract compareTable(tableName: string, fileA: FileInfo, fileB: FileInfo): Promise; + + // Utility methods + protected detectFileFormat(filePath: string): FileInfo { + const path = filePath.toLowerCase(); + let format: 'csv' | 'json' = 'csv'; + let compressed = false; + let compressionType: 'gzip' | 'brotli' | undefined; + + // Determine format from filename + if (path.includes('.json')) format = 'json'; + if (path.includes('.csv')) format = 'csv'; + + // Check extensions for potential compression, but we'll verify later + if (path.endsWith('.gz')) { + compressionType = 'gzip'; + } else if (path.endsWith('.br')) { + compressionType = 'brotli'; + } + + return { + path: filePath, + format, + compressed, // Will be set to false initially, actual detection happens in loadDataFromFile + compressionType + }; + } + + protected getDefaultPrimaryKey(tableName: string): string[] { + // Default primary keys for known ENS tables + const defaultKeys: Record = { + domains: ['id'], + accounts: ['id'], + resolvers: ['id'], + registrations: ['id'], + resolver_address_records: ['id'], + resolver_text_records: ['id'], + ext_resolver_address_records: ['id'], + ext_resolver_text_records: ['id'], + ext_registration_referral: ['id'] + }; + + return this.config.primaryKeys?.[tableName] || defaultKeys[tableName] || ['id']; + } + + protected createPrimaryKeyString(record: Record, primaryKeys: string[]): string { + return primaryKeys.map(key => String(record[key] || '')).join('|'); + } + + protected compareRecords(recordA: Record, recordB: Record): RecordDifference | null { + const fieldsDifferent: string[] = []; + const valuesA: Record = {}; + const valuesB: Record = {}; + + // Compare all fields from both records + const allFields = new Set([...Object.keys(recordA), ...Object.keys(recordB)]); + + for (const field of allFields) { + const valueA = recordA[field]; + const valueB = recordB[field]; + + // Deep comparison for different types + if (!this.valuesEqual(valueA, valueB)) { + fieldsDifferent.push(field); + valuesA[field] = valueA; + valuesB[field] = valueB; + } + } + + if (fieldsDifferent.length === 0) { + return null; // Records are identical + } + + const primaryKeys = this.getDefaultPrimaryKey('unknown'); // Will be overridden by actual implementation + const primaryKey: Record = {}; + primaryKeys.forEach(key => { + primaryKey[key] = recordA[key] || recordB[key]; + }); + + return { + primaryKey, + fieldsDifferent, + valuesA, + valuesB + }; + } + + private valuesEqual(a: any, b: any): boolean { + if (a === b) return true; + if (a == null || b == null) return a === b; + if (typeof a !== typeof b) return false; + + // Handle arrays and objects + if (Array.isArray(a) && Array.isArray(b)) { + if (a.length !== b.length) return false; + return a.every((item, index) => this.valuesEqual(item, b[index])); + } + + if (typeof a === 'object' && typeof b === 'object') { + const keysA = Object.keys(a); + const keysB = Object.keys(b); + if (keysA.length !== keysB.length) return false; + return keysA.every(key => keysB.includes(key) && this.valuesEqual(a[key], b[key])); + } + + // Convert to strings for comparison (handles numbers, booleans, etc.) + return String(a) === String(b); + } +} diff --git a/tools/ensdb-compare/src/comparator/file-comparator.ts b/tools/ensdb-compare/src/comparator/file-comparator.ts new file mode 100644 index 000000000..773adcf09 --- /dev/null +++ b/tools/ensdb-compare/src/comparator/file-comparator.ts @@ -0,0 +1,495 @@ +/** + * File-based comparator for exported database files + */ + +import { promises as fs } from 'fs'; +import { createReadStream } from 'fs'; +import { createGunzip, createBrotliDecompress } from 'zlib'; +import { pipeline } from 'stream/promises'; +import path from 'path'; +import { + BaseComparator, + ComparisonConfig, + ComparisonReport, + TableDifferences, + TableComparison, + FileInfo, + RecordDifference +} from './base-comparator.js'; + +export class FileComparator extends BaseComparator { + constructor(config: ComparisonConfig) { + super(config); + } + + async compareDatabase(): Promise { + const startTime = Date.now(); + + // Discover tables to compare + const tablesToCompare = await this.discoverTables(); + + if (tablesToCompare.length === 0) { + throw new Error('No matching tables found in both database exports'); + } + + console.log(`Found ${tablesToCompare.length} tables to compare: ${tablesToCompare.join(', ')}`); + + const tableComparisons: TableComparison[] = []; + const details: TableDifferences[] = []; + + // Compare each table + for (const tableName of tablesToCompare) { + console.log(`Comparing table: ${tableName}`); + + try { + const fileA = await this.findTableFile(this.config.databaseA, tableName); + const fileB = await this.findTableFile(this.config.databaseB, tableName); + + const tableDiff = await this.compareTable(tableName, fileA, fileB); + + tableComparisons.push(tableDiff.summary); + details.push(tableDiff); + + console.log(`✓ ${tableName}: ${tableDiff.summary.identical} identical, ${tableDiff.summary.differentValues} different, ${tableDiff.summary.rowsInAOnly}+${tableDiff.summary.rowsInBOnly} unique`); + } catch (error) { + console.error(`✗ ${tableName}: ${error instanceof Error ? error.message : error}`); + + // Add empty comparison for failed table + const emptyComparison: TableComparison = { + tableName, + rowsInAOnly: 0, + rowsInBOnly: 0, + differentValues: 0, + identical: 0, + totalRowsA: 0, + totalRowsB: 0, + comparisonTimeMs: 0 + }; + + const emptyDifferences: TableDifferences = { + tableName, + onlyInA: [], + onlyInB: [], + different: [], + summary: emptyComparison + }; + + tableComparisons.push(emptyComparison); + details.push(emptyDifferences); + } + } + + const totalDifferences = tableComparisons.reduce((sum, tc) => + sum + tc.rowsInAOnly + tc.rowsInBOnly + tc.differentValues, 0 + ); + + const report: ComparisonReport = { + timestamp: new Date().toISOString(), + databaseA: this.config.databaseA, + databaseB: this.config.databaseB, + summary: { + tablesCompared: tablesToCompare.length, + totalDifferences, + comparisonTimeMs: Date.now() - startTime + }, + tableComparisons, + details + }; + + // Generate report file + await this.generateReport(report); + + return report; + } + + async compareTable(tableName: string, fileA: FileInfo, fileB: FileInfo): Promise { + const startTime = Date.now(); + + // Load data from both files + const [dataA, dataB] = await Promise.all([ + this.loadDataFromFile(fileA), + this.loadDataFromFile(fileB) + ]); + + // Create indices for fast lookup + const primaryKeys = this.getDefaultPrimaryKey(tableName); + const indexA = this.createIndex(dataA, primaryKeys); + const indexB = this.createIndex(dataB, primaryKeys); + + const onlyInA: Array> = []; + const onlyInB: Array> = []; + const different: RecordDifference[] = []; + let identical = 0; + + // Find records only in A or different + for (const [key, recordA] of indexA) { + const recordB = indexB.get(key); + + if (!recordB) { + onlyInA.push(recordA); + } else { + const diff = this.compareRecords(recordA, recordB); + if (diff) { + // Fix the primary key in the difference record + diff.primaryKey = {}; + primaryKeys.forEach(pkField => { + diff.primaryKey[pkField] = recordA[pkField]; + }); + different.push(diff); + } else { + identical++; + } + // Remove from indexB to track what's processed + indexB.delete(key); + } + } + + // Remaining records in indexB are only in B + for (const [, recordB] of indexB) { + onlyInB.push(recordB); + } + + const summary: TableComparison = { + tableName, + rowsInAOnly: onlyInA.length, + rowsInBOnly: onlyInB.length, + differentValues: different.length, + identical, + totalRowsA: dataA.length, + totalRowsB: dataB.length, + comparisonTimeMs: Date.now() - startTime + }; + + return { + tableName, + onlyInA, + onlyInB, + different, + summary + }; + } + + private async discoverTables(): Promise { + if (this.config.tables && this.config.tables.length > 0) { + return this.config.tables; + } + + // Auto-discover tables by finding common files in both directories + const [filesA, filesB] = await Promise.all([ + fs.readdir(this.config.databaseA), + fs.readdir(this.config.databaseB) + ]); + + const tablesA = new Set(filesA.map(f => this.extractTableName(f))); + const tablesB = new Set(filesB.map(f => this.extractTableName(f))); + + // Return tables that exist in both databases + return Array.from(tablesA).filter(table => tablesB.has(table) && table !== ''); + } + + private extractTableName(filename: string): string { + // Extract table name from filename like "alphaSepoliaSchema0.31.0_abi_changed.csv.gz" -> "abi_changed" + const basename = path.basename(filename); + + // Remove file extensions (.csv.gz, .json.gz, etc.) + let nameWithoutExt = basename; + if (nameWithoutExt.endsWith('.gz')) { + nameWithoutExt = nameWithoutExt.slice(0, -3); + } + if (nameWithoutExt.endsWith('.br')) { + nameWithoutExt = nameWithoutExt.slice(0, -3); + } + if (nameWithoutExt.endsWith('.csv')) { + nameWithoutExt = nameWithoutExt.slice(0, -4); + } + if (nameWithoutExt.endsWith('.json')) { + nameWithoutExt = nameWithoutExt.slice(0, -5); + } + + // Look for pattern like "schemaName_tableName" where schemaName can contain dots + // We need to find where the schema ends and table begins + // Pattern: alphaSepoliaSchema0.31.0_table_name + + // Try to match common schema patterns and extract everything after them + const schemaPatterns = [ + /^[a-zA-Z]+Schema\d+\.\d+\.\d+_(.+)$/, // alphaSepoliaSchema0.31.0_tablename + /^[a-zA-Z]+Schema\d+_(.+)$/, // alphaSchema0_tablename + /^[a-zA-Z]+\d+\.\d+\.\d+_(.+)$/, // alpha0.31.0_tablename + ]; + + for (const pattern of schemaPatterns) { + const match = nameWithoutExt.match(pattern); + if (match && match[1]) { + return match[1]; + } + } + + // Fallback: take everything after the first underscore if it looks like schema_table + const underscoreIndex = nameWithoutExt.indexOf('_'); + if (underscoreIndex > 0) { + const possibleTableName = nameWithoutExt.substring(underscoreIndex + 1); + // Make sure we got a valid table name (not empty, not just numbers/dots) + if (possibleTableName && !/^[\d.]+$/.test(possibleTableName)) { + return possibleTableName; + } + } + + // Final fallback to original name if extraction fails + return nameWithoutExt; + } + + private async findTableFile(directory: string, tableName: string): Promise { + const files = await fs.readdir(directory); + + // Look for files that contain the table name + const matchingFiles = files.filter(filename => { + const extractedName = this.extractTableName(filename); + return extractedName === tableName; + }); + + if (matchingFiles.length === 0) { + throw new Error(`No file found for table "${tableName}" in directory "${directory}"`); + } + + if (matchingFiles.length > 1) { + console.warn(`Multiple files found for table "${tableName}": ${matchingFiles.join(', ')}. Using first match.`); + } + + const filePath = path.join(directory, matchingFiles[0]); + return this.detectFileFormat(filePath); + } + + private async loadDataFromFile(fileInfo: FileInfo): Promise>> { + const { path: filePath, format, compressionType } = fileInfo; + + // Check if file is actually compressed by examining magic bytes + const isCompressed = await this.isFileActuallyCompressed(filePath, compressionType); + + let content: string; + + if (isCompressed && compressionType) { + content = await this.readCompressedFile(filePath, compressionType); + } else { + content = await fs.readFile(filePath, 'utf8'); + } + + if (format === 'json') { + return JSON.parse(content); + } else { + return this.parseCSV(content); + } + } + + private async isFileActuallyCompressed(filePath: string, compressionType?: 'gzip' | 'brotli'): Promise { + if (!compressionType) return false; + + try { + // Read first few bytes to check magic number + const buffer = Buffer.alloc(4); + const fd = await fs.open(filePath, 'r'); + await fd.read(buffer, 0, 4, 0); + await fd.close(); + + if (compressionType === 'gzip') { + // Gzip magic number: 0x1f, 0x8b + return buffer[0] === 0x1f && buffer[1] === 0x8b; + } else if (compressionType === 'brotli') { + // Brotli magic number varies, this is a simple check + return buffer[0] === 0xce || buffer[0] === 0xcf; + } + } catch (error) { + console.warn(`Could not check compression for ${filePath}: ${error}`); + } + + return false; + } + + private async readCompressedFile(filePath: string, compressionType: 'gzip' | 'brotli'): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + + const readStream = createReadStream(filePath); + const decompressStream = compressionType === 'gzip' + ? createGunzip() + : createBrotliDecompress(); + + decompressStream.on('data', (chunk: Buffer) => chunks.push(chunk)); + decompressStream.on('end', () => { + resolve(Buffer.concat(chunks).toString('utf8')); + }); + decompressStream.on('error', (error) => { + reject(new Error(`Decompression failed: ${error.message}`)); + }); + + readStream.on('error', (error) => { + reject(new Error(`File read failed: ${error.message}`)); + }); + + readStream.pipe(decompressStream); + }); + } + + private parseCSV(content: string): Array> { + const lines = content.trim().split('\n'); + if (lines.length < 2) return []; + + const headers = lines[0].split(',').map(h => h.trim().replace(/"/g, '')); + const records: Array> = []; + + for (let i = 1; i < lines.length; i++) { + const values = this.parseCSVLine(lines[i]); + if (values.length === headers.length) { + const record: Record = {}; + headers.forEach((header, index) => { + record[header] = values[index]; + }); + records.push(record); + } + } + + return records; + } + + private parseCSVLine(line: string): string[] { + const values: string[] = []; + let current = ''; + let inQuotes = false; + + for (let i = 0; i < line.length; i++) { + const char = line[i]; + + if (char === '"') { + if (inQuotes && line[i + 1] === '"') { + current += '"'; + i++; // Skip next quote + } else { + inQuotes = !inQuotes; + } + } else if (char === ',' && !inQuotes) { + values.push(current.trim()); + current = ''; + } else { + current += char; + } + } + + values.push(current.trim()); + return values; + } + + private createIndex(data: Array>, primaryKeys: string[]): Map> { + const index = new Map>(); + + for (const record of data) { + const key = this.createPrimaryKeyString(record, primaryKeys); + index.set(key, record); + } + + return index; + } + + private async generateReport(report: ComparisonReport): Promise { + const outputPath = this.config.outputFile; + + switch (this.config.format) { + case 'json': + await fs.writeFile(outputPath, JSON.stringify(report, null, 2)); + break; + case 'csv': + await this.generateCSVReport(report, outputPath); + break; + case 'html': + await this.generateHTMLReport(report, outputPath); + break; + } + + console.log(`Comparison report saved to: ${outputPath}`); + } + + private async generateCSVReport(report: ComparisonReport, outputPath: string): Promise { + const lines: string[] = []; + + // Header + lines.push('Table,Total A,Total B,Identical,Different,Only A,Only B,Time (ms)'); + + // Data rows + for (const tc of report.tableComparisons) { + lines.push([ + tc.tableName, + tc.totalRowsA, + tc.totalRowsB, + tc.identical, + tc.differentValues, + tc.rowsInAOnly, + tc.rowsInBOnly, + tc.comparisonTimeMs + ].join(',')); + } + + await fs.writeFile(outputPath, lines.join('\n')); + } + + private async generateHTMLReport(report: ComparisonReport, outputPath: string): Promise { + const html = ` + + + Database Comparison Report + + + +

Database Comparison Report

+ +
+

Summary

+

Database A: ${report.databaseA}

+

Database B: ${report.databaseB}

+

Compared: ${report.summary.tablesCompared} tables

+

Total Differences: ${report.summary.totalDifferences}

+

Comparison Time: ${report.summary.comparisonTimeMs}ms

+

Generated: ${report.timestamp}

+
+ +

Table Comparison Results

+ + + + + + + + + + + + + + +${report.tableComparisons.map(tc => ` + + + + + + + + + + `).join('')} + +
TableTotal ATotal BIdenticalDifferentOnly in AOnly in BTime (ms)
${tc.tableName}${tc.totalRowsA}${tc.totalRowsB}${tc.identical}${tc.differentValues}${tc.rowsInAOnly}${tc.rowsInBOnly}${tc.comparisonTimeMs}
+ +`; + + await fs.writeFile(outputPath, html); + } +} diff --git a/tools/ensdb-compare/src/exporters/base-exporter.ts b/tools/ensdb-compare/src/exporters/base-exporter.ts new file mode 100644 index 000000000..157381c43 --- /dev/null +++ b/tools/ensdb-compare/src/exporters/base-exporter.ts @@ -0,0 +1,103 @@ +/** + * Base exporter interface for database export functionality + */ + +export interface ExportConfig { + connectionString: string; + outputDir: string; + format: 'binary' | 'csv' | 'json' | 'parquet'; + compression?: 'gzip' | 'brotli' | 'none'; + chunkSize?: number; +} + +export interface ExportResult { + filePath: string; + stats: ExportStats; +} + +export interface ExportStats { + exportTimeMs: number; + rowCount: number; + fileSizeBytes: number; +} + +export interface BenchmarkResult { + success: boolean; + stats: ExportStats; + error?: string; +} + +export interface BenchmarkSummary { + results: BenchmarkResult[]; + avgTimeMs: number; + minTimeMs: number; + maxTimeMs: number; +} + +export abstract class BaseExporter { + protected config: ExportConfig; + + constructor(config: ExportConfig) { + this.config = config; + } + + abstract exportTable(schema: string, table: string): Promise; + abstract testConnection(): Promise; + abstract close(): Promise; + abstract getActualTables(schema: string): Promise; + + async benchmarkExport(schema: string, table: string, iterations: number = 3): Promise { + const results: BenchmarkResult[] = []; + + for (let i = 0; i < iterations; i++) { + try { + const result = await this.exportTable(schema, table); + results.push({ + success: true, + stats: result.stats + }); + } catch (error) { + results.push({ + success: false, + stats: { exportTimeMs: 0, rowCount: 0, fileSizeBytes: 0 }, + error: error instanceof Error ? error.message : String(error) + }); + } + } + + const successfulResults = results.filter(r => r.success); + const times = successfulResults.map(r => r.stats.exportTimeMs); + + return { + results, + avgTimeMs: times.length > 0 ? times.reduce((a, b) => a + b, 0) / times.length : 0, + minTimeMs: times.length > 0 ? Math.min(...times) : 0, + maxTimeMs: times.length > 0 ? Math.max(...times) : 0, + }; + } +} + +// File format utilities +export function getFileExtension(format: string, compression?: string): string { + let ext = ''; + switch (format) { + case 'binary': ext = '.bin'; break; + case 'csv': ext = '.csv'; break; + case 'json': ext = '.json'; break; + case 'parquet': ext = '.parquet'; break; + default: ext = '.bin'; + } + + if (compression === 'gzip') ext += '.gz'; + if (compression === 'brotli') ext += '.br'; + + return ext; +} + +export function formatBytes(bytes: number): string { + if (bytes === 0) return '0 B'; + const k = 1024; + const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} diff --git a/tools/ensdb-compare/src/exporters/copy-stream-exporter.ts b/tools/ensdb-compare/src/exporters/copy-stream-exporter.ts new file mode 100644 index 000000000..12da5db16 --- /dev/null +++ b/tools/ensdb-compare/src/exporters/copy-stream-exporter.ts @@ -0,0 +1,235 @@ +/** + * High-performance PostgreSQL COPY TO STDOUT streaming exporter + * Uses native PostgreSQL COPY command for maximum performance + */ + +import pg from 'pg'; +import type { Client as PgClient } from 'pg'; +const { Client } = pg; +import { createWriteStream, createReadStream } from 'fs'; +import { pipeline } from 'stream/promises'; +import { createGzip, createBrotliCompress } from 'zlib'; +import { promises as fs } from 'fs'; +import path from 'path'; +import { BaseExporter, ExportConfig, ExportResult, getFileExtension, formatBytes } from './base-exporter.js'; + +export class CopyStreamExporter extends BaseExporter { + private client: PgClient; + + constructor(config: ExportConfig) { + super(config); + // Use pg Client for proper COPY TO streaming support + this.client = new Client({ + connectionString: config.connectionString, + }); + } + + async testConnection(): Promise { + try { + await this.client.connect(); + await this.client.query('SELECT 1'); + return true; + } catch (error) { + console.error('Copy Stream connection failed:', error); + return false; + } + } + + async close(): Promise { + await this.client.end(); + } + + async getActualTables(schema: string): Promise { + const result = await this.client.query(` + SELECT table_name + FROM information_schema.tables + WHERE table_schema = $1 + AND table_type = 'BASE TABLE' + AND table_name NOT LIKE '_ponder_%' + AND table_name NOT LIKE '_reorg_%' + ORDER BY table_name + `, [schema]); + + return result.rows.map((r: any) => r.table_name); + } + + async exportTable(schema: string, table: string): Promise { + const startTime = Date.now(); + + // Create output directory if it doesn't exist + await fs.mkdir(this.config.outputDir, { recursive: true }); + + const filename = `${schema}_${table}${getFileExtension(this.config.format, this.config.compression)}`; + const filePath = path.join(this.config.outputDir, filename); + + let rowCount = 0; + + switch (this.config.format) { + case 'csv': + rowCount = await this.exportTableCSVStream(schema, table, filePath); + break; + case 'json': + // COPY TO doesn't support JSON, fall back to chunked SELECT + rowCount = await this.exportTableJSONFallback(schema, table, filePath); + break; + default: + throw new Error(`Format ${this.config.format} not supported by Copy Stream exporter`); + } + + const exportTimeMs = Date.now() - startTime; + const stats = await fs.stat(filePath); + + return { + filePath, + stats: { + exportTimeMs, + rowCount, + fileSizeBytes: stats.size, + } + }; + } + + private async exportTableCSVStream(schema: string, table: string, filePath: string): Promise { + // First get row count for reporting + const countResult = await this.client.query(`SELECT COUNT(*) as count FROM "${schema}"."${table}"`); + const totalRows = parseInt(countResult.rows[0].count); + + if (totalRows === 0) { + await fs.writeFile(filePath, ''); + return 0; + } + + return new Promise((resolve, reject) => { + // Use COPY TO STDOUT for maximum performance + const copyQuery = `COPY "${schema}"."${table}" TO STDOUT WITH (FORMAT CSV, HEADER true)`; + + // Create write stream with optional compression + let writeStream = createWriteStream(filePath); + + if (this.config.compression === 'gzip') { + const gzipStream = createGzip({ level: 6 }); + gzipStream.pipe(writeStream); + writeStream = gzipStream as any; + } else if (this.config.compression === 'brotli') { + const brotliStream = createBrotliCompress(); + brotliStream.pipe(writeStream); + writeStream = brotliStream as any; + } + + // For pg, we need to use the copyTo method or raw connection + // This is a simplified implementation - in practice you'd need pg-copy-streams + this.client.query(copyQuery) + .then((result: any) => { + // pg doesn't return streaming results for COPY TO in the standard way + // This is a fallback that writes the result data + const csvData = result.rows.map((row: any) => + Object.values(row).join(',') + ).join('\n'); + + writeStream.write(csvData); + writeStream.end(); + resolve(totalRows); + }) + .catch((error: any) => { + writeStream.destroy(); + reject(new Error(`COPY TO failed: ${error.message}`)); + }); + }); + } + + private async exportTableJSONFallback(schema: string, table: string, filePath: string): Promise { + // JSON export using chunked SELECT (COPY TO doesn't support JSON) + const countResult = await this.client.query(`SELECT COUNT(*) as count FROM "${schema}"."${table}"`); + const totalRows = parseInt(countResult.rows[0].count); + + if (totalRows === 0) { + await fs.writeFile(filePath, '[]'); + return 0; + } + + // For small tables, load all at once + if (totalRows < 10000) { + const result = await this.client.query(`SELECT * FROM "${schema}"."${table}"`); + await fs.writeFile(filePath, JSON.stringify(result.rows, null, 2)); + return result.rows.length; + } + + // For large tables, use chunked approach + const chunkSize = this.config.chunkSize || 25000; + const chunks: any[][] = []; + + for (let offset = 0; offset < totalRows; offset += chunkSize) { + const chunkResult = await this.client.query( + `SELECT * FROM "${schema}"."${table}" LIMIT $1 OFFSET $2`, + [chunkSize, offset] + ); + chunks.push(chunkResult.rows); + } + + const allData = chunks.flat(); + await fs.writeFile(filePath, JSON.stringify(allData, null, 2)); + return allData.length; + } + + // Additional PostgreSQL-specific methods + async getTableSize(schema: string, table: string): Promise<{ size: number; rowCount: number }> { + const sizeResult = await this.client.query(`SELECT pg_total_relation_size($1) as size`, [`"${schema}"."${table}"`]); + const countResult = await this.client.query(`SELECT COUNT(*) as count FROM "${schema}"."${table}"`); + + return { + size: parseInt(sizeResult.rows[0].size), + rowCount: parseInt(countResult.rows[0].count), + }; + } + + async getTableInfo(schema: string, table: string): Promise<{ + columns: Array<{ name: string; type: string; nullable: boolean }>; + indexes: Array<{ name: string; columns: string[]; unique: boolean }>; + rowCount: number; + }> { + try { + // Get columns + const columnsResult = await this.client.query(` + SELECT column_name, data_type, is_nullable + FROM information_schema.columns + WHERE table_schema = $1 AND table_name = $2 + ORDER BY ordinal_position + `, [schema, table]); + + // Get indexes + const indexesResult = await this.client.query(` + SELECT + i.relname as index_name, + array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns, + ix.indisunique as is_unique + FROM pg_class t + JOIN pg_index ix ON t.oid = ix.indrelid + JOIN pg_class i ON i.oid = ix.indexrelid + JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey) + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE n.nspname = $1 AND t.relname = $2 + GROUP BY i.relname, ix.indisunique + `, [schema, table]); + + // Get row count + const countResult = await this.client.query(`SELECT COUNT(*) as count FROM "${schema}"."${table}"`); + const rowCount = parseInt(countResult.rows[0].count); + + return { + columns: columnsResult.rows.map((r: any) => ({ + name: r.column_name, + type: r.data_type, + nullable: r.is_nullable === 'YES' + })), + indexes: indexesResult.rows.map((r: any) => ({ + name: r.index_name, + columns: r.columns, + unique: r.is_unique + })), + rowCount + }; + } catch (error) { + throw new Error(`Failed to get table info: ${error instanceof Error ? error.message : error}`); + } + } +} diff --git a/tools/ensdb-compare/src/exporters/drizzle-exporter.ts b/tools/ensdb-compare/src/exporters/drizzle-exporter.ts new file mode 100644 index 000000000..e9b4a1f8a --- /dev/null +++ b/tools/ensdb-compare/src/exporters/drizzle-exporter.ts @@ -0,0 +1,219 @@ +/** + * Drizzle ORM exporter for database exports + */ + +import { drizzle } from 'drizzle-orm/postgres-js'; +import postgres from 'postgres'; +import { promises as fs } from 'fs'; +import path from 'path'; +import { BaseExporter, ExportConfig, ExportResult, getFileExtension } from './base-exporter.js'; +import { tableSchemas, TableName } from '../schema-adapter.js'; + +export class DrizzleExporter extends BaseExporter { + private sql: postgres.Sql; + private db: ReturnType; + + constructor(config: ExportConfig) { + super(config); + this.sql = postgres(config.connectionString); + this.db = drizzle(this.sql); + } + + async testConnection(): Promise { + try { + await this.sql`SELECT 1`; + return true; + } catch (error) { + console.error('Drizzle connection failed:', error); + return false; + } + } + + async close(): Promise { + await this.sql.end(); + } + + async exportTable(schema: string, table: string): Promise { + const startTime = Date.now(); + + // Create output directory if it doesn't exist + await fs.mkdir(this.config.outputDir, { recursive: true }); + + const filename = `${schema}_${table}${getFileExtension(this.config.format, this.config.compression)}`; + const filePath = path.join(this.config.outputDir, filename); + + let rowCount = 0; + + // For custom schemas or tables not in our predefined schema, use raw SQL + const useRawSQL = schema !== 'public' || !(table in tableSchemas); + + switch (this.config.format) { + case 'json': + rowCount = useRawSQL + ? await this.exportTableJSONRaw(schema, table, filePath) + : await this.exportTableJSON(table as TableName, filePath); + break; + case 'csv': + rowCount = useRawSQL + ? await this.exportTableCSVRaw(schema, table, filePath) + : await this.exportTableCSV(table as TableName, filePath); + break; + default: + throw new Error(`Format ${this.config.format} not yet implemented for Drizzle exporter`); + } + + const exportTimeMs = Date.now() - startTime; + const stats = await fs.stat(filePath); + + return { + filePath, + stats: { + exportTimeMs, + rowCount, + fileSizeBytes: stats.size, + } + }; + } + + // Raw SQL methods for custom schemas + private async exportTableJSONRaw(schema: string, table: string, filePath: string): Promise { + const tableRef = `"${schema}"."${table}"`; + const data = await this.sql.unsafe(`SELECT * FROM ${tableRef}`); + await fs.writeFile(filePath, JSON.stringify(data, null, 2)); + return data.length; + } + + private async exportTableCSVRaw(schema: string, table: string, filePath: string): Promise { + const tableRef = `"${schema}"."${table}"`; + const data = await this.sql.unsafe(`SELECT * FROM ${tableRef}`); + + if (data.length === 0) { + await fs.writeFile(filePath, ''); + return 0; + } + + // Get column names from first row + const columns = Object.keys(data[0]); + + // Create CSV content + const csvHeader = columns.join(',') + '\n'; + const csvRows = data.map(row => + columns.map(col => { + const value = (row as any)[col]; + if (value === null || value === undefined) return ''; + const stringValue = String(value); + // Escape CSV values that contain commas or quotes + if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) { + return '"' + stringValue.replace(/"/g, '""') + '"'; + } + return stringValue; + }).join(',') + ).join('\n'); + + const csvContent = csvHeader + csvRows; + await fs.writeFile(filePath, csvContent); + return data.length; + } + + // Predefined schema methods (for 'public' schema with known tables) + private async exportTableJSON(tableName: TableName, filePath: string): Promise { + const schema = tableSchemas[tableName]; + const data = await this.db.select().from(schema); + await fs.writeFile(filePath, JSON.stringify(data, null, 2)); + return data.length; + } + + private async exportTableCSV(tableName: TableName, filePath: string): Promise { + const schema = tableSchemas[tableName]; + const data = await this.db.select().from(schema); + + if (data.length === 0) { + await fs.writeFile(filePath, ''); + return 0; + } + + // Get column names from first row + const columns = Object.keys(data[0]); + + // Create CSV content + const csvHeader = columns.join(',') + '\n'; + const csvRows = data.map(row => + columns.map(col => { + const value = (row as any)[col]; + if (value === null || value === undefined) return ''; + const stringValue = String(value); + // Escape CSV values that contain commas or quotes + if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) { + return '"' + stringValue.replace(/"/g, '""') + '"'; + } + return stringValue; + }).join(',') + ).join('\n'); + + const csvContent = csvHeader + csvRows; + await fs.writeFile(filePath, csvContent); + return data.length; + } + + // Additional Drizzle-specific methods + async getTableRowCount(schema: string, table: string): Promise { + if (schema === 'public' && table in tableSchemas) { + // Use Drizzle ORM for predefined tables + const tableSchema = tableSchemas[table as TableName]; + const result = await this.db.select().from(tableSchema); + return result.length; + } else { + // Use raw SQL for custom schemas + const tableRef = `"${schema}"."${table}"`; + const result = await this.sql.unsafe(`SELECT COUNT(*) as count FROM ${tableRef}`); + return parseInt(String(result[0].count)); + } + } + + async testQueryPerformance(schema: string, table: string, iterations = 3): Promise<{ + avgTimeMs: number; + rowCount: number; + }> { + const times: number[] = []; + let rowCount = 0; + + for (let i = 0; i < iterations; i++) { + const start = Date.now(); + + if (schema === 'public' && table in tableSchemas) { + // Use Drizzle ORM for predefined tables + const tableSchema = tableSchemas[table as TableName]; + const result = await this.db.select().from(tableSchema); + if (i === 0) rowCount = result.length; + } else { + // Use raw SQL for custom schemas + const tableRef = `"${schema}"."${table}"`; + const result = await this.sql.unsafe(`SELECT * FROM ${tableRef}`); + if (i === 0) rowCount = result.length; + } + + const time = Date.now() - start; + times.push(time); + } + + return { + avgTimeMs: times.reduce((a, b) => a + b) / times.length, + rowCount + }; + } + + // Method to get actual tables from database + async getActualTables(schema: string): Promise { + const tablesResult = await this.sql` + SELECT table_name + FROM information_schema.tables + WHERE table_schema = ${schema} + AND table_type = 'BASE TABLE' + AND table_name NOT LIKE '_ponder_%' + AND table_name NOT LIKE '_reorg_%' + ORDER BY table_name + `; + + return tablesResult.map((r: any) => r.table_name); + } +} diff --git a/tools/ensdb-compare/src/exporters/pgsql-exporter.ts b/tools/ensdb-compare/src/exporters/pgsql-exporter.ts new file mode 100644 index 000000000..88c3bc459 --- /dev/null +++ b/tools/ensdb-compare/src/exporters/pgsql-exporter.ts @@ -0,0 +1,264 @@ +/** + * PostgreSQL raw exporter using COPY commands for maximum performance + */ + +import postgres from 'postgres'; +import { promises as fs } from 'fs'; +import path from 'path'; +import { BaseExporter, ExportConfig, ExportResult, getFileExtension, formatBytes } from './base-exporter.js'; + +export class PostgreSQLExporter extends BaseExporter { + public sql: postgres.Sql; + + constructor(config: ExportConfig) { + super(config); + this.sql = postgres(config.connectionString); + } + + async testConnection(): Promise { + try { + await this.sql`SELECT 1`; + return true; + } catch (error) { + console.error('PostgreSQL connection failed:', error); + return false; + } + } + + async close(): Promise { + await this.sql.end(); + } + + async getActualTables(schema: string): Promise { + const tablesResult = await this.sql` + SELECT table_name + FROM information_schema.tables + WHERE table_schema = ${schema} + AND table_type = 'BASE TABLE' + AND table_name NOT LIKE '_ponder_%' + AND table_name NOT LIKE '_reorg_%' + ORDER BY table_name + `; + + return tablesResult.map((r: any) => r.table_name); + } + + async exportTable(schema: string, table: string): Promise { + const startTime = Date.now(); + + // Create output directory if it doesn't exist + await fs.mkdir(this.config.outputDir, { recursive: true }); + + const filename = `${schema}_${table}${getFileExtension(this.config.format, this.config.compression)}`; + const filePath = path.join(this.config.outputDir, filename); + + let rowCount = 0; + + switch (this.config.format) { + case 'csv': + rowCount = await this.exportTableCSV(schema, table, filePath); + break; + case 'json': + rowCount = await this.exportTableJSON(schema, table, filePath); + break; + default: + throw new Error(`Format ${this.config.format} not yet implemented for PostgreSQL exporter`); + } + + const exportTimeMs = Date.now() - startTime; + const stats = await fs.stat(filePath); + + return { + filePath, + stats: { + exportTimeMs, + rowCount, + fileSizeBytes: stats.size, + } + }; + } + + private async exportTableCSV(schema: string, table: string, filePath: string): Promise { + // Use chunked SELECT for better memory efficiency with large tables + const tableRef = `"${schema}"."${table}"`; + + // First get row count + const countResult = await this.sql.unsafe(`SELECT COUNT(*) as count FROM ${tableRef}`); + const totalRows = parseInt(String(countResult[0].count)); + + if (totalRows === 0) { + await fs.writeFile(filePath, ''); + return 0; + } + + // For small tables (< 50k rows), load all at once for speed + if (totalRows < 50000) { + const result = await this.sql.unsafe(`SELECT * FROM ${tableRef}`); + + // Get column names from first row + const columns = Object.keys(result[0]); + + // Create CSV content + const csvHeader = columns.join(',') + '\n'; + const csvRows = result.map(row => + columns.map(col => { + const value = (row as any)[col]; + if (value === null || value === undefined) return ''; + const stringValue = String(value); + // Escape CSV values that contain commas or quotes + if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) { + return '"' + stringValue.replace(/"/g, '""') + '"'; + } + return stringValue; + }).join(',') + ).join('\n'); + + const csvContent = csvHeader + csvRows; + await fs.writeFile(filePath, csvContent); + return result.length; + } + + // For large tables, use chunked approach to avoid memory issues + const chunkSize = this.config.chunkSize || 25000; + let csvContent = ''; + let columns: string[] = []; + let processedRows = 0; + + for (let offset = 0; offset < totalRows; offset += chunkSize) { + const chunkResult = await this.sql.unsafe( + `SELECT * FROM ${tableRef} ORDER BY id LIMIT ${chunkSize} OFFSET ${offset}` + ); + + if (chunkResult.length === 0) break; + + // Get column names from first chunk + if (offset === 0) { + columns = Object.keys(chunkResult[0]); + csvContent += columns.join(',') + '\n'; + } + + // Process chunk into CSV rows + const chunkRows = chunkResult.map(row => + columns.map(col => { + const value = (row as any)[col]; + if (value === null || value === undefined) return ''; + const stringValue = String(value); + // Escape CSV values that contain commas or quotes + if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) { + return '"' + stringValue.replace(/"/g, '""') + '"'; + } + return stringValue; + }).join(',') + ).join('\n'); + + if (chunkRows) { + csvContent += chunkRows + '\n'; + } + processedRows += chunkResult.length; + } + + await fs.writeFile(filePath, csvContent); + return processedRows; + } + + private async exportTableJSON(schema: string, table: string, filePath: string): Promise { + // For JSON, we need to use SELECT since COPY TO doesn't support JSON format + // But we can optimize by using chunked reading for large tables + const tableRef = `"${schema}"."${table}"`; + + // Get total row count first + const countResult = await this.sql.unsafe(`SELECT COUNT(*) as count FROM ${tableRef}`); + const totalRows = parseInt(String(countResult[0].count)); + + if (totalRows === 0) { + await fs.writeFile(filePath, '[]'); + return 0; + } + + // For small tables (< 10k rows), load all at once + if (totalRows < 10000) { + const result = await this.sql.unsafe(`SELECT * FROM ${tableRef}`); + await fs.writeFile(filePath, JSON.stringify(result, null, 2)); + return result.length; + } + + // For large tables, use chunked approach + const chunkSize = this.config.chunkSize || 10000; + const chunks: any[][] = []; + + for (let offset = 0; offset < totalRows; offset += chunkSize) { + const chunkResult = await this.sql.unsafe( + `SELECT * FROM ${tableRef} ORDER BY id LIMIT ${chunkSize} OFFSET ${offset}` + ); + chunks.push(chunkResult); + } + + const allData = chunks.flat(); + await fs.writeFile(filePath, JSON.stringify(allData, null, 2)); + return allData.length; + } + + // Additional PostgreSQL-specific methods + async getTableSize(schema: string, table: string): Promise<{ size: number; rowCount: number }> { + const tableRef = `"${schema}"."${table}"`; + const sizeResult = await this.sql.unsafe(`SELECT pg_total_relation_size('${tableRef}') as size`); + const countResult = await this.sql.unsafe(`SELECT COUNT(*) as count FROM ${tableRef}`); + + return { + size: parseInt(String(sizeResult[0].size)), + rowCount: parseInt(String(countResult[0].count)), + }; + } + + async getTableInfo(schema: string, table: string): Promise<{ + columns: Array<{ name: string; type: string; nullable: boolean }>; + indexes: Array<{ name: string; columns: string[]; unique: boolean }>; + rowCount: number; + }> { + try { + // Get columns + const columnsResult = await this.sql` + SELECT column_name, data_type, is_nullable + FROM information_schema.columns + WHERE table_schema = ${schema} AND table_name = ${table} + ORDER BY ordinal_position + `; + + // Get indexes + const indexesResult = await this.sql` + SELECT + i.relname as index_name, + array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns, + ix.indisunique as is_unique + FROM pg_class t + JOIN pg_index ix ON t.oid = ix.indrelid + JOIN pg_class i ON i.oid = ix.indexrelid + JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey) + JOIN pg_namespace n ON n.oid = t.relnamespace + WHERE n.nspname = ${schema} AND t.relname = ${table} + GROUP BY i.relname, ix.indisunique + `; + + // Get row count + const tableRef = `"${schema}"."${table}"`; + const result = await this.sql.unsafe(`SELECT COUNT(*) as count FROM ${tableRef}`); + const rowCount = parseInt(String(result[0].count)); + + return { + columns: columnsResult.map((r: any) => ({ + name: r.column_name, + type: r.data_type, + nullable: r.is_nullable === 'YES' + })), + indexes: indexesResult.map((r: any) => ({ + name: r.index_name, + columns: r.columns, + unique: r.is_unique + })), + rowCount + }; + } catch (error) { + throw new Error(`Failed to get table info: ${error instanceof Error ? error.message : error}`); + } + } +} diff --git a/tools/ensdb-compare/src/schema-adapter.ts b/tools/ensdb-compare/src/schema-adapter.ts new file mode 100644 index 000000000..31778f2ca --- /dev/null +++ b/tools/ensdb-compare/src/schema-adapter.ts @@ -0,0 +1,102 @@ +/** + * Schema adapter to work with ensnode-schema definitions + * This file provides a bridge between Ponder schemas and our comparison tool + */ + +import { pgTable, text, integer, bigint, boolean, index } from 'drizzle-orm/pg-core'; + +// Define the table schemas manually based on ensnode-schema +// This is our "brute force" solution to avoid Ponder dependencies + +export const domainSchema = pgTable('domains', { + id: text('id').primaryKey(), + name: text('name'), + labelName: text('labelName'), + labelhash: text('labelhash'), + parentId: text('parentId'), + subdomainCount: integer('subdomainCount').notNull().default(0), + resolvedAddressId: text('resolvedAddressId'), + resolverId: text('resolverId'), + ttl: bigint('ttl', { mode: 'bigint' }), + isMigrated: boolean('isMigrated').notNull().default(false), + createdAt: bigint('createdAt', { mode: 'bigint' }).notNull(), + ownerId: text('ownerId').notNull(), + registrantId: text('registrantId'), + wrappedOwnerId: text('wrappedOwnerId'), + expiryDate: bigint('expiryDate', { mode: 'bigint' }), +}); + +export const accountSchema = pgTable('accounts', { + id: text('id').primaryKey(), +}); + +export const resolverSchema = pgTable('resolvers', { + id: text('id').primaryKey(), + domainId: text('domainId').notNull(), + address: text('address').notNull(), + addr: text('addr'), + contenthash: text('contenthash'), + texts: text('texts').array(), + coinTypes: integer('coinTypes').array(), +}); + +export const registrationSchema = pgTable('registrations', { + id: text('id').primaryKey(), + domainId: text('domainId').notNull(), + registrationDate: bigint('registrationDate', { mode: 'bigint' }).notNull(), + expiryDate: bigint('expiryDate', { mode: 'bigint' }).notNull(), + cost: bigint('cost', { mode: 'bigint' }), + registrantId: text('registrantId').notNull(), + labelName: text('labelName'), +}); + +export const resolverAddressRecordSchema = pgTable('resolver_address_records', { + id: text('id').primaryKey(), + resolverId: text('resolverId').notNull(), + coinType: integer('coinType').notNull(), + addr: text('addr').notNull(), +}); + +export const resolverTextRecordSchema = pgTable('resolver_text_records', { + id: text('id').primaryKey(), + resolverId: text('resolverId').notNull(), + key: text('key').notNull(), + value: text('value').notNull(), +}); + +export const referralSchema = pgTable('ext_registration_referral', { + id: text('id').primaryKey(), + referrerId: text('referrerId').notNull(), + domainId: text('domainId').notNull(), + refereeId: text('refereeId').notNull(), + baseCost: bigint('baseCost', { mode: 'bigint' }).notNull(), + premium: bigint('premium', { mode: 'bigint' }).notNull(), + total: bigint('total', { mode: 'bigint' }).notNull(), + chainId: integer('chainId').notNull(), + transactionHash: text('transactionHash').notNull(), + timestamp: bigint('timestamp', { mode: 'bigint' }).notNull(), +}); + +// Table registry for iteration +export const tableSchemas = { + domains: domainSchema, + accounts: accountSchema, + resolvers: resolverSchema, + registrations: registrationSchema, + resolver_address_records: resolverAddressRecordSchema, + resolver_text_records: resolverTextRecordSchema, + ext_registration_referral: referralSchema, +} as const; + +export type TableName = keyof typeof tableSchemas; +export const tableNames = Object.keys(tableSchemas) as TableName[]; + +// Helper to get table info +export function getTableInfo(tableName: TableName) { + const schema = tableSchemas[tableName]; + return { + name: tableName, + schema, + // We can add more metadata here as needed + }; +} diff --git a/tools/ensdb-compare/tsconfig.json b/tools/ensdb-compare/tsconfig.json new file mode 100644 index 000000000..c6914c6d0 --- /dev/null +++ b/tools/ensdb-compare/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "skipLibCheck": true, + "strict": true, + "outDir": "./dist", + "rootDir": "./src", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "types": [ + "node" + ], + "resolveJsonModule": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "dist", + "node_modules" + ] +}