diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 87ac5b4d..b95c92b5 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -7,12 +7,14 @@ "type": "npm", "script": "webpack-dev", "problemMatcher": "$ts-webpack-watch", + "isBackground": false, + "presentation": { "reveal": "never" }, "group": { "kind": "build", - "isDefault": true + "isDefault": true, } } ] diff --git a/package-lock.json b/package-lock.json index 5af274c1..cda89eb0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,26 +1,28 @@ { "name": "vscode-db2i", - "version": "1.4.1", + "version": "1.5.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-db2i", - "version": "1.4.1", + "version": "1.5.2", "dependencies": { "@ibm/mapepire-js": "^0.3.0", "chart.js": "^4.4.2", "csv": "^6.1.3", "json-to-markdown-table": "^1.0.0", + "lru-cache": "^6.0.0", "node-fetch": "^3.3.1", + "ollama": "^0.5.2", "showdown": "^2.1.0", "sql-formatter": "^14.0.0" }, "devDependencies": { - "@halcyontech/vscode-ibmi-types": "^2.12.1", + "@halcyontech/vscode-ibmi-types": "^2.0.0", "@types/glob": "^7.1.3", "@types/node": "14.x", - "@types/vscode": "^1.70.0", + "@types/vscode": "^1.90.0", "esbuild-loader": "^3.0.1", "eslint": "^7.32.0", "glob": "^7.1.7", @@ -29,13 +31,12 @@ "ts-loader": "^9.3.1", "typescript": "^4.3.2", "vitest": "^0.33.0", - "vscd": "^1.0.0", "vscode-test": "^1.5.2", "webpack": "^5.91.0", "webpack-cli": "^4.5.0" }, "engines": { - "vscode": "^1.70.0" + "vscode": "^1.90.0" } }, "node_modules/@babel/code-frame": { @@ -150,10 +151,26 @@ "node": ">=10.0.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz", - "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", "cpu": [ "arm" ], @@ -167,9 +184,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz", - "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", "cpu": [ "arm64" ], @@ -183,9 +200,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz", - "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", "cpu": [ "x64" ], @@ -199,9 +216,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz", - "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", "cpu": [ "arm64" ], @@ -215,9 +232,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz", - "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "cpu": [ "x64" ], @@ -231,9 +248,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz", - "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", "cpu": [ "arm64" ], @@ -247,9 +264,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz", - "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", "cpu": [ "x64" ], @@ -263,9 +280,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz", - "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", "cpu": [ "arm" ], @@ -279,9 +296,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz", - "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", "cpu": [ "arm64" ], @@ -295,9 +312,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz", - "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", "cpu": [ "ia32" ], @@ -311,9 +328,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz", - "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", "cpu": [ "loong64" ], @@ -327,9 +344,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz", - "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "cpu": [ "mips64el" ], @@ -343,9 +360,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz", - "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "cpu": [ "ppc64" ], @@ -359,9 +376,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz", - "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "cpu": [ "riscv64" ], @@ -375,9 +392,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz", - "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", "cpu": [ "s390x" ], @@ -391,9 +408,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz", - "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "cpu": [ "x64" ], @@ -407,9 +424,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz", - "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", "cpu": [ "x64" ], @@ -423,9 +440,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz", - "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", "cpu": [ "x64" ], @@ -439,9 +456,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz", - "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", "cpu": [ "x64" ], @@ -455,9 +472,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz", - "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", "cpu": [ "arm64" ], @@ -471,9 +488,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz", - "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", "cpu": [ "ia32" ], @@ -487,9 +504,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz", - "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "cpu": [ "x64" ], @@ -559,73 +576,6 @@ "so": "dist/index.js" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1058,16 +1008,6 @@ "integrity": "sha512-y92CpG4kFFtBBjni8LHoV12IegJ+KFxLgKRengrVjKmGE5XMeCuGvlfRe75lTRrgXaG6XIWJlFpIDTlkoJsU8w==", "dev": true }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1154,9 +1094,9 @@ "dev": true }, "node_modules/@types/vscode": { - "version": "1.77.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.77.0.tgz", - "integrity": "sha512-MWFN5R7a33n8eJZJmdVlifjig3LWUNRrPeO1xemIcZ0ae0TEQuRc7G2xV0LUX78RZFECY1plYBn+dP/Acc3L0Q==", + "version": "1.90.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.90.0.tgz", + "integrity": "sha512-oT+ZJL7qHS9Z8bs0+WKf/kQ27qWYR3trsXpq46YDjFqBsMLG4ygGGjPaJ2tyrH0wJzjOEmDyg9PDJBBhWg9pkQ==", "dev": true }, "node_modules/@vitest/expect": { @@ -2010,12 +1950,6 @@ "readable-stream": "^2.0.2" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -2090,9 +2024,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz", - "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, "hasInstallScript": true, "bin": { @@ -2102,38 +2036,39 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.15", - "@esbuild/android-arm64": "0.17.15", - "@esbuild/android-x64": "0.17.15", - "@esbuild/darwin-arm64": "0.17.15", - "@esbuild/darwin-x64": "0.17.15", - "@esbuild/freebsd-arm64": "0.17.15", - "@esbuild/freebsd-x64": "0.17.15", - "@esbuild/linux-arm": "0.17.15", - "@esbuild/linux-arm64": "0.17.15", - "@esbuild/linux-ia32": "0.17.15", - "@esbuild/linux-loong64": "0.17.15", - "@esbuild/linux-mips64el": "0.17.15", - "@esbuild/linux-ppc64": "0.17.15", - "@esbuild/linux-riscv64": "0.17.15", - "@esbuild/linux-s390x": "0.17.15", - "@esbuild/linux-x64": "0.17.15", - "@esbuild/netbsd-x64": "0.17.15", - "@esbuild/openbsd-x64": "0.17.15", - "@esbuild/sunos-x64": "0.17.15", - "@esbuild/win32-arm64": "0.17.15", - "@esbuild/win32-ia32": "0.17.15", - "@esbuild/win32-x64": "0.17.15" + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "node_modules/esbuild-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-3.0.1.tgz", - "integrity": "sha512-aZfGybqTeuyCd4AsVvWOOfkhIuN+wfZFjMyh3gyQEU1Uvsl8L6vye9HqP93iRa0iTA+6Jclap514PJIC3cLnMA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-3.2.0.tgz", + "integrity": "sha512-lnIdRMQpk50alCa0QoW0ozc0D3rjJXl02mtMsk9INIcW25RPZhDja332bu85ixwVNbhQ7VfBRcQyZ/qza8mWiA==", "dev": true, "dependencies": { - "esbuild": "^0.17.6", - "get-tsconfig": "^4.4.0", + "esbuild": "^0.19.0", + "get-tsconfig": "^4.6.2", "loader-utils": "^2.0.4", "webpack-sources": "^1.4.3" }, @@ -2495,34 +2430,6 @@ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -2626,10 +2533,13 @@ } }, "node_modules/get-tsconfig": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.5.0.tgz", - "integrity": "sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, "funding": { "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } @@ -2933,24 +2843,6 @@ "node": ">=0.10.0" } }, - "node_modules/jackspeak": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", - "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -3227,7 +3119,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -3317,15 +3208,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -3498,6 +3380,14 @@ "node": ">= 18" } }, + "node_modules/ollama": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/ollama/-/ollama-0.5.2.tgz", + "integrity": "sha512-nH9WEU8lGxX2RhTH9TukjwrQBlyoprIh8wIGMfFlprgzzJgAr+MFFmHzCt7BZt4SMFMXVwM2xnKrfshfHkBLyQ==", + "dependencies": { + "whatwg-fetch": "^3.6.20" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3563,12 +3453,6 @@ "node": ">=6" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3614,31 +3498,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", - "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", - "dev": true, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/pathe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", @@ -3987,6 +3846,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -4011,9 +3879,9 @@ } }, "node_modules/rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -4283,21 +4151,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4310,19 +4163,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -4722,9 +4562,9 @@ "dev": true }, "node_modules/vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", + "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", "dev": true, "dependencies": { "esbuild": "^0.18.10", @@ -5277,80 +5117,6 @@ "node": ">=0.4.0" } }, - "node_modules/vscd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vscd/-/vscd-1.0.0.tgz", - "integrity": "sha512-RdLCxxjFLNYRfYmun4C1WFPoILS/lXb2o1NYh4KKZI501Er12uL6OR0BTRzpRUEyF81ACslLjHhbrWig1SIDgA==", - "dev": true, - "dependencies": { - "glob": "^11.0.0", - "ts-loader": "^9.5.1", - "typescript": "^5.5.4" - }, - "bin": { - "vscd": "dist/index.js" - } - }, - "node_modules/vscd/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/vscd/node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/vscd/node_modules/minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/vscd/node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/vscode-test": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.6.1.tgz", @@ -5528,6 +5294,11 @@ "acorn": "^8" } }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5574,103 +5345,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -5700,8 +5374,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yocto-queue": { "version": "1.0.0", @@ -5807,157 +5480,164 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "dev": true, + "optional": true + }, "@esbuild/android-arm": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz", - "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz", - "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz", - "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz", - "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz", - "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz", - "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz", - "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz", - "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz", - "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz", - "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz", - "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz", - "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz", - "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz", - "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz", - "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz", - "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz", - "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz", - "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz", - "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz", - "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz", - "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz", - "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "dev": true, "optional": true }, @@ -6009,54 +5689,6 @@ "ws": "^8.16.0" } }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, "@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -6396,13 +6028,6 @@ "integrity": "sha512-y92CpG4kFFtBBjni8LHoV12IegJ+KFxLgKRengrVjKmGE5XMeCuGvlfRe75lTRrgXaG6XIWJlFpIDTlkoJsU8w==", "dev": true }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, "@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -6486,9 +6111,9 @@ "dev": true }, "@types/vscode": { - "version": "1.77.0", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.77.0.tgz", - "integrity": "sha512-MWFN5R7a33n8eJZJmdVlifjig3LWUNRrPeO1xemIcZ0ae0TEQuRc7G2xV0LUX78RZFECY1plYBn+dP/Acc3L0Q==", + "version": "1.90.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.90.0.tgz", + "integrity": "sha512-oT+ZJL7qHS9Z8bs0+WKf/kQ27qWYR3trsXpq46YDjFqBsMLG4ygGGjPaJ2tyrH0wJzjOEmDyg9PDJBBhWg9pkQ==", "dev": true }, "@vitest/expect": { @@ -7159,12 +6784,6 @@ "readable-stream": "^2.0.2" } }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "ecdsa-sig-formatter": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", @@ -7224,43 +6843,44 @@ "dev": true }, "esbuild": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz", - "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.17.15", - "@esbuild/android-arm64": "0.17.15", - "@esbuild/android-x64": "0.17.15", - "@esbuild/darwin-arm64": "0.17.15", - "@esbuild/darwin-x64": "0.17.15", - "@esbuild/freebsd-arm64": "0.17.15", - "@esbuild/freebsd-x64": "0.17.15", - "@esbuild/linux-arm": "0.17.15", - "@esbuild/linux-arm64": "0.17.15", - "@esbuild/linux-ia32": "0.17.15", - "@esbuild/linux-loong64": "0.17.15", - "@esbuild/linux-mips64el": "0.17.15", - "@esbuild/linux-ppc64": "0.17.15", - "@esbuild/linux-riscv64": "0.17.15", - "@esbuild/linux-s390x": "0.17.15", - "@esbuild/linux-x64": "0.17.15", - "@esbuild/netbsd-x64": "0.17.15", - "@esbuild/openbsd-x64": "0.17.15", - "@esbuild/sunos-x64": "0.17.15", - "@esbuild/win32-arm64": "0.17.15", - "@esbuild/win32-ia32": "0.17.15", - "@esbuild/win32-x64": "0.17.15" + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "esbuild-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-3.0.1.tgz", - "integrity": "sha512-aZfGybqTeuyCd4AsVvWOOfkhIuN+wfZFjMyh3gyQEU1Uvsl8L6vye9HqP93iRa0iTA+6Jclap514PJIC3cLnMA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-3.2.0.tgz", + "integrity": "sha512-lnIdRMQpk50alCa0QoW0ozc0D3rjJXl02mtMsk9INIcW25RPZhDja332bu85ixwVNbhQ7VfBRcQyZ/qza8mWiA==", "dev": true, "requires": { - "esbuild": "^0.17.6", - "get-tsconfig": "^4.4.0", + "esbuild": "^0.19.0", + "get-tsconfig": "^4.6.2", "loader-utils": "^2.0.4", "webpack-sources": "^1.4.3" }, @@ -7531,24 +7151,6 @@ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, - "foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "dependencies": { - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } - } - }, "formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -7623,10 +7225,13 @@ "dev": true }, "get-tsconfig": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.5.0.tgz", - "integrity": "sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==", - "dev": true + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } }, "glob": { "version": "7.2.0", @@ -7843,16 +7448,6 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true }, - "jackspeak": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.1.tgz", - "integrity": "sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, "jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -8091,7 +7686,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -8157,12 +7751,6 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, - "minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true - }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -8280,6 +7868,14 @@ "@octokit/types": "^12.0.0" } }, + "ollama": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/ollama/-/ollama-0.5.2.tgz", + "integrity": "sha512-nH9WEU8lGxX2RhTH9TukjwrQBlyoprIh8wIGMfFlprgzzJgAr+MFFmHzCt7BZt4SMFMXVwM2xnKrfshfHkBLyQ==", + "requires": { + "whatwg-fetch": "^3.6.20" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -8327,12 +7923,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -8366,24 +7956,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-scurry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", - "dev": true, - "requires": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "dependencies": { - "lru-cache": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", - "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", - "dev": true - } - } - }, "pathe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz", @@ -8638,6 +8210,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -8653,9 +8231,9 @@ } }, "rollup": { - "version": "3.29.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", - "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "version": "3.29.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", + "integrity": "sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -8860,17 +8438,6 @@ "strip-ansi": "^6.0.1" } }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -8880,15 +8447,6 @@ "ansi-regex": "^5.0.1" } }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -9165,9 +8723,9 @@ "dev": true }, "vite": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz", - "integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==", + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.5.tgz", + "integrity": "sha512-ifW3Lb2sMdX+WU91s3R0FyQlAyLxOzCSCP37ujw0+r5POeHPwe6udWVIElKQq8gk3t7b8rkmvqC6IHBpCff4GQ==", "dev": true, "requires": { "esbuild": "^0.18.10", @@ -9416,57 +8974,6 @@ } } }, - "vscd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/vscd/-/vscd-1.0.0.tgz", - "integrity": "sha512-RdLCxxjFLNYRfYmun4C1WFPoILS/lXb2o1NYh4KKZI501Er12uL6OR0BTRzpRUEyF81ACslLjHhbrWig1SIDgA==", - "dev": true, - "requires": { - "glob": "^11.0.0", - "ts-loader": "^9.5.1", - "typescript": "^5.5.4" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^4.0.1", - "minimatch": "^10.0.0", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - } - }, - "minimatch": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", - "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "dev": true - } - } - }, "vscode-test": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-1.6.1.tgz", @@ -9584,6 +9091,11 @@ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true }, + "whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==" + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9615,68 +9127,6 @@ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -9692,8 +9142,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yocto-queue": { "version": "1.0.0", diff --git a/package.json b/package.json index 4aaff651..4fc8523a 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,9 @@ "name": "vscode-db2i", "displayName": "Db2 for IBM i", "description": "Db2 for IBM i tools in VS Code", - "version": "1.5.1", + "version": "1.5.2", "engines": { - "vscode": "^1.70.0" + "vscode": "^1.90.0" }, "icon": "media/logo.png", "keywords": [ @@ -28,7 +28,8 @@ "onLanguage:sql" ], "extensionDependencies": [ - "halcyontechltd.code-for-ibmi" + "halcyontechltd.code-for-ibmi", + "github.copilot-chat" ], "main": "./dist/extension.js", "scripts": { @@ -37,39 +38,31 @@ "language:test": "vitest", "dsc": "mkdir -p dist && npx tsx src/dsc", "package": "vsce package", - "vscode:prepublish": "rm -rf dist && npm run webpack && npm run dsc", - "webpack": "vscd --clean && webpack --mode development", - "webpack-dev": "vscd --clean && webpack --mode development", + "vscode:prepublish": "rm -rf dist && webpack --mode production && npm run dsc", + "webpack": "webpack --mode development", + "webpack-dev": "webpack --mode development", "typings": "npx -p typescript tsc ./src/extension.ts --declaration --allowJs --emitDeclarationOnly --outDir types --esModuleInterop -t es2019 --moduleResolution node" }, - "devDependencies": { - "@halcyontech/vscode-ibmi-types": "^2.12.1", - "@types/glob": "^7.1.3", - "@types/node": "14.x", - "@types/vscode": "^1.70.0", - "esbuild-loader": "^3.0.1", - "eslint": "^7.32.0", - "glob": "^7.1.7", - "octokit": "^3.1.2", - "raw-loader": "^4.0.2", - "ts-loader": "^9.3.1", - "typescript": "^4.3.2", - "vitest": "^0.33.0", - "vscd": "^1.0.0", - "vscode-test": "^1.5.2", - "webpack": "^5.91.0", - "webpack-cli": "^4.5.0" - }, - "dependencies": { - "@ibm/mapepire-js": "^0.3.0", - "chart.js": "^4.4.2", - "csv": "^6.1.3", - "json-to-markdown-table": "^1.0.0", - "node-fetch": "^3.3.1", - "showdown": "^2.1.0", - "sql-formatter": "^14.0.0" - }, "contributes": { + "chatParticipants": [ + { + "id": "vscode-db2i.chat", + "name": "db2i", + "fullName": "Db2 for i", + "description": "Chat with the Db2 for i AI assistant", + "isSticky": true, + "commands": [ + { + "name": "build", + "description": "Build an SQL statement" + }, + { + "name": "activity", + "description": "Summarize the activity on the system" + } + ] + } + ], "configuration": [ { "id": "vscode-db2i", @@ -128,6 +121,33 @@ } } }, + { + "id": "vscode-db2i.ai", + "title": "Db2 for IBM i with AI", + "properties": { + "vscode-db2i.ai.provider": { + "order": 0, + "type": "string", + "description": "Model Provider", + "default": "none", + "enum": [ + "none", + "Ollama", + "GitHub Copilot" + ], + "enumDescriptions": [ + "Ollama instance, with specific model", + "GitHub Copilot. Requires the GitHub Copilot extension to be installed" + ] + }, + "vscode-db2i.ai.model": { + "order": 1, + "type": "string", + "description": "Model to use with the provider", + "default": "ibm-granite" + } + } + }, { "id": "vscode-db2i.resultsets", "title": "Viewing Data", @@ -306,6 +326,24 @@ ] }, "commands": [ + { + "command": "vscode-db2i.ai.changeModel", + "title": "Change AI Model", + "category": "Db2 for i" + }, + { + "command": "vscode-db2i.notebook.open", + "title": "New Notebook", + "category": "IBM i Notebooks", + "enablement": "code-for-ibmi:connected == true", + "icon": "$(notebook)" + }, + { + "command": "vscode-db2i.notebook.fromSqlUri", + "title": "Open as Notebook", + "category": "IBM i Notebooks", + "icon": "$(notebook)" + }, { "command": "vscode-db2i.json.pasteGenerator", "title": "Paste JSON as SQL", @@ -1225,6 +1263,18 @@ } ], "snippets": [ + { + "language": "sql", + "path": "snippets/scalars.code-snippets" + }, + { + "language": "sql", + "path": "snippets/variables.code-snippets" + }, + { + "language": "sql", + "path": "snippets/aggregates.code-snippets" + }, { "language": "sql", "path": "snippets/http.code-snippets" @@ -1246,5 +1296,33 @@ "path": "snippets/aggregates.code-snippets" } ] + }, + "devDependencies": { + "@halcyontech/vscode-ibmi-types": "^2.0.0", + "@types/glob": "^7.1.3", + "@types/node": "14.x", + "@types/vscode": "^1.90.0", + "esbuild-loader": "^3.0.1", + "eslint": "^7.32.0", + "glob": "^7.1.7", + "octokit": "^3.1.2", + "raw-loader": "^4.0.2", + "ts-loader": "^9.3.1", + "typescript": "^4.3.2", + "vitest": "^0.33.0", + "vscode-test": "^1.5.2", + "webpack": "^5.91.0", + "webpack-cli": "^4.5.0" + }, + "dependencies": { + "@ibm/mapepire-js": "^0.3.0", + "chart.js": "^4.4.2", + "csv": "^6.1.3", + "json-to-markdown-table": "^1.0.0", + "lru-cache": "^6.0.0", + "node-fetch": "^3.3.1", + "ollama": "^0.5.2", + "showdown": "^2.1.0", + "sql-formatter": "^14.0.0" } } diff --git a/src/chat/aiConfig.ts b/src/chat/aiConfig.ts new file mode 100644 index 00000000..21a69e85 --- /dev/null +++ b/src/chat/aiConfig.ts @@ -0,0 +1,25 @@ +import Configuration from "../configuration"; + +/** + * Matches config vscode-db2i.ai.provider + */ +export type AiProvider = "none"|"Ollama"|"GitHub Copilot"; + +export class AiConfig { + + static getProvider(): AiProvider { + return Configuration.get(`ai.provider`); + } + + static getModel(): string { + return Configuration.get("ai.model"); + } + + static setProvider(provider: AiProvider) { + return Configuration.set(`ai.provider`, provider); + } + + static setModel(model: string) { + return Configuration.set(`ai.model`, model); + } +} \ No newline at end of file diff --git a/src/chat/chat.ts b/src/chat/chat.ts new file mode 100644 index 00000000..2b0b55b9 --- /dev/null +++ b/src/chat/chat.ts @@ -0,0 +1,218 @@ +import ollama, { ListResponse } from "ollama"; +import * as vscode from "vscode"; +import Statement from "../database/statement"; +import { AiConfig, AiProvider } from "./aiConfig"; +import { + canTalkToDb, + findPossibleTables, + getDefaultSchema, + getSystemStatus, + refsToMarkdown, +} from "./context"; +import { chatRequest } from "./send"; + +const CHAT_ID = `vscode-db2i.chat`; + +interface IDB2ChatResult extends vscode.ChatResult { + metadata: { + command: string; + }; +} + +interface ModelQuickPickItem extends vscode.QuickPickItem { + provider: AiProvider; + family: string; +} + +export function activateChat(context: vscode.ExtensionContext) { + // chatHandler deals with the input from the chat windows, + // and uses streamModelResponse to send the response back to the chat window + const chatHandler: vscode.ChatRequestHandler = async ( + request: vscode.ChatRequest, + context: vscode.ChatContext, + stream: vscode.ChatResponseStream, + token: vscode.CancellationToken + ): Promise => { + let messages: vscode.LanguageModelChatMessage[]; + + if (canTalkToDb()) { + const usingSchema = getDefaultSchema(); + + switch (request.command) { + case `activity`: + stream.progress(`Grabbing Information about IBM i system`); + const data = await getSystemStatus(); + console.log( + `summarize the following data in a readable paragraph: ${data}` + ); + messages = [ + vscode.LanguageModelChatMessage.User( + `You are a an IBM i savant speciallizing in database features in Db2 for i. Please provide a summary of the current IBM i system state based on the developer requirement.` + ), + vscode.LanguageModelChatMessage.User( + `Here is the current IBM i state: ${data}` + ), + vscode.LanguageModelChatMessage.User(request.prompt), + ]; + + await streamModelResponse(messages, stream, token); + + return { metadata: { command: "activity" } }; + + default: + stream.progress( + `Getting information from ${Statement.prettyName(usingSchema)}...` + ); + let refs = await findPossibleTables( + stream, + usingSchema, + request.prompt.split(` `) + ); + + messages = [ + vscode.LanguageModelChatMessage.Assistant( + `You are a an IBM i savant speciallizing in database features in Db2 for i. Your job is to help developers write and debug their SQL along with offering SQL programming advice.` + ), + vscode.LanguageModelChatMessage.Assistant( + `The developers current schema is ${usingSchema}.` + ), + vscode.LanguageModelChatMessage.Assistant( + `Provide the developer with SQL statements or relevant information based on the user's prompt and referenced table structures. Always include practical code examples where applicable. Ensure all suggestions are directly applicable to the structures and data provided and avoid making suggestions outside the scope of the available information.` + ), + ]; + + if (context.history.length > 0) { + messages.push(...context.history.map(h => { + if ('prompt' in h) { + return vscode.LanguageModelChatMessage.Assistant(h.prompt); + } else { + return vscode.LanguageModelChatMessage.Assistant( + h.response.filter(r => 'value' in r.value).map(r => r.value.value).join(`\n\n`) + ); + } + })); + + messages = messages.filter(m => m.content.trim().length > 0); + } + + if (Object.keys(refs).length > 0) { + messages.push( + vscode.LanguageModelChatMessage.Assistant( + `Here are new table references ${JSON.stringify(refs)}` + ), + ); + } + + stream.progress(`Building response...`); + + messages.push(vscode.LanguageModelChatMessage.User(request.prompt)) + + await streamModelResponse(messages, stream, token); + + return { metadata: { command: "build" } }; + } + } else { + throw new Error( + `Not connected to the database. Please check your configuration.` + ); + } + }; + + const chat = vscode.chat.createChatParticipant(CHAT_ID, chatHandler); + chat.iconPath = new vscode.ThemeIcon(`database`); + + const changeModelCommand = vscode.commands.registerCommand( + `vscode-db2i.ai.changeModel`, + selectProviderAndModel + ); + + context.subscriptions.push(chat, changeModelCommand); +} + +let lastSelectedModel: string | null = null; + +async function showModelProviderIfNeeded( + stream: vscode.ChatResponseStream, + chosenProvider: AiProvider, + chosenModel: string +) { + const currentModel = AiConfig.getModel(); + + if (lastSelectedModel === null || lastSelectedModel !== currentModel) { + stream.markdown( + `**Provider👨‍💻:** ${chosenProvider}\n\n**Model🧠:** ${chosenModel}\n\n***\n\n` + ); + lastSelectedModel = currentModel; + } +} + +async function streamModelResponse( + messages: vscode.LanguageModelChatMessage[], + stream: vscode.ChatResponseStream, + token: vscode.CancellationToken +) { + const chosenProvider = AiConfig.getProvider(); + const chosenModel = AiConfig.getModel(); + + if (chosenProvider === `none`) { + stream.markdown( + `No AI provider selected. Please select an AI provider and model.` + ); + stream.button({ + command: `vscode-db2i.ai.changeModel`, + title: `Select AI Provider and Model`, + }); + return; + } + + showModelProviderIfNeeded(stream, chosenProvider, chosenModel); + stream.progress(`Provider: ${chosenProvider} Model: ${chosenModel}`); + + return chatRequest(chosenProvider, messages, {}, token, stream); +} + +async function selectProviderAndModel() { + const selected = AiConfig.getModel(); + const copilotModels = await vscode.lm.selectChatModels(); + let ollamaModels: ListResponse = { models: [] }; + + // try { + // ollamaModels = await ollama.list(); + // } catch (e) {} + + const provider = await vscode.window.showQuickPick( + [ + { kind: vscode.QuickPickItemKind.Separator, label: "Ollama Models" }, + ...ollamaModels.models.map( + (model): ModelQuickPickItem => ({ + label: model.name, + family: model.name, + provider: "Ollama", + iconPath: new vscode.ThemeIcon("heart"), + description: selected === model.name ? "Selected" : "", + }) + ), + { + kind: vscode.QuickPickItemKind.Separator, + label: "GitHub Copilot Models", + }, + ...copilotModels.map( + (model): ModelQuickPickItem => ({ + label: model.name, + family: model.family, + provider: "GitHub Copilot", + iconPath: new vscode.ThemeIcon("copilot"), + description: selected === model.family ? "Selected" : "", + }) + ), + ], + { + title: "Select the AI model", + } + ); + + if (provider && "provider" in provider && "family" in provider) { + AiConfig.setProvider(provider.provider); + AiConfig.setModel(provider.family); + } +} diff --git a/src/chat/context.ts b/src/chat/context.ts new file mode 100644 index 00000000..5c622670 --- /dev/null +++ b/src/chat/context.ts @@ -0,0 +1,178 @@ +import { JobManager } from "../config"; +import * as vscode from "vscode"; +import Statement from "../database/statement"; + +export function canTalkToDb() { + return JobManager.getSelection() !== undefined; +} + +export function getDefaultSchema(): string { + const currentJob = JobManager.getSelection(); + return currentJob && currentJob.job.options.libraries[0] + ? currentJob.job.options.libraries[0] + : `QGPL`; +}; + +export type TableRefs = { [key: string]: TableColumn[] }; + +export async function getTableMetaData(schema: string, tableName: string): Promise { + const objectFindStatement = [ + `SELECT `, + ` column.TABLE_NAME,`, + ` column.COLUMN_NAME,`, + ` key.CONSTRAINT_NAME,`, + ` column.DATA_TYPE, `, + ` column.CHARACTER_MAXIMUM_LENGTH,`, + ` column.NUMERIC_SCALE, `, + ` column.NUMERIC_PRECISION,`, + ` column.IS_NULLABLE, `, + // ` column.HAS_DEFAULT, `, + // ` column.COLUMN_DEFAULT, `, + ` column.COLUMN_TEXT, `, + ` column.IS_IDENTITY`, + `FROM QSYS2.SYSCOLUMNS2 as column`, + `LEFT JOIN QSYS2.syskeycst as key`, + ` on `, + ` column.table_schema = key.table_schema and`, + ` column.table_name = key.table_name and`, + ` column.column_name = key.column_name`, + `WHERE column.TABLE_SCHEMA = '${Statement.delimName(schema, true)}'`, + `AND column.TABLE_NAME = '${Statement.delimName(tableName, true)}'`, + `ORDER BY column.ORDINAL_POSITION`, + ].join(` `); + + return await JobManager.runSQL(objectFindStatement); +} + +export async function parsePromptForRefs(stream: vscode.ChatResponseStream, prompt: string[]): Promise { + const tables: TableRefs = {}; + for (const word of prompt) { + const [schema, table] = word.split(`.`); + const cleanedTable = table.replace(/[,\/#!?$%\^&\*;:{}=\-_`~()]/g, ""); + if (schema && cleanedTable) { + stream.progress(`looking up information for ${schema}.${cleanedTable}`) + const data = await getTableMetaData(schema, cleanedTable); + tables[cleanedTable] = tables[cleanedTable] || []; + tables[cleanedTable].push(...data); + } + } + return tables; +} + +export async function findPossibleTables(stream: vscode.ChatResponseStream, schema: string, words: string[]) { + + let tables: TableRefs = {} + + // parse all SCHEMA.TABLE references first + tables = await parsePromptForRefs(stream, words.filter(word => word.includes('.'))); + + const justWords = words.map(word => word.replace(/[,\/#!?$%\^&\*;:{}=\-_`~()]/g, "")); + + // Remove plurals from words + justWords.push(...justWords.filter(word => word.endsWith('s')).map(word => word.slice(0, -1))); + + // filter prompt for possible refs to tables + const validWords = justWords + .filter(word => word.length > 2 && !word.endsWith('s') && !word.includes(`'`)) + .map(word => `'${Statement.delimName(word, true)}'`); + + const objectFindStatement = [ + `SELECT `, + ` column.TABLE_NAME,`, + ` column.COLUMN_NAME,`, + ` key.CONSTRAINT_NAME,`, + ` column.DATA_TYPE, `, + ` column.CHARACTER_MAXIMUM_LENGTH,`, + ` column.NUMERIC_SCALE, `, + ` column.NUMERIC_PRECISION,`, + ` column.IS_NULLABLE, `, + // ` column.HAS_DEFAULT, `, + // ` column.COLUMN_DEFAULT, `, + ` column.COLUMN_TEXT, `, + ` column.IS_IDENTITY`, + `FROM QSYS2.SYSCOLUMNS2 as column`, + `LEFT JOIN QSYS2.syskeycst as key`, + ` on `, + ` column.table_schema = key.table_schema and`, + ` column.table_name = key.table_name and`, + ` column.column_name = key.column_name`, + `WHERE column.TABLE_SCHEMA = '${schema}'`, + ...[ + words.length > 0 + ? `AND column.TABLE_NAME in (${validWords.join(`, `)})` + : ``, + ], + `ORDER BY column.ORDINAL_POSITION`, + ].join(` `); + + // TODO + const result: TableColumn[] = await JobManager.runSQL(objectFindStatement); + + result.forEach(row => { + if (!tables[row.TABLE_NAME]) tables[row.TABLE_NAME] = []; + tables[row.TABLE_NAME].push(row); + }); + return tables; +} + + +/** + * Converts a given set of table references to a Markdown string. + * + * Experimental feature for @db2i chat participant + * + * @param refs - An object containing table references, where each key is a table name + * and the value is an array of column definitions for that table. + * + * @returns A string formatted in Markdown representing the table references. + * + * The function generates a Markdown representation of the table references. If the number + * of tables is greater than 5, a condensed format is used, otherwise a detailed format is used. + * + * The condensed format includes columns: Column, Type, and Text. + * The detailed format includes columns: Column, Type, Nullable, Identity, Text, and Constraint. + * + * Tables with names starting with 'SYS' are skipped. + */ +export function refsToMarkdown(refs: TableRefs) { + const condensedResult = Object.keys(refs).length > 5; + + let markdown: string[] = []; + + for (const tableName in refs) { + if (tableName.startsWith(`SYS`)) continue; + + markdown.push(`# ${tableName}`, ``); + + if (condensedResult) { + markdown.push(`| Column | Type | Text |`); + markdown.push(`| - | - | - |`); + } else { + markdown.push( + `| Column | Type | Nullable | Identity | Text | Constraint |` + ); + markdown.push(`| - | - | - | - | - | - |`); + } + for (const column of refs[tableName]) { + if (condensedResult) { + markdown.push( + `| ${column.COLUMN_NAME} | ${column.DATA_TYPE} | ${column.COLUMN_TEXT} |` + ); + } else { + markdown.push( + `| ${column.COLUMN_NAME} | ${column.DATA_TYPE} | ${column.IS_NULLABLE} | ${column.IS_IDENTITY} | ${column.COLUMN_TEXT} | ${column.CONSTRAINT_NAME} |` + ); + } + } + + markdown.push(``); + } + + return markdown.join(`\n`); +} + +export async function getSystemStatus(): Promise { + const sqlStatment = `SELECT * FROM TABLE(QSYS2.SYSTEM_STATUS(RESET_STATISTICS=>'YES',DETAILED_INFO=>'ALL')) X`; + const result = await JobManager.runSQL(sqlStatment, undefined); + return JSON.stringify(result); +} \ No newline at end of file diff --git a/src/chat/send.ts b/src/chat/send.ts new file mode 100644 index 00000000..5e55005c --- /dev/null +++ b/src/chat/send.ts @@ -0,0 +1,69 @@ +import * as vscode from "vscode"; +import ollama from "ollama"; +import { + CancellationToken, + LanguageModelChatMessage, + LanguageModelChatRequestOptions, + LanguageModelChatResponse, +} from "vscode"; +import { AiConfig, AiProvider } from "./aiConfig"; + +export function chatRequest( + provider: AiProvider, + messages: LanguageModelChatMessage[], + options: LanguageModelChatRequestOptions, + token: CancellationToken, + stream: vscode.ChatResponseStream +): Promise { + const chosenModel = AiConfig.getModel(); + + switch (provider) { + case "Ollama": + return ollamaRequest(chosenModel, messages, stream); + case "GitHub Copilot": + return copilotRequest(chosenModel, messages, options, token, stream); + } +} + +async function copilotRequest( + model: string, + messages: LanguageModelChatMessage[], + options: LanguageModelChatRequestOptions, + token: CancellationToken, + stream: vscode.ChatResponseStream +): Promise { + const models = await vscode.lm.selectChatModels({ family: model }); + if (models.length > 0) { + const [first] = models; + const response = await first.sendRequest(messages, options, token); + + for await (const fragment of response.text) { + stream.markdown(fragment); + } + } +} + +async function ollamaRequest( + model: string, + messages: LanguageModelChatMessage[], + stream: vscode.ChatResponseStream +): Promise { + const chats = []; + for (const message of messages) { + chats.push({ + role: "user", + content: message.content, + }); + } + + const response = await ollama.chat({ + model: model, + messages: chats, + }); + + console.log(response.message.content); + + for await (const fragment of response.message.content) { + stream.markdown(fragment); + } +} diff --git a/src/configuration.ts b/src/configuration.ts index 8d8fc50b..21bd1596 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -1,5 +1,5 @@ -import vscode from "vscode"; +import * as vscode from "vscode"; const getConfiguration = (): vscode.WorkspaceConfiguration => { return vscode.workspace.getConfiguration(`vscode-db2i`); diff --git a/src/extension.ts b/src/extension.ts index 1830ccda..0f198e39 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -19,6 +19,7 @@ import { OldSQLJob } from "./connection/sqlJob"; import { notebookInit } from "./notebooks/IBMiSerializer"; import { SelfTreeDecorationProvider, selfCodesResultsView } from "./views/jobManager/selfCodes/selfCodesResultsView"; import Configuration from "./configuration"; +import { activateChat } from "./chat/chat"; import { JDBCOptions } from "@ibm/mapepire-js/dist/src/types"; import { Db2iUriHandler, getStatementUri } from "./uriHandler"; import { DbCache } from "./language/providers/logic/cache"; @@ -28,6 +29,15 @@ export interface Db2i { sqlJob: (options?: JDBCOptions) => OldSQLJob } +const CHAT_ID = `vscode-db2i.chat`; +const LANGUAGE_MODEL_ID = `copilot-gpt-3.5-turbo`; + +interface IDB2ChatResult extends vscode.ChatResult { + metadata: { + command: string; + }; +} + // this method is called when your extension is activated // your extension is activated the very first time the command is executed @@ -103,6 +113,53 @@ export function activate(context: vscode.ExtensionContext): Db2i { }); }); + activateChat(context); + + + // /** + // * The Following is an experimental implemenation of chat extension for Db2 for i + // */ + // const chatHandler: vscode.ChatRequestHandler = async ( + // request: vscode.ChatRequest, + // context: vscode.ChatContext, + // stream: vscode.ChatResponseStream, + // token: vscode.CancellationToken + // ): Promise => { + + // if (request.command == `build`) { + // stream.progress(`Querying database for information...`); + // // const text = processUserMessage(request.prompt); + // const messages = [ + // new vscode.LanguageModelChatSystemMessage(`You are a an IBM i savant speciallizing in database features in Db2 for i. Your job is to help developers write and debug their SQL along with offering SQL programming advice. Help the developer write an SQL statement based on the prompt information. Always include code examples where is makes sense.`), + // new vscode.LanguageModelChatUserMessage(request.prompt) + // ]; + // try { + // const chatResponse = await vscode.lm.sendChatRequest(LANGUAGE_MODEL_ID, messages, {}, token); + // for await (const fragement of chatResponse.stream) { + // stream.markdown(fragement); + // } + + // } catch (err) { + // if (err instanceof vscode.LanguageModelError) { + // console.log(err.message, err.code, err.stack); + // } else { + // console.log(err); + // } + // } + + // return { metadata: { command: '' } }; + // } + + // }; + + // const chat = vscode.chat.createChatParticipant(CHAT_ID, chatHandler); + // chat.isSticky = true; + // chat.iconPath = new vscode.ThemeIcon(`database`); + + + + + return { sqlJobManager: JobManager, sqlJob: (options?: JDBCOptions) => new OldSQLJob(options) }; } diff --git a/src/language/sql/document.ts b/src/language/sql/document.ts index 2bbf41df..6664035e 100644 --- a/src/language/sql/document.ts +++ b/src/language/sql/document.ts @@ -35,6 +35,7 @@ export default class Document { let statementStart = 0; for (let i = 0; i < tokens.length; i++) { + const upperValue = tokens[i].value?.toUpperCase(); switch (tokens[i].type) { case `semicolon`: const statementTokens = tokens.slice(statementStart, i); @@ -45,19 +46,25 @@ export default class Document { break; case `statementType`: - currentStatementType = StatementTypeWord[tokens[i].value?.toUpperCase()]; + currentStatementType = StatementTypeWord[upperValue]; break; case `keyword`: - switch (tokens[i].value?.toUpperCase()) { + switch (upperValue) { case `LOOP`: - // This handles the case that 'END LOOP' is supported. - if (currentStatementType === StatementType.End) { - break; - } + case `THEN`: case `BEGIN`: case `DO`: - case `THEN`: + // This handles the case that 'END LOOP' is supported. + if (upperValue === `LOOP` && currentStatementType === StatementType.End) { + break; + } + + // Support for THEN in conditionals + if (upperValue === `THEN` && !Statement.typeIsConditional(currentStatementType)) { + break; + } + // We include BEGIN in the current statement // then the next statement beings const statementTokens = tokens.slice(statementStart, i+1); @@ -102,7 +109,7 @@ export default class Document { let depth = 0; for (const statement of this.statements) { - if (statement.isBlockEnder()) { + if (statement.isCompoundEnd()) { if (depth > 0) { currentGroup.push(statement); @@ -118,7 +125,7 @@ export default class Document { currentGroup = []; } } else - if (statement.isBlockOpener()) { + if (statement.isCompoundStart()) { if (depth > 0) { currentGroup.push(statement); } else { diff --git a/src/language/sql/statement.ts b/src/language/sql/statement.ts index e40a84a1..a9a14182 100644 --- a/src/language/sql/statement.ts +++ b/src/language/sql/statement.ts @@ -7,6 +7,7 @@ const tokenIs = (token: Token|undefined, type: string, value?: string) => { export default class Statement { public type: StatementType = StatementType.Unknown; + private label: string|undefined; constructor(public tokens: Token[], public range: IRange) { this.tokens = this.tokens.filter(newToken => newToken.type !== `newline`); @@ -19,11 +20,15 @@ export default class Statement { first = this.tokens[2]; } - if (tokenIs(first, `statementType`) || tokenIs(first, `keyword`, `END`) || tokenIs(first, `keyword`, `BEGIN`)) { - const wordValue = first.value?.toUpperCase(); - - this.type = StatementTypeWord[wordValue]; + if (tokenIs(first, `word`) && tokenIs(this.tokens[1], `colon`)) { + // Possible label? + this.label = first.value; + first = this.tokens[2]; } + + const wordValue = first.value?.toUpperCase(); + + this.type = StatementTypeWord[wordValue] || StatementType.Unknown; switch (this.type) { case StatementType.Create: @@ -35,7 +40,7 @@ export default class Statement { } } - isBlockOpener() { + isCompoundStart() { if (this.tokens.length === 1 && tokenIs(this.tokens[0], `keyword`, `BEGIN`)) { return true; } @@ -51,7 +56,19 @@ export default class Statement { return false; } - isBlockEnder() { + static typeIsConditional(type: StatementType) { + return [StatementType.If, StatementType.While, StatementType.Loop, StatementType.For].includes(type); + } + + isConditionStart() { + return Statement.typeIsConditional(this.type); + } + + isConditionEnd() { + return this.type === StatementType.End && this.tokens.length > 1; + } + + isCompoundEnd() { return this.type === StatementType.End && this.tokens.length === 1; } @@ -314,17 +331,21 @@ export default class Statement { } const basicQueryFinder = (startIndex: number): void => { + let currentClause: undefined|"select"|"from"; for (let i = startIndex; i < this.tokens.length; i++) { if (tokenIs(this.tokens[i], `clause`, `FROM`)) { - inFromClause = true; - } else if (inFromClause && tokenIs(this.tokens[i], `clause`) || tokenIs(this.tokens[i], `join`) || tokenIs(this.tokens[i], `closebracket`)) { - inFromClause = false; + currentClause = `from`; + } + else if (tokenIs(this.tokens[i], `statementType`, `SELECT`)) { + currentClause = `select`; + } else if (currentClause === `from` && tokenIs(this.tokens[i], `clause`) || tokenIs(this.tokens[i], `join`) || tokenIs(this.tokens[i], `closebracket`)) { + currentClause = undefined; } if (tokenIs(this.tokens[i], `clause`, `FROM`) || (this.type !== StatementType.Select && tokenIs(this.tokens[i], `clause`, `INTO`)) || tokenIs(this.tokens[i], `join`) || - (inFromClause && tokenIs(this.tokens[i], `comma`) + (currentClause === `from` && tokenIs(this.tokens[i], `comma`) )) { const sqlObj = this.getRefAtToken(i+1); if (sqlObj) { @@ -334,6 +355,15 @@ export default class Statement { i += 3; //For the brackets } } + } else if (currentClause === `select` && tokenIs(this.tokens[i], `function`)) { + const sqlObj = this.getRefAtToken(i); + if (sqlObj) { + doAdd(sqlObj); + i += sqlObj.tokens.length; + if (sqlObj.isUDTF || sqlObj.fromLateral) { + i += 3; //For the brackets + } + } } } } @@ -592,7 +622,7 @@ export default class Statement { } if (options.withSystemName) { - if (tokenIs(this.tokens[endIndex+1], `keyword`, `FOR`) && tokenIs(this.tokens[endIndex+2], `word`, `SYSTEM`) && tokenIs(this.tokens[endIndex+3], `word`, `NAME`)) { + if (tokenIs(this.tokens[endIndex+1], `statementType`, `FOR`) && tokenIs(this.tokens[endIndex+2], `word`, `SYSTEM`) && tokenIs(this.tokens[endIndex+3], `word`, `NAME`)) { if (this.tokens[endIndex+4] && NameTypes.includes(this.tokens[endIndex+4].type)) { sqlObj.object.system = this.tokens[endIndex+4].value; } @@ -624,10 +654,25 @@ export default class Statement { switch (currentToken.type) { case `statementType`: - if (declareStmt) continue; + const currentValue = currentToken.value.toLowerCase(); + if (declareStmt) { + if (currentValue === `for`) { + ranges.push({ + type: `remove`, + range: { + start: declareStmt.range.start, + end: currentToken.range.end + } + }); + + declareStmt = undefined; + } + + continue; + }; // If we're in a DECLARE, it's likely a cursor definition - if (currentToken.value.toLowerCase() === `declare`) { + if (currentValue === `declare`) { declareStmt = currentToken; } break; @@ -716,19 +761,6 @@ export default class Statement { } }); } - } else - if (declareStmt && tokenIs(currentToken, `keyword`, `FOR`)) { - // If we're a DECLARE, and we found the FOR keyword, the next - // set of tokens should be the select. - ranges.push({ - type: `remove`, - range: { - start: declareStmt.range.start, - end: currentToken.range.end - } - }); - - declareStmt = undefined; } break; } diff --git a/src/language/sql/tests/blocks.test.ts b/src/language/sql/tests/blocks.test.ts index 1da9a81d..1b74cb55 100644 --- a/src/language/sql/tests/blocks.test.ts +++ b/src/language/sql/tests/blocks.test.ts @@ -1,9 +1,12 @@ -import { assert, describe, expect, test } from 'vitest' +import { describe, expect, test } from 'vitest' import Document from '../document'; -import { StatementType } from '../types'; -describe(`Block statement tests`, () => { +const parserScenarios = describe.each([ + {newDoc: (content: string) => new Document(content), isFormatted: false}, +]); + +parserScenarios(`Block statement tests`, ({newDoc, isFormatted}) => { test('Block start tests', () => { const lines = [ `CREATE ALIAS "TestDelimiters"."Delimited Alias" FOR "TestDelimiters"."Delimited Table";`, @@ -15,19 +18,19 @@ describe(`Block statement tests`, () => { `LANGUAGE SQL BEGIN SET "Delimited Parameter" = 13; END;`, ].join(`\n`); - const doc = new Document(lines); + const doc = newDoc(lines); // CREATE, CREATE, RETURN, END, CREATE, SET, END expect(doc.statements.length).toBe(7); const aliasDef = doc.statements[0]; - expect(aliasDef.isBlockOpener()).toBeFalsy(); + expect(aliasDef.isCompoundStart()).toBeFalsy(); const functionDef = doc.statements[1]; - expect(functionDef.isBlockOpener()).toBeTruthy(); + expect(functionDef.isCompoundStart()).toBeTruthy(); const procedureDef = doc.statements[4]; - expect(procedureDef.isBlockOpener()).toBeTruthy(); + expect(procedureDef.isCompoundStart()).toBeTruthy(); }); test('Compound statement test', () => { @@ -53,21 +56,21 @@ describe(`Block statement tests`, () => { `LANGUAGE SQL BEGIN SET "Delimited Parameter" = 13; END;`, ].join(`\n`); - const doc = new Document(lines); + const doc = newDoc(lines); const t = doc.statements.length; const aliasDef = doc.statements[0]; - expect(aliasDef.isBlockOpener()).toBeFalsy(); + expect(aliasDef.isCompoundStart()).toBeFalsy(); const functionDef = doc.statements[1]; - expect(functionDef.isBlockOpener()).toBeTruthy(); + expect(functionDef.isCompoundStart()).toBeTruthy(); const functionEnd = doc.statements[3]; - expect(functionEnd.isBlockEnder()).toBeTruthy(); + expect(functionEnd.isCompoundEnd()).toBeTruthy(); const beginBlock = doc.statements[4]; - expect(beginBlock.isBlockOpener()).toBeTruthy(); + expect(beginBlock.isCompoundStart()).toBeTruthy(); }); test('Statement groups', () => { @@ -96,23 +99,58 @@ describe(`Block statement tests`, () => { `LANGUAGE SQL BEGIN SET "Delimited Parameter" = 13; END;`, ].join(`\r\n`); - const doc = new Document(lines); + const doc = newDoc(lines); const groups = doc.getStatementGroups(); expect(groups.length).toBe(4); const aliasStatement = groups[0]; - const aliasSubstring = lines.substring(aliasStatement.range.start, aliasStatement.range.end); + const aliasSubstring = doc.content.substring(aliasStatement.range.start, aliasStatement.range.end); expect(aliasSubstring).toBe(`CREATE ALIAS "TestDelimiters"."Delimited Alias" FOR "TestDelimiters"."Delimited Table"`); + const functionStatement = groups[1]; + const functionSubstring = doc.content.substring(functionStatement.range.start, functionStatement.range.end); + + if (isFormatted) { + expect(functionSubstring).toBe([ + `CREATE FUNCTION "TestDelimiters"."Delimited Function"(`, + ` "Delimited Parameter" INTEGER`, + `) RETURNS INTEGER LANGUAGE SQL BEGIN`, + ` RETURN "Delimited Parameter";`, + `END`, + ].join(`\r\n`)); + } else { + expect(functionSubstring).toBe([ + `CREATE FUNCTION "TestDelimiters"."Delimited Function" ("Delimited Parameter" INTEGER) `, + `RETURNS INTEGER LANGUAGE SQL BEGIN RETURN "Delimited Parameter"; END` + ].join(`\r\n`)) + } const beginStatement = groups[2]; - const compoundSubstring = lines.substring(beginStatement.range.start, beginStatement.range.end); - expect(compoundSubstring).toBe(compoundStatement); + expect(beginStatement.statements.length).toBe(9); + const compoundSubstring = doc.content.substring(beginStatement.range.start, beginStatement.range.end); + + if (isFormatted) { + expect(compoundSubstring).toBe([ + `BEGIN`, + ` DECLARE already_exists SMALLINT DEFAULT 0;`, + ` DECLARE dup_object_hdlr CONDITION FOR SQLSTATE '42710';`, + ` DECLARE CONTINUE HANDLER FOR dup_object_hdlr SET already_exists = 1;`, + ` CREATE TABLE table1(`, + ` col1 INT`, + ` );`, + ` IF already_exists > 0 THEN;`, + ` DELETE FROM table1;`, + ` END IF;`, + `END`, + ].join(`\r\n`)); + } else { + expect(compoundSubstring).toBe(compoundStatement); + } }); }); -describe(`Definition tests`, () => { +parserScenarios(`Definition tests`, ({newDoc}) => { test(`Alias, function, procedure`, () => { const lines = [ `CREATE ALIAS "TestDelimiters"."Delimited Alias" FOR "TestDelimiters"."Delimited Table";`, @@ -124,7 +162,7 @@ describe(`Definition tests`, () => { `LANGUAGE SQL BEGIN SET "Delimited Parameter" = 13; END;`, ].join(`\n`); - const doc = new Document(lines); + const doc = newDoc(lines); const defs = doc.getDefinitions(); @@ -161,7 +199,7 @@ describe(`Definition tests`, () => { `END;`, ].join(`\r\n`); - const doc = new Document(lines); + const doc = newDoc(lines); const defs = doc.getDefinitions(); @@ -245,7 +283,7 @@ describe(`Definition tests`, () => { `END ; `, ].join(`\n`); - const doc = new Document(lines); + const doc = newDoc(lines); const groups = doc.getStatementGroups(); expect(groups.length).toBe(1); diff --git a/src/language/sql/tests/statements.test.ts b/src/language/sql/tests/statements.test.ts index f06008aa..cd046ceb 100644 --- a/src/language/sql/tests/statements.test.ts +++ b/src/language/sql/tests/statements.test.ts @@ -3,16 +3,20 @@ import SQLTokeniser from '../tokens' import Document from '../document'; import { ClauseType, StatementType } from '../types'; -describe(`Basic statements`, () => { +const parserScenarios = describe.each([ + {newDoc: (content: string) => new Document(content)}, +]); + +parserScenarios(`Basic statements`, ({newDoc}) => { test('One statement, no end', () => { - const document = new Document(`select * from sample`); + const document = newDoc(`select * from sample`); expect(document.statements.length).toBe(1); expect(document.statements[0].tokens.length).toBe(4); }); test('One statement, with end', () => { - const document = new Document(`select * from sample;`); + const document = newDoc(`select * from sample;`); expect(document.statements.length).toBe(1); expect(document.statements[0].type).toBe(StatementType.Select); @@ -20,7 +24,7 @@ describe(`Basic statements`, () => { }); test('Two statements, one end', () => { - const document = new Document([ + const document = newDoc([ `select * from sample;`, `select a from b.b` ].join(`\n`)); @@ -34,7 +38,7 @@ describe(`Basic statements`, () => { }); test('Two statements, both end', () => { - const document = new Document([ + const document = newDoc([ `select * from sample;`, `select a from b.b;` ].join(`\n`)); @@ -45,7 +49,7 @@ describe(`Basic statements`, () => { }); test('Two statements, both end, with comments', () => { - const document = new Document([ + const document = newDoc([ `select * from sample; --Yep`, `select a from b.b; -- Nope` ].join(`\n`)); @@ -56,7 +60,7 @@ describe(`Basic statements`, () => { }); test('Two statements, both end, with comments, trimmed', () => { - const document = new Document([ + const document = newDoc([ ``, `select * from sample; --Yep`, ``, @@ -72,9 +76,9 @@ describe(`Basic statements`, () => { }); }); -describe(`Object references`, () => { +parserScenarios(`Object references`, ({newDoc}) => { test('SELECT: Simple unqualified object', () => { - const document = new Document(`select * from sample;`); + const document = newDoc(`select * from sample;`); expect(document.statements.length).toBe(1); expect(document.statements[0].tokens.length).toBe(4); @@ -92,7 +96,7 @@ describe(`Object references`, () => { }); test('SELECT: Simple qualified object', () => { - const document = new Document(`select * from myschema.sample;`); + const document = newDoc(`select * from myschema.sample;`); expect(document.statements.length).toBe(1); expect(document.statements[0].tokens.length).toBe(6); @@ -110,7 +114,7 @@ describe(`Object references`, () => { }); test('SELECT: Simple qualified object with alias', () => { - const document = new Document(`select * from myschema.sample as a;`); + const document = newDoc(`select * from myschema.sample as a;`); expect(document.statements.length).toBe(1); expect(document.statements[0].tokens.length).toBe(8); @@ -128,7 +132,7 @@ describe(`Object references`, () => { }); test('SELECT: Simple unqualified object with alias (no AS)', () => { - const document = new Document(`select * from sample a;`); + const document = newDoc(`select * from sample a;`); expect(document.statements.length).toBe(1); expect(document.statements[0].tokens.length).toBe(5); @@ -146,7 +150,7 @@ describe(`Object references`, () => { }); test('SELECT: Simple qualified object with alias (no AS)', () => { - const document = new Document(`select * from myschema.sample a;`); + const document = newDoc(`select * from myschema.sample a;`); expect(document.statements.length).toBe(1); expect(document.statements[0].tokens.length).toBe(7); @@ -164,7 +168,7 @@ describe(`Object references`, () => { }); test('SELECT: Simple qualified object with alias (system naming)', () => { - const document = new Document(`select * from myschema/sample as a;`); + const document = newDoc(`select * from myschema/sample as a;`); expect(document.statements.length).toBe(1); expect(document.statements[0].tokens.length).toBe(8); @@ -192,14 +196,14 @@ describe(`Object references`, () => { `WHERE ORCUID = CUID`, ].join(`\r\n`); - const document = new Document(query); + const document = newDoc(query); expect(document.statements.length).toBe(1); const statement = document.statements[0]; const refs = statement.getObjectReferences(); - expect(refs.length).toBe(3); + expect(refs.length).toBe(5); expect(statement.getClauseForOffset(10)).toBe(ClauseType.Unknown); expect(statement.getClauseForOffset(125)).toBe(ClauseType.From); @@ -216,7 +220,7 @@ describe(`Object references`, () => { `WHERE LASTNAME > 'S';`, ].join(`\n`); - const document = new Document(query); + const document = newDoc(query); expect(document.statements.length).toBe(1); @@ -246,7 +250,7 @@ describe(`Object references`, () => { `WHERE LASTNAME > 'S'`, ].join(`\n`); - const document = new Document(query); + const document = newDoc(query); expect(document.statements.length).toBe(1); @@ -279,7 +283,7 @@ describe(`Object references`, () => { `WHERE LASTNAME > 'S';`, ].join(`\n`); - const document = new Document(query); + const document = newDoc(query); expect(document.statements.length).toBe(1); @@ -309,7 +313,7 @@ describe(`Object references`, () => { `WHERE LASTNAME > 'S'`, ].join(`\n`); - const document = new Document(query); + const document = newDoc(query); expect(document.statements.length).toBe(1); @@ -336,7 +340,7 @@ describe(`Object references`, () => { `SELECT * FROM A CROSS JOIN B`, ].join(`\n`); - const document = new Document(query); + const document = newDoc(query); expect(document.statements.length).toBe(1); @@ -366,7 +370,7 @@ describe(`Object references`, () => { `WHERE LASTNAME > 'S'`, ].join(`\n`); - const document = new Document(query); + const document = newDoc(query); expect(document.statements.length).toBe(1); @@ -398,7 +402,7 @@ describe(`Object references`, () => { `insert into "myschema".hashtags (tag, base_talk) values('#hi', 2);`, ].join(`\r\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(2); @@ -423,7 +427,7 @@ describe(`Object references`, () => { `delete from talks where id > 2;` ].join(`\r\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -441,7 +445,7 @@ describe(`Object references`, () => { `call create_Sql_sample('MYNEWSCHEMA');` ].join(`\r\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -459,7 +463,7 @@ describe(`Object references`, () => { `call "QSYS".create_Sql_sample('MYNEWSCHEMA');` ].join(`\r\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -480,7 +484,7 @@ describe(`Object references`, () => { ` ON DELETE SET NULL;`, ].join(`\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -509,7 +513,7 @@ describe(`Object references`, () => { ` ON DELETE SET NULL;`, ].join(`\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -539,7 +543,7 @@ describe(`Object references`, () => { ` ON DEPARTMENT (MGRNO);`, ].join(`\r\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(2); @@ -588,7 +592,7 @@ describe(`Object references`, () => { ` ON other.DEPARTMENT (MGRNO);`, ].join(`\r\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(2); @@ -635,7 +639,7 @@ describe(`Object references`, () => { ` PRIMARY KEY( COL_B ) );`, ].join(`\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -658,7 +662,7 @@ describe(`Object references`, () => { `);`, ].join(`\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -701,7 +705,7 @@ describe(`Object references`, () => { ` ;`, ].join(`\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -747,7 +751,7 @@ describe(`Object references`, () => { ` ;`, ].join(`\n`); - const document = new Document(content); + const document = newDoc(content); expect(document.statements.length).toBe(1); @@ -797,7 +801,7 @@ describe(`Object references`, () => { `end;`, ].join(`\n`); - const document = new Document(lines); + const document = newDoc(lines); const groups = document.getStatementGroups(); expect(groups.length).toBe(1); @@ -829,9 +833,11 @@ describe(`Object references`, () => { const selectStatement = group.statements[2]; expect(selectStatement.type).toBe(StatementType.Select); const refsC = selectStatement.getObjectReferences(); - expect(refsC.length).toBe(1); + expect(refsC.length).toBe(2); expect(refsC[0].createType).toBeUndefined(); - expect(refsC[0].object.name).toBe(`employee`); + expect(refsC[0].object.name).toBe(`sum`); + expect(refsC[1].createType).toBeUndefined(); + expect(refsC[1].object.name).toBe(`employee`); }); test(`CREATE FUNCTION: with multiple parameters`, () => { @@ -858,7 +864,7 @@ describe(`Object references`, () => { `end;`, ].join(`\n`); - const document = new Document(lines); + const document = newDoc(lines); const groups = document.getStatementGroups(); expect(groups.length).toBe(1); @@ -886,7 +892,7 @@ describe(`Object references`, () => { `EXTERNAL NAME LIB.PROGRAM GENERAL;`, ].join(`\n`); - const document = new Document(lines); + const document = newDoc(lines); const groups = document.getStatementGroups(); expect(groups.length).toBe(1); @@ -913,7 +919,7 @@ describe(`Object references`, () => { }); test(`DECLARE VARIABLE`, () => { - const document = new Document(`declare watsonx_response Varchar(10000) CCSID 1208;`); + const document = newDoc(`declare watsonx_response Varchar(10000) CCSID 1208;`); const groups = document.getStatementGroups(); expect(groups.length).toBe(1); @@ -928,7 +934,7 @@ describe(`Object references`, () => { }); test(`CREATE OR REPLACE VARIABLE`, () => { - const document = new Document(`create or replace variable watsonx.apiVersion varchar(10) ccsid 1208 default '2023-07-07';`); + const document = newDoc(`create or replace variable watsonx.apiVersion varchar(10) ccsid 1208 default '2023-07-07';`); const groups = document.getStatementGroups(); @@ -1059,10 +1065,10 @@ describe(`Object references`, () => { expect(group.statements.map(s => s.type)).toEqual([ 'Create', 'Declare', 'Declare', 'Call', + 'Loop', 'Set', 'Unknown', 'Unknown', - 'Unknown', 'Unknown', - 'Unknown', 'Call', - 'Unknown', 'End', + 'If', 'Call', + 'Leave', 'End', 'Call', 'End', 'Unknown', 'End' ]); @@ -1086,9 +1092,9 @@ describe(`Object references`, () => { }) }); -describe(`Offset reference tests`, () => { +parserScenarios(`Offset reference tests`, ({newDoc}) => { test(`Writing select`, () => { - const document = new Document(`select * from sample.;`); + const document = newDoc(`select * from sample.;`); expect(document.statements.length).toBe(1); @@ -1101,7 +1107,7 @@ describe(`Offset reference tests`, () => { }); test(`Writing select, invalid middle`, () => { - const document = new Document(`select b. from department b;`); + const document = newDoc(`select b. from department b;`); expect(document.statements.length).toBe(1); @@ -1120,7 +1126,7 @@ describe(`Offset reference tests`, () => { }); }); -describe(`PL body tests`, () => { +parserScenarios(`PL body tests`, ({newDoc}) => { test(`CREATE PROCEDURE: with body`, () => { const lines = [ `CREATE PROCEDURE MEDIAN_RESULT_SET (OUT medianSalary DECIMAL(7,2))`, @@ -1152,12 +1158,12 @@ describe(`PL body tests`, () => { `END`, ].join(`\r\n`); - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; const medianResultSetProc = statements[0]; expect(medianResultSetProc.type).toBe(StatementType.Create); - expect(medianResultSetProc.isBlockOpener()).toBe(true); + expect(medianResultSetProc.isCompoundStart()).toBe(true); const parms = medianResultSetProc.getRoutineParameters(); expect(parms.length).toBe(1); @@ -1178,6 +1184,12 @@ describe(`PL body tests`, () => { // END expect(endStatements[1].tokens.length).toBe(1); + + const whileStatement = statements.find(stmt => stmt.type === StatementType.While); + expect(whileStatement).toBeDefined(); + + const fetchStatement = statements.find(stmt => stmt.type === StatementType.Fetch); + expect(fetchStatement).toBeDefined(); }); test(`CREATE PROCEDURE followed by CALL statement`, () => { @@ -1213,12 +1225,12 @@ describe(`PL body tests`, () => { `CALL MEDIAN_RESULT_SET(12345.55);`, ].join(`\r\n`); - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; const medianResultSetProc = statements[0]; expect(medianResultSetProc.type).toBe(StatementType.Create); - expect(medianResultSetProc.isBlockOpener()).toBe(true); + expect(medianResultSetProc.isCompoundStart()).toBe(true); const parms = medianResultSetProc.getRoutineParameters(); expect(parms.length).toBe(1); @@ -1237,7 +1249,7 @@ describe(`PL body tests`, () => { const callStatement = statements[statements.length - 1]; expect(callStatement.type).toBe(StatementType.Call); - expect(callStatement.isBlockOpener()).toBe(false); + expect(callStatement.isCompoundStart()).toBe(false); const blockParent = callStatement.getCallableDetail(callStatement.tokens[3].range.start); expect(blockParent).toBeDefined(); @@ -1268,7 +1280,7 @@ describe(`PL body tests`, () => { `select * from Temp02`, ].join(`\n`); - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; expect(statements.length).toBe(1); @@ -1279,27 +1291,36 @@ describe(`PL body tests`, () => { const refs = statement.getObjectReferences(); const ctes = statement.getCTEReferences(); - expect(refs.length).toBe(7); + expect(refs.length).toBe(10); expect(refs[0].object.name).toBe(`shipments`); expect(refs[0].alias).toBe(`s`); expect(refs[1].object.name).toBe(`BillingDate`); expect(refs[1].alias).toBeUndefined(); - expect(refs[2].object.name).toBe(`Temp01`); - expect(refs[2].alias).toBe(`t1`); + expect(refs[2].object.name).toBe(`sum`); + expect(refs[2].alias).toBeUndefined(); expect(refs[3].object.name).toBe(`Temp01`); expect(refs[3].alias).toBe(`t1`); - expect(refs[4].object.name).toBe(`Temp02`); - expect(refs[4].alias).toBe(`t2`); + expect(refs[4].object.name).toBe(`dec`); + expect(refs[4].alias).toBeUndefined(); + + expect(refs[5].object.name).toBe(`round`); + expect(refs[5].alias).toBeUndefined(); + + expect(refs[6].object.name).toBe(`Temp01`); + expect(refs[6].alias).toBe(`t1`); + + expect(refs[7].object.name).toBe(`Temp02`); + expect(refs[7].alias).toBe(`t2`); - expect(refs[5].object.name).toBe(`customers`); - expect(refs[5].alias).toBe(`c`); + expect(refs[8].object.name).toBe(`customers`); + expect(refs[8].alias).toBe(`c`); - expect(refs[6].object.name).toBe(`Temp02`); - expect(refs[6].alias).toBeUndefined(); + expect(refs[9].object.name).toBe(`Temp02`); + expect(refs[9].alias).toBeUndefined(); expect(ctes.length).toBe(3); expect(ctes[0].name).toBe(`Temp01`); @@ -1310,11 +1331,13 @@ describe(`PL body tests`, () => { expect(ctes[2].name).toBe(`Temp03`); expect(ctes[2].columns.length).toBe(0); + const temp03Stmt = ctes[2].statement.getObjectReferences(); - expect(temp03Stmt.length).toBe(3); - expect(temp03Stmt[0].object.name).toBe(`Temp01`); - expect(temp03Stmt[1].object.name).toBe(`Temp02`); - expect(temp03Stmt[2].object.name).toBe(`customers`); + + expect(temp03Stmt[0].object.name).toBe(`dec`); + expect(temp03Stmt[1].object.name).toBe(`Temp01`); + expect(temp03Stmt[2].object.name).toBe(`Temp02`); + expect(temp03Stmt[3].object.name).toBe(`customers`); }) test(`WITH: explicit columns`, () => { @@ -1326,7 +1349,7 @@ describe(`PL body tests`, () => { `select * from cteme` ].join(`\r\n`); - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; expect(statements.length).toBe(1); @@ -1355,7 +1378,7 @@ describe(`PL body tests`, () => { test(`SELECT: table function`, () => { const lines = `select * from table(qsys2.mti_info());`; - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; expect(statements.length).toBe(1); @@ -1373,7 +1396,7 @@ describe(`PL body tests`, () => { test(`SELECT: table function with name (no AS)`, () => { const lines = `select * from table(qsys2.mti_info()) x;`; - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; expect(statements.length).toBe(1); @@ -1391,7 +1414,7 @@ describe(`PL body tests`, () => { test(`SELECT: table function with name (with AS)`, () => { const lines = `select * from table(qsys2.mti_info()) as x;`; - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; expect(statements.length).toBe(1); @@ -1419,7 +1442,7 @@ describe(`PL body tests`, () => { `stop;`, ].join(`\n`); - const document = new Document(lines); + const document = newDoc(lines); const statements = document.statements; expect(statements.length).toBe(2); @@ -1427,10 +1450,65 @@ describe(`PL body tests`, () => { expect(statement.type).toBe(StatementType.Select); const objs = statement.getObjectReferences(); - expect(objs.length).toBe(1); - expect(objs[0].object.schema).toBe(`qsys2`); - expect(objs[0].object.name).toBe(`ACTIVE_JOB_INFO`); - }) + + expect(objs.length).toBe(2); + expect(objs[1].object.schema).toBe(`qsys2`); + expect(objs[1].object.name).toBe(`ACTIVE_JOB_INFO`); + }); + + test('CASE, WHEN, END', () => { + const lines = [ + `--`, + ``, + `--`, + `-- Hold any jobs that started running an SQL statement more than 2 hours ago.`, + `--`, + `select JOB_NAME,`, + ` case`, + ` when QSYS2.QCMDEXC('HLDJOB ' concat JOB_NAME) = 1 then 'Job Held'`, + ` else 'Job not held'`, + ` end as HLDJOB_RESULT`, + ` from table (`, + ` QSYS2.ACTIVE_JOB_INFO(DETAILED_INFO => 'ALL')`, + ` )`, + ` where SQL_STATEMENT_START_TIMESTAMP < current timestamp - 2 hours;`, + ].join(`\n`); + + const document = newDoc(lines); + + + const statements = document.statements; + expect(statements.length).toBe(1); + + const statement = statements[0]; + expect(statement.type).toBe(StatementType.Select); + + const objs = statement.getObjectReferences(); + + expect(objs.length).toBe(2); + }); + + + + test('SELECT statement with CASE', () => { + const content = [ + `SELECT`, + ` CLE,`, + ` CASE`, + ` WHEN CLE = 1 THEN 'FIRST' Else VALEUR End As VALEUR`, + `FROM`, + ` QTEMP.Test`, + ].join(` `); + + const document = new Document(content); + const statements = document.statements; + expect(statements.length).toBe(1); + + const statement = statements[0]; + expect(statement.type).toBe(StatementType.Select); + + + }); }); describe(`Parameter statement tests`, () => { @@ -1670,10 +1748,10 @@ describe(`Parameter statement tests`, () => { test(`Exec with basic DECLARE`, () => { const lines = [ `EXEC SQL`, - `DECLARE cursor-name SCROLL CURSOR FOR`, - `SELECT column-1, column-2`, - ` FROM table-name`, - ` WHERE column-1 = expression`, + `DECLARE cursor_name SCROLL CURSOR FOR`, + `SELECT column_1, column_2`, + `FROM table_name`, + `WHERE column_1 = expression`, ].join(`\n`); const document = new Document(lines); @@ -1685,9 +1763,9 @@ describe(`Parameter statement tests`, () => { const result = document.removeEmbeddedAreas(statement); expect(result.parameterCount).toBe(0); expect(result.content).toBe([ - `SELECT column-1, column-2`, - ` FROM table-name`, - ` WHERE column-1 = expression`, + `SELECT column_1, column_2`, + `FROM table_name`, + `WHERE column_1 = expression`, ].join(`\n`)); }); @@ -1704,6 +1782,50 @@ describe(`Parameter statement tests`, () => { expect(result.parameterCount).toBe(0); expect(result.content).toBe(content); }); + + test(`Callable blocks`, () => { + const lines = [ + `call qsys2.create_abcd();`, + `call qsys2.create_abcd(a, cool(a + b));`, + ].join(` `); + + const document = new Document(lines); + const statements = document.statements; + + expect(statements.length).toBe(2); + + const a = statements[0]; + expect(a.type).toBe(StatementType.Call); + + const b = statements[1]; + expect(b.type).toBe(StatementType.Call); + + const blockA = a.getBlockRangeAt(23); + expect(blockA).toMatchObject({ start: 5, end: 5 }); + + const callableA = a.getCallableDetail(23); + expect(callableA).toBeDefined(); + expect(callableA.parentRef.object.schema).toBe(`qsys2`); + expect(callableA.parentRef.object.name).toBe(`create_abcd`); + + const blockB = a.getBlockRangeAt(24); + expect(blockB).toMatchObject({ start: 5, end: 5 }); + + const callableB = a.getCallableDetail(24); + expect(callableB).toBeDefined(); + expect(callableB.parentRef.object.schema).toBe(`qsys2`); + expect(callableB.parentRef.object.name).toBe(`create_abcd`); + + const blockC = b.getBlockRangeAt(49); + expect(blockC).toMatchObject({ start: 5, end: 13 }); + + const callableC = b.getCallableDetail(49, true); + expect(callableC).toBeDefined(); + expect(callableC.tokens.length).toBe(4); + expect(callableC.tokens.some(t => t.type === `block` && t.block.length === 3)).toBeTruthy(); + expect(callableC.parentRef.object.schema).toBe(`qsys2`); + expect(callableC.parentRef.object.name).toBe(`create_abcd`); + }); }); describe(`Prefix tests`, () => { @@ -1725,48 +1847,4 @@ describe(`Prefix tests`, () => { expect(statement.type).toBe(StatementType.Select); }); -}); - -test(`Callable blocks`, () => { - const lines = [ - `call qsys2.create_abcd();`, - `call qsys2.create_abcd(a, cool(a + b));`, - ].join(` `); - - const document = new Document(lines); - const statements = document.statements; - - expect(statements.length).toBe(2); - - const a = statements[0]; - expect(a.type).toBe(StatementType.Call); - - const b = statements[1]; - expect(b.type).toBe(StatementType.Call); - - const blockA = a.getBlockRangeAt(23); - expect(blockA).toMatchObject({ start: 5, end: 5 }); - - const callableA = a.getCallableDetail(23); - expect(callableA).toBeDefined(); - expect(callableA.parentRef.object.schema).toBe(`qsys2`); - expect(callableA.parentRef.object.name).toBe(`create_abcd`); - - const blockB = a.getBlockRangeAt(24); - expect(blockB).toMatchObject({ start: 5, end: 5 }); - - const callableB = a.getCallableDetail(24); - expect(callableB).toBeDefined(); - expect(callableB.parentRef.object.schema).toBe(`qsys2`); - expect(callableB.parentRef.object.name).toBe(`create_abcd`); - - const blockC = b.getBlockRangeAt(49); - expect(blockC).toMatchObject({ start: 5, end: 13 }); - - const callableC = b.getCallableDetail(49, true); - expect(callableC).toBeDefined(); - expect(callableC.tokens.length).toBe(4); - expect(callableC.tokens.some(t => t.type === `block` && t.block.length === 3)).toBeTruthy(); - expect(callableC.parentRef.object.schema).toBe(`qsys2`); - expect(callableC.parentRef.object.name).toBe(`create_abcd`); }); \ No newline at end of file diff --git a/src/language/sql/tokens.ts b/src/language/sql/tokens.ts index e462c064..dc153c90 100644 --- a/src/language/sql/tokens.ts +++ b/src/language/sql/tokens.ts @@ -34,10 +34,18 @@ export default class SQLTokeniser { { name: `STATEMENTTYPE`, match: [{ type: `word`, match: (value: string) => { - return [`CREATE`, `ALTER`, `SELECT`, `WITH`, `INSERT`, `UPDATE`, `DELETE`, `DROP`, `CALL`, `DECLARE`].includes(value.toUpperCase()); + return [`CREATE`, `ALTER`, `SELECT`, `WITH`, `INSERT`, `UPDATE`, `DELETE`, `DROP`, `CALL`, `DECLARE`, `IF`, `FOR`, `WHILE`].includes(value.toUpperCase()); } }], becomes: `statementType`, }, + { + name: `CLAUSE-ORDER`, + match: [ + {type: `word`, match: (value: string) => {return value.toUpperCase() === `ORDER`}}, + {type: `word`, match: (value: string) => {return value.toUpperCase() === `BY`}} + ], + becomes: `clause`, + }, { name: `CLAUSE`, match: [{ type: `word`, match: (value: string) => { @@ -98,6 +106,11 @@ export default class SQLTokeniser { match: [{ type: `equals` }, { type: `morethan` }], becomes: `rightpipe`, }, + { + name: `NOT`, + match: [{type: `lessthan`}, {type: `morethan`}], + becomes: `not` + } ]; readonly spaces = [`\t`, ` `]; readonly splitParts: string[] = [`(`, `)`, `/`, `.`, `*`, `-`, `+`, `;`, `"`, `&`, `%`, `,`, `|`, `?`, `:`, `=`, `<`, `>`, `\n`, `\r`, ...this.spaces]; diff --git a/src/language/sql/types.ts b/src/language/sql/types.ts index b79f1479..0084b6e9 100644 --- a/src/language/sql/types.ts +++ b/src/language/sql/types.ts @@ -3,6 +3,7 @@ import Statement from "./statement"; export enum StatementType { Unknown = "Unknown", Create = "Create", + Close = "Close", Insert = "Insert", Select = "Select", With = "With", @@ -12,8 +13,27 @@ export enum StatementType { Begin = "Begin", Drop = "Drop", End = "End", + Else = "Else", + Elseif = "Elseif", Call = "Call", - Alter = "Alter" + Alter = "Alter", + Fetch = "Fetch", + For = "For", + Get = "Get", + Goto = "Goto", + If = "If", + Include = "Include", + Iterate = "Iterate", + Leave = "Leave", + Loop = "Loop", + Open = "Open", + Pipe = "Pipe", + Repeat = "Repeat", + Resignal = "Resignal", + Return = "Return", + Signal = "Signal", + Set = "Set", + While = "While" } export const StatementTypeWord = { @@ -26,9 +46,27 @@ export const StatementTypeWord = { 'DECLARE': StatementType.Declare, 'DROP': StatementType.Drop, 'END': StatementType.End, + 'ELSE': StatementType.Else, + 'ELSEIF': StatementType.Elseif, 'CALL': StatementType.Call, 'BEGIN': StatementType.Begin, - 'ALTER': StatementType.Alter + 'ALTER': StatementType.Alter, + 'FOR': StatementType.For, + 'FETCH': StatementType.Fetch, + 'GET': StatementType.Get, + 'GOTO': StatementType.Goto, + 'IF': StatementType.If, + 'INCLUDE': StatementType.Include, + 'ITERATE': StatementType.Iterate, + 'LEAVE': StatementType.Leave, + 'LOOP': StatementType.Loop, + 'PIPE': StatementType.Pipe, + 'REPEAT': StatementType.Repeat, + 'RESIGNAL': StatementType.Resignal, + 'RETURN': StatementType.Return, + 'SIGNAL': StatementType.Signal, + 'SET': StatementType.Set, + 'WHILE': StatementType.While, }; export enum ClauseType { diff --git a/jsconfig.json b/tsconfig.json similarity index 70% rename from jsconfig.json rename to tsconfig.json index 950f5c27..f9194d29 100644 --- a/jsconfig.json +++ b/tsconfig.json @@ -1,11 +1,12 @@ { "compilerOptions": { "module": "commonjs", - "target": "es6", + "target": "ES2019", "checkJs": true, /* Typecheck .js files. */ "lib": [ - "es6" - ] + "ES2019" + ], + "outDir": "./dist", }, "exclude": [ "node_modules" diff --git a/webpack.config.js b/webpack.config.js index 5f680cfa..64e8d4d9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -66,7 +66,11 @@ const config = { exclude: /node_modules/, use: [ { - loader: `esbuild-loader` + loader: `esbuild-loader`, + options: { + // JavaScript version to transpile to + target: 'node18' + } } ] },