diff --git a/package-lock.json b/package-lock.json index b144ae7..440a309 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@azure/functions", - "version": "4.8.0", + "version": "4.8.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@azure/functions", - "version": "4.8.0", + "version": "4.8.1", "license": "MIT", "dependencies": { "cookie": "^0.7.0", @@ -66,9 +66,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -180,9 +180,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, "license": "MIT", "dependencies": { @@ -199,9 +199,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -291,9 +291,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -304,9 +304,9 @@ } }, "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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -320,18 +320,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -344,20 +340,10 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/source-map": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", - "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "dev": true, "license": "MIT", "dependencies": { @@ -366,16 +352,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -486,9 +472,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -538,9 +524,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "18.19.100", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.100.tgz", - "integrity": "sha512-ojmMP8SZBKprc3qGrGk8Ujpo80AXkrP7G2tOT4VWr5jlr5DHjsJF+emXJz+Wm0glmy4Js62oKMdZZ6B9Y+tEcA==", + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "dev": true, "license": "MIT", "dependencies": { @@ -555,9 +541,9 @@ "license": "MIT" }, "node_modules/@types/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", "dev": true, "license": "MIT" }, @@ -1141,18 +1127,20 @@ } }, "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -1316,6 +1304,16 @@ "dev": true, "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.21", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.21.tgz", + "integrity": "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -1330,9 +1328,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -1361,9 +1359,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.24.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", - "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", "dev": true, "funding": [ { @@ -1381,10 +1379,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001716", - "electron-to-chromium": "^1.5.149", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" @@ -1474,9 +1473,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001718", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", - "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", "dev": true, "funding": [ { @@ -1818,9 +1817,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -1915,9 +1914,9 @@ } }, "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -1973,9 +1972,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.152", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.152.tgz", - "integrity": "sha512-xBOfg/EBaIlVsHipHl2VdTPJRSvErNUaqW8ejTq5OlOlIYx1wOllCHsAvAIrr55jD1IYEfdR86miUEt8H5IeJg==", + "version": "1.5.243", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.243.tgz", + "integrity": "sha512-ZCphxFW3Q1TVhcgS9blfut1PX8lusVi2SvXQgmEEnK4TCmE1JhH2JkjJN+DNt0pJJwfBri5AROBnz2b/C+YU9g==", "dev": true, "license": "ISC" }, @@ -1987,9 +1986,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "dev": true, "license": "MIT", "dependencies": { @@ -2015,9 +2014,9 @@ } }, "node_modules/envinfo": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", - "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.19.0.tgz", + "integrity": "sha512-DoSM9VyG6O3vqBf+p3Gjgr/Q52HYBBtO3v+4koAxt1MnWr+zEnxE+nke/yXS4lt2P4SYCHQ4V3f1i88LQVOpAw==", "dev": true, "license": "MIT", "bin": { @@ -2028,9 +2027,9 @@ } }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2038,9 +2037,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.9", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", - "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", "dev": true, "license": "MIT", "dependencies": { @@ -2048,18 +2047,18 @@ "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", + "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.0", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", @@ -2071,21 +2070,24 @@ "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", + "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.0", + "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.3", + "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.3", + "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", @@ -2094,7 +2096,7 @@ "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.18" + "which-typed-array": "^1.1.19" }, "engines": { "node": ">= 0.4" @@ -2273,9 +2275,9 @@ } }, "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.2.tgz", + "integrity": "sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==", "dev": true, "license": "MIT", "bin": { @@ -2308,9 +2310,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "dev": true, "license": "MIT", "dependencies": { @@ -2362,30 +2364,30 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", + "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", - "is-core-module": "^2.15.1", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", + "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "engines": { @@ -2429,9 +2431,9 @@ } }, "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.5.tgz", + "integrity": "sha512-9Ni+xgemM2IWLq6aXEpP2+V/V30GeA/46Ar629vcMqVPodFFWC9skHu/D1phvuqtS8bJCFnNf01/qcmqYEwNfg==", "dev": true, "license": "MIT", "dependencies": { @@ -2719,9 +2721,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, "funding": [ { @@ -2948,9 +2950,9 @@ } }, "node_modules/fs-monkey": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", - "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", "dev": true, "license": "Unlicense" }, @@ -2961,6 +2963,21 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -3009,6 +3026,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -3128,9 +3155,9 @@ "license": "BSD-2-Clause" }, "node_modules/glob/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==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3651,14 +3678,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" }, @@ -3695,6 +3723,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3722,6 +3763,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -4037,9 +4088,9 @@ } }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "dev": true, "license": "MIT", "dependencies": { @@ -4091,13 +4142,17 @@ "license": "MIT" }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -4323,29 +4378,30 @@ } }, "node_modules/mocha": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.2.2.tgz", - "integrity": "sha512-VlSBxrPYHK4YNOEbFdkCxHQbZMoNzBkoPprqtZRW6311EUF/DlSxoycE2e/2NtRk4WKkIXzyrXDTrlikJMWgbw==", + "version": "11.7.4", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.4.tgz", + "integrity": "sha512-1jYAaY8x0kAZ0XszLWu14pzsf4KV740Gld4HXkhNTXwcHx4AUEDkPzgEHg9CM5dVcW+zv036tjpsEbLraPJj4w==", "dev": true, "license": "MIT", "dependencies": { "browser-stdout": "^1.3.1", "chokidar": "^4.0.1", "debug": "^4.3.5", - "diff": "^5.2.0", + "diff": "^7.0.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^10.4.5", "he": "^1.2.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", + "minimatch": "^9.0.5", "ms": "^2.1.3", "picocolors": "^1.1.1", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", - "workerpool": "^6.5.1", + "workerpool": "^9.2.0", "yargs": "^17.7.2", "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" @@ -4400,9 +4456,9 @@ "license": "Python-2.0" }, "node_modules/mocha/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==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4439,16 +4495,19 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha/node_modules/readdirp": { @@ -4517,9 +4576,9 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -5134,13 +5193,13 @@ } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -5338,9 +5397,9 @@ } }, "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", "dependencies": { @@ -5395,9 +5454,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -5620,13 +5679,13 @@ } }, "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "dev": true, "license": "BSD-3-Clause", "engines": { - "node": ">= 8" + "node": ">= 12" } }, "node_modules/source-map-support": { @@ -5656,6 +5715,20 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -5698,9 +5771,9 @@ "license": "MIT" }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -5711,9 +5784,9 @@ } }, "node_modules/string-width/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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -5925,24 +5998,28 @@ } }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.39.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.1.tgz", - "integrity": "sha512-Mm6+uad0ZuDtcV8/4uOZQDQ8RuiC5Pu+iZRedJtF7yA/27sPL7d++In/AJKpWZlU3SYMPPkVfwetn6sgZ66pUA==", + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -6020,9 +6097,9 @@ } }, "node_modules/terser/node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -6074,9 +6151,9 @@ } }, "node_modules/ts-loader": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz", - "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==", + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", + "integrity": "sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6477,9 +6554,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "dev": true, "funding": [ { @@ -6538,9 +6615,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "dev": true, "license": "MIT", "dependencies": { @@ -6552,22 +6629,23 @@ } }, "node_modules/webpack": { - "version": "5.99.8", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.8.tgz", - "integrity": "sha512-lQ3CPiSTpfOnrEGeXDwoq5hIGzSjmwD72GdfVzF7CQAI7t47rJG9eDWvcEkEn3CUQymAElVvDg3YNTlCYj+qUQ==", + "version": "5.102.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", + "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", "dev": true, "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", + "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", + "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -6577,11 +6655,11 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.2", - "tapable": "^2.1.1", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" @@ -6673,9 +6751,9 @@ } }, "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "dev": true, "license": "MIT", "engines": { @@ -6683,9 +6761,9 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", "bin": { @@ -6695,6 +6773,19 @@ "node": ">=0.4.0" } }, + "node_modules/webpack/node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6818,9 +6909,9 @@ } }, "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", "dev": true, "license": "Apache-2.0" }, @@ -6884,9 +6975,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -6897,9 +6988,9 @@ } }, "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==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -6910,9 +7001,9 @@ } }, "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==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/src/converters/toMcpToolTriggerOptionsToRpc.ts b/src/converters/toMcpToolTriggerOptionsToRpc.ts index fe6cf1e..c3025e4 100644 --- a/src/converters/toMcpToolTriggerOptionsToRpc.ts +++ b/src/converters/toMcpToolTriggerOptionsToRpc.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { McpToolProperty, McpToolTriggerOptions, McpToolTriggerOptionsToRpc } from '../../types'; +import { normalizeToolProperties } from '../utils/toolProperties'; // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT License. @@ -21,129 +22,33 @@ export function converToMcpToolTriggerOptionsToRpc( description: mcpToolTriggerOptions.description, }; - // Check for null or undefined toolProperties - if (!mcpToolTriggerOptions?.toolProperties) { - return { - ...baseResult, - toolProperties: JSON.stringify([]), // Default to an empty array - }; - } - - // Check if toolProperties is an array of McpToolProperty objects - if (Array.isArray(mcpToolTriggerOptions.toolProperties)) { - const isValid = mcpToolTriggerOptions.toolProperties.every(isMcpToolProperty); - if (isValid) { - return { - ...baseResult, - toolProperties: JSON.stringify(mcpToolTriggerOptions.toolProperties), - }; - } else { - throw new Error( - 'Invalid toolProperties: Array contains invalid McpToolProperty, please validate the parameters.' - ); + // Try to normalize tool properties first (handles both array and fluent formats) + let normalizedProperties: McpToolProperty[] | undefined; + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + normalizedProperties = normalizeToolProperties(mcpToolTriggerOptions.toolProperties); + } catch (error) { + // Re-throw validation errors from normalizeToolProperties + if ( + error instanceof Error && + (error.message.includes('Property type is required') || + error.message.includes('Property type must be specified')) + ) { + throw error; } + normalizedProperties = undefined; } - // Handle cases where toolProperties is an object (e.g., Zod schema) - if (typeof mcpToolTriggerOptions.toolProperties === 'object') { - // Define the type of the ZodObject shape and ZodPropertyDef - type ZodPropertyDef = { - description?: string; - typeName: string; - }; - type ZodObjectShape = Record; - - // Define the type of the toolProperties object - type ToolProperties = - | { - _def?: { - typeName?: string; - }; - shape?: ZodObjectShape; - } - | Record; - - let isZodObject = false; - - const toolProperties = mcpToolTriggerOptions.toolProperties as ToolProperties; - - // Check if the object is a ZodObject - if ((toolProperties?._def as { typeName?: string })?.typeName === 'ZodObject') { - isZodObject = true; - } - - // Check if shape is a valid ZodObject shape - const shape: ZodObjectShape | Record = isZodObject - ? (toolProperties as { shape: ZodObjectShape }).shape - : toolProperties; - - // Extract properties from the ZodObject shape - const result = Object.keys(shape).map((propertyName) => { - const property = shape[propertyName] as { _def: ZodPropertyDef }; - const description = property?._def?.description || ''; - const propertyType = getPropertyType(property?._def?.typeName?.toLowerCase() || 'unknown'); // Extract type name or default to "unknown" - - return { - propertyName, - propertyType, - description, - }; - }); - + // If we successfully normalized the properties, use them + if (normalizedProperties !== undefined) { return { ...baseResult, - toolProperties: JSON.stringify(result), + toolProperties: JSON.stringify(normalizedProperties), }; } - // Handle cases where toolProperties is not an array - throw new Error('Invalid toolProperties: Expected an array of McpToolProperty objects or zod objects.'); -} - -// Helper function to infer property type from zod schema -function getPropertyType(zodType: string): string { - switch (zodType) { - case 'zodnumber': - return 'number'; - case 'zodstring': - return 'string'; - case 'zodboolean': - return 'boolean'; - case 'zodarray': - return 'array'; - case 'zodobject': - return 'object'; - case 'zodbigint': - return 'long'; - case 'zoddate': - return 'DateTime'; - case 'zodtuple': - return 'Tuple'; - default: - console.warn(`Unknown zod type: ${zodType}`); - return 'unknown'; - } -} -/** - * Type guard to check if a given object is of type McpToolProperty. - * - * @param property - The object to check. - * @returns True if the object is of type McpToolProperty, otherwise false. - * - * This function ensures that the object: - * - Is not null and is of type 'object'. - * - Contains the required properties: 'propertyName', 'propertyValue', and 'description'. - * - Each of these properties is of the correct type (string). - */ -function isMcpToolProperty(property: unknown): property is McpToolProperty { - return ( - typeof property === 'object' && - property !== null && - 'propertyName' in property && - 'propertyType' in property && - 'description' in property && - typeof (property as McpToolProperty).propertyName === 'string' && - typeof (property as McpToolProperty).propertyType === 'string' && - typeof (property as McpToolProperty).description === 'string' + // Handle cases where toolProperties is not an array + throw new Error( + `Invalid toolProperties for tool '${mcpToolTriggerOptions.toolName}': Expected an array of McpToolProperty or ToolProps objects or ToolProps need a type defined.` ); } diff --git a/src/index.ts b/src/index.ts index d3e2911..7af877d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,6 +16,7 @@ export { InvocationContext } from './InvocationContext'; export * as output from './output'; export * as trigger from './trigger'; export { Disposable } from './utils/Disposable'; +export { arg } from './utils/toolProperties'; export enum SqlChangeOperation { Insert = 0, diff --git a/src/utils/toolProperties.ts b/src/utils/toolProperties.ts new file mode 100644 index 0000000..6c018c3 --- /dev/null +++ b/src/utils/toolProperties.ts @@ -0,0 +1,267 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import { Args, McpToolProperty } from '../../types/mcpTool'; + +/** + * Fluent API builder for creating MCP Tool properties + * Also implements McpToolProperty interface to work seamlessly in object contexts + */ +export class ToolPropertyBuilder implements McpToolProperty { + private property: Partial = {}; + + // Implement McpToolProperty interface with getters + get propertyName(): string { + return this.property.propertyName || ''; + } + + get propertyType(): string { + if (!this.property.propertyType) { + throw new Error('Property type must be specified (use .string(), .number(), etc.)'); + } + return this.property.propertyType; + } + + get description(): string { + return this.property.description || ''; + } + + get isRequired(): boolean { + return this.property.isRequired ?? true; // Default to true (required by default) + } + + get isArray(): boolean { + return this.property.isArray ?? false; + } + + /** + * Set the property type to string + */ + string(): ToolPropertyBuilder { + this.property.propertyType = 'string'; + return this; + } + + /** + * Set the property type to number + */ + number(): ToolPropertyBuilder { + this.property.propertyType = 'number'; + return this; + } + + /** + * Set the property type to boolean + */ + boolean(): ToolPropertyBuilder { + this.property.propertyType = 'boolean'; + return this; + } + + /** + * Set the property type to object + */ + object(): ToolPropertyBuilder { + this.property.propertyType = 'object'; + return this; + } + + /** + * Set the property type to long + */ + integer(): ToolPropertyBuilder { + this.property.propertyType = 'integer'; + return this; + } + + /** + * Set the property type to long + */ + datetime(): ToolPropertyBuilder { + this.property.propertyType = 'string'; + return this; + } + + /** + * Set the description for the property + * @param description - Description of the property's purpose + */ + describe(description: string): ToolPropertyBuilder { + this.property.description = description; + return this; + } + + /** + * Mark the property as optional + */ + optional(): McpToolProperty { + this.property.isRequired = false; + return this.buildInternal(); + } + + /** + * Mark the property as an array type + */ + asArray(): ToolPropertyBuilder { + this.property.isArray = true; + return this; + } + + /** + * Build the final McpToolProperty object + * @private + */ + private buildInternal(): McpToolProperty { + if (!this.property.propertyType) { + throw new Error('Property type must be specified (use .string(), .number(), etc.)'); + } + + return { + propertyName: '', // Will be set by the consumer based on the key + propertyType: this.property.propertyType, + description: this.property.description || '', // Default to empty string if not provided + isRequired: this.property.isRequired ?? true, // Default to true (required by default) + isArray: this.property.isArray ?? false, + }; + } +} + +/** + * Factory function to create a new tool property builder + * + * @example + * ```typescript + * const toolProperties = { + * snippetName: arg + * .string() + * .describe("Some Description"), + * + * optionalField: arg + * .number() + * .describe("Optional number field") + * .optional(), + * }; + * ``` + */ +export const arg = { + /** + * Start building a string property + */ + string(): ToolPropertyBuilder { + return new ToolPropertyBuilder().string(); + }, + + /** + * Start building a number property + */ + integer(): ToolPropertyBuilder { + return new ToolPropertyBuilder().integer(); + }, + + /** + * Start building a number property + */ + number(): ToolPropertyBuilder { + return new ToolPropertyBuilder().number(); + }, + + /** + * Start building a boolean property + */ + boolean(): ToolPropertyBuilder { + return new ToolPropertyBuilder().boolean(); + }, + + /** + * Start building a datetime property + */ + datetime(): ToolPropertyBuilder { + return new ToolPropertyBuilder().datetime(); + }, + + /** + * Start building an object property + */ + object(): ToolPropertyBuilder { + return new ToolPropertyBuilder().object(); + }, +}; + +/** + * Convert a tool properties object to McpToolProperty array + * @param toolProps - Object with property names as keys and ToolProperty as values + * @returns Array of McpToolProperty objects with propertyName set correctly + */ +export function convertToolProperties(args: Args): McpToolProperty[] { + return Object.entries(args).map(([propertyName, property]) => ({ + propertyName, + propertyType: property.propertyType, + description: property.description || '', // Default to empty string if not provided + isRequired: property.isRequired, + isArray: property.isArray, + })); +} + +/** + * Type guard to check if properties are in toolProp format + */ +export function isToolProperties(properties: unknown): properties is Args { + return ( + typeof properties === 'object' && + properties !== null && + !Array.isArray(properties) && + Object.values(properties as Record).every( + (prop) => + typeof prop === 'object' && + prop !== null && + 'propertyType' in prop && + 'description' in prop && + 'isRequired' in prop && + 'isArray' in prop + ) + ); +} + +/** + * Validate that a tool property has required fields + */ +function validateToolProperty(property: McpToolProperty, propertyName?: string): void { + const nameContext = propertyName ? ` for property '${propertyName}'` : ''; + + if (!property.propertyType || property.propertyType.trim() === '') { + throw new Error(`Property type is required${nameContext}`); + } + + // Ensure description defaults to empty string if not provided + if (property.description === undefined || property.description === null) { + property.description = ''; + } +} + +/** + * Normalize tool properties to McpToolProperty array format + * Supports both legacy array format and new toolProp object format + */ +export function normalizeToolProperties( + properties: McpToolProperty[] | Args | undefined +): McpToolProperty[] | undefined { + if (!properties) { + return undefined; + } + + if (Array.isArray(properties)) { + // Validate each property in the array + properties.forEach((property, index) => { + validateToolProperty(property, property.propertyName || `index ${index}`); + }); + return properties; + } + + if (isToolProperties(properties)) { + const converted = convertToolProperties(properties); + return converted; + } + + // Unknown format + throw new Error('Invalid tool properties format'); +} diff --git a/test/converters/toMcpToolTriggerOptionsToRpc.test.ts b/test/converters/toMcpToolTriggerOptionsToRpc.test.ts new file mode 100644 index 0000000..c841d91 --- /dev/null +++ b/test/converters/toMcpToolTriggerOptionsToRpc.test.ts @@ -0,0 +1,412 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import 'mocha'; +import { expect } from 'chai'; +import { converToMcpToolTriggerOptionsToRpc } from '../../src/converters/toMcpToolTriggerOptionsToRpc'; +import { arg } from '../../src/utils/toolProperties'; +import { Args, McpToolProperty, McpToolTriggerOptions } from '../../types/mcpTool'; + +describe('converToMcpToolTriggerOptionsToRpc', () => { + describe('basic conversion', () => { + it('should throw error for minimal input without toolProperties', () => { + const input: McpToolTriggerOptions = { + toolName: 'simple-tool', + description: 'A test tool', + }; + + expect(() => converToMcpToolTriggerOptionsToRpc(input)).to.throw( + /Invalid toolProperties for tool 'simple-tool':/ + ); + }); + + it('should handle empty properties array', () => { + const input: McpToolTriggerOptions = { + toolName: 'empty-props-tool', + description: 'A tool with empty properties', + toolProperties: [], + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolName).to.equal('empty-props-tool'); + expect(result.description).to.equal('A tool with empty properties'); + expect(result.toolProperties).to.equal('[]'); + }); + + it('should throw error for undefined properties', () => { + const input: McpToolTriggerOptions = { + toolName: 'undefined-props-tool', + description: 'A tool with undefined properties', + toolProperties: undefined, + }; + + expect(() => converToMcpToolTriggerOptionsToRpc(input)).to.throw( + /Invalid toolProperties for tool 'undefined-props-tool':/ + ); + }); + }); + + describe('array format (legacy)', () => { + it('should handle array format for properties', () => { + const properties: McpToolProperty[] = [ + { + propertyName: 'testProp', + propertyType: 'string', + description: 'A test property', + isRequired: true, + isArray: false, + }, + { + propertyName: 'arrayProp', + propertyType: 'number', + description: 'An array property', + isRequired: false, + isArray: true, + }, + ]; + + const input: McpToolTriggerOptions = { + toolName: 'array-tool', + description: 'A tool with array properties', + toolProperties: properties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolName).to.equal('array-tool'); + expect(result.description).to.equal('A tool with array properties'); + expect(result.toolProperties).to.be.a('string'); + + // Test that it's valid JSON + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[]; + expect(parsedProperties).to.be.an('array'); + expect(parsedProperties).to.have.length(2); + }); + }); + + describe('toolProps object format', () => { + it('should handle toolProps object format', () => { + const toolProperties: Args = { + name: arg.string().describe('The name of the item'), + age: arg.number().describe('The age of the person').optional(), + }; + + const input: McpToolTriggerOptions = { + toolName: 'fluent-tool', + description: 'A tool with fluent properties', + toolProperties: toolProperties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolName).to.equal('fluent-tool'); + expect(result.description).to.equal('A tool with fluent properties'); + expect(result.toolProperties).to.be.a('string'); + + // Test that it's valid JSON + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[]; + expect(parsedProperties).to.be.an('array'); + expect(parsedProperties).to.have.length(2); + }); + + it('should handle all supported property types', () => { + const toolProperties: Args = { + stringProp: arg.string().describe('A string property'), + numberProp: arg.number().describe('A number property').optional(), + booleanProp: arg.boolean().describe('A boolean property'), + objectProp: arg.object().describe('An object property').optional(), + integerProp: arg.integer().describe('An integer property'), + }; + + const input: McpToolTriggerOptions = { + toolName: 'types-tool', + description: 'A tool with different property types', + toolProperties: toolProperties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolProperties).to.be.a('string'); + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[]; + expect(parsedProperties).to.have.length(5); + }); + + it('should handle array properties correctly', () => { + const toolProperties: Args = { + stringArray: arg.string().describe('A string array').asArray().optional(), + numberArray: arg.number().describe('A number array').asArray(), + }; + + const input: McpToolTriggerOptions = { + toolName: 'array-types-tool', + description: 'A tool with array properties', + toolProperties: toolProperties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolProperties).to.be.a('string'); + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[]; + expect(parsedProperties).to.have.length(2); + }); + }); + + describe('error handling', () => { + it('should throw error for invalid input', () => { + const invalidInput = null as any; + + expect(() => converToMcpToolTriggerOptionsToRpc(invalidInput)).to.throw(); + }); + + it('should throw error for undefined toolName', () => { + const invalidInput = { + description: 'A tool without name', + } as any; + + expect(() => converToMcpToolTriggerOptionsToRpc(invalidInput)).to.throw( + /Invalid toolProperties for tool 'undefined':/ + ); + }); + + it('should throw error for empty toolName', () => { + const invalidInput: McpToolTriggerOptions = { + toolName: '', + description: 'A tool with empty name', + }; + + expect(() => converToMcpToolTriggerOptionsToRpc(invalidInput)).to.throw( + /Invalid toolProperties for tool '':/ + ); + }); + + it('should throw error for null properties', () => { + const input: McpToolTriggerOptions = { + toolName: 'null-props-tool', + description: 'A tool with null properties', + toolProperties: null as any, + }; + + expect(() => converToMcpToolTriggerOptionsToRpc(input)).to.throw( + /Invalid toolProperties for tool 'null-props-tool':/ + ); + }); + + it('should throw error for invalid properties format', () => { + const input: McpToolTriggerOptions = { + toolName: 'invalid-props-tool', + description: 'A tool with invalid properties', + toolProperties: 'invalid string' as any, + }; + + expect(() => converToMcpToolTriggerOptionsToRpc(input)).to.throw( + /Invalid toolProperties for tool 'invalid-props-tool':/ + ); + }); + + it('should throw error for array properties with missing type', () => { + const propertiesWithMissingType: McpToolProperty[] = [ + { + propertyName: 'testProp', + propertyType: '', // Missing type + description: 'A test property', + isRequired: true, + isArray: false, + }, + ]; + + const input: McpToolTriggerOptions = { + toolName: 'missing-type-tool', + description: 'A tool with missing type', + toolProperties: propertiesWithMissingType, + }; + + expect(() => converToMcpToolTriggerOptionsToRpc(input)).to.throw( + /Property type is required for property 'testProp'/ + ); + }); + + it('should handle array properties with missing description by defaulting to empty string', () => { + const propertiesWithMissingDescription: McpToolProperty[] = [ + { + propertyName: 'testProp', + propertyType: 'string', + description: '', // Missing description should default to empty string + isRequired: true, + isArray: false, + }, + ]; + + const input: McpToolTriggerOptions = { + toolName: 'missing-description-tool', + description: 'A tool with missing description', + toolProperties: propertiesWithMissingDescription, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + expect(result).to.not.be.null; + expect(result.toolProperties).to.be.a('string'); + + const parsed = JSON.parse(result.toolProperties || '[]'); + expect(parsed).to.have.length(1); + expect(parsed[0].description).to.equal(''); + }); + + it('should throw error for array properties with both missing type and description', () => { + const propertiesWithMissingFields: McpToolProperty[] = [ + { + propertyName: 'testProp', + propertyType: '', // Missing type + description: '', // Missing description + isRequired: true, + isArray: false, + }, + ]; + + const input: McpToolTriggerOptions = { + toolName: 'missing-fields-tool', + description: 'A tool with missing fields', + toolProperties: propertiesWithMissingFields, + }; + + expect(() => converToMcpToolTriggerOptionsToRpc(input)).to.throw( + /Property type is required for property 'testProp'/ + ); + }); + + it('should handle fluent properties with missing description by defaulting to empty string', () => { + // Create properties with object that lacks description but has other required properties + const validToolProps = { + validProp: { + propertyType: 'string', + description: '', // Empty description should default to empty string + isRequired: true, + isArray: false, + } as any, + }; + + const input: McpToolTriggerOptions = { + toolName: 'missing-desc-fluent-tool', + description: 'A tool with missing description', + toolProperties: validToolProps, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + expect(result).to.not.be.null; + expect(result.toolProperties).to.be.a('string'); + + const parsed = JSON.parse(result.toolProperties || '[]'); + expect(parsed).to.have.length(1); + expect(parsed[0].description).to.equal(''); + }); + }); + + describe('JSON serialization', () => { + it('should produce valid JSON in toolProperties', () => { + const toolProperties: Args = { + test: arg.string().describe('Test property'), + }; + + const input: McpToolTriggerOptions = { + toolName: 'json-test-tool', + description: 'A tool for JSON testing', + toolProperties: toolProperties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolProperties).to.be.a('string'); + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsed = JSON.parse(result.toolProperties || '[]'); + expect(parsed).to.be.an('array'); + expect(parsed).to.have.length(1); + }); + + it('should handle empty array serialization', () => { + const input: McpToolTriggerOptions = { + toolName: 'empty-array-tool', + description: 'A tool with empty array', + toolProperties: [], + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolProperties).to.equal('[]'); + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsed = JSON.parse(result.toolProperties || '[]'); + expect(parsed).to.be.an('array'); + expect(parsed).to.have.length(0); + }); + }); + + describe('edge cases', () => { + it('should handle properties with special characters', () => { + const toolProperties: Args = { + 'special-field_with$symbols': arg.string().describe('A property with special characters in name'), + }; + + const input: McpToolTriggerOptions = { + toolName: 'special-tool', + description: 'A tool with special character properties', + toolProperties: toolProperties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolProperties).to.be.a('string'); + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[]; + expect(parsedProperties).to.have.length(1); + }); + + it('should handle properties with non-empty descriptions', () => { + const toolProperties: Args = { + validDesc: arg.string().describe('A valid description'), + }; + + const input: McpToolTriggerOptions = { + toolName: 'valid-desc-tool', + description: 'A tool with valid description property', + toolProperties: toolProperties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolProperties).to.be.a('string'); + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + + const parsedProperties = JSON.parse(result.toolProperties || '[]') as McpToolProperty[]; + expect(parsedProperties).to.have.length(1); + }); + it('should handle whitespace in names and descriptions', () => { + const toolProperties: Args = { + ' spaced name ': arg.string().describe(' spaced description ').optional(), + }; + + const input: McpToolTriggerOptions = { + toolName: ' spaced tool ', + description: ' spaced tool description ', + toolProperties: toolProperties, + }; + + const result = converToMcpToolTriggerOptionsToRpc(input); + + expect(result.toolName).to.equal(' spaced tool '); + expect(result.description).to.equal(' spaced tool description '); + + expect(result.toolProperties).to.be.a('string'); + expect(() => JSON.parse(result.toolProperties || '')).to.not.throw(); + }); + }); +}); diff --git a/test/toolArrayProperties.test.ts b/test/toolArrayProperties.test.ts new file mode 100644 index 0000000..9913ab3 --- /dev/null +++ b/test/toolArrayProperties.test.ts @@ -0,0 +1,118 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. + +import 'mocha'; +import { expect } from 'chai'; +import { arg, convertToolProperties, normalizeToolProperties, ToolPropertyBuilder } from '../src/utils/toolProperties'; + +describe('isArray property support', () => { + it('asArray() method sets isArray to true', () => { + const stringArrayProp = arg.string().asArray().describe('String array'); + expect(stringArrayProp.isArray).to.equal(true); + expect(stringArrayProp.propertyType).to.equal('string'); + expect(stringArrayProp.description).to.equal('String array'); + expect(stringArrayProp.isRequired).to.equal(true); + }); + + it('regular properties have isArray set to false', () => { + const regularProp = arg.string().describe('Regular string').optional(); + expect(regularProp.isArray).to.equal(false); + expect(regularProp.propertyType).to.equal('string'); + expect(regularProp.description).to.equal('Regular string'); + expect(regularProp.isRequired).to.equal(false); + }); + + it('convertToolProperties preserves isArray property', () => { + const toolProps = { + stringArray: arg.string().asArray().describe('String array'), + numberArray: arg.number().asArray().describe('Number array').optional(), + regularProp: arg.boolean().describe('Regular boolean'), + }; + + const converted = convertToolProperties(toolProps); + + expect(converted).to.have.lengthOf(3); + + const stringArrayProp = converted.find((p) => p.propertyName === 'stringArray'); + expect(stringArrayProp?.isArray).to.equal(true); + expect(stringArrayProp?.propertyType).to.equal('string'); + + const numberArrayProp = converted.find((p) => p.propertyName === 'numberArray'); + expect(numberArrayProp?.isArray).to.equal(true); + expect(numberArrayProp?.propertyType).to.equal('number'); + + const regularBooleanProp = converted.find((p) => p.propertyName === 'regularProp'); + expect(regularBooleanProp?.isArray).to.equal(false); + expect(regularBooleanProp?.propertyType).to.equal('boolean'); + }); + + it('normalizeToolProperties handles legacy format with isArray', () => { + const legacyProps = [ + { + propertyName: 'categories', + propertyType: 'string', + description: 'Categories', + isRequired: false, + isArray: true, + }, + { + propertyName: 'count', + propertyType: 'number', + description: 'Count', + isRequired: true, + isArray: false, + }, + ]; + + const normalized = normalizeToolProperties(legacyProps); + expect(normalized).to.deep.equal(legacyProps); + expect(normalized).to.not.be.undefined; + if (normalized) { + expect(normalized[0]?.isArray).to.equal(true); + expect(normalized[1]?.isArray).to.equal(false); + } + }); + + it('all property types support asArray()', () => { + const stringArray = arg.string().asArray().describe('String array'); + const numberArray = arg.number().asArray().describe('Number array'); + const booleanArray = arg.boolean().asArray().describe('Boolean array'); + const objectArray = arg.object().asArray().describe('Object array'); + const integerArray = arg.integer().asArray().describe('Integer array'); + + expect(stringArray.isArray).to.equal(true); + expect(numberArray.isArray).to.equal(true); + expect(booleanArray.isArray).to.equal(true); + expect(objectArray.isArray).to.equal(true); + expect(integerArray.isArray).to.equal(true); + }); + + it('supports seamless property access after desc()', () => { + // Test the specific pattern from user's example - this should work seamlessly + const toolProperties = { + name: arg.string().describe('Required property to identify the caller.').optional(), + arrayT: arg.string().asArray().describe('An array of strings property.'), + }; + + expect(toolProperties.name).to.have.property('propertyType', 'string'); + expect(toolProperties.name).to.have.property('isRequired', false); + + expect(toolProperties.arrayT.propertyType).to.equal('string'); + expect(toolProperties.arrayT.isArray).to.equal(true); + expect(toolProperties.arrayT.description).to.equal('An array of strings property.'); + expect(toolProperties.arrayT.isRequired).to.equal(true); // explicitly required + }); + + it('property access validates required fields and defaults description', () => { + expect(() => { + // Missing propertyType should throw when propertyType getter is accessed + const builder = new ToolPropertyBuilder(); + builder.describe('Some description'); + return builder.propertyType; // This should throw + }).to.throw('Property type must be specified'); + + // Missing description should default to empty string when description getter is accessed + const builder = arg.string(); + expect(builder.description).to.equal(''); // Should default to empty string + }); +}); diff --git a/types/InvocationContext.d.ts b/types/InvocationContext.d.ts index 8815bdf..c991557 100644 --- a/types/InvocationContext.d.ts +++ b/types/InvocationContext.d.ts @@ -129,7 +129,7 @@ export interface InvocationContextExtraInputs { * @input the configuration object for this SQL input */ get(input: SqlInput): unknown; - + /** * Get a secondary MySql items input for this invocation * @input the configuration object for this MySql input @@ -223,7 +223,7 @@ export interface InvocationContextExtraOutputs { * @message the output event(s) value */ set(output: EventGridOutput, events: EventGridPartialEvent | EventGridPartialEvent[]): void; - + /** * Set a secondary MySql items output for this invocation * @output the configuration object for this MySql output diff --git a/types/index.d.ts b/types/index.d.ts index 314c4c1..4f4a3b5 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -30,6 +30,9 @@ export * as trigger from './trigger'; export * from './warmup'; export * from './webpubsub'; +// Export toolProp for fluent tool properties API +export { arg } from '../src/utils/toolProperties'; + /** * Void if no `return` output is registered * Otherwise, the registered `return` output diff --git a/types/input.d.ts b/types/input.d.ts index 52d8c68..b264405 100644 --- a/types/input.d.ts +++ b/types/input.d.ts @@ -4,10 +4,10 @@ import { CosmosDBInput, CosmosDBInputOptions } from './cosmosDB'; import { GenericInputOptions } from './generic'; import { FunctionInput } from './index'; +import { MySqlInput, MySqlInputOptions } from './mySql'; import { SqlInput, SqlInputOptions } from './sql'; import { StorageBlobInput, StorageBlobInputOptions } from './storage'; import { TableInput, TableInputOptions } from './table'; -import { MySqlInput, MySqlInputOptions } from './mySql'; import { WebPubSubConnectionInput, WebPubSubConnectionInputOptions, diff --git a/types/mcpTool.d.ts b/types/mcpTool.d.ts index aa92c2a..ce1b669 100644 --- a/types/mcpTool.d.ts +++ b/types/mcpTool.d.ts @@ -48,9 +48,9 @@ export interface McpToolTriggerOptions { /** * Additional properties or metadata for the tool. - * This is a dictionary of key-value pairs that can be used to configure the trigger. + * Can be provided as an array or as a Args object format. */ - toolProperties?: any | McpToolProperty[]; + toolProperties?: McpToolProperty[] | Args; } /** @@ -98,10 +98,25 @@ export interface McpToolProperty { * A description of the property. * This provides additional context about the purpose or usage of the property. */ - description: string; + description?: string; /** * Indicates whether the property is required. */ isRequired?: boolean; + + /** + * Indicates whether the property is an array type. + */ + isArray?: boolean; } + +/** + * Represents a tool property definition (same as McpToolProperty but without propertyName) + */ +export type Arg = Omit; + +/** + * Tool properties format - an object mapping property names to their definitions + */ +export type Args = Record; diff --git a/types/output.d.ts b/types/output.d.ts index b9d9d83..e9e08d9 100644 --- a/types/output.d.ts +++ b/types/output.d.ts @@ -7,6 +7,7 @@ import { EventHubOutput, EventHubOutputOptions } from './eventHub'; import { GenericOutputOptions } from './generic'; import { HttpOutput, HttpOutputOptions } from './http'; import { FunctionOutput } from './index'; +import { MySqlOutput, MySqlOutputOptions } from './mySql'; import { ServiceBusQueueOutput, ServiceBusQueueOutputOptions, @@ -16,7 +17,6 @@ import { import { SqlOutput, SqlOutputOptions } from './sql'; import { StorageBlobOutput, StorageBlobOutputOptions, StorageQueueOutput, StorageQueueOutputOptions } from './storage'; import { TableOutput, TableOutputOptions } from './table'; -import { MySqlOutput, MySqlOutputOptions } from './mySql'; import { WebPubSubOutput, WebPubSubOutputOptions } from './webpubsub'; /**