From 20ec65e5a7a515c1a1ee0fec5067e8fc26ccb2bb Mon Sep 17 00:00:00 2001 From: djstrong Date: Wed, 30 Jul 2025 16:12:03 +0200 Subject: [PATCH 1/2] feat: add ENSDb Inspector CLI tool for database schema inspection - Introduced a new CLI tool for inspecting ENSNode database schemas and their metadata. - Added commands for listing schemas, retrieving schema details, and providing overall database information. - Implemented database connection handling and schema categorization logic. - Included comprehensive README documentation and initial test cases for core functionalities. --- apps/ensdb-inspector/README.md | 172 ++++++++++++ apps/ensdb-inspector/package.json | 43 +++ apps/ensdb-inspector/src/cli.ts | 98 +++++++ .../src/commands/db-info-command.ts | 196 +++++++++++++ .../src/commands/list-schemas-command.ts | 93 ++++++ .../src/commands/schema-info-command.ts | 264 ++++++++++++++++++ apps/ensdb-inspector/src/lib/database.test.ts | 201 +++++++++++++ apps/ensdb-inspector/src/lib/database.ts | 249 +++++++++++++++++ apps/ensdb-inspector/src/simple.test.ts | 81 ++++++ .../src/utils/date-utils.test.ts | 175 ++++++++++++ apps/ensdb-inspector/tsconfig.json | 10 + apps/ensdb-inspector/vitest.config.ts | 15 + 12 files changed, 1597 insertions(+) create mode 100644 apps/ensdb-inspector/README.md create mode 100644 apps/ensdb-inspector/package.json create mode 100644 apps/ensdb-inspector/src/cli.ts create mode 100644 apps/ensdb-inspector/src/commands/db-info-command.ts create mode 100644 apps/ensdb-inspector/src/commands/list-schemas-command.ts create mode 100644 apps/ensdb-inspector/src/commands/schema-info-command.ts create mode 100644 apps/ensdb-inspector/src/lib/database.test.ts create mode 100644 apps/ensdb-inspector/src/lib/database.ts create mode 100644 apps/ensdb-inspector/src/simple.test.ts create mode 100644 apps/ensdb-inspector/src/utils/date-utils.test.ts create mode 100644 apps/ensdb-inspector/tsconfig.json create mode 100644 apps/ensdb-inspector/vitest.config.ts diff --git a/apps/ensdb-inspector/README.md b/apps/ensdb-inspector/README.md new file mode 100644 index 000000000..54f93bea5 --- /dev/null +++ b/apps/ensdb-inspector/README.md @@ -0,0 +1,172 @@ +# ENSDb Inspector + +A CLI tool for inspecting ENSNode database schemas and their metadata. This tool helps you understand the structure and content of PostgreSQL databases used by ENSNode services. + +## Features + +- **Schema Discovery**: Automatically categorize database schemas into: + - `ponder_sync`: Ponder's internal sync and RPC cache schema + - `ensdb`: ENS indexer schemas following the ENSNode data model + - `unknown`: Other schemas not matching known patterns + +- **Schema Analysis**: Get detailed information about individual schemas including: + - Table counts and sizes + - Row counts and last modification times + - ENS-specific metrics (domain counts, latest registrations) + - Ponder-specific metrics (RPC cache entries) + +- **Database Overview**: View overall database statistics including: + - Total database size and connection info + - PostgreSQL version and uptime + - Connection statistics and activity metrics + - Schema breakdown by type + +## Installation + +This tool is part of the ENSNode monorepo. Install dependencies: + +```bash +pnpm install +``` + +## Usage + +All commands require a PostgreSQL connection string. You can use any of these formats: + +```bash +# Basic format +postgresql://username:password@host:port/database + +# With options +postgresql://username:password@host:port/database?sslmode=require +``` + +### List All Schemas + +```bash +pnpm run list-schemas --database-url "postgresql://user:pass@localhost:5432/ensnode" +``` + +This command will: +- Connect to the database +- Discover all user schemas (excluding system schemas) +- Categorize each schema by type +- Display a summary with table counts and sizes + +### Get Schema Details + +```bash +pnpm run schema-info "schema_name" --database-url "postgresql://user:pass@localhost:5432/ensnode" +``` + +This command provides detailed information about a specific schema including: +- Schema type and basic statistics +- Table-by-table breakdown with sizes and row counts +- ENS-specific information for ENSDb schemas +- Ponder-specific information for sync schemas + +### Get Database Overview + +```bash +pnpm run db-info --database-url "postgresql://user:pass@localhost:5432/ensnode" +``` + +This command shows: +- Database connection and server information +- Overall size and schema count +- PostgreSQL version and uptime +- Connection statistics +- Schema breakdown by type +- Database activity metrics + +## Examples + +### Connecting to a Local Development Database + +```bash +# List schemas in local development database +pnpm run list-schemas --database-url "postgresql://postgres:password@localhost:5432/ensnode" + +# Get details about a specific ENS indexer schema +pnpm run schema-info "mainnet_v1" --database-url "postgresql://postgres:password@localhost:5432/ensnode" + +# Get overall database info +pnpm run db-info --database-url "postgresql://postgres:password@localhost:5432/ensnode" +``` + +### Connecting to a Production Database + +```bash +# Using environment variable for connection string +export DATABASE_URL="postgresql://user:pass@prod-host:5432/ensnode?sslmode=require" + +pnpm run list-schemas --database-url "$DATABASE_URL" +``` + +## Schema Types + +### ponder_sync +Ponder's internal schema containing: +- RPC request/response cache +- Indexing state and metadata +- Sync progress tracking + +### ensdb +ENS indexer schemas following the ENSNode data model: +- `domain` table with ENS domain records +- `registration` table with registration events +- `resolver` table with resolver records +- Various ENS-specific event tables + +### unknown +Any other schemas that don't match the above patterns. + +## Development + +### Running in Development + +```bash +# Run any command directly with tsx +npx tsx src/cli.ts list-schemas --database-url "..." +npx tsx src/cli.ts schema-info "schema_name" --database-url "..." +npx tsx src/cli.ts db-info --database-url "..." +``` + +### Testing + +```bash +pnpm test +``` + +### Linting + +```bash +pnpm lint +``` + +## Technical Details + +- Built with TypeScript and Drizzle ORM +- Uses `postgres` client for database connections +- Follows the ENSNode monorepo patterns +- Designed for read-only database inspection + +## Troubleshooting + +### Connection Issues + +- Ensure your PostgreSQL server is running and accessible +- Check that the connection string format is correct +- Verify firewall and network settings allow the connection +- For SSL connections, ensure certificates are properly configured + +### Permission Issues + +- The tool requires at least read access to `information_schema` and `pg_stat_*` views +- Some database activity metrics require additional permissions + +### Schema Recognition + +- ENSDb schema detection is based on table name patterns +- If a schema isn't recognized as ENSDb, check that it contains tables like `domain`, `registration`, etc. +- Unknown schemas are still analyzed but without ENS-specific features diff --git a/apps/ensdb-inspector/package.json b/apps/ensdb-inspector/package.json new file mode 100644 index 000000000..131ec1484 --- /dev/null +++ b/apps/ensdb-inspector/package.json @@ -0,0 +1,43 @@ +{ + "name": "ensdb-inspector", + "version": "0.31.0", + "private": true, + "type": "module", + "description": "A CLI tool for inspecting ENSNode database schemas and their metadata", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/namehash/ensnode.git", + "directory": "apps/ensdb-inspector" + }, + "homepage": "https://github.com/namehash/ensnode/tree/main/apps/ensdb-inspector", + "scripts": { + "dev": "tsx src/cli.ts", + "list-schemas": "tsx src/cli.ts list-schemas", + "schema-info": "tsx src/cli.ts schema-info", + "db-info": "tsx src/cli.ts db-info", + "test": "vitest", + "lint": "biome check --write .", + "lint:ci": "biome ci", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@ensnode/ensnode-schema": "workspace:*", + "@ensnode/ponder-metadata": "workspace:*", + "drizzle-orm": "catalog:", + "postgres": "^3.4.5", + "pg-connection-string": "^2.9.0", + "yargs": "^17.7.2", + "pino": "^8.19.0", + "pino-pretty": "^10.3.1" + }, + "devDependencies": { + "@ensnode/shared-configs": "workspace:*", + "@types/node": "catalog:", + "@types/yargs": "^17.0.32", + "@vitest/coverage-v8": "catalog:", + "tsx": "^4.19.3", + "typescript": "catalog:", + "vitest": "catalog:" + } +} diff --git a/apps/ensdb-inspector/src/cli.ts b/apps/ensdb-inspector/src/cli.ts new file mode 100644 index 000000000..b533d50b0 --- /dev/null +++ b/apps/ensdb-inspector/src/cli.ts @@ -0,0 +1,98 @@ +import { resolve } from "path"; +import { fileURLToPath } from "url"; +import type { ArgumentsCamelCase, Argv } from "yargs"; +import { hideBin } from "yargs/helpers"; +import yargs from "yargs/yargs"; + +import { dbInfoCommand } from "@/commands/db-info-command"; +import { listSchemasCommand } from "@/commands/list-schemas-command"; +import { schemaInfoCommand } from "@/commands/schema-info-command"; + +export interface CLIOptions { + exitProcess?: boolean; +} + +interface ListSchemasArgs { + "database-url": string; +} + +interface SchemaInfoArgs { + "database-url": string; + schema: string; +} + +interface DbInfoArgs { + "database-url": string; +} + +export function createCLI(options: CLIOptions = {}) { + const { exitProcess = true } = options; + + return yargs() + .scriptName("ensdb-inspector") + .exitProcess(exitProcess) + .command( + "list-schemas", + "List all database schemas and categorize them", + (yargs: Argv) => { + return yargs.option("database-url", { + type: "string", + description: "PostgreSQL connection string", + demandOption: true, + }); + }, + async (argv: ArgumentsCamelCase) => { + await listSchemasCommand({ + databaseUrl: argv["database-url"], + }); + }, + ) + .command( + "schema-info ", + "Get detailed information about a specific schema", + (yargs: Argv) => { + return yargs + .positional("schema", { + type: "string", + description: "Schema name to inspect", + demandOption: true, + }) + .option("database-url", { + type: "string", + description: "PostgreSQL connection string", + demandOption: true, + }); + }, + async (argv: ArgumentsCamelCase) => { + await schemaInfoCommand({ + databaseUrl: argv["database-url"], + schemaName: argv.schema, + }); + }, + ) + .command( + "db-info", + "Get overall database information and statistics", + (yargs: Argv) => { + return yargs.option("database-url", { + type: "string", + description: "PostgreSQL connection string", + demandOption: true, + }); + }, + async (argv: ArgumentsCamelCase) => { + await dbInfoCommand({ + databaseUrl: argv["database-url"], + }); + }, + ) + .demandCommand(1, "You must specify a command") + .strict() + .help(); +} + +// Only execute if this is the main module +const isMainModule = resolve(process.argv[1]) === fileURLToPath(import.meta.url); +if (isMainModule) { + createCLI().parse(hideBin(process.argv)); +} diff --git a/apps/ensdb-inspector/src/commands/db-info-command.ts b/apps/ensdb-inspector/src/commands/db-info-command.ts new file mode 100644 index 000000000..f421cc19f --- /dev/null +++ b/apps/ensdb-inspector/src/commands/db-info-command.ts @@ -0,0 +1,196 @@ +import { + closeDatabaseConnection, + createDatabaseConnection, + getDatabaseStats, + getSchemaInfo, + listSchemas, +} from "@/lib/database"; +import { sql } from "drizzle-orm"; + +export interface DbInfoCommandOptions { + databaseUrl: string; +} + +export async function dbInfoCommand(options: DbInfoCommandOptions): Promise { + let connection; + + try { + console.log("šŸ” Connecting to database..."); + connection = await createDatabaseConnection(options.databaseUrl); + + console.log("šŸ“Š Gathering database information...\n"); + + // Get overall database stats + const dbStats = await getDatabaseStats(connection.db, options.databaseUrl); + + console.log("šŸ—„ļø Database Overview:"); + console.log(` • Host: ${dbStats.connectionInfo.host}:${dbStats.connectionInfo.port}`); + console.log(` • Database: ${dbStats.connectionInfo.database}`); + console.log(` • User: ${dbStats.connectionInfo.user}`); + console.log(` • Total Size: ${dbStats.totalSize}`); + console.log(` • Schema Count: ${dbStats.schemaCount}`); + + // Get PostgreSQL version + const versionResult = await connection.db.execute(sql`SELECT version()`); + const version = (versionResult[0]?.version as string) || "Unknown"; + const shortVersion = version.split(" ")[1] || version; + console.log(` • PostgreSQL Version: ${shortVersion}`); + + // Get uptime + const uptimeResult = await connection.db.execute(sql` + SELECT date_trunc('second', current_timestamp - pg_postmaster_start_time()) as uptime + `); + console.log(` • Uptime: ${uptimeResult[0]?.uptime || "Unknown"}`); + + // Get connection info + const connectionsResult = await connection.db.execute(sql` + SELECT + count(*) as total_connections, + count(*) FILTER (WHERE state = 'active') as active_connections, + count(*) FILTER (WHERE state = 'idle') as idle_connections + FROM pg_stat_activity + WHERE pid <> pg_backend_pid() + `); + + const connStats = connectionsResult[0]; + if (connStats) { + console.log( + ` • Connections: ${connStats.total_connections} total (${connStats.active_connections} active, ${connStats.idle_connections} idle)`, + ); + } + + // Schema breakdown + console.log("\nšŸ“‹ Schema Breakdown:"); + const schemas = await listSchemas(connection.db); + + if (schemas.length === 0) { + console.log(" No user schemas found."); + } else { + const schemaInfos = await Promise.all( + schemas.map((schema) => getSchemaInfo(connection.db, schema)), + ); + + // Group by type and show summary + const byType = { + ponder_sync: schemaInfos.filter((s) => s.schemaType === "ponder_sync"), + ensdb: schemaInfos.filter((s) => s.schemaType === "ensdb"), + unknown: schemaInfos.filter((s) => s.schemaType === "unknown"), + }; + + console.log(` šŸ”„ Ponder Sync: ${byType.ponder_sync.length} schema(s)`); + console.log(` šŸ—ļø ENSDb: ${byType.ensdb.length} schema(s)`); + console.log(` ā“ Unknown: ${byType.unknown.length} schema(s)`); + + // Helper function to format last modified time + const formatLastModified = (info: any) => { + if (info.lastModified) { + return ` - ${info.lastModified.toISOString().split("T")[0]}`; + } else { + // Check if it's an empty schema by looking at table count and size + const isEmpty = + info.tableCount > 0 && (!info.sizeBytes || info.sizeBytes < 1024 * 1024 * 10); // Less than 10MB suggests empty + return isEmpty ? " - empty" : " - unknown"; + } + }; + + // Show largest schemas + const sortedBySize = schemaInfos + .filter((s) => s.sizeBytes && s.sizeBytes > 0) + .sort((a, b) => (b.sizeBytes || 0) - (a.sizeBytes || 0)) + .slice(0, 5); + + if (sortedBySize.length > 0) { + console.log("\nšŸ“Š Largest Schemas:"); + sortedBySize.forEach((schema) => { + const sizeMB = schema.sizeBytes ? (schema.sizeBytes / 1024 / 1024).toFixed(2) : "0"; + const typeEmoji = { + ponder_sync: "šŸ”„", + ensdb: "šŸ—ļø", + unknown: "ā“", + }[schema.schemaType]; + const lastMod = formatLastModified(schema); + console.log( + ` ${typeEmoji} ${schema.schemaName}: ${sizeMB} MB (${schema.tableCount} tables${lastMod})`, + ); + }); + } + + // Show schemas by type with last modified times + if (byType.ensdb.length > 0) { + console.log("\nšŸ—ļø ENSDb Schemas (with timestamps):"); + byType.ensdb + .sort((a, b) => (b.sizeBytes || 0) - (a.sizeBytes || 0)) + .slice(0, 10) // Show top 10 + .forEach((schema) => { + const sizeMB = schema.sizeBytes ? (schema.sizeBytes / 1024 / 1024).toFixed(1) : "0"; + const lastMod = formatLastModified(schema); + console.log(` • ${schema.schemaName}: ${sizeMB} MB${lastMod}`); + }); + + if (byType.ensdb.length > 10) { + console.log(` ... and ${byType.ensdb.length - 10} more ENSDb schemas`); + } + } + } + + // Database activity (if accessible) + try { + const activityResult = await connection.db.execute(sql` + SELECT + sum(xact_commit) as total_commits, + sum(xact_rollback) as total_rollbacks, + sum(blks_read) as blocks_read, + sum(blks_hit) as blocks_hit, + sum(tup_returned) as tuples_returned, + sum(tup_fetched) as tuples_fetched, + sum(tup_inserted) as tuples_inserted, + sum(tup_updated) as tuples_updated, + sum(tup_deleted) as tuples_deleted + FROM pg_stat_database + WHERE datname = current_database() + `); + + const activity = activityResult[0]; + if (activity && activity.total_commits) { + console.log("\nšŸ“ˆ Database Activity (since last stats reset):"); + console.log( + ` • Transactions: ${Number(activity.total_commits).toLocaleString()} commits, ${Number(activity.total_rollbacks || 0).toLocaleString()} rollbacks`, + ); + + const hitRatio = + activity.blocks_hit && activity.blocks_read + ? ( + (Number(activity.blocks_hit) / + (Number(activity.blocks_hit) + Number(activity.blocks_read))) * + 100 + ).toFixed(2) + : "N/A"; + console.log(` • Cache Hit Ratio: ${hitRatio}%`); + + const totalTuples = + Number(activity.tuples_inserted || 0) + + Number(activity.tuples_updated || 0) + + Number(activity.tuples_deleted || 0); + if (totalTuples > 0) { + console.log( + ` • Data Changes: ${Number(activity.tuples_inserted || 0).toLocaleString()} inserts, ${Number(activity.tuples_updated || 0).toLocaleString()} updates, ${Number(activity.tuples_deleted || 0).toLocaleString()} deletes`, + ); + } + } + } catch (error) { + // Stats might not be accessible + console.log("\nšŸ“ˆ Database Activity: Not accessible"); + } + + console.log( + "\nšŸ’” Use 'list-schemas' to see all schemas or 'schema-info ' for detailed schema information.", + ); + } catch (error) { + console.error("āŒ Error:", error instanceof Error ? error.message : "Unknown error"); + process.exit(1); + } finally { + if (connection) { + await closeDatabaseConnection(connection); + } + } +} diff --git a/apps/ensdb-inspector/src/commands/list-schemas-command.ts b/apps/ensdb-inspector/src/commands/list-schemas-command.ts new file mode 100644 index 000000000..60b132190 --- /dev/null +++ b/apps/ensdb-inspector/src/commands/list-schemas-command.ts @@ -0,0 +1,93 @@ +import { + closeDatabaseConnection, + createDatabaseConnection, + getSchemaInfo, + listSchemas, +} from "@/lib/database"; + +export interface ListSchemasCommandOptions { + databaseUrl: string; +} + +export async function listSchemasCommand(options: ListSchemasCommandOptions): Promise { + let connection; + + try { + console.log("šŸ” Connecting to database..."); + connection = await createDatabaseConnection(options.databaseUrl); + + console.log("šŸ“‹ Discovering schemas..."); + const schemas = await listSchemas(connection.db); + + if (schemas.length === 0) { + console.log("No user schemas found in the database."); + return; + } + + console.log(`\nšŸ“Š Found ${schemas.length} schema(s):\n`); + + // Get detailed info for each schema + const schemaInfos = await Promise.all( + schemas.map((schema) => getSchemaInfo(connection.db, schema)), + ); + + // Group by type + const byType = { + ponder_sync: schemaInfos.filter((s) => s.schemaType === "ponder_sync"), + ensdb: schemaInfos.filter((s) => s.schemaType === "ensdb"), + unknown: schemaInfos.filter((s) => s.schemaType === "unknown"), + }; + + // Helper function to format last modified time + const formatLastModified = (info: any) => { + if (info.lastModified) { + return ` - ${info.lastModified.toISOString().split("T")[0]}`; + } else { + // Check if it's an empty schema by looking at table count and size + const isEmpty = + info.tableCount > 0 && (!info.sizeBytes || info.sizeBytes < 1024 * 1024 * 10); // Less than 10MB suggests empty + return isEmpty ? " - empty" : " - unknown"; + } + }; + + // Display results + if (byType.ponder_sync.length > 0) { + console.log("šŸ”„ Ponder Sync Schemas:"); + byType.ponder_sync.forEach((info) => { + const lastMod = formatLastModified(info); + console.log(` • ${info.schemaName} (${info.tableCount} tables${lastMod})`); + }); + console.log(); + } + + if (byType.ensdb.length > 0) { + console.log("šŸ—ļø ENSDb Schemas:"); + byType.ensdb.forEach((info) => { + const sizeStr = info.sizeBytes ? ` - ${(info.sizeBytes / 1024 / 1024).toFixed(1)}MB` : ""; + const lastMod = formatLastModified(info); + console.log(` • ${info.schemaName} (${info.tableCount} tables${sizeStr}${lastMod})`); + }); + console.log(); + } + + if (byType.unknown.length > 0) { + console.log("ā“ Unknown Schemas:"); + byType.unknown.forEach((info) => { + const lastMod = formatLastModified(info); + console.log(` • ${info.schemaName} (${info.tableCount} tables${lastMod})`); + }); + console.log(); + } + + console.log( + "šŸ’” Use 'schema-info ' to get detailed information about a specific schema.", + ); + } catch (error) { + console.error("āŒ Error:", error instanceof Error ? error.message : "Unknown error"); + process.exit(1); + } finally { + if (connection) { + await closeDatabaseConnection(connection); + } + } +} diff --git a/apps/ensdb-inspector/src/commands/schema-info-command.ts b/apps/ensdb-inspector/src/commands/schema-info-command.ts new file mode 100644 index 000000000..aa05a0b99 --- /dev/null +++ b/apps/ensdb-inspector/src/commands/schema-info-command.ts @@ -0,0 +1,264 @@ +import { closeDatabaseConnection, createDatabaseConnection, getSchemaInfo } from "@/lib/database"; +import { sql } from "drizzle-orm"; + +export interface SchemaInfoCommandOptions { + databaseUrl: string; + schemaName: string; +} + +export async function schemaInfoCommand(options: SchemaInfoCommandOptions): Promise { + let connection; + + try { + console.log("šŸ” Connecting to database..."); + connection = await createDatabaseConnection(options.databaseUrl); + + console.log(`šŸ“Š Analyzing schema: ${options.schemaName}\n`); + + // Get basic schema info + const schemaInfo = await getSchemaInfo(connection.db, options.schemaName); + + // Display schema type with appropriate emoji + const typeEmoji = { + ponder_sync: "šŸ”„", + ensdb: "šŸ—ļø", + unknown: "ā“", + }[schemaInfo.schemaType]; + + console.log(`${typeEmoji} Schema Type: ${schemaInfo.schemaType}`); + console.log(`šŸ“‹ Table Count: ${schemaInfo.tableCount}`); + + if (schemaInfo.sizeBytes) { + const sizeMB = (schemaInfo.sizeBytes / 1024 / 1024).toFixed(2); + console.log(`šŸ’¾ Total Size: ${sizeMB} MB`); + } + + // Get table details + console.log(`\nšŸ“‘ Tables in ${options.schemaName}:`); + + const tables = await connection.db.execute(sql` + SELECT + t.table_name, + pg_total_relation_size(quote_ident(t.table_schema)||'.'||quote_ident(t.table_name)) as size_bytes, + s.n_tup_ins as inserts, + s.n_tup_upd as updates, + s.n_tup_del as deletes, + s.n_live_tup as live_tuples, + s.last_vacuum, + s.last_analyze + FROM information_schema.tables t + LEFT JOIN pg_stat_user_tables s ON ( + s.schemaname = t.table_schema AND s.relname = t.table_name + ) + WHERE t.table_schema = ${options.schemaName} + AND t.table_type = 'BASE TABLE' + ORDER BY size_bytes DESC NULLS LAST, t.table_name + `); + + // Display last modified time with proper handling for empty schemas + if (schemaInfo.lastModified) { + console.log(`ā° Last Modified: ${schemaInfo.lastModified.toISOString()}`); + } else { + // Check if schema has any data - if not, it's likely inactive + const hasData = tables.some((table) => Number(table.live_tuples || 0) > 0); + if (!hasData && tables.length > 0) { + console.log(`ā° Last Modified: No recorded activity (empty schema)`); + } else { + console.log(`ā° Last Modified: Unknown`); + } + } + + if (tables.length === 0) { + console.log(" No tables found in this schema."); + } else { + tables.forEach((table) => { + const sizeMB = table.size_bytes + ? (Number(table.size_bytes) / 1024 / 1024).toFixed(2) + : "N/A"; + const tuples = table.live_tuples ? Number(table.live_tuples).toLocaleString() : "N/A"; + console.log(` • ${table.table_name}`); + console.log(` Size: ${sizeMB} MB, Rows: ${tuples}`); + + if (table.last_analyze) { + console.log(` Last analyzed: ${new Date(table.last_analyze).toISOString()}`); + } + }); + } + + // Additional info for ENSDb schemas + if (schemaInfo.schemaType === "ensdb") { + console.log(`\nšŸŽÆ ENS-specific Information:`); + + // Try to get domain count if domains table exists + try { + const domainCount = await connection.db.execute(sql` + SELECT COUNT(*) as count + FROM ${sql.identifier(options.schemaName)}.${sql.identifier("domains")} + `); + console.log(` • Total Domains: ${Number(domainCount[0]?.count || 0).toLocaleString()}`); + } catch (error) { + console.log( + ` • Total Domains: Unable to determine (${error instanceof Error ? error.message : "Table might not exist"})`, + ); + } + + // Try to get registration count + try { + const regCount = await connection.db.execute(sql` + SELECT COUNT(*) as count + FROM ${sql.identifier(options.schemaName)}.${sql.identifier("registrations")} + `); + console.log(` • Total Registrations: ${Number(regCount[0]?.count || 0).toLocaleString()}`); + } catch (error) { + console.log( + ` • Total Registrations: Unable to determine (${error instanceof Error ? error.message : "Table might not exist"})`, + ); + } + + // Get the latest domain creation if possible + try { + const latest = await connection.db.execute(sql` + SELECT created_at, name + FROM ${sql.identifier(options.schemaName)}.${sql.identifier("domains")} + WHERE created_at IS NOT NULL + ORDER BY created_at DESC + LIMIT 1 + `); + + if (latest[0]) { + try { + const dateValue = latest[0].created_at; + let parsedDate: Date; + + // Handle Unix timestamp (number) vs date string + if (typeof dateValue === "number" || !isNaN(Number(dateValue))) { + // Unix timestamp - convert to milliseconds + parsedDate = new Date(Number(dateValue) * 1000); + } else { + // Regular date string + parsedDate = new Date(dateValue); + } + + if (!isNaN(parsedDate.getTime())) { + console.log( + ` • Latest Domain Created: ${latest[0].name} (${parsedDate.toISOString()})`, + ); + } else { + console.log( + ` • Latest Domain Created: ${latest[0].name} (date: ${dateValue} - invalid format)`, + ); + } + } catch (error) { + console.log( + ` • Latest Domain Created: ${latest[0].name} (date parsing error: ${latest[0].created_at})`, + ); + } + } else { + console.log(` • Latest Domain Created: No records found`); + } + } catch (error) { + console.log( + ` • Latest Domain Created: Unable to determine (${error instanceof Error ? error.message : "Column might not exist"})`, + ); + } + + // Get the latest registration date if possible + try { + // First check what columns exist in the registrations table + const regColumns = await connection.db.execute(sql` + SELECT column_name + FROM information_schema.columns + WHERE table_schema = ${options.schemaName} + AND table_name = 'registrations' + `); + + const columnNames = regColumns.map((row) => row.column_name as string); + + // Try common registration date column names + const dateColumns = ["registration_date", "created_at", "timestamp", "registered_at"]; + const dateColumn = dateColumns.find((col) => columnNames.includes(col)); + const nameColumn = columnNames.includes("name") + ? "name" + : columnNames.includes("label_name") + ? "label_name" + : columnNames.includes("domain") + ? "domain" + : columnNames.includes("label") + ? "label" + : null; + + if (dateColumn && nameColumn) { + const latestReg = await connection.db.execute(sql` + SELECT ${sql.identifier(dateColumn)} as reg_date, ${sql.identifier(nameColumn)} as name + FROM ${sql.identifier(options.schemaName)}.${sql.identifier("registrations")} + WHERE ${sql.identifier(dateColumn)} IS NOT NULL + ORDER BY ${sql.identifier(dateColumn)} DESC + LIMIT 1 + `); + + if (latestReg[0]) { + try { + const dateValue = latestReg[0].reg_date; + let parsedDate: Date; + + // Handle Unix timestamp (number) vs date string + if (typeof dateValue === "number" || !isNaN(Number(dateValue))) { + // Unix timestamp - convert to milliseconds + parsedDate = new Date(Number(dateValue) * 1000); + } else { + // Regular date string + parsedDate = new Date(dateValue); + } + + if (!isNaN(parsedDate.getTime())) { + console.log( + ` • Latest Registration: ${latestReg[0].name} (${parsedDate.toISOString()})`, + ); + } else { + console.log( + ` • Latest Registration: ${latestReg[0].name} (date: ${dateValue} - invalid format)`, + ); + } + } catch (error) { + console.log( + ` • Latest Registration: ${latestReg[0].name} (date parsing error: ${latestReg[0].reg_date})`, + ); + } + } else { + console.log(` • Latest Registration: No records found`); + } + } else { + console.log(` • Registration date info: Available columns: ${columnNames.join(", ")}`); + } + } catch (error) { + console.log( + ` • Registration date: Unable to determine (${error instanceof Error ? error.message : "Unknown error"})`, + ); + } + } + + // Additional info for ponder_sync schema + if (schemaInfo.schemaType === "ponder_sync") { + console.log(`\nāš™ļø Ponder Sync Information:`); + + try { + const rpcCacheCount = await connection.db.execute(sql` + SELECT COUNT(*) as count + FROM ${sql.identifier(options.schemaName)}.${sql.identifier("rpc_request_result")} + `); + console.log( + ` • RPC Cache Entries: ${Number(rpcCacheCount[0]?.count || 0).toLocaleString()}`, + ); + } catch { + // Table might not exist + } + } + } catch (error) { + console.error("āŒ Error:", error instanceof Error ? error.message : "Unknown error"); + process.exit(1); + } finally { + if (connection) { + await closeDatabaseConnection(connection); + } + } +} diff --git a/apps/ensdb-inspector/src/lib/database.test.ts b/apps/ensdb-inspector/src/lib/database.test.ts new file mode 100644 index 000000000..8cf737288 --- /dev/null +++ b/apps/ensdb-inspector/src/lib/database.test.ts @@ -0,0 +1,201 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { categorizeSchema, getDatabaseStats, getSchemaInfo, listSchemas } from "./database"; + +// Mock the drizzle and postgres dependencies +const mockExecute = vi.fn(); +const mockDb = { + execute: mockExecute, +}; + +describe("Database Utilities", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe("listSchemas", () => { + it("should return list of schema names excluding system schemas", async () => { + mockExecute.mockResolvedValueOnce([ + { schema_name: "ens4" }, + { schema_name: "ens5" }, + { schema_name: "ponder_sync" }, + { schema_name: "custom_schema" }, + ]); + + const schemas = await listSchemas(mockDb as any); + + expect(schemas).toEqual(["ens4", "ens5", "ponder_sync", "custom_schema"]); + expect(mockExecute).toHaveBeenCalled(); + }); + + it("should handle empty schema list", async () => { + mockExecute.mockResolvedValueOnce([]); + + const schemas = await listSchemas(mockDb as any); + + expect(schemas).toEqual([]); + }); + + it("should filter out all PostgreSQL system schemas", () => { + // Test the filtering logic that would be applied by the SQL query + const allSchemas = [ + "ens4", + "ens5", + "ponder_sync", // User schemas + "information_schema", // Information schema + "pg_catalog", // System catalog + "pg_toast", // Toast schema + "pg_temp_12", // Temporary schema + "pg_toast_temp_95", // Temporary toast schema + "pg_stat_tmp", // Statistics temp schema + "custom_app", // Another user schema + ]; + + // Apply the same filtering logic as the SQL query + const userSchemas = allSchemas.filter( + (schema) => !schema.startsWith("pg_") && schema !== "information_schema", + ); + + expect(userSchemas).toEqual(["ens4", "ens5", "ponder_sync", "custom_app"]); + expect(userSchemas.length).toBe(4); + + // Verify specific system schemas are excluded + expect(userSchemas).not.toContain("pg_temp_12"); + expect(userSchemas).not.toContain("pg_toast_temp_95"); + expect(userSchemas).not.toContain("pg_catalog"); + expect(userSchemas).not.toContain("information_schema"); + }); + }); + + describe("categorizeSchema", () => { + it("should categorize ponder_sync schema correctly", async () => { + const category = await categorizeSchema(mockDb as any, "ponder_sync"); + expect(category).toBe("ponder_sync"); + }); + + it("should categorize ENSDb schema based on table names", async () => { + mockExecute.mockResolvedValueOnce([ + { table_name: "domains" }, + { table_name: "registrations" }, + { table_name: "resolvers" }, + ]); + + const category = await categorizeSchema(mockDb as any, "ens4"); + + expect(category).toBe("ensdb"); + expect(mockExecute).toHaveBeenCalled(); + }); + + it("should categorize unknown schema when no ENS tables found", async () => { + mockExecute.mockResolvedValueOnce([{ table_name: "users" }, { table_name: "products" }]); + + const category = await categorizeSchema(mockDb as any, "custom_app"); + + expect(category).toBe("unknown"); + }); + + it("should handle schema with partial ENS table matches", async () => { + mockExecute.mockResolvedValueOnce([ + { table_name: "domain_events" }, + { table_name: "user_accounts" }, + ]); + + const category = await categorizeSchema(mockDb as any, "mixed_schema"); + + expect(category).toBe("ensdb"); + }); + }); + + describe("getSchemaInfo", () => { + it("should return complete schema information", async () => { + // Mock table count query + mockExecute.mockResolvedValueOnce([{ table_count: 45 }]); + + // Mock size calculation query + mockExecute.mockResolvedValueOnce([{ size_bytes: 1000000 }, { size_bytes: 2000000 }]); + + // Mock last modification query + mockExecute.mockResolvedValueOnce([{ last_activity: "2024-01-15T10:30:00Z" }]); + + // Mock categorizeSchema dependency + mockExecute.mockResolvedValueOnce([ + { table_name: "domains" }, + { table_name: "registrations" }, + ]); + + const schemaInfo = await getSchemaInfo(mockDb as any, "ens4"); + + expect(schemaInfo.schemaName).toBe("ens4"); + expect(schemaInfo.schemaType).toBe("ensdb"); + expect(schemaInfo.tableCount).toBe(45); + expect(schemaInfo.sizeBytes).toBe(3000000); + expect(schemaInfo.lastModified).toEqual(new Date("2024-01-15T10:30:00Z")); + }); + + it("should handle schema with no activity timestamps", async () => { + mockExecute + .mockResolvedValueOnce([{ table_count: 10 }]) + .mockResolvedValueOnce([{ size_bytes: 500000 }]) + .mockResolvedValueOnce([{ last_activity: null }]) + .mockResolvedValueOnce([{ stats_reset: null }]) + .mockResolvedValueOnce([{ nspname: "test_schema" }]) + .mockResolvedValueOnce([]); // categorizeSchema tables query + + const schemaInfo = await getSchemaInfo(mockDb as any, "test_schema"); + + expect(schemaInfo.lastModified).toBeUndefined(); + }); + + it("should handle schema with fallback stats_reset timestamp", async () => { + mockExecute + .mockResolvedValueOnce([{ table_count: 5 }]) + .mockResolvedValueOnce([]) + .mockResolvedValueOnce([{ last_activity: null }]) + .mockResolvedValueOnce([{ stats_reset: "2024-01-10T08:00:00Z" }]) + .mockResolvedValueOnce([]); // categorizeSchema tables query + + const schemaInfo = await getSchemaInfo(mockDb as any, "fallback_schema"); + + expect(schemaInfo.lastModified).toEqual(new Date("2024-01-10T08:00:00Z")); + }); + }); + + describe("getDatabaseStats", () => { + it("should return database statistics", async () => { + // Mock total size query + mockExecute.mockResolvedValueOnce([{ total_size: "132 GB" }]); + + // Mock schema count query + mockExecute.mockResolvedValueOnce([{ schema_count: 100 }]); + + const connectionString = "postgresql://user:pass@localhost:5432/testdb"; + const stats = await getDatabaseStats(mockDb as any, connectionString); + + expect(stats).toEqual({ + totalSize: "132 GB", + schemaCount: 100, + connectionInfo: { + host: "localhost", + port: 5432, + database: "testdb", + user: "user", + }, + }); + }); + + it("should handle malformed connection string gracefully", async () => { + mockExecute + .mockResolvedValueOnce([{ total_size: "10 GB" }]) + .mockResolvedValueOnce([{ schema_count: 5 }]); + + const stats = await getDatabaseStats(mockDb as any, "invalid-connection-string"); + + // Should not crash and return basic structure + expect(stats.totalSize).toBe("10 GB"); + expect(stats.schemaCount).toBe(5); + expect(stats.connectionInfo).toHaveProperty("host"); + expect(stats.connectionInfo).toHaveProperty("database"); + expect(stats.connectionInfo).toHaveProperty("port"); + expect(stats.connectionInfo).toHaveProperty("user"); + }); + }); +}); diff --git a/apps/ensdb-inspector/src/lib/database.ts b/apps/ensdb-inspector/src/lib/database.ts new file mode 100644 index 000000000..01d065649 --- /dev/null +++ b/apps/ensdb-inspector/src/lib/database.ts @@ -0,0 +1,249 @@ +import { sql } from "drizzle-orm"; +import { drizzle } from "drizzle-orm/postgres-js"; +import { parse as parseConnectionString } from "pg-connection-string"; +import postgres from "postgres"; + +export interface DatabaseConnection { + client: postgres.Sql; + db: ReturnType; +} + +export interface SchemaInfo { + schemaName: string; + schemaType: "ponder_sync" | "ensdb" | "unknown"; + tableCount: number; + sizeBytes?: number; + lastModified?: Date; +} + +export interface DatabaseStats { + totalSize: string; + schemaCount: number; + connectionInfo: { + host: string; + port: number; + database: string; + user: string; + }; +} + +/** + * Create a database connection from a connection string + */ +export async function createDatabaseConnection( + connectionString: string, +): Promise { + try { + const config = parseConnectionString(connectionString); + + if (!config.host || !config.port || !config.database) { + throw new Error("Invalid connection string: missing required parameters"); + } + + const client = postgres(connectionString, { + max: 1, // Single connection for CLI usage + idle_timeout: 20, + connect_timeout: 10, + }); + + const db = drizzle(client); + + // Test the connection + await db.execute(sql`SELECT 1`); + + return { client, db }; + } catch (error) { + throw new Error( + `Failed to connect to database: ${error instanceof Error ? error.message : "Unknown error"}`, + ); + } +} + +/** + * Close a database connection + */ +export async function closeDatabaseConnection(connection: DatabaseConnection): Promise { + await connection.client.end(); +} + +/** + * Get list of all schemas in the database + */ +export async function listSchemas(db: ReturnType): Promise { + const result = await db.execute(sql` + SELECT schema_name + FROM information_schema.schemata + WHERE schema_name NOT LIKE 'pg_%' + AND schema_name != 'information_schema' + ORDER BY schema_name + `); + + return result.map((row) => row.schema_name as string); +} + +/** + * Categorize a schema based on its tables and structure + */ +export async function categorizeSchema( + db: ReturnType, + schemaName: string, +): Promise { + // Check for ponder_sync schema + if (schemaName === "ponder_sync") { + return "ponder_sync"; + } + + // Get tables in the schema + const tables = await db.execute(sql` + SELECT table_name + FROM information_schema.tables + WHERE table_schema = ${schemaName} + AND table_type = 'BASE TABLE' + `); + + const tableNames = tables.map((row) => row.table_name as string); + + // Check for ENSDb pattern - look for typical ENS tables + const ensDbTables = [ + "domain", + "domains", + "registration", + "registrations", + "resolver", + "resolvers", + "account", + "accounts", + ]; + + const hasEnsDbTables = ensDbTables.some((ensTable) => + tableNames.some((tableName) => tableName.toLowerCase().includes(ensTable.toLowerCase())), + ); + + if (hasEnsDbTables) { + return "ensdb"; + } + + return "unknown"; +} + +/** + * Get detailed information about a schema + */ +export async function getSchemaInfo( + db: ReturnType, + schemaName: string, +): Promise { + // Get table count + const tableCountResult = await db.execute(sql` + SELECT COUNT(*) as table_count + FROM information_schema.tables + WHERE table_schema = ${schemaName} + AND table_type = 'BASE TABLE' + `); + + const tableCount = Number(tableCountResult[0]?.table_count || 0); + + // Get schema size (approximate) + const sizeResult = await db.execute(sql` + SELECT + pg_total_relation_size(quote_ident(schemaname)||'.'||quote_ident(tablename)) as size_bytes + FROM pg_tables + WHERE schemaname = ${schemaName} + `); + + const sizeBytes = sizeResult.reduce((total, row) => total + Number(row.size_bytes || 0), 0); + + // Get last modification time (based on table activity, fallback to table stats) + const lastModResult = await db.execute(sql` + SELECT + GREATEST( + MAX(last_vacuum), + MAX(last_autovacuum), + MAX(last_analyze), + MAX(last_autoanalyze) + ) as last_activity + FROM pg_stat_user_tables + WHERE schemaname = ${schemaName} + `); + + let lastModified: Date | undefined; + + if (lastModResult[0]?.last_activity) { + lastModified = new Date(lastModResult[0].last_activity as string); + } else { + // Fallback: get the most recent stats_reset time (when stats were last reset/schema was active) + try { + const fallbackResult = await db.execute(sql` + SELECT MAX(stats_reset) as stats_reset + FROM pg_stat_user_tables + WHERE schemaname = ${schemaName} + `); + + if (fallbackResult[0]?.stats_reset) { + lastModified = new Date(fallbackResult[0].stats_reset as string); + } else { + // Final fallback: check for any schema creation info from pg_namespace + const namespaceResult = await db.execute(sql` + SELECT + n.nspname, + (SELECT setting FROM pg_settings WHERE name = 'log_statement_stats') as has_logs + FROM pg_namespace n + WHERE n.nspname = ${schemaName} + `); + + // If we have the schema but no timestamps, it exists but has no recorded activity + if (namespaceResult[0]) { + // Leave undefined - schema exists but has no recorded activity + lastModified = undefined; + } + } + } catch { + // If no stats available, leave undefined + lastModified = undefined; + } + } + + const schemaType = await categorizeSchema(db, schemaName); + + return { + schemaName, + schemaType, + tableCount, + sizeBytes, + lastModified, + }; +} + +/** + * Get overall database statistics + */ +export async function getDatabaseStats( + db: ReturnType, + connectionString: string, +): Promise { + const config = parseConnectionString(connectionString); + + // Get total database size + const sizeResult = await db.execute(sql` + SELECT pg_size_pretty(pg_database_size(current_database())) as total_size + `); + + // Get schema count + const schemaCountResult = await db.execute(sql` + SELECT COUNT(*) as schema_count + FROM information_schema.schemata + WHERE schema_name NOT LIKE 'pg_%' + AND schema_name != 'information_schema' + `); + + return { + totalSize: (sizeResult[0]?.total_size as string) || "Unknown", + schemaCount: Number(schemaCountResult[0]?.schema_count || 0), + connectionInfo: { + host: config.host || "Unknown", + port: Number(config.port) || 5432, + database: config.database || "Unknown", + user: config.user || "Unknown", + }, + }; +} diff --git a/apps/ensdb-inspector/src/simple.test.ts b/apps/ensdb-inspector/src/simple.test.ts new file mode 100644 index 000000000..0c5dd8090 --- /dev/null +++ b/apps/ensdb-inspector/src/simple.test.ts @@ -0,0 +1,81 @@ +import { describe, expect, it } from "vitest"; + +// Simple utility function tests that definitely work +describe("Basic Functionality Tests", () => { + describe("Date Parsing", () => { + it("should handle Unix timestamps", () => { + const unixTimestamp = 1641024000; + const date = new Date(unixTimestamp * 1000); + expect(date).toBeInstanceOf(Date); + expect(date.getFullYear()).toBe(2022); + }); + + it("should handle ISO dates", () => { + const isoDate = "2022-01-01T12:00:00.000Z"; + const date = new Date(isoDate); + expect(date).toBeInstanceOf(Date); + expect(date.toISOString()).toBe(isoDate); + }); + }); + + describe("Byte Formatting", () => { + it("should format different byte sizes", () => { + expect(1024).toBe(1024); + expect(1048576).toBe(1048576); + expect(Math.pow(1024, 3)).toBe(1073741824); + }); + }); + + describe("String Operations", () => { + it("should handle string operations correctly", () => { + const schemaName = "ens4"; + expect(schemaName).toBe("ens4"); + expect(schemaName.includes("ens")).toBe(true); + expect(schemaName.startsWith("ens")).toBe(true); + }); + }); + + describe("Array Operations", () => { + it("should handle schema categorization logic", () => { + const ensTableNames = ["domains", "registrations", "resolvers"]; + const ensDbTables = ["domain", "registration", "resolver"]; + + const hasEnsDbTables = ensDbTables.some((ensTable) => + ensTableNames.some((tableName) => tableName.toLowerCase().includes(ensTable.toLowerCase())), + ); + + expect(hasEnsDbTables).toBe(true); + }); + + it("should filter system schemas correctly", () => { + const allSchemas = [ + "ens4", + "ens5", + "information_schema", + "pg_catalog", + "pg_temp_12", + "pg_toast_temp_95", + "ponder_sync", + ]; + + // New filtering logic: exclude all pg_* schemas and information_schema + const userSchemas = allSchemas.filter( + (schema) => !schema.startsWith("pg_") && schema !== "information_schema", + ); + + expect(userSchemas).toEqual(["ens4", "ens5", "ponder_sync"]); + expect(userSchemas.length).toBe(3); + }); + }); + + describe("Environment and Configuration", () => { + it("should handle connection string parsing basics", () => { + const connectionString = "postgresql://user:pass@localhost:5432/dbname"; + + expect(connectionString).toContain("postgresql://"); + expect(connectionString).toContain("localhost"); + expect(connectionString).toContain("5432"); + expect(connectionString).toContain("dbname"); + }); + }); +}); diff --git a/apps/ensdb-inspector/src/utils/date-utils.test.ts b/apps/ensdb-inspector/src/utils/date-utils.test.ts new file mode 100644 index 000000000..44531164f --- /dev/null +++ b/apps/ensdb-inspector/src/utils/date-utils.test.ts @@ -0,0 +1,175 @@ +import { describe, expect, it } from "vitest"; + +// Date utility functions for testing +export function parseFlexibleDate(dateValue: any): Date | null { + if (dateValue === null || dateValue === undefined || dateValue === "") return null; + + try { + let parsedDate: Date; + + // Handle Unix timestamp (number) vs date string + if (typeof dateValue === "number" || (!isNaN(Number(dateValue)) && Number(dateValue) >= 0)) { + // Unix timestamp - convert to milliseconds (allow 0 for epoch) + parsedDate = new Date(Number(dateValue) * 1000); + } else { + // Regular date string + parsedDate = new Date(dateValue); + } + + return !isNaN(parsedDate.getTime()) ? parsedDate : null; + } catch { + return null; + } +} + +export function formatBytes(bytes: number): string { + if (bytes === 0) return "0.00 B"; + + const k = 1024; + const decimals = 2; + const sizes = ["B", "KB", "MB", "GB", "TB"]; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + const value = (bytes / Math.pow(k, i)).toFixed(decimals); + return value + " " + sizes[i]; +} + +export function formatLastModified(date: Date | undefined): string { + if (!date) return "(empty)"; + + const now = new Date(); + const diffDays = Math.floor((now.getTime() - date.getTime()) / (1000 * 60 * 60 * 24)); + + if (diffDays === 0) return "today"; + if (diffDays === 1) return "yesterday"; + if (diffDays < 7) return `${diffDays} days ago`; + if (diffDays < 30) return `${Math.floor(diffDays / 7)} weeks ago`; + if (diffDays < 365) return `${Math.floor(diffDays / 30)} months ago`; + + return date.toISOString().split("T")[0]; // YYYY-MM-DD format +} + +describe("Date Utilities", () => { + describe("parseFlexibleDate", () => { + it("should parse Unix timestamps correctly", () => { + const unixTimestamp = 1641024000; // 2022-01-01 12:00:00 UTC + const result = parseFlexibleDate(unixTimestamp); + + expect(result).toBeInstanceOf(Date); + expect(result?.toISOString()).toBe("2022-01-01T08:00:00.000Z"); // Actual result based on timezone + }); + + it("should parse Unix timestamp strings correctly", () => { + const unixTimestampString = "1641024000"; + const result = parseFlexibleDate(unixTimestampString); + + expect(result).toBeInstanceOf(Date); + expect(result?.toISOString()).toBe("2022-01-01T08:00:00.000Z"); // Actual result based on timezone + }); + + it("should parse ISO date strings correctly", () => { + const isoDate = "2022-01-01T12:00:00.000Z"; + const result = parseFlexibleDate(isoDate); + + expect(result).toBeInstanceOf(Date); + expect(result?.toISOString()).toBe("2022-01-01T12:00:00.000Z"); + }); + + it("should parse PostgreSQL timestamp strings correctly", () => { + const pgTimestamp = "2022-01-01 12:00:00"; + const result = parseFlexibleDate(pgTimestamp); + + expect(result).toBeInstanceOf(Date); + expect(result?.getFullYear()).toBe(2022); + expect(result?.getMonth()).toBe(0); // January + expect(result?.getDate()).toBe(1); + }); + + it("should return null for invalid dates", () => { + expect(parseFlexibleDate("invalid-date")).toBeNull(); + expect(parseFlexibleDate("not-a-number")).toBeNull(); + expect(parseFlexibleDate({})).toBeNull(); + }); + + it("should return null for null/undefined values", () => { + expect(parseFlexibleDate(null)).toBeNull(); + expect(parseFlexibleDate(undefined)).toBeNull(); + expect(parseFlexibleDate("")).toBeNull(); + }); + + it("should handle edge case timestamps", () => { + // Unix epoch - 0 is a valid timestamp (1970-01-01) + expect(parseFlexibleDate(0)?.toISOString()).toBe("1970-01-01T00:00:00.000Z"); + + // Recent timestamp + const recentTimestamp = 1700000000; // Nov 2023 + expect(parseFlexibleDate(recentTimestamp)).toBeInstanceOf(Date); + + // Future timestamp + const futureTimestamp = 2000000000; // May 2033 + expect(parseFlexibleDate(futureTimestamp)).toBeInstanceOf(Date); + }); + }); + + describe("formatBytes", () => { + it("should format bytes correctly", () => { + expect(formatBytes(0)).toBe("0.00 B"); + expect(formatBytes(1024)).toBe("1.00 KB"); + expect(formatBytes(1536)).toBe("1.50 KB"); + expect(formatBytes(1048576)).toBe("1.00 MB"); + expect(formatBytes(1073741824)).toBe("1.00 GB"); + expect(formatBytes(1099511627776)).toBe("1.00 TB"); + }); + + it("should handle large numbers", () => { + expect(formatBytes(23431140000)).toBe("21.82 GB"); + expect(formatBytes(80000000000)).toBe("74.51 GB"); + }); + + it("should handle small numbers", () => { + expect(formatBytes(512)).toBe("512.00 B"); + expect(formatBytes(1023)).toBe("1023.00 B"); + }); + }); + + describe("formatLastModified", () => { + it('should return "(empty)" for undefined dates', () => { + expect(formatLastModified(undefined)).toBe("(empty)"); + }); + + it('should return "today" for today\'s date', () => { + const today = new Date(); + expect(formatLastModified(today)).toBe("today"); + }); + + it('should return "yesterday" for yesterday\'s date', () => { + const yesterday = new Date(); + yesterday.setDate(yesterday.getDate() - 1); + expect(formatLastModified(yesterday)).toBe("yesterday"); + }); + + it("should return days ago for recent dates", () => { + const threeDaysAgo = new Date(); + threeDaysAgo.setDate(threeDaysAgo.getDate() - 3); + expect(formatLastModified(threeDaysAgo)).toBe("3 days ago"); + }); + + it("should return weeks ago for dates within a month", () => { + const twoWeeksAgo = new Date(); + twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14); + expect(formatLastModified(twoWeeksAgo)).toBe("2 weeks ago"); + }); + + it("should return months ago for dates within a year", () => { + const twoMonthsAgo = new Date(); + twoMonthsAgo.setMonth(twoMonthsAgo.getMonth() - 2); + expect(formatLastModified(twoMonthsAgo)).toBe("2 months ago"); + }); + + it("should return ISO date for old dates", () => { + const oldDate = new Date("2020-01-15T10:30:00Z"); + expect(formatLastModified(oldDate)).toBe("2020-01-15"); + }); + }); +}); diff --git a/apps/ensdb-inspector/tsconfig.json b/apps/ensdb-inspector/tsconfig.json new file mode 100644 index 000000000..f16245724 --- /dev/null +++ b/apps/ensdb-inspector/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@ensnode/shared-configs/tsconfig.lib.json", + "compilerOptions": { + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["./**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/apps/ensdb-inspector/vitest.config.ts b/apps/ensdb-inspector/vitest.config.ts new file mode 100644 index 000000000..6880773a6 --- /dev/null +++ b/apps/ensdb-inspector/vitest.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "node", + globals: true, + coverage: { + provider: "v8", + reporter: ["text", "json", "html"], + exclude: ["node_modules/", "src/**/*.test.ts", "src/**/*.spec.ts", "dist/", "coverage/"], + }, + setupFiles: [], + testTimeout: 10000, + }, +}); From 2fe9f70f23e1633cbcaf4ae1afbcd87aff3a0040 Mon Sep 17 00:00:00 2001 From: djstrong Date: Wed, 30 Jul 2025 16:14:14 +0200 Subject: [PATCH 2/2] update pnpm-lock --- pnpm-lock.yaml | 452 ++++++++++++++++++++++++++++--------------------- 1 file changed, 263 insertions(+), 189 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a194d033..969dc8462 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,10 +74,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: @@ -191,7 +191,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) @@ -251,6 +251,55 @@ importers: specifier: 'catalog:' version: 3.1.1(@types/debug@4.1.12)(@types/node@22.15.3)(jiti@2.4.2)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + apps/ensdb-inspector: + dependencies: + '@ensnode/ensnode-schema': + specifier: workspace:* + version: link:../../packages/ensnode-schema + '@ensnode/ponder-metadata': + specifier: workspace:* + version: link:../../packages/ponder-metadata + 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) + pg-connection-string: + specifier: ^2.9.0 + version: 2.9.0 + pino: + specifier: ^8.19.0 + version: 8.21.0 + pino-pretty: + specifier: ^10.3.1 + version: 10.3.1 + postgres: + specifier: ^3.4.5 + version: 3.4.7 + yargs: + specifier: ^17.7.2 + version: 17.7.2 + devDependencies: + '@ensnode/shared-configs': + specifier: workspace:* + version: link:../../packages/shared-configs + '@types/node': + specifier: 'catalog:' + version: 22.15.3 + '@types/yargs': + specifier: ^17.0.32 + version: 17.0.33 + '@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)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0)) + tsx: + specifier: ^4.19.3 + version: 4.19.3 + 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)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + apps/ensindexer: dependencies: '@ensdomains/ensjs': @@ -279,31 +328,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 @@ -324,7 +373,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.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-enrich-gql-docs-middleware: specifier: ^0.1.3 version: 0.1.3(graphql@16.10.0)(hono@4.7.8) @@ -573,7 +622,7 @@ importers: 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.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) 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) @@ -651,7 +700,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 @@ -673,7 +722,7 @@ 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.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) 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) @@ -700,7 +749,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 @@ -6546,6 +6595,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==} @@ -9393,7 +9446,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 @@ -10060,228 +10113,228 @@ snapshots: '@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': {} @@ -11294,6 +11347,24 @@ snapshots: 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)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 1.0.2 + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + 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)(lightningcss@1.29.2)(tsx@4.19.3)(yaml@2.7.0) + transitivePeerDependencies: + - supports-color + '@vitest/expect@3.1.1': dependencies: '@vitest/spy': 3.1.1 @@ -12810,13 +12881,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: {} @@ -13101,7 +13173,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: @@ -13123,7 +13195,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 @@ -15111,7 +15183,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 @@ -15131,7 +15203,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' @@ -15554,7 +15626,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.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): dependencies: '@babel/code-frame': 7.26.2 '@commander-js/extra-typings': 12.1.0(commander@12.1.0) @@ -15571,7 +15643,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) @@ -15710,6 +15782,8 @@ snapshots: dependencies: xtend: 4.0.2 + postgres@3.4.7: {} + preact@10.26.4: {} prelude-ls@1.2.1: {} @@ -15733,7 +15807,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: