diff --git a/package-lock.json b/package-lock.json index a300b45..ebd12ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,8 @@ "dependencies": { "@clerk/clerk-sdk-node": "^4.13.23", "@clerk/express": "^1.7.13", + "@google/genai": "^1.30.0", + "@google/generative-ai": "^0.24.1", "@modelcontextprotocol/sdk": "^1.20.2", "@tiptap/starter-kit": "^3.5.1", "@types/express": "^5.0.3", @@ -19,6 +21,7 @@ "crypto": "^1.0.1", "dotenv": "^16.5.0", "express": "^5.1.0", + "google": "^2.1.0", "jsdom": "^27.0.0", "jsonwebtoken": "^9.0.2", "lodash.isequal": "^4.5.0", @@ -992,6 +995,53 @@ "node": ">=18" } }, + "node_modules/@google/genai": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.30.0.tgz", + "integrity": "sha512-3MRcgczBFbUat1wIlZoLJ0vCCfXgm7Qxjh59cZi2X08RgWLtm9hKOspzp7TOg1TV2e26/MLxR2GR5yD5GmBV2w==", + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^10.3.0", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.20.1" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@google/generative-ai": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz", + "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "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==", + "license": "ISC", + "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/@modelcontextprotocol/sdk": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.20.2.tgz", @@ -1054,6 +1104,16 @@ "node": ">=10.12.0" } }, + "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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@remirror/core-constants": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", @@ -1688,6 +1748,30 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/anymatch": { "version": "3.1.3", "license": "ISC", @@ -1705,6 +1789,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/asn1js": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.6.tgz", @@ -1719,12 +1812,30 @@ "node": ">=12.0.0" } }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, "node_modules/aws-ssl-profiles": { "version": "1.1.2", "license": "MIT", @@ -1732,10 +1843,36 @@ "node": ">= 6.0.0" } }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", @@ -1759,6 +1896,15 @@ "version": "5.1.2", "license": "MIT" }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/bidi-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", @@ -1768,6 +1914,15 @@ "require-from-string": "^2.0.2" } }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "license": "MIT", @@ -1796,6 +1951,12 @@ "node": ">=18" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, "node_modules/brace-expansion": { "version": "1.1.12", "license": "MIT", @@ -1888,10 +2049,38 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "license": "Apache-2.0" + }, "node_modules/change-case": { "version": "5.4.4", "license": "MIT" }, + "node_modules/cheerio": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", + "integrity": "sha512-Fwcm3zkR37STnPC8FepSHeSYJM5Rd596TZOcfDUdojR4Q735aK1Xn+M+ISagNneuCwMjK28w4kX+ETILGNT/UQ==", + "license": "MIT", + "dependencies": { + "css-select": "~1.0.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "~3.8.1", + "lodash": "^3.2.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cheerio/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "license": "BSD-2-Clause" + }, "node_modules/chokidar": { "version": "3.6.0", "license": "MIT", @@ -1914,6 +2103,24 @@ "fsevents": "~2.3.2" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1976,6 +2183,12 @@ "node": ">=6.6.0" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/cors": { "version": "2.8.5", "license": "MIT", @@ -2011,6 +2224,18 @@ "version": "1.0.1", "license": "ISC" }, + "node_modules/css-select": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", + "integrity": "sha512-/xPlD7betkfd7ChGkLGGWx5HWyiHDOSn7aACLzdH0nwucPvB0EAm8hMBm7Xn7vGfAeRRN7KZ8wumGm8NoNcMRw==", + "license": "BSD-like", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "1.0", + "domutils": "1.4", + "nth-check": "~1.0.0" + } + }, "node_modules/css-tree": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", @@ -2024,6 +2249,15 @@ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, + "node_modules/css-what": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", + "integrity": "sha512-60SUMPBreXrLXgvpM8kYpO0AOyMRhdRlXFX5BMQbZq1SIJCyNE56nqFQhmvREQdUJpedbGRYZ5wOyq3/F6q5Zw==", + "license": "BSD-like", + "engines": { + "node": "*" + } + }, "node_modules/cssstyle": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.1.tgz", @@ -2042,6 +2276,27 @@ "version": "3.1.3", "license": "MIT" }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/data-urls": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", @@ -2115,6 +2370,44 @@ "node": ">=6" } }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "license": "BSD-2-Clause" + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", + "integrity": "sha512-ZkVgS/PpxjyJMb+S2iVHHEZjVnOUtjGp0/zstqKGTE9lrZtNHlNQmLwP/lhLMEApYbzc08BKMx9IFpKhaSbW1w==", + "dependencies": { + "domelementtype": "1" + } + }, "node_modules/dot-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", @@ -2147,6 +2440,22 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", "license": "Apache-2.0", @@ -2158,6 +2467,12 @@ "version": "1.1.1", "license": "MIT" }, + "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==", + "license": "MIT" + }, "node_modules/encodeurl": { "version": "2.0.0", "license": "MIT", @@ -2518,6 +2833,21 @@ "express": ">= 4.11" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2534,6 +2864,29 @@ "version": "1.3.0", "license": "Unlicense" }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/fill-range": { "version": "7.1.1", "license": "MIT", @@ -2559,6 +2912,31 @@ "node": ">= 0.8" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, "node_modules/form-data": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", @@ -2599,6 +2977,18 @@ "node": ">= 0.6" } }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/forwarded": { "version": "0.2.0", "license": "MIT", @@ -2620,6 +3010,53 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gaxios/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/gcp-metadata": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/generate-function": { "version": "2.3.1", "license": "MIT", @@ -2660,6 +3097,35 @@ "node": ">= 0.4" } }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "5.1.2", "license": "ISC", @@ -2674,21 +3140,160 @@ "version": "0.4.1", "license": "BSD-2-Clause" }, - "node_modules/gopd": { - "version": "1.2.0", + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">= 0.4" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/has-flag": { - "version": "3.0.0", + "node_modules/google": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/google/-/google-2.1.0.tgz", + "integrity": "sha512-z1lOESyokyPB+nVIZ96LyW6Hw3u3AWSSQAZD0L9IrncRSCqCU12wOK6CH8AKsmZe6+6rSX+lJgIRq8LdRiVAUg==", "license": "MIT", - "engines": { - "node": ">=4" + "dependencies": { + "cheerio": "^0.19.0", + "request": "^2.54.0" + } + }, + "node_modules/google-auth-library": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", + "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.0.0", + "gcp-metadata": "^8.0.0", + "google-logging-utils": "^1.0.0", + "gtoken": "^8.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-auth-library/node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-auth-library/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gtoken": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", + "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", + "license": "MIT", + "dependencies": { + "gaxios": "^7.0.0", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gtoken/node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/gtoken/node_modules/jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" } }, "node_modules/has-symbols": { @@ -2738,6 +3343,34 @@ "node": ">=18" } }, + "node_modules/htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", + "license": "MIT", + "dependencies": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, + "node_modules/htmlparser2/node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", + "license": "BSD-like" + }, "node_modules/http-errors": { "version": "2.0.0", "license": "MIT", @@ -2765,6 +3398,21 @@ "node": ">= 14" } }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -2820,6 +3468,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "license": "MIT", @@ -2851,6 +3508,18 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2867,6 +3536,27 @@ "url": "https://github.com/sponsors/dmonad" } }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "license": "MIT" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-cookie": { "version": "3.0.5", "license": "MIT", @@ -2881,6 +3571,12 @@ "license": "MIT", "peer": true }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" + }, "node_modules/jsdom": { "version": "27.0.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.0.0.tgz", @@ -2920,12 +3616,33 @@ } } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "license": "MIT" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, "node_modules/jsonwebtoken": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", @@ -2948,6 +3665,21 @@ "npm": ">=6" } }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/jwa": { "version": "1.4.2", "license": "MIT", @@ -3001,6 +3733,12 @@ "integrity": "sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==", "license": "MIT" }, + "node_modules/lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==", + "license": "MIT" + }, "node_modules/lodash.includes": { "version": "4.3.0", "license": "MIT" @@ -3184,6 +3922,15 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/morgan": { "version": "1.10.0", "license": "MIT", @@ -3287,6 +4034,26 @@ "tslib": "^2.0.3" } }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -3368,6 +4135,24 @@ "node": ">=0.10.0" } }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, "node_modules/object-assign": { "version": "4.1.1", "license": "MIT", @@ -3434,6 +4219,12 @@ "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", "license": "MIT" }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, "node_modules/parse5": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", @@ -3462,6 +4253,28 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/path-to-regexp": { "version": "8.2.0", "license": "MIT", @@ -3469,6 +4282,12 @@ "node": ">=16" } }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3730,6 +4549,18 @@ "node": ">= 0.10" } }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, "node_modules/pstree.remy": { "version": "1.1.8", "license": "MIT" @@ -3825,6 +4656,18 @@ "node": ">=0.10.0" } }, + "node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/readdirp": { "version": "3.6.0", "license": "MIT", @@ -3835,6 +4678,95 @@ "node": ">=8.10.0" } }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/request/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -3844,6 +4776,21 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/rope-sequence": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", @@ -4039,6 +4986,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/simple-update-notifier": { "version": "2.0.0", "license": "MIT", @@ -4275,6 +5234,31 @@ "node": ">= 0.6" } }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/standardwebhooks": { "version": "1.0.0", "license": "MIT", @@ -4294,6 +5278,108 @@ "version": "3.9.0", "license": "MIT" }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "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/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==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/stripe": { "version": "18.3.0", "license": "MIT", @@ -4433,6 +5519,24 @@ "version": "2.8.1", "license": "0BSD" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, "node_modules/type-fest": { "version": "4.41.0", "license": "(MIT OR CC0-1.0)", @@ -4503,6 +5607,16 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/vary": { "version": "1.1.2", "license": "MIT", @@ -4510,6 +5624,26 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, "node_modules/w3c-keyname": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", @@ -4528,6 +5662,15 @@ "node": ">=18" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/webcrypto-core": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.8.1.tgz", @@ -4599,6 +5742,97 @@ "node": ">= 8" } }, + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "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-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/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==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrappy": { "version": "1.0.2", "license": "ISC" diff --git a/package.json b/package.json index 1b230fa..f03771e 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,8 @@ "dependencies": { "@clerk/clerk-sdk-node": "^4.13.23", "@clerk/express": "^1.7.13", + "@google/genai": "^1.30.0", + "@google/generative-ai": "^0.24.1", "@modelcontextprotocol/sdk": "^1.20.2", "@tiptap/starter-kit": "^3.5.1", "@types/express": "^5.0.3", @@ -27,6 +29,7 @@ "crypto": "^1.0.1", "dotenv": "^16.5.0", "express": "^5.1.0", + "google": "^2.1.0", "jsdom": "^27.0.0", "jsonwebtoken": "^9.0.2", "lodash.isequal": "^4.5.0", diff --git a/src/assets/config/jeremy_ai.json b/src/assets/config/jeremy_ai.json index da62d77..6a8bdd6 100644 --- a/src/assets/config/jeremy_ai.json +++ b/src/assets/config/jeremy_ai.json @@ -1,3 +1,3 @@ { - "prompt_system": "Tu dois ecrir au format MarkDown en html. Pour faire des todolist tu dois faire une list sous ce format d'example : . Pour integrer un saut de ligne, met ce code décolé avec un espace : '#34'. Pour le markdown, les fonction comme **text** et __text__ doivent être colé au text. Tu es le chatbot de l'application de prise de notes 'silvernote', tu te nommes 'SilverIA'. Tu parles par default français. Ton rôle est d'aider l'utilisateur à organiser ses notes, gerer ses dossiers, répondre aux questions sur l'application et donner des conseils pour mieux gérer ses notes. Tu dois être toujours poli, clair et encourageant. Tu dois repondre avec des reponse breve. Tu ne peux pas inventer d'informations sur l'utilisateur en dehors de ce qu'il te fournit. Si une question est hors sujet ou que tu ne sais pas, tu dois le dire poliment. Les notes et tag de cet utilisateur te seront fournit a chaque message. Ne dit pas de truc inutile dans tes reponses. L'utilisateur sait qui tu est sauf si il te le demande. Tu peut effectué des acction pour agir sur les notes et dossier/tag de l'utilisateur." + "prompt_system": "Tu dois ecrir au format MarkDown en html. Pour faire des todolist tu dois faire une list sous ce format d'example : . Pour le markdown, les fonction comme **text** et __text__ doivent être colé au text. Tu es le chatbot de l'application de prise de notes 'silvernote'. Tu parles par default en français. Ton rôle est d'aider l'utilisateur à organiser ses notes, gerer ses dossiers, répondre aux questions sur l'application et donner des conseils pour mieux gérer ses notes. Tu dois être toujours poli, clair et encourageant. Tu dois repondre avec des reponse breve. Tu ne peux pas inventer d'informations sur l'utilisateur en dehors de ce qu'il te fournit. Si une question est hors sujet ou que tu ne sais pas, tu dois le dire poliment. Les notes et tag de cet utilisateur te seront fournit a chaque message. Ne dit pas de truc inutile dans tes reponses. L'utilisateur sait qui tu est sauf si il te le demande. Tu peut effectué des acction pour agir sur les notes et dossier/tag de l'utilisateur." } diff --git a/src/mcp.ts b/src/mcp.ts index d5b9855..8b525b9 100644 --- a/src/mcp.ts +++ b/src/mcp.ts @@ -71,13 +71,69 @@ export class MCPService { console.log(`Loaded tools: ${this.tools.map(t => t.name).join(', ')}`); } - getOpenAITools() { + public getOpenAITools() { return this.openaiTools.map(tool => ({ ...tool, resources: ["note://*"], })); } + public getGeminiTools() + { + if (!this.tools || this.tools.length === 0) { + return []; + } + + return this.tools + .filter(tool => tool && (tool.function?.name || tool.name)) + .map(tool => { + const isOpenAIFormat = 'function' in tool; + + const parameters = isOpenAIFormat + ? tool.function.parameters + : (tool.inputSchema || tool.parameters || {}); + + const cleanedParameters = this.cleanSchemaForGemini(parameters); + + return { + name: isOpenAIFormat ? tool.function.name : tool.name, + description: isOpenAIFormat ? tool.function.description : tool.description, + parameters: cleanedParameters + }; + }); + } + + private cleanSchemaForGemini(schema: any): any + { + if (!schema || typeof schema !== 'object') { + return schema; + } + + const cleaned = JSON.parse(JSON.stringify(schema)); + + const removeInvalidFields = (obj: any): any => { + if (Array.isArray(obj)) { + return obj.map(removeInvalidFields); + } + + if (obj && typeof obj === 'object') { + + delete obj.$schema; + delete obj.additionalProperties; + delete obj.$defs; + delete obj.definitions; + + for (const key in obj) { + obj[key] = removeInvalidFields(obj[key]); + } + } + + return obj; + }; + + return removeInvalidFields(cleaned); + } + async callTool(name: string, args: any = {}) { if (!this.client) { throw new Error('MCP client not connected'); @@ -104,6 +160,34 @@ export class MCPService { } } + async handleToolCallsGemini(toolCalls: any[]) { + const results = []; + + for (const toolCall of toolCalls) { + const name = toolCall.function.name; + const args = JSON.parse(toolCall.function.arguments); + + try { + const result = await this.callTool(name, args); + + results.push({ + role: 'function', + name: name, + content: result + }); + + } catch (error: any) { + results.push({ + role: 'function', + name: name, + content: `Error: ${error.message}` + }); + } + } + + return results; + } + async handleToolCalls(toolCalls: OpenAI.Chat.Completions.ChatCompletionMessageToolCall[]) { const results = []; diff --git a/src/routes/api.ai.ts b/src/routes/api.ai.ts index 4986fea..bf8f92b 100644 --- a/src/routes/api.ai.ts +++ b/src/routes/api.ai.ts @@ -1,6 +1,5 @@ import { UUID, randomUUID } from 'crypto'; import { Router, Request, Response, NextFunction } from 'express'; -import OpenAI from "openai"; import fs from 'fs'; import path from 'path'; import __dirname from '../assets/ts/_dirname.js'; @@ -10,19 +9,14 @@ import db from '../assets/ts/database.js'; import notes_db from '../assets/ts/notes.js'; import tags_db from '../assets/ts/tags.js'; import { getMCPService } from '../mcp.js'; -import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions'; +import send_to_chatgpt from './api.ai/send_to_chatgpt.js'; +import { Chat } from './api.ai/types.js'; +import send_to_gemini from './api.ai/send_to_gemini.js'; -const AIclient = new OpenAI({ apiKey: process.env.OPENAI_SECRET_KEY }); const router = Router(); -type Chat = { - uuid: UUID; - userID: string; - data: { notes: any; tags: any }; - messages: ChatCompletionMessageParam[]; -} -let chats: Chat[] = []; +let chats: any[] = []; function verify_auth(req: Request, res: Response, next: NextFunction) { next(); @@ -101,141 +95,18 @@ router.post('/close', verify_auth, async (req: Request, res: Response) => { }); router.post('/send', verify_auth, async (req: Request, res: Response) => { - const { uuid, message } = req.body; - const note = req.body?.note || undefined; - - try { - const chat = chats.find(chat => chat.uuid == uuid); - - if (!chat) { - res.json({ error: true, message: 'Chat non trouvé' }); - return; - } - - // Préparer le prompt - let prompt: string = ''; - - if (!note) { - prompt = `Message de l'utilisateur : ${message}`; - } else { - let db_note = (await notes_db.getNoteByUUID(note)).note; - if (db_note) { - db_note = { ...db_note, content: db_note.content.replace(/]*>/g, '') }; - } - prompt = `Note ouverte : ${JSON.stringify({ db_note })}\n Message de l'utilisateur : ${message}`; - } - - chat.messages.push({ - role: 'user', - content: prompt - }); - - // Obtenir le service MCP - const mcpService = getMCPService(); - await mcpService.ensureConnected(); - - // Obtenir les outils MCP au format OpenAI - const mcpTools = mcpService.getOpenAITools(); - - // Configuration SSE - res.setHeader("Content-Type", "text/event-stream"); - res.setHeader("Cache-Control", "no-cache"); - res.setHeader("Connection", "keep-alive"); - res.flushHeaders(); - res.socket?.setNoDelay(true); - - let conversationMessages = [...chat.messages.slice(-10)]; - let iterationCount = 0; - const maxIterations = 5; - - // Boucle pour gérer les appels d'outils - while (iterationCount < maxIterations) { - iterationCount++; - - // Appel à OpenAI avec les outils MCP - const stream = await AIclient.chat.completions.create({ - model: "gpt-5-mini", - messages: conversationMessages, - tools: mcpTools.length > 0 ? mcpTools : undefined, - tool_choice: 'auto', - stream: true - }); - - let assistantMessage: string = ""; - let buffer: string = ''; - let toolCalls: any[] = []; - let currentToolCall: any = null; - - for await (const chunk of stream) { - const delta = chunk.choices[0]?.delta; + + const model = req.query?.model as 'gpt' | 'gemini'; - // Gérer le contenu texte - if (delta?.content) { - const token = delta.content; - assistantMessage += token; - buffer += token; - res.write(`data: ${token}\n\n`); - } - - // Gérer les appels d'outils - if (delta?.tool_calls) { - for (const toolCallDelta of delta.tool_calls) { - if (toolCallDelta.index !== undefined) { - if (!toolCalls[toolCallDelta.index]) { - toolCalls[toolCallDelta.index] = { - id: toolCallDelta.id || '', - type: 'function', - function: { - name: toolCallDelta.function?.name || '', - arguments: '' - } - }; - } - - if (toolCallDelta.function?.arguments) { - toolCalls[toolCallDelta.index].function.arguments += toolCallDelta.function.arguments; - } - } - } - } - } - - // Ajouter le message de l'assistant - conversationMessages.push({ - role: 'assistant', - content: assistantMessage || null, - tool_calls: toolCalls.length > 0 ? toolCalls : undefined - } as any); - - chat.messages.push({ - role: 'assistant', - content: assistantMessage - }); - - // Si pas d'appel d'outil, on termine - if (toolCalls.length === 0) { - break; - } - - // Exécuter les appels d'outils via MCP - res.write(`data: [TOOLS:${toolCalls.map(tc => tc.function.name).join(',')}]\n\n`); - - const toolResults = await mcpService.handleToolCalls(toolCalls); - conversationMessages.push(...toolResults); - - // Envoyer les résultats au client - for (const result of toolResults) { - res.write(`data: [TOOL_RESULT:${result.content}]\n\n`); - } - } - - res.write("data: [DONE]\n\n"); - res.end(); - - } catch (err: any) { - console.error('Error in /send:', err); - res.status(500).json({ error: true, message: err.message }); + if (true || model && model == 'gpt') + { + send_to_chatgpt(req, res, chats); + } + else + { + send_to_gemini(req, res, chats); } + }); export default router; \ No newline at end of file diff --git a/src/routes/api.ai/send_to_chatgpt.ts b/src/routes/api.ai/send_to_chatgpt.ts new file mode 100644 index 0000000..da580a1 --- /dev/null +++ b/src/routes/api.ai/send_to_chatgpt.ts @@ -0,0 +1,148 @@ +import type { Request, Response } from 'express'; +import OpenAI from "openai"; +import { Chat } from './types.js'; +import notes_db from '../../assets/ts/notes.js'; +import { getMCPService } from '../../mcp.js'; + +const AIclient = new OpenAI({ apiKey: process.env.OPENAI_SECRET_KEY }); + +export default async function send_to_chatgpt +(req: Request, res: Response, chats: Chat[]) +{ + + const { uuid, message } = req.body; + const note = req.body?.note || undefined; + + try { + const chat = chats.find(chat => chat.uuid == uuid); + + if (!chat) { + res.json({ error: true, message: 'Chat non trouvé' }); + return; + } + + // Préparer le prompt + let prompt: string = ''; + + if (!note) { + prompt = `Message de l'utilisateur : ${message}`; + } else { + let db_note = (await notes_db.getNoteByUUID(note)).note; + if (db_note) { + db_note = { ...db_note, content: db_note.content.replace(/]*>/g, '') }; + } + prompt = `Note ouverte : ${JSON.stringify({ db_note })}\n Message de l'utilisateur : ${message}`; + } + + chat.messages.push({ + role: 'user', + content: prompt + }); + + // Obtenir le service MCP + const mcpService = getMCPService(); + await mcpService.ensureConnected(); + + // Obtenir les outils MCP au format OpenAI + const mcpTools = mcpService.getOpenAITools(); + + // Configuration SSE + res.setHeader("Content-Type", "text/event-stream"); + res.setHeader("Cache-Control", "no-cache"); + res.setHeader("Connection", "keep-alive"); + res.flushHeaders(); + res.socket?.setNoDelay(true); + + let conversationMessages = [...chat.messages.slice(-10)]; + let iterationCount = 0; + const maxIterations = 5; + + // Boucle pour gérer les appels d'outils + while (iterationCount < maxIterations) { + iterationCount++; + + // Appel à OpenAI avec les outils MCP + const stream = await AIclient.chat.completions.create({ + model: "gpt-5.1", + messages: conversationMessages, + tools: mcpTools.length > 0 ? mcpTools : undefined, + tool_choice: 'auto', + stream: true + }); + + let assistantMessage: string = ""; + let buffer: string = ''; + let toolCalls: any[] = []; + let currentToolCall: any = null; + + for await (const chunk of stream) { + const delta = chunk.choices[0]?.delta; + + // Gérer le contenu texte + if (delta?.content) { + const token = delta.content; + assistantMessage += token; + buffer += token; + res.write(`data: ${token}\n\n`); + } + + // Gérer les appels d'outils + if (delta?.tool_calls) { + for (const toolCallDelta of delta.tool_calls) { + if (toolCallDelta.index !== undefined) { + if (!toolCalls[toolCallDelta.index]) { + toolCalls[toolCallDelta.index] = { + id: toolCallDelta.id || '', + type: 'function', + function: { + name: toolCallDelta.function?.name || '', + arguments: '' + } + }; + } + + if (toolCallDelta.function?.arguments) { + toolCalls[toolCallDelta.index].function.arguments += toolCallDelta.function.arguments; + } + } + } + } + } + + // Ajouter le message de l'assistant + conversationMessages.push({ + role: 'assistant', + content: assistantMessage || null, + tool_calls: toolCalls.length > 0 ? toolCalls : undefined + } as any); + + chat.messages.push({ + role: 'assistant', + content: assistantMessage + }); + + // Si pas d'appel d'outil, on termine + if (toolCalls.length === 0) { + break; + } + + // Exécuter les appels d'outils via MCP + res.write(`data: [TOOLS:${toolCalls.map(tc => tc.function.name).join(',')}]\n\n`); + + const toolResults = await mcpService.handleToolCalls(toolCalls); + conversationMessages.push(...toolResults); + + // Envoyer les résultats au client + for (const result of toolResults) { + res.write(`data: [TOOL_RESULT:${result.content}]\n\n`); + } + } + + res.write("data: [DONE]\n\n"); + res.end(); + + } catch (err: any) { + console.error('Error in /send:', err); + res.status(500).json({ error: true, message: err.message }); + } +} \ No newline at end of file diff --git a/src/routes/api.ai/send_to_gemini.ts b/src/routes/api.ai/send_to_gemini.ts new file mode 100644 index 0000000..a6a412d --- /dev/null +++ b/src/routes/api.ai/send_to_gemini.ts @@ -0,0 +1,222 @@ +import type { Request, Response } from 'express'; +import { GoogleGenerativeAI, Content, Part } from '@google/generative-ai'; +import notes_db from '../../assets/ts/notes.js'; +import { getMCPService } from '../../mcp.js'; +import { UUID } from 'crypto'; + +export interface Chat { + uuid: UUID; + userID: string; + data: { notes: any; tags: any }; + messages: { content: string, role: string }[]; +} + +const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY || ''); + +export default async function send_to_gemini +(req: Request, res: Response, chats: Chat[]) +{ + + const { uuid, message } = req.body; + const note = req.body?.note || undefined; + + try { + const chat = chats.find(chat => chat.uuid == uuid); + + if (!chat) { + res.json({ error: true, message: 'Chat non trouvé' }); + return; + } + + // Préparer le prompt + let prompt: string = ''; + + if (!note) { + prompt = `Message de l'utilisateur : ${message}`; + } else { + let db_note = (await notes_db.getNoteByUUID(note)).note; + if (db_note) { + db_note = { ...db_note, content: db_note.content.replace(/]*>/g, '') }; + } + prompt = `Note ouverte : ${JSON.stringify({ db_note })}\n Message de l'utilisateur : ${message}`; + } + + chat.messages.push({ + role: 'user', + content: prompt + }); + + + const mcpService = getMCPService(); + await mcpService.ensureConnected(); + + // Obtenir les outils MCP au format Gemini + const mcpTools = mcpService.getGeminiTools(); + + // Configuration SSE + res.setHeader("Content-Type", "text/event-stream"); + res.setHeader("Cache-Control", "no-cache"); + res.setHeader("Connection", "keep-alive"); + res.flushHeaders(); + res.socket?.setNoDelay(true); + + // Convertir les messages au format Gemini + const convertToGeminiMessages = (messages: any[]): Content[] => { + return messages + .filter(msg => msg.role !== 'system') + .map(msg => { + const parts: Part[] = []; + + if (msg.role === 'function') { + return { + role: 'function', + parts: [{ + functionResponse: { + name: msg.name || 'unknown_tool', + response: { content: msg.content } + } + }] + } as Content; + } + + if (msg.content) { + parts.push({ text: msg.content }); + } + + // if (msg.tool_calls && msg.tool_calls.length > 0) { + // for (const toolCall of msg.tool_calls) { + // parts.push({ + // functionCall: { + // name: toolCall.function.name, + // args: JSON.parse(toolCall.function.arguments) + // } + // }); + // } + // } + + return { + role: msg.role === 'assistant' ? 'model' : 'user', + parts + } as Content; + }); + }; + + let conversationMessages = [...chat.messages.slice(-10)]; + let iterationCount = 0; + const maxIterations = 5; + + // Extraire le system message s'il existe + const systemMessage = conversationMessages.find(m => m.role === 'system'); + + // Boucle pour gérer les appels d'outils + while (iterationCount < maxIterations) { + iterationCount++; + + // Configurer le modèle Gemini + const model = genAI.getGenerativeModel({ + model: "gemini-2.5-pro", + systemInstruction: systemMessage?.content, + tools: mcpTools.length > 0 ? [{ + functionDeclarations: mcpTools + }] : undefined + }); + + // Convertir l'historique au format Gemini + const geminiHistory = convertToGeminiMessages(conversationMessages); + + // Démarrer le chat + const geminiChat = model.startChat({ + history: geminiHistory.slice(0, -1) // Tous sauf le dernier + }); + + // Envoyer le dernier message en streaming + const lastMessage = geminiHistory[geminiHistory.length - 1]; + const result = await geminiChat.sendMessageStream( + lastMessage.parts[0].text || '' + ); + + let assistantMessage: string = ""; + let buffer: string = ''; + let toolCalls: any[] = []; + + for await (const chunk of result.stream) { + const candidate = chunk.candidates?.[0]; + + if (!candidate) continue; + + // Gérer le contenu texte + if (candidate.content?.parts) { + for (const part of candidate.content.parts) { + if (part.text) { + const token = part.text; + assistantMessage += token; + buffer += token; + res.write(`data: ${token}\n\n`); + } + + // Gérer les appels d'outils + if (part.functionCall) { + const toolCall = { + id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, + type: 'function' as const, + function: { + name: part.functionCall.name, + arguments: JSON.stringify(part.functionCall.args) + } + }; + + toolCalls.push(toolCall); + } + } + } + } + + // Ajouter le message de l'assistant + conversationMessages.push({ + role: 'function', + content: assistantMessage || null, + tool_calls: toolCalls.length > 0 ? toolCalls : undefined + } as any); + + chat.messages.push({ + role: 'function', + content: assistantMessage + }); + + // Si pas d'appel d'outil, on termine + if (toolCalls.length === 0) { + break; + } + + // Exécuter les appels d'outils via MCP + res.write(`data: [TOOLS:${toolCalls.map(tc => tc.function.name).join(',')}]\n\n`); + + const toolResults = await mcpService.handleToolCallsGemini(toolCalls); + + // Convertir les résultats au format compatible + for (const result of toolResults) { + conversationMessages.push({ + role: 'function', + //name: result.name, + content: result.content + }); + + res.write(`data: [TOOL_RESULT:${result.content}]\n\n`); + } + } + + res.write("data: [DONE]\n\n"); + res.end(); + + } catch (err: any) { + console.error('Error in /send:', err); + + if (!res.headersSent) { + res.status(500).json({ error: true, message: err.message }); + } else { + res.write(`data: [ERROR]${err.message}\n\n`); + res.end(); + } + } + +} \ No newline at end of file diff --git a/src/routes/api.ai/types.ts b/src/routes/api.ai/types.ts new file mode 100644 index 0000000..c00e824 --- /dev/null +++ b/src/routes/api.ai/types.ts @@ -0,0 +1,9 @@ +import { UUID } from "crypto"; +import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions'; + +export interface Chat { + uuid: UUID; + userID: string; + data: { notes: any; tags: any }; + messages: ChatCompletionMessageParam[]; +} diff --git a/src/routes/api.ts b/src/routes/api.ts index 6777f24..3890029 100644 --- a/src/routes/api.ts +++ b/src/routes/api.ts @@ -13,7 +13,7 @@ const router = Router(); router.get('/get_news', async (req: Request, res: Response) => { - const data = await fs.promises.readFile('./dist/config.json', 'utf-8'); + const data = await fs.promises.readFile('./dist/config.json', 'utf-8'); // remettre ./config pour prod const news: Promise = JSON.parse(data).news; res.json( (await news).active ? news : false ); diff --git a/src/ws.ts b/src/ws.ts index b8c704b..c33c620 100644 --- a/src/ws.ts +++ b/src/ws.ts @@ -45,14 +45,18 @@ io.on("connection", (socket) => { console.log("Client connected :", socket.id); socket.on("join-room", async ({ room, userId }: { room: string, userId?: string }) => { + if (!room) return; socket.join(room); let docData = docs.get(room); if (!docData) { + const ydoc = new Y.Doc(); - new Y.Text(); + + // TipTap stocke le contenu ProseMirror dans un XmlFragment (pas utiliser de ytext) + const fragment = ydoc.getXmlFragment("prosemirror"); const awareness = new awarenessProtocol.Awareness(ydoc); const note = await get_note(room); @@ -60,21 +64,26 @@ io.on("connection", (socket) => { const title = note?.title || ""; const icon = note?.icon || ""; - const saveNote = async () => { - const currentDoc = docs.get(room); - const currentNote = await get_note(room); - if (currentNote && currentDoc) { - await save_note({ - ...currentNote, - title: currentDoc.title, - icon: currentDoc.icon - }); - } - } + // Ne pas initialiser le contenu manuellement + // il sera géré par TipTap côté client - await saveNote(); + // const saveNote = async () => { + // const currentDoc = docs.get(room); + // const currentNote = await get_note(room); + // if (currentNote && currentDoc) { + // await save_note({ + // ...currentNote, + // title: currentDoc.title, + // icon: currentDoc.icon + // }); + // } + // } + // await saveNote(); + const saveInterval = setInterval(async () => { - await saveNote(); + // auto save gérer par le client !!! + clearInterval(saveInterval); + //await saveNote(); }, 10000); docs.set(room, { ydoc, awareness, saveInterval, title, icon }); @@ -83,59 +92,86 @@ io.on("connection", (socket) => { const { ydoc, awareness } = docData; - // Envoi de l'état complet const initialState = Y.encodeStateAsUpdate(ydoc); - socket.emit("sync", initialState); + + const stateArray = Array.from(initialState); + socket.emit("sync", stateArray); + + socket.emit("title-update", docData.title); + socket.emit("icon-update", docData.icon); + if (userId) { socket.emit('new_user', userId); } - socket.on("y-update", async (update: Uint8Array) => { + socket.on("y-update", async (update: Uint8Array | number[]) => + { + try { - - const uint8Array = new Uint8Array(update); + + const uint8Array = update instanceof Uint8Array + ? update + : new Uint8Array(update); + Y.applyUpdate(ydoc, uint8Array); - socket.to(room).emit("y-update", uint8Array); - + socket.to(room).emit("y-update", Array.from(uint8Array)); + } catch (error) { console.error("Error applying update:", error); } + }); - socket.on('title-update', async (update: string) => { + socket.on('title-update', async (update: string) => + { + try { + const currentDoc = docs.get(room); - if (currentDoc) { + + if (currentDoc) + { currentDoc.title = update; socket.to(room).emit("title-update", update); - console.log('title update : ', update) } + } catch (error) { console.error("Error applying update:", error); } + }); - socket.on('icon-update', async (update: string) => { + socket.on('icon-update', async (update: string) => + { + try { + const currentDoc = docs.get(room); - if (currentDoc) { + + if (currentDoc) + { currentDoc.icon = update; socket.to(room).emit("icon-update", update); } + } catch (error) { console.error("Error applying update:", error); } + }) - socket.on("awareness-update", (update: Uint8Array) => { + socket.on("awareness-update", (update: Uint8Array | number[]) => + { try { - const uint8Array = new Uint8Array(update); + const uint8Array = update instanceof Uint8Array + ? update + : new Uint8Array(update); awarenessProtocol.applyAwarenessUpdate(awareness, uint8Array, socket); - socket.to(room).emit("awareness-update", uint8Array); + socket.to(room).emit("awareness-update", Array.from(uint8Array)); } catch (error) { console.error("Error applying awareness update:", error); @@ -143,16 +179,21 @@ io.on("connection", (socket) => { }); - socket.on('ai-command', async (data: { command: string; content: any }) => { + socket.on('ai-command', async (data: { command: string; content: any }) => + { + console.log(`AI command received in room ${room}:`, data.command); try { + if (data.command === 'insertContent') { io.to(room).emit('ai-command', data); } + } catch (error) { console.error("Error handling AI command:", error); } + }); socket.on("disconnect", async () => { @@ -164,13 +205,19 @@ io.on("connection", (socket) => { if (!docData) return; const { ydoc, saveInterval } = docData; - const content = ydoc.getText("prosemirror").toString(); + + // info de claude pour passer autosave dans back // + + // Pour sauvegarder en HTML, vous devrez utiliser une librairie + // comme prosemirror-model pour convertir le XmlFragment en HTML + // Pour l'instant, on sauvegarde juste les métadonnées + // Le contenu sera sauvegardé via l'autosave périodique côté client const note: Note | undefined = await get_note(roomId); if (note) { await save_note({ ...note, - content, + // contenu maj avec autosave du client title: docData.title, icon: docData.icon }); @@ -179,7 +226,6 @@ io.on("connection", (socket) => { awareness.setLocalState(null); if (room && io.sockets.adapter.rooms.get(room)?.size === 0) { - // Clear the save interval when the last user leaves if (saveInterval) { clearInterval(saveInterval); } @@ -187,21 +233,12 @@ io.on("connection", (socket) => { } console.log("Client disconnected:", socket.id); - }); - - }); - - }); - - console.log("Socket.IO server running..."); - -// Démarrage serveur httpServer.listen('3434', () => { console.log(`Serveur WebSocket sur le port 3434`); -}); +}); \ No newline at end of file