diff --git a/package-lock.json b/package-lock.json index d05f78a..5d724b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@anthropic-ai/mcpb": "^2.1.2", "@modelcontextprotocol/sdk": "^1.29.0", - "cdb-converter": "^0.1.2", + "cdb-converter": "^0.2.0", "sql-query-identifier": "^3.1.1", "sql.js": "^1.14.1", "zod": "^3.25.76" @@ -20,7 +20,7 @@ "pcm-mcp": "dist/index.js" }, "devDependencies": { - "@biomejs/biome": "2.4.13", + "@biomejs/biome": "2.5.4", "@types/node": "^22.20.0", "@types/sql.js": "^1.4.11", "@vitest/coverage-v8": "^4.1.5", @@ -115,9 +115,9 @@ } }, "node_modules/@biomejs/biome": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.13.tgz", - "integrity": "sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.4.tgz", + "integrity": "sha512-xy5FNE5kQJKyK5MR1gJy6ztXYx4WBAbYGlK04lMEgmyPRWKybY9NFwiG9yo0XdzOU8Xvhj41u034J1ywfoWfMw==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -131,20 +131,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.4.13", - "@biomejs/cli-darwin-x64": "2.4.13", - "@biomejs/cli-linux-arm64": "2.4.13", - "@biomejs/cli-linux-arm64-musl": "2.4.13", - "@biomejs/cli-linux-x64": "2.4.13", - "@biomejs/cli-linux-x64-musl": "2.4.13", - "@biomejs/cli-win32-arm64": "2.4.13", - "@biomejs/cli-win32-x64": "2.4.13" + "@biomejs/cli-darwin-arm64": "2.5.4", + "@biomejs/cli-darwin-x64": "2.5.4", + "@biomejs/cli-linux-arm64": "2.5.4", + "@biomejs/cli-linux-arm64-musl": "2.5.4", + "@biomejs/cli-linux-x64": "2.5.4", + "@biomejs/cli-linux-x64-musl": "2.5.4", + "@biomejs/cli-win32-arm64": "2.5.4", + "@biomejs/cli-win32-x64": "2.5.4" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.13.tgz", - "integrity": "sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.4.tgz", + "integrity": "sha512-4o3NFRobXHynkgcFVrlZsoDAFtF2ldlEGN8sORSws5ZQqyY4PXnPUIylu4ksfyHuwkfvDREuWh3JK+niRwGq3w==", "cpu": [ "arm64" ], @@ -159,9 +159,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.13.tgz", - "integrity": "sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.4.tgz", + "integrity": "sha512-D32P5HkU2Y6PySuC/WsVDTOgsDwVFmujzhhhOQjajtATpVWFDXuVd3oRbsWNSEA+aaFzyzZm22szsyydBYlSyQ==", "cpu": [ "x64" ], @@ -176,13 +176,16 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.13.tgz", - "integrity": "sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.4.tgz", + "integrity": "sha512-pSEfW7B8kTsXUjUxC1xVVK+y85Ht3C5XxZ9gclmC7/3Ku9Vqz8jmI7k0p/BNIjQ6t4sFERI2sFeH73ybiZl6YQ==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -193,13 +196,16 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.13.tgz", - "integrity": "sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.4.tgz", + "integrity": "sha512-Rpm5/AT1m+DlJmUoYvS4/vXc+0tXJPJ2NQz25TGPyHVF5JrWy75PE0GH6kVxsKtQDuCH4OgzquZq0R4kj/wCVg==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -210,13 +216,16 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.13.tgz", - "integrity": "sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.4.tgz", + "integrity": "sha512-FNxojWJkL7EajAuzBgoLe0T2G0y112M4lBrDIFl/DomFTx8yqenYOIdsRLNXvOvBBofE8hJi85LjzLmBDpY7/Q==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -227,13 +236,16 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.13.tgz", - "integrity": "sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.4.tgz", + "integrity": "sha512-aby/PohmmgbShcHqFsZVzG8H6D98+P+A6xRWRrQcLW1pCjabcov5UUlke4UqNQBYTkDQav+jB4zyyDDeKB2GaA==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT OR Apache-2.0", "optional": true, "os": [ @@ -244,9 +256,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.13.tgz", - "integrity": "sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.4.tgz", + "integrity": "sha512-emoXexPZIPAZkz2RKmA95WJUqK3I5MJNYtwEbL5ESciRzhmFMMyekDhNG8hpeOaK+ZGRDxAU4wvGuA5IHQ0h0w==", "cpu": [ "arm64" ], @@ -261,9 +273,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.4.13", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.13.tgz", - "integrity": "sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.4.tgz", + "integrity": "sha512-U1jaluLw1qQc2Tx7/CeSoL9N5XcqIH+GWjpUAy1ouB5nVjSCMNO+NNHdY3RAs8zxNurLWAdj6pehQdCA2zyU+Q==", "cpu": [ "x64" ], @@ -1210,9 +1222,9 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.137.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.137.0.tgz", - "integrity": "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==", + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", "dev": true, "license": "MIT", "funding": { @@ -1220,9 +1232,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.3.tgz", - "integrity": "sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", "cpu": [ "arm64" ], @@ -1237,9 +1249,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.3.tgz", - "integrity": "sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", "cpu": [ "arm64" ], @@ -1254,9 +1266,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.3.tgz", - "integrity": "sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", "cpu": [ "x64" ], @@ -1271,9 +1283,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.3.tgz", - "integrity": "sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", "cpu": [ "x64" ], @@ -1288,9 +1300,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.3.tgz", - "integrity": "sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", "cpu": [ "arm" ], @@ -1305,13 +1317,16 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.3.tgz", - "integrity": "sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1322,13 +1337,16 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.3.tgz", - "integrity": "sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1339,13 +1357,16 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.3.tgz", - "integrity": "sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", "cpu": [ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1356,13 +1377,16 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.3.tgz", - "integrity": "sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", "cpu": [ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1373,13 +1397,16 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.3.tgz", - "integrity": "sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -1390,13 +1417,16 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.3.tgz", - "integrity": "sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -1407,9 +1437,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.3.tgz", - "integrity": "sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", "cpu": [ "arm64" ], @@ -1424,9 +1454,9 @@ } }, "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.3.tgz", - "integrity": "sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", "cpu": [ "wasm32" ], @@ -1443,9 +1473,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.3.tgz", - "integrity": "sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", "cpu": [ "arm64" ], @@ -1460,9 +1490,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.3.tgz", - "integrity": "sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", "cpu": [ "x64" ], @@ -1892,9 +1922,9 @@ } }, "node_modules/@types/node": { - "version": "22.20.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.0.tgz", - "integrity": "sha512-QWlFW2wf3nTjC13/DqRnBpR4ZO36VJH/JVBkA/vcnmbTBNQIlnObqyqZE1tUR7+Ni23Lda8R1BxMfbXRpCUx5g==", + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -1917,14 +1947,14 @@ "license": "MIT" }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.9.tgz", - "integrity": "sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", + "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.9", + "@vitest/utils": "4.1.10", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -1938,8 +1968,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.9", - "vitest": "4.1.9" + "@vitest/browser": "4.1.10", + "vitest": "4.1.10" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -1948,16 +1978,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.9.tgz", - "integrity": "sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.9", - "@vitest/utils": "4.1.9", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -1966,13 +1996,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.9.tgz", - "integrity": "sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.9", + "@vitest/spy": "4.1.10", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -1993,9 +2023,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.9.tgz", - "integrity": "sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -2006,13 +2036,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.9.tgz", - "integrity": "sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.9", + "@vitest/utils": "4.1.10", "pathe": "^2.0.3" }, "funding": { @@ -2020,14 +2050,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.9.tgz", - "integrity": "sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.9", - "@vitest/utils": "4.1.9", + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -2036,9 +2066,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.9.tgz", - "integrity": "sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", "dev": true, "license": "MIT", "funding": { @@ -2046,13 +2076,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.9.tgz", - "integrity": "sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.9", + "@vitest/pretty-format": "4.1.10", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2305,15 +2335,18 @@ } }, "node_modules/cdb-converter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/cdb-converter/-/cdb-converter-0.1.2.tgz", - "integrity": "sha512-sxKQy6oTNhR45MHJde715MGk0E8mBsbKufRwDmDdEl2d7o1qRRxD5XIwufOp11EZj1Ay5s1weVG/Em+O4SFeKA==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cdb-converter/-/cdb-converter-0.2.0.tgz", + "integrity": "sha512-1MEhLUEjsSHhJmMHF+I6q6UZvEd4eTU0U7fnluJroN3DXID+hPPC14Jmrep2ca9eJYmy1s2MlCmPGGZVno0Tvg==", "license": "MIT", "dependencies": { "@types/sql.js": "^1.4.11", "pako": "^2.2.0", "sql.js": "^1.14.1" }, + "bin": { + "cdb-converter": "dist/cli.mjs" + }, "engines": { "node": ">=22.0.0" } @@ -3393,9 +3426,9 @@ } }, "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -3409,23 +3442,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", "cpu": [ "arm64" ], @@ -3444,9 +3477,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", "cpu": [ "arm64" ], @@ -3465,9 +3498,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", "cpu": [ "x64" ], @@ -3486,9 +3519,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", "cpu": [ "x64" ], @@ -3507,9 +3540,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", "cpu": [ "arm" ], @@ -3528,13 +3561,16 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3549,13 +3585,16 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", "cpu": [ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3570,13 +3609,16 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3591,13 +3633,16 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", "cpu": [ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -3612,9 +3657,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", "cpu": [ "arm64" ], @@ -3633,9 +3678,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", "cpu": [ "x64" ], @@ -3963,9 +4008,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "dev": true, "funding": [ { @@ -4225,9 +4270,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "version": "8.5.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.21.tgz", + "integrity": "sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==", "dev": true, "funding": [ { @@ -4245,7 +4290,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -4434,13 +4479,13 @@ "license": "MIT" }, "node_modules/rolldown": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.3.tgz", - "integrity": "sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", "dev": true, "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.137.0", + "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -4450,21 +4495,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.1.3", - "@rolldown/binding-darwin-arm64": "1.1.3", - "@rolldown/binding-darwin-x64": "1.1.3", - "@rolldown/binding-freebsd-x64": "1.1.3", - "@rolldown/binding-linux-arm-gnueabihf": "1.1.3", - "@rolldown/binding-linux-arm64-gnu": "1.1.3", - "@rolldown/binding-linux-arm64-musl": "1.1.3", - "@rolldown/binding-linux-ppc64-gnu": "1.1.3", - "@rolldown/binding-linux-s390x-gnu": "1.1.3", - "@rolldown/binding-linux-x64-gnu": "1.1.3", - "@rolldown/binding-linux-x64-musl": "1.1.3", - "@rolldown/binding-openharmony-arm64": "1.1.3", - "@rolldown/binding-wasm32-wasi": "1.1.3", - "@rolldown/binding-win32-arm64-msvc": "1.1.3", - "@rolldown/binding-win32-x64-msvc": "1.1.3" + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" } }, "node_modules/rollup": { @@ -4748,9 +4793,9 @@ } }, "node_modules/sql-query-identifier": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/sql-query-identifier/-/sql-query-identifier-3.1.1.tgz", - "integrity": "sha512-yKLx1hMFM5RKyNkFRCJrOFCPX/ZLhVMl45PWdOH1+UuEX3khELbCdgZuBnSaU9hpVvdYGMPqWc5JAAE27aybRA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/sql-query-identifier/-/sql-query-identifier-3.2.0.tgz", + "integrity": "sha512-DUIx0pyyPYIJzFCuD5euzHOjj1n9BxTEkq8iXOHgOTd/RwuKsHUMhn0tb6pAwJR2rccy925Fhe4NaDDadIjTUQ==", "license": "MIT", "engines": { "node": ">= 10.13" @@ -5193,16 +5238,16 @@ } }, "node_modules/vite": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.0.tgz", - "integrity": "sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", + "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", - "picomatch": "^4.0.4", - "postcss": "^8.5.15", - "rolldown": "~1.1.2", + "picomatch": "^4.0.5", + "postcss": "^8.5.17", + "rolldown": "~1.1.5", "tinyglobby": "^0.2.17" }, "bin": { @@ -5271,9 +5316,9 @@ } }, "node_modules/vite/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { @@ -5284,19 +5329,19 @@ } }, "node_modules/vitest": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.9.tgz", - "integrity": "sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==", + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.9", - "@vitest/mocker": "4.1.9", - "@vitest/pretty-format": "4.1.9", - "@vitest/runner": "4.1.9", - "@vitest/snapshot": "4.1.9", - "@vitest/spy": "4.1.9", - "@vitest/utils": "4.1.9", + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -5324,12 +5369,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.9", - "@vitest/browser-preview": "4.1.9", - "@vitest/browser-webdriverio": "4.1.9", - "@vitest/coverage-istanbul": "4.1.9", - "@vitest/coverage-v8": "4.1.9", - "@vitest/ui": "4.1.9", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index ecd5de0..a6b742d 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "start:dev": "tsup --watch --onSuccess \"node ./dist/index.js\"" }, "devDependencies": { - "@biomejs/biome": "2.4.13", + "@biomejs/biome": "2.5.4", "@types/node": "^22.20.0", "@types/sql.js": "^1.4.11", "@vitest/coverage-v8": "^4.1.5", @@ -50,7 +50,7 @@ "dependencies": { "@anthropic-ai/mcpb": "^2.1.2", "@modelcontextprotocol/sdk": "^1.29.0", - "cdb-converter": "^0.1.2", + "cdb-converter": "^0.2.0", "sql-query-identifier": "^3.1.1", "sql.js": "^1.14.1", "zod": "^3.25.76" diff --git a/test/tools/get-player-info.test.ts b/test/tools/get-player-info.test.ts index 7717a58..1a3b12e 100644 --- a/test/tools/get-player-info.test.ts +++ b/test/tools/get-player-info.test.ts @@ -20,13 +20,14 @@ describe("getPlayerInfo", () => { // The official-release fixtures are databases, not played careers, so they // have no active human player (GAM_user.game_i_active = 1). The tool should // surface that as a graceful error rather than throwing. - it.each( - saveFixtures, - )("errors when there is no active player for %s", async (name, path) => { - const result = await mcp.callTool("pcm_get_player_info", { - savePath: path, - }); + it.each(saveFixtures)( + "errors when there is no active player for %s", + async (name, path) => { + const result = await mcp.callTool("pcm_get_player_info", { + savePath: path, + }); - expect(result.isError).toBe(true); - }); + expect(result.isError).toBe(true); + }, + ); }); diff --git a/test/tools/get-table-schema.test.ts b/test/tools/get-table-schema.test.ts index 98d4ab5..00936ea 100644 --- a/test/tools/get-table-schema.test.ts +++ b/test/tools/get-table-schema.test.ts @@ -17,15 +17,16 @@ describe("getTableSchema", () => { expect(mcp.registerTool).toHaveBeenCalledOnce(); }); - it.each( - saveFixtures, - )("returns STA_race table schema for %s", async (name, path) => { - const result = await mcp.callTool("pcm_get_table_schema", { - savePath: path, - tableName: "STA_race", - }); + it.each(saveFixtures)( + "returns STA_race table schema for %s", + async (name, path) => { + const result = await mcp.callTool("pcm_get_table_schema", { + savePath: path, + tableName: "STA_race", + }); - expect(result.structuredContent).toBeDefined(); - expect(result.structuredContent).toMatchSnapshot(); - }); + expect(result.structuredContent).toBeDefined(); + expect(result.structuredContent).toMatchSnapshot(); + }, + ); }); diff --git a/test/tools/get-team-roster.test.ts b/test/tools/get-team-roster.test.ts index a3c0f53..a0f94c0 100644 --- a/test/tools/get-team-roster.test.ts +++ b/test/tools/get-team-roster.test.ts @@ -17,17 +17,18 @@ describe("getTeamRoster", () => { expect(mcp.registerTool).toHaveBeenCalledOnce(); }); - it.each( - saveFixtures, - )("returns the roster for a given team for %s", async (name, path) => { - const result = await mcp.callTool("pcm_get_team_roster", { - savePath: path, - teamId: 1, - }); + it.each(saveFixtures)( + "returns the roster for a given team for %s", + async (name, path) => { + const result = await mcp.callTool("pcm_get_team_roster", { + savePath: path, + teamId: 1, + }); - expect(result.structuredContent).toBeDefined(); - expect(result.structuredContent).toMatchSnapshot(); - }); + expect(result.structuredContent).toBeDefined(); + expect(result.structuredContent).toMatchSnapshot(); + }, + ); it("returns an error for an unknown team", async () => { const result = await mcp.callTool("pcm_get_team_roster", { diff --git a/test/tools/query-save.test.ts b/test/tools/query-save.test.ts index 4605c63..b235173 100644 --- a/test/tools/query-save.test.ts +++ b/test/tools/query-save.test.ts @@ -20,34 +20,36 @@ describe("querySave", () => { expect(mcp.registerTool).toHaveBeenCalledOnce(); }); - it.each( - saveFixtures, - )("runs a read-only SELECT against %s", async (_name, path) => { - const result = await mcp.callTool("pcm_query_save", { - savePath: path, - query: "SELECT COUNT(*) AS n FROM STA_race", - }); - - expect(result.isError).toBeUndefined(); - expect(result.structuredContent).toMatchObject({ rowCount: 1 }); - }); - - it.each( - saveFixtures, - )("rejects a WITH … DELETE CTE for %s", async (_name, path) => { - const result = await mcp.callTool("pcm_query_save", { - savePath: path, - query: "WITH x AS (SELECT 1) DELETE FROM STA_race", - }); - - expect(result.isError).toBe(true); - expect(result.content).toEqual([ - { - type: "text", - text: "Only read-only SELECT (or WITH … SELECT) queries are allowed.", - }, - ]); - }); + it.each(saveFixtures)( + "runs a read-only SELECT against %s", + async (_name, path) => { + const result = await mcp.callTool("pcm_query_save", { + savePath: path, + query: "SELECT COUNT(*) AS n FROM STA_race", + }); + + expect(result.isError).toBeUndefined(); + expect(result.structuredContent).toMatchObject({ rowCount: 1 }); + }, + ); + + it.each(saveFixtures)( + "rejects a WITH … DELETE CTE for %s", + async (_name, path) => { + const result = await mcp.callTool("pcm_query_save", { + savePath: path, + query: "WITH x AS (SELECT 1) DELETE FROM STA_race", + }); + + expect(result.isError).toBe(true); + expect(result.content).toEqual([ + { + type: "text", + text: "Only read-only SELECT (or WITH … SELECT) queries are allowed.", + }, + ]); + }, + ); describe("assertReadOnlyQuery", () => { describe("allowed queries", () => { diff --git a/test/tools/search-cyclist.test.ts b/test/tools/search-cyclist.test.ts index a1511e2..bfad8bb 100644 --- a/test/tools/search-cyclist.test.ts +++ b/test/tools/search-cyclist.test.ts @@ -17,17 +17,18 @@ describe("searchCyclist", () => { expect(mcp.registerTool).toHaveBeenCalledOnce(); }); - it.each( - saveFixtures, - )("finds cyclists by last name for %s", async (name, path) => { - const result = await mcp.callTool("pcm_search_cyclist", { - savePath: path, - lastName: "van der", - }); - - expect(result.structuredContent).toBeDefined(); - expect(result.structuredContent).toMatchSnapshot(); - }); + it.each(saveFixtures)( + "finds cyclists by last name for %s", + async (name, path) => { + const result = await mcp.callTool("pcm_search_cyclist", { + savePath: path, + lastName: "van der", + }); + + expect(result.structuredContent).toBeDefined(); + expect(result.structuredContent).toMatchSnapshot(); + }, + ); it("caps results at 10 and flags truncation for a broad search", async () => { const result = await mcp.callTool("pcm_search_cyclist", { diff --git a/test/tools/update-cyclist-ratings.test.ts b/test/tools/update-cyclist-ratings.test.ts index 8c21dd7..28d9eb0 100644 --- a/test/tools/update-cyclist-ratings.test.ts +++ b/test/tools/update-cyclist-ratings.test.ts @@ -60,129 +60,135 @@ describe("updateCyclistRatings", () => { expect(mcp.registerTool).toHaveBeenCalledOnce(); }); - it.each( - saveFixtures, - )("updates ratings and writes the change to a new .cdb for %s", async (_name, path) => { - const cyclistId = await readFirstCyclistId(path); - const outputPath = join(outDir, "edited.cdb"); - - const result = await mcp.callTool("pcm_update_cyclist_ratings", { - savePath: path, - outputPath, - cyclistId, - ratings: { sprint: 81, mountain: 72 }, - }); - - expect(result.isError).toBeUndefined(); - expect(result.structuredContent).toMatchObject({ - outputPath, - cyclist: { - id: cyclistId, - sprint: 81, - mountain: 72, - }, - }); - expect( - await readRatings(outputPath, cyclistId, [ - "charac_i_sprint", - "charac_i_mountain", - ]), - ).toEqual([81, 72]); - }); - - it.each( - saveFixtures, - )("only changes the ratings that were passed for %s", async (_name, path) => { - const cyclistId = await readFirstCyclistId(path); - const before = await readRatings(path, cyclistId, [ - "charac_i_plain", - "charac_i_cobble", - ]); - const outputPath = join(outDir, "edited.cdb"); - - await mcp.callTool("pcm_update_cyclist_ratings", { - savePath: path, - outputPath, - cyclistId, - ratings: { sprint: 81 }, - }); - - expect( - await readRatings(outputPath, cyclistId, [ + it.each(saveFixtures)( + "updates ratings and writes the change to a new .cdb for %s", + async (_name, path) => { + const cyclistId = await readFirstCyclistId(path); + const outputPath = join(outDir, "edited.cdb"); + + const result = await mcp.callTool("pcm_update_cyclist_ratings", { + savePath: path, + outputPath, + cyclistId, + ratings: { sprint: 81, mountain: 72 }, + }); + + expect(result.isError).toBeUndefined(); + expect(result.structuredContent).toMatchObject({ + outputPath, + cyclist: { + id: cyclistId, + sprint: 81, + mountain: 72, + }, + }); + expect( + await readRatings(outputPath, cyclistId, [ + "charac_i_sprint", + "charac_i_mountain", + ]), + ).toEqual([81, 72]); + }, + ); + + it.each(saveFixtures)( + "only changes the ratings that were passed for %s", + async (_name, path) => { + const cyclistId = await readFirstCyclistId(path); + const before = await readRatings(path, cyclistId, [ "charac_i_plain", "charac_i_cobble", - ]), - ).toEqual(before); - }); - - it.each( - saveFixtures, - )("errors on an unknown cyclist ID for %s", async (_name, path) => { - const result = await mcp.callTool("pcm_update_cyclist_ratings", { - savePath: path, - outputPath: join(outDir, "edited.cdb"), - cyclistId: 999999999, - ratings: { sprint: 81 }, - }); - - expect(result.isError).toBe(true); - expect(result.content[0]).toEqual({ - type: "text", - text: "No cyclist with IDcyclist = 999999999 in this save — use pcm_search_cyclist to find the right ID.", - }); - }); - - it.each( - saveFixtures, - )("errors when no rating is provided for %s", async (_name, path) => { - const cyclistId = await readFirstCyclistId(path); - const result = await mcp.callTool("pcm_update_cyclist_ratings", { - savePath: path, - outputPath: join(outDir, "edited.cdb"), - cyclistId, - ratings: {}, - }); - - expect(result.isError).toBe(true); - expect(result.content[0]).toEqual({ - type: "text", - text: "Provide at least one rating to change in `ratings`.", - }); - }); - - it.each( - saveFixtures.filter(([, , hasMediumMountain]) => hasMediumMountain), - )("sets mediumMountain for %s", async (_name, path) => { - const cyclistId = await readFirstCyclistId(path); - const outputPath = join(outDir, "edited.cdb"); - const result = await mcp.callTool("pcm_update_cyclist_ratings", { - savePath: path, - outputPath, - cyclistId, - ratings: { mediumMountain: 77 }, - }); - - expect(result.isError).toBeUndefined(); - expect( - await readRatings(outputPath, cyclistId, ["charac_i_medium_mountain"]), - ).toEqual([77]); - }); - - it.each( - saveFixtures.filter(([, , hasMediumMountain]) => !hasMediumMountain), - )("rejects mediumMountain on saves that pre-date the column for %s", async (_name, path) => { - const cyclistId = await readFirstCyclistId(path); - const result = await mcp.callTool("pcm_update_cyclist_ratings", { - savePath: path, - outputPath: join(outDir, "edited.cdb"), - cyclistId, - ratings: { mediumMountain: 77 }, - }); - - expect(result.isError).toBe(true); - expect(result.content[0]).toEqual({ - type: "text", - text: "This save pre-dates the charac_i_medium_mountain column — mediumMountain cannot be set on it.", - }); - }); + ]); + const outputPath = join(outDir, "edited.cdb"); + + await mcp.callTool("pcm_update_cyclist_ratings", { + savePath: path, + outputPath, + cyclistId, + ratings: { sprint: 81 }, + }); + + expect( + await readRatings(outputPath, cyclistId, [ + "charac_i_plain", + "charac_i_cobble", + ]), + ).toEqual(before); + }, + ); + + it.each(saveFixtures)( + "errors on an unknown cyclist ID for %s", + async (_name, path) => { + const result = await mcp.callTool("pcm_update_cyclist_ratings", { + savePath: path, + outputPath: join(outDir, "edited.cdb"), + cyclistId: 999999999, + ratings: { sprint: 81 }, + }); + + expect(result.isError).toBe(true); + expect(result.content[0]).toEqual({ + type: "text", + text: "No cyclist with IDcyclist = 999999999 in this save — use pcm_search_cyclist to find the right ID.", + }); + }, + ); + + it.each(saveFixtures)( + "errors when no rating is provided for %s", + async (_name, path) => { + const cyclistId = await readFirstCyclistId(path); + const result = await mcp.callTool("pcm_update_cyclist_ratings", { + savePath: path, + outputPath: join(outDir, "edited.cdb"), + cyclistId, + ratings: {}, + }); + + expect(result.isError).toBe(true); + expect(result.content[0]).toEqual({ + type: "text", + text: "Provide at least one rating to change in `ratings`.", + }); + }, + ); + + it.each(saveFixtures.filter(([, , hasMediumMountain]) => hasMediumMountain))( + "sets mediumMountain for %s", + async (_name, path) => { + const cyclistId = await readFirstCyclistId(path); + const outputPath = join(outDir, "edited.cdb"); + const result = await mcp.callTool("pcm_update_cyclist_ratings", { + savePath: path, + outputPath, + cyclistId, + ratings: { mediumMountain: 77 }, + }); + + expect(result.isError).toBeUndefined(); + expect( + await readRatings(outputPath, cyclistId, ["charac_i_medium_mountain"]), + ).toEqual([77]); + }, + ); + + it.each(saveFixtures.filter(([, , hasMediumMountain]) => !hasMediumMountain))( + "rejects mediumMountain on saves that pre-date the column for %s", + async (_name, path) => { + const cyclistId = await readFirstCyclistId(path); + const result = await mcp.callTool("pcm_update_cyclist_ratings", { + savePath: path, + outputPath: join(outDir, "edited.cdb"), + cyclistId, + ratings: { mediumMountain: 77 }, + }); + + expect(result.isError).toBe(true); + expect(result.content[0]).toEqual({ + type: "text", + text: "This save pre-dates the charac_i_medium_mountain column — mediumMountain cannot be set on it.", + }); + }, + ); }); diff --git a/test/tools/update-save.test.ts b/test/tools/update-save.test.ts index 307a04b..f0e6f92 100644 --- a/test/tools/update-save.test.ts +++ b/test/tools/update-save.test.ts @@ -43,132 +43,139 @@ describe("updateSave", () => { expect(mcp.registerTool).toHaveBeenCalledOnce(); }); - it.each( - saveFixtures, - )("applies an UPDATE and writes the change to a new .cdb for %s", async (_name, path) => { - const outputPath = join(outDir, "edited.cdb"); - const result = await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath, - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); - - expect(result.isError).toBeUndefined(); - expect(result.structuredContent).toMatchObject({ - outputPath, - rowsModified: 1, - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); - - // The change must actually persist in the written file. - expect(await readGameDate(outputPath)).toBe(20991231); - }); - - it.each( - saveFixtures, - )("leaves the source save untouched for %s", async (_name, path) => { - const before = await stat(path); - const outputPath = join(outDir, "edited.cdb"); - - await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath, - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); - - const after = await stat(path); - expect(after.size).toBe(before.size); - expect(after.mtimeMs).toBe(before.mtimeMs); - }); - - it.each( - saveFixtures, - )("refuses to overwrite the source save for %s", async (_name, path) => { - const result = await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath: path, - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); - - expect(result.isError).toBe(true); - expect(result.content[0]).toEqual({ - type: "text", - text: "outputPath must differ from the source save — the input .cdb is never overwritten.", - }); - }); + it.each(saveFixtures)( + "applies an UPDATE and writes the change to a new .cdb for %s", + async (_name, path) => { + const outputPath = join(outDir, "edited.cdb"); + const result = await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath, + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); - it.each( - saveFixtures, - )("rejects a non-.cdb output path for %s", async (_name, path) => { - const result = await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath: join(outDir, "edited.txt"), - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); + expect(result.isError).toBeUndefined(); + expect(result.structuredContent).toMatchObject({ + outputPath, + rowsModified: 1, + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); - expect(result.isError).toBe(true); - expect(result.content[0]).toEqual({ - type: "text", - text: expect.stringMatching(/must be a \.cdb file/), - }); - }); + // The change must actually persist in the written file. + expect(await readGameDate(outputPath)).toBe(20991231); + }, + ); + + it.each(saveFixtures)( + "leaves the source save untouched for %s", + async (_name, path) => { + const before = await stat(path); + const outputPath = join(outDir, "edited.cdb"); + + await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath, + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); - it.each( - saveFixtures, - )("refuses to overwrite an existing output file for %s", async (_name, path) => { - const outputPath = join(outDir, "edited.cdb"); - // First write succeeds and creates the file. - const first = await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath, - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); - expect(first.isError).toBeUndefined(); + const after = await stat(path); + expect(after.size).toBe(before.size); + expect(after.mtimeMs).toBe(before.mtimeMs); + }, + ); + + it.each(saveFixtures)( + "refuses to overwrite the source save for %s", + async (_name, path) => { + const result = await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath: path, + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); - // A second write to the same path must not clobber it. - const second = await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath, - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); - expect(second.isError).toBe(true); - expect(second.content[0]).toEqual({ - type: "text", - text: expect.stringMatching(/already exists/), - }); - }); + expect(result.isError).toBe(true); + expect(result.content[0]).toEqual({ + type: "text", + text: "outputPath must differ from the source save — the input .cdb is never overwritten.", + }); + }, + ); + + it.each(saveFixtures)( + "rejects a non-.cdb output path for %s", + async (_name, path) => { + const result = await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath: join(outDir, "edited.txt"), + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); - it.each( - saveFixtures, - )("errors when the output directory does not exist for %s", async (_name, path) => { - const result = await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath: join(outDir, "missing", "edited.cdb"), - statement: "UPDATE GAM_config SET gene_i_date = 20991231", - }); + expect(result.isError).toBe(true); + expect(result.content[0]).toEqual({ + type: "text", + text: expect.stringMatching(/must be a \.cdb file/), + }); + }, + ); + + it.each(saveFixtures)( + "refuses to overwrite an existing output file for %s", + async (_name, path) => { + const outputPath = join(outDir, "edited.cdb"); + // First write succeeds and creates the file. + const first = await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath, + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); + expect(first.isError).toBeUndefined(); - expect(result.isError).toBe(true); - expect(result.content[0]).toEqual({ - type: "text", - text: expect.stringMatching(/Output directory does not exist/), - }); - }); + // A second write to the same path must not clobber it. + const second = await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath, + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); + expect(second.isError).toBe(true); + expect(second.content[0]).toEqual({ + type: "text", + text: expect.stringMatching(/already exists/), + }); + }, + ); + + it.each(saveFixtures)( + "errors when the output directory does not exist for %s", + async (_name, path) => { + const result = await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath: join(outDir, "missing", "edited.cdb"), + statement: "UPDATE GAM_config SET gene_i_date = 20991231", + }); - it.each( - saveFixtures, - )("maps a missing table to a schema-discovery hint for %s", async (_name, path) => { - const result = await mcp.callTool("pcm_update_save", { - savePath: path, - outputPath: join(outDir, "edited.cdb"), - statement: "UPDATE not_a_table SET x = 1", - }); + expect(result.isError).toBe(true); + expect(result.content[0]).toEqual({ + type: "text", + text: expect.stringMatching(/Output directory does not exist/), + }); + }, + ); + + it.each(saveFixtures)( + "maps a missing table to a schema-discovery hint for %s", + async (_name, path) => { + const result = await mcp.callTool("pcm_update_save", { + savePath: path, + outputPath: join(outDir, "edited.cdb"), + statement: "UPDATE not_a_table SET x = 1", + }); - expect(result.isError).toBe(true); - expect(result.content[0]).toEqual({ - type: "text", - text: 'Table "not_a_table" does not exist in this save — use pcm_get_save_schema to list available tables.', - }); - }); + expect(result.isError).toBe(true); + expect(result.content[0]).toEqual({ + type: "text", + text: 'Table "not_a_table" does not exist in this save — use pcm_get_save_schema to list available tables.', + }); + }, + ); describe("assertWriteStatement", () => { describe("allowed statements", () => {