diff --git a/package-lock.json b/package-lock.json index 4200d0f..2984f66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -887,9 +887,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.0.tgz", - "integrity": "sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.1.tgz", + "integrity": "sha512-/pqA4DmqyCm8u5YIDzIdlLcEmuvxb0v8fZdFhVMszSpDTgbQKdw3/mB3eMUHIbubtJ6F9j+LtmyCnHTEqIHyzA==", "cpu": [ "arm" ], @@ -901,9 +901,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.0.tgz", - "integrity": "sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.32.1.tgz", + "integrity": "sha512-If3PDskT77q7zgqVqYuj7WG3WC08G1kwXGVFi9Jr8nY6eHucREHkfpX79c0ACAjLj3QIWKPJR7w4i+f5EdLH5Q==", "cpu": [ "arm64" ], @@ -915,9 +915,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.0.tgz", - "integrity": "sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.1.tgz", + "integrity": "sha512-zCpKHioQ9KgZToFp5Wvz6zaWbMzYQ2LJHQ+QixDKq52KKrF65ueu6Af4hLlLWHjX1Wf/0G5kSJM9PySW9IrvHA==", "cpu": [ "arm64" ], @@ -929,9 +929,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.0.tgz", - "integrity": "sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.32.1.tgz", + "integrity": "sha512-sFvF+t2+TyUo/ZQqUcifrJIgznx58oFZbdHS9TvHq3xhPVL9nOp+yZ6LKrO9GWTP+6DbFtoyLDbjTpR62Mbr3Q==", "cpu": [ "x64" ], @@ -943,9 +943,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.0.tgz", - "integrity": "sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.32.1.tgz", + "integrity": "sha512-NbOa+7InvMWRcY9RG+B6kKIMD/FsnQPH0MWUvDlQB1iXnF/UcKSudCXZtv4lW+C276g3w5AxPbfry5rSYvyeYA==", "cpu": [ "arm64" ], @@ -957,9 +957,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.0.tgz", - "integrity": "sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.32.1.tgz", + "integrity": "sha512-JRBRmwvHPXR881j2xjry8HZ86wIPK2CcDw0EXchE1UgU0ubWp9nvlT7cZYKc6bkypBt745b4bglf3+xJ7hXWWw==", "cpu": [ "x64" ], @@ -971,9 +971,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.0.tgz", - "integrity": "sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.32.1.tgz", + "integrity": "sha512-PKvszb+9o/vVdUzCCjL0sKHukEQV39tD3fepXxYrHE3sTKrRdCydI7uldRLbjLmDA3TFDmh418XH19NOsDRH8g==", "cpu": [ "arm" ], @@ -985,9 +985,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.0.tgz", - "integrity": "sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.32.1.tgz", + "integrity": "sha512-9WHEMV6Y89eL606ReYowXuGF1Yb2vwfKWKdD1A5h+OYnPZSJvxbEjxTRKPgi7tkP2DSnW0YLab1ooy+i/FQp/Q==", "cpu": [ "arm" ], @@ -999,9 +999,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.0.tgz", - "integrity": "sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.32.1.tgz", + "integrity": "sha512-tZWc9iEt5fGJ1CL2LRPw8OttkCBDs+D8D3oEM8mH8S1ICZCtFJhD7DZ3XMGM8kpqHvhGUTvNUYVDnmkj4BDXnw==", "cpu": [ "arm64" ], @@ -1013,9 +1013,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.0.tgz", - "integrity": "sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.32.1.tgz", + "integrity": "sha512-FTYc2YoTWUsBz5GTTgGkRYYJ5NGJIi/rCY4oK/I8aKowx1ToXeoVVbIE4LGAjsauvlhjfl0MYacxClLld1VrOw==", "cpu": [ "arm64" ], @@ -1027,9 +1027,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.0.tgz", - "integrity": "sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.32.1.tgz", + "integrity": "sha512-F51qLdOtpS6P1zJVRzYM0v6MrBNypyPEN1GfMiz0gPu9jN8ScGaEFIZQwteSsGKg799oR5EaP7+B2jHgL+d+Kw==", "cpu": [ "loong64" ], @@ -1041,9 +1041,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.0.tgz", - "integrity": "sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.32.1.tgz", + "integrity": "sha512-wO0WkfSppfX4YFm5KhdCCpnpGbtgQNj/tgvYzrVYFKDpven8w2N6Gg5nB6w+wAMO3AIfSTWeTjfVe+uZ23zAlg==", "cpu": [ "ppc64" ], @@ -1055,9 +1055,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.0.tgz", - "integrity": "sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.32.1.tgz", + "integrity": "sha512-iWswS9cIXfJO1MFYtI/4jjlrGb/V58oMu4dYJIKnR5UIwbkzR0PJ09O0PDZT0oJ3LYWXBSWahNf/Mjo6i1E5/g==", "cpu": [ "riscv64" ], @@ -1069,9 +1069,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.0.tgz", - "integrity": "sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.32.1.tgz", + "integrity": "sha512-RKt8NI9tebzmEthMnfVgG3i/XeECkMPS+ibVZjZ6mNekpbbUmkNWuIN2yHsb/mBPyZke4nlI4YqIdFPgKuoyQQ==", "cpu": [ "s390x" ], @@ -1083,9 +1083,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.0.tgz", - "integrity": "sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.32.1.tgz", + "integrity": "sha512-WQFLZ9c42ECqEjwg/GHHsouij3pzLXkFdz0UxHa/0OM12LzvX7DzedlY0SIEly2v18YZLRhCRoHZDxbBSWoGYg==", "cpu": [ "x64" ], @@ -1097,9 +1097,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.0.tgz", - "integrity": "sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.32.1.tgz", + "integrity": "sha512-BLoiyHDOWoS3uccNSADMza6V6vCNiphi94tQlVIL5de+r6r/CCQuNnerf+1g2mnk2b6edp5dk0nhdZ7aEjOBsA==", "cpu": [ "x64" ], @@ -1111,9 +1111,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.0.tgz", - "integrity": "sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.32.1.tgz", + "integrity": "sha512-w2l3UnlgYTNNU+Z6wOR8YdaioqfEnwPjIsJ66KxKAf0p+AuL2FHeTX6qvM+p/Ue3XPBVNyVSfCrfZiQh7vZHLQ==", "cpu": [ "arm64" ], @@ -1125,9 +1125,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.0.tgz", - "integrity": "sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.32.1.tgz", + "integrity": "sha512-Am9H+TGLomPGkBnaPWie4F3x+yQ2rr4Bk2jpwy+iV+Gel9jLAu/KqT8k3X4jxFPW6Zf8OMnehyutsd+eHoq1WQ==", "cpu": [ "ia32" ], @@ -1139,9 +1139,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.0.tgz", - "integrity": "sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.32.1.tgz", + "integrity": "sha512-ar80GhdZb4DgmW3myIS9nRFYcpJRSME8iqWgzH2i44u+IdrzmiXVxeFnExQ5v4JYUSpg94bWjevMG8JHf1Da5Q==", "cpu": [ "x64" ], @@ -1172,15 +1172,15 @@ "license": "MIT" }, "node_modules/@types/lodash": { - "version": "4.17.14", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.14.tgz", - "integrity": "sha512-jsxagdikDiDBeIRaPYtArcT8my4tN1og7MtMRquFT3XNA6axxyHDRUemqDz/taRDdOUn0GnGHRCuff4q48sW9A==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw==", "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.10.tgz", - "integrity": "sha512-X47y/mPNzxviAGY5TcYPtYL8JsY3kAq2n8fMmKoRCxq/c4v4pyGNCzM2R6+M5/umG4ZfHuT+sgqDYqWc9rJ6ww==", + "version": "22.12.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz", + "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", "dev": true, "license": "MIT", "dependencies": { @@ -2326,9 +2326,9 @@ "license": "MIT" }, "node_modules/loupe": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", - "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", "dev": true, "license": "MIT" }, @@ -2722,9 +2722,9 @@ } }, "node_modules/rollup": { - "version": "4.32.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.0.tgz", - "integrity": "sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==", + "version": "4.32.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.32.1.tgz", + "integrity": "sha512-z+aeEsOeEa3mEbS1Tjl6sAZ8NE3+AalQz1RJGj81M+fizusbdDMoEJwdJNHfaB40Scr4qNu+welOfes7maKonA==", "dev": true, "license": "MIT", "dependencies": { @@ -2738,25 +2738,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.32.0", - "@rollup/rollup-android-arm64": "4.32.0", - "@rollup/rollup-darwin-arm64": "4.32.0", - "@rollup/rollup-darwin-x64": "4.32.0", - "@rollup/rollup-freebsd-arm64": "4.32.0", - "@rollup/rollup-freebsd-x64": "4.32.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.32.0", - "@rollup/rollup-linux-arm-musleabihf": "4.32.0", - "@rollup/rollup-linux-arm64-gnu": "4.32.0", - "@rollup/rollup-linux-arm64-musl": "4.32.0", - "@rollup/rollup-linux-loongarch64-gnu": "4.32.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.32.0", - "@rollup/rollup-linux-riscv64-gnu": "4.32.0", - "@rollup/rollup-linux-s390x-gnu": "4.32.0", - "@rollup/rollup-linux-x64-gnu": "4.32.0", - "@rollup/rollup-linux-x64-musl": "4.32.0", - "@rollup/rollup-win32-arm64-msvc": "4.32.0", - "@rollup/rollup-win32-ia32-msvc": "4.32.0", - "@rollup/rollup-win32-x64-msvc": "4.32.0", + "@rollup/rollup-android-arm-eabi": "4.32.1", + "@rollup/rollup-android-arm64": "4.32.1", + "@rollup/rollup-darwin-arm64": "4.32.1", + "@rollup/rollup-darwin-x64": "4.32.1", + "@rollup/rollup-freebsd-arm64": "4.32.1", + "@rollup/rollup-freebsd-x64": "4.32.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.32.1", + "@rollup/rollup-linux-arm-musleabihf": "4.32.1", + "@rollup/rollup-linux-arm64-gnu": "4.32.1", + "@rollup/rollup-linux-arm64-musl": "4.32.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.32.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.32.1", + "@rollup/rollup-linux-riscv64-gnu": "4.32.1", + "@rollup/rollup-linux-s390x-gnu": "4.32.1", + "@rollup/rollup-linux-x64-gnu": "4.32.1", + "@rollup/rollup-linux-x64-musl": "4.32.1", + "@rollup/rollup-win32-arm64-msvc": "4.32.1", + "@rollup/rollup-win32-ia32-msvc": "4.32.1", + "@rollup/rollup-win32-x64-msvc": "4.32.1", "fsevents": "~2.3.2" } }, diff --git a/package.json b/package.json index 0e73123..ca4a2fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@octocloud/core", - "version": "1.0.66", + "version": "1.0.67", "license": "ISC", "author": "", "exports": { diff --git a/src/models/HeaderParser.ts b/src/models/HeaderParser.ts new file mode 100644 index 0000000..0293b04 --- /dev/null +++ b/src/models/HeaderParser.ts @@ -0,0 +1,25 @@ +export class HeaderParser { + public static getRetryAfterInSeconds(response: Response): number { + if (!response?.headers) { + return 0; + } + + const retryAfterHeader = response.headers.get('retry-after'); + if (retryAfterHeader === null) { + return 0; + } + + const retryAfterHeaderNumberValue = Number(retryAfterHeader); + if (Number.isFinite(retryAfterHeaderNumberValue)) { + return retryAfterHeaderNumberValue || 1; + } + + const retryDateMS = Date.parse(retryAfterHeader); + if (Number.isNaN(retryDateMS)) { + return 0; + } + + const deltaMS = retryDateMS - Date.now(); + return deltaMS > 0 ? Math.ceil(deltaMS / 1000) : 1; + } +} diff --git a/src/models/RequestContext.ts b/src/models/RequestContext.ts index 3776ab2..9fa8dfb 100644 --- a/src/models/RequestContext.ts +++ b/src/models/RequestContext.ts @@ -159,7 +159,7 @@ export class RequestContext { public getError = (): Error | null => this.error; - public setError = (error: Error): void => { + public setError = (error: Error | null): void => { this.error = error; }; diff --git a/src/models/__tests__/HeaderParser.test.ts b/src/models/__tests__/HeaderParser.test.ts new file mode 100644 index 0000000..6852474 --- /dev/null +++ b/src/models/__tests__/HeaderParser.test.ts @@ -0,0 +1,87 @@ +import { describe, expect, it, vi } from 'vitest'; +import { HeaderParser } from '../HeaderParser'; + +describe('HeaderParser.getRetryAfterInSeconds', () => { + it('should return 0 if response is null or undefined', () => { + expect(HeaderParser.getRetryAfterInSeconds(null as any)).toBe(0); + expect(HeaderParser.getRetryAfterInSeconds(undefined as any)).toBe(0); + }); + + it('should return 0 if response.headers is null or undefined', () => { + const response = { headers: null } as any; + expect(HeaderParser.getRetryAfterInSeconds(response)).toBe(0); + }); + + it('should return 0 if the "retry-after" header is not present', () => { + const response = { + headers: { + get: vi.fn().mockReturnValue(null), + }, + } as unknown as Response; + + expect(HeaderParser.getRetryAfterInSeconds(response)).toBe(0); + expect(response.headers.get).toHaveBeenCalledWith('retry-after'); + }); + + it('should return the numeric value if "retry-after" header is a valid number', () => { + const response = { + headers: { + get: vi.fn().mockReturnValue('10'), + }, + } as unknown as Response; + + expect(HeaderParser.getRetryAfterInSeconds(response)).toBe(10); + expect(response.headers.get).toHaveBeenCalledWith('retry-after'); + }); + + it('should return 1 if "retry-after" header is 0 or NaN when parsed as a number', () => { + const responseWithZero = { + headers: { + get: vi.fn().mockReturnValue('0'), + }, + } as unknown as Response; + + const responseWithNaN = { + headers: { + get: vi.fn().mockReturnValue('not-a-number'), + }, + } as unknown as Response; + + expect(HeaderParser.getRetryAfterInSeconds(responseWithZero)).toBe(1); + expect(HeaderParser.getRetryAfterInSeconds(responseWithNaN)).toBe(0); + }); + + it('should return the difference in seconds if "retry-after" is a valid date string in the future', () => { + const futureDate = new Date(Date.now() + 5000).toUTCString(); // 5 seconds in the future + const response = { + headers: { + get: vi.fn().mockReturnValue(futureDate), + }, + } as unknown as Response; + + expect(HeaderParser.getRetryAfterInSeconds(response)).toBeGreaterThanOrEqual(4); + expect(HeaderParser.getRetryAfterInSeconds(response)).toBeLessThanOrEqual(5); + }); + + it('should return 1 if "retry-after" is a valid date string in the past', () => { + const pastDate = new Date(Date.now() - 5000).toUTCString(); // 5 seconds in the past + const response = { + headers: { + get: vi.fn().mockReturnValue(pastDate), + }, + } as unknown as Response; + + expect(HeaderParser.getRetryAfterInSeconds(response)).toBe(1); + }); + + it('should return 0 if "retry-after" is an invalid date string', () => { + const invalidDate = 'invalid-date'; + const response = { + headers: { + get: vi.fn().mockReturnValue(invalidDate), + }, + } as unknown as Response; + + expect(HeaderParser.getRetryAfterInSeconds(response)).toBe(0); + }); +}); diff --git a/src/util/__tests__/fetchRetry.test.ts b/src/util/__tests__/fetchRetry.test.ts index e1201df..ed11313 100644 --- a/src/util/__tests__/fetchRetry.test.ts +++ b/src/util/__tests__/fetchRetry.test.ts @@ -691,13 +691,31 @@ describe('fetchRetry', () => { it('should succeed at third retry with successful response', async () => { global.fetch = vi .fn() - .mockReturnValueOnce(Promise.resolve(new Response('503 Service Unavailable', { status: 503 }))) - .mockReturnValueOnce(Promise.resolve(new Response('502 Bad Gateway', { status: 502 }))) + .mockReturnValueOnce( + Promise.resolve( + new Response('503 Service Unavailable', { status: 503, headers: { 'Retry-After': '1' } }), + ), + ) + .mockReturnValueOnce( + Promise.resolve(new Response('502 Bad Gateway', { status: 502, headers: { 'Retry-After': '2' } })), + ) .mockReturnValue(Promise.resolve(new Response('{}', { status: 200 }))); response = await fetchRetry(input, init, { retryDelayMultiplierInMs: RETRY_DELAY_MULTIPLIER_IN_MS }); expect(response.status).toBe(200); }); + it('should fail without any retries based on retry-again header', async () => { + global.fetch = vi + .fn() + .mockReturnValueOnce( + Promise.resolve( + new Response('500 Internal Server Error', { status: 500, headers: { 'Retry-After': '100' } }), + ), + ); + response = await fetchRetry(input, init, { retryDelayMultiplierInMs: RETRY_DELAY_MULTIPLIER_IN_MS }); + expect(response.status).toBe(500); + }); + it('should fail after three retries with server error response', async () => { global.fetch = vi .fn() diff --git a/src/util/fetchRetry.ts b/src/util/fetchRetry.ts index 3661e97..f07c757 100644 --- a/src/util/fetchRetry.ts +++ b/src/util/fetchRetry.ts @@ -1,3 +1,4 @@ +import { HeaderParser } from '../models/HeaderParser'; import { SubRequestContext } from '../models/SubRequestContext'; import { SubRequestRetryContext } from '../models/SubRequestRetryContext'; @@ -92,11 +93,13 @@ export async function fetchRetry( currentRetryAttempt++; + const retryAfterInSeconds = HeaderParser.getRetryAfterInSeconds(res); const status = res.status; if ( ((status >= 500 && status < 599) || status === 429 || (await shouldForceRetry(status, res.clone()))) && - currentRetryAttempt < maxRetryAttempts + currentRetryAttempt < maxRetryAttempts && + retryAfterInSeconds <= currentRetryAttempt ) { return await fetchRetry(request, undefined, { subRequestContext,