diff --git a/package-lock.json b/package-lock.json index f6a71eb..518446f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,17 +16,17 @@ "devDependencies": { "@babel/preset-env": "7.29.0", "@babel/preset-typescript": "7.28.5", - "@eslint/js": "9.39.2", + "@eslint/js": "9.39.3", "@types/jest": "30.0.0", "babel-jest": "30.2.0", - "eslint": "9.39.2", + "eslint": "9.39.3", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "eslint-plugin-prettier": "5.5.5", - "globals": "17.3.0", + "globals": "17.4.0", "jest": "30.2.0", "typescript": "5.9.3", - "typescript-eslint": "8.54.0" + "typescript-eslint": "8.56.1" } }, "node_modules/@ampproject/remapping": { @@ -1969,23 +1969,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -2019,17 +2002,10 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@eslint/eslintrc/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==", - "dev": true, - "license": "MIT" - }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.3.tgz", + "integrity": "sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==", "dev": true, "license": "MIT", "engines": { @@ -2888,17 +2864,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", - "integrity": "sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.1.tgz", + "integrity": "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/type-utils": "8.54.0", - "@typescript-eslint/utils": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/type-utils": "8.56.1", + "@typescript-eslint/utils": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -2911,8 +2887,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.54.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -2927,17 +2903,17 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.54.0.tgz", - "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.1.tgz", + "integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "engines": { @@ -2948,19 +2924,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.54.0.tgz", - "integrity": "sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.54.0", - "@typescript-eslint/types": "^8.54.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -2975,14 +2951,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.54.0.tgz", - "integrity": "sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2993,9 +2969,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.54.0.tgz", - "integrity": "sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, "license": "MIT", "engines": { @@ -3010,15 +2986,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.54.0.tgz", - "integrity": "sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.1.tgz", + "integrity": "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/utils": "8.54.0", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -3030,14 +3006,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.54.0.tgz", - "integrity": "sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, "license": "MIT", "engines": { @@ -3049,18 +3025,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.54.0.tgz", - "integrity": "sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.54.0", - "@typescript-eslint/tsconfig-utils": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/visitor-keys": "8.54.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -3076,36 +3052,49 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/typescript-estree/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==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -3116,16 +3105,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.54.0.tgz", - "integrity": "sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.54.0", - "@typescript-eslint/types": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3135,19 +3124,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.54.0.tgz", - "integrity": "sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.54.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.1", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3157,6 +3146,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", @@ -3457,6 +3459,23 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -4537,9 +4556,9 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "9.39.3", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.3.tgz", + "integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==", "dev": true, "license": "MIT", "peer": true, @@ -4550,7 +4569,7 @@ "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", + "@eslint/js": "9.39.3", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -4769,23 +4788,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/eslint/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4803,13 +4805,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/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==", - "dev": true, - "license": "MIT" - }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -5325,13 +5320,13 @@ } }, "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==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5341,9 +5336,9 @@ } }, "node_modules/globals": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.3.0.tgz", - "integrity": "sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", "dev": true, "license": "MIT", "engines": { @@ -6801,6 +6796,13 @@ "dev": true, "license": "MIT" }, + "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==", + "dev": true, + "license": "MIT" + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -6980,9 +6982,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -8498,16 +8500,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.54.0.tgz", - "integrity": "sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.1.tgz", + "integrity": "sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.54.0", - "@typescript-eslint/parser": "8.54.0", - "@typescript-eslint/typescript-estree": "8.54.0", - "@typescript-eslint/utils": "8.54.0" + "@typescript-eslint/eslint-plugin": "8.56.1", + "@typescript-eslint/parser": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1", + "@typescript-eslint/utils": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8517,7 +8519,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, diff --git a/package.json b/package.json index 2853e36..4b80f13 100644 --- a/package.json +++ b/package.json @@ -40,16 +40,16 @@ "devDependencies": { "@babel/preset-env": "7.29.0", "@babel/preset-typescript": "7.28.5", - "@eslint/js": "9.39.2", + "@eslint/js": "9.39.3", "@types/jest": "30.0.0", "babel-jest": "30.2.0", - "eslint": "9.39.2", + "eslint": "9.39.3", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "eslint-plugin-prettier": "5.5.5", - "globals": "17.3.0", + "globals": "17.4.0", "jest": "30.2.0", "typescript": "5.9.3", - "typescript-eslint": "8.54.0" + "typescript-eslint": "8.56.1" } } diff --git a/src/StateTransitionClient.ts b/src/StateTransitionClient.ts index 411fafa..3b6fcb9 100644 --- a/src/StateTransitionClient.ts +++ b/src/StateTransitionClient.ts @@ -18,6 +18,6 @@ export class StateTransitionClient { } public submitCertificationRequest(certificationData: CertificationData): Promise { - return this.client.submitCertificationRequest(certificationData, false); + return this.client.submitCertificationRequest(certificationData); } } diff --git a/src/api/AggregatorClient.ts b/src/api/AggregatorClient.ts index 35a856c..30d7fc5 100644 --- a/src/api/AggregatorClient.ts +++ b/src/api/AggregatorClient.ts @@ -54,11 +54,8 @@ export class AggregatorClient implements IAggregatorClient { /** * @inheritDoc */ - public async submitCertificationRequest( - certificationData: CertificationData, - receipt: boolean = false, - ): Promise { - const request = await CertificationRequest.create(certificationData, receipt); + public async submitCertificationRequest(certificationData: CertificationData): Promise { + const request = await CertificationRequest.create(certificationData); const response = await this.transport.request( 'certification_request', diff --git a/src/api/CertificationRequest.ts b/src/api/CertificationRequest.ts index 31b6823..384e930 100644 --- a/src/api/CertificationRequest.ts +++ b/src/api/CertificationRequest.ts @@ -10,23 +10,20 @@ export class CertificationRequest { * Constructs a CertificationRequest instance. * @param {StateId} stateId Unique state identifier. * @param {CertificationData} certificationData Certification data. - * @param {boolean} receipt Optional flag to request a receipt. */ private constructor( public readonly stateId: StateId, public readonly certificationData: CertificationData, - public readonly receipt: boolean = false, ) {} /** * Create a new CertificationRequest instance. * @param {CertificationData} certificationData Certification data. - * @param {boolean} receipt Optional flag to request a receipt. * * @returns {Promise} A promise that resolves to a CertificationRequest instance. */ - public static async create(certificationData: CertificationData, receipt?: boolean): Promise { - return new CertificationRequest(await StateId.fromCertificationData(certificationData), certificationData, receipt); + public static async create(certificationData: CertificationData): Promise { + return new CertificationRequest(await StateId.fromCertificationData(certificationData), certificationData); } /** @@ -38,7 +35,6 @@ export class CertificationRequest { return CborSerializer.encodeArray( this.stateId.toCBOR(), this.certificationData.toCBOR(), - CborSerializer.encodeBoolean(this.receipt), CborSerializer.encodeUnsignedInteger(0), ); } diff --git a/src/api/CertificationResponse.ts b/src/api/CertificationResponse.ts index 1917e6b..848694c 100644 --- a/src/api/CertificationResponse.ts +++ b/src/api/CertificationResponse.ts @@ -1,13 +1,4 @@ -import { CertificationData } from './CertificationData.js'; -import { DataHasher } from '../crypto/hash/DataHasher.js'; -import { HashAlgorithm } from '../crypto/hash/HashAlgorithm.js'; -import { ISigningService } from '../crypto/ISigningService.js'; -import { Signature } from '../crypto/secp256k1/Signature.js'; -import { SigningService } from '../crypto/secp256k1/SigningService.js'; import { InvalidJsonStructureError } from '../InvalidJsonStructureError.js'; -import { CborDeserializer } from '../serialization/cbor/CborDeserializer.js'; -import { CborSerializer } from '../serialization/cbor/CborSerializer.js'; -import { HexConverter } from '../serialization/HexConverter.js'; /** * Possible results from the aggregator when submitting a certification request. @@ -36,99 +27,14 @@ export enum CertificationStatus { } export interface ICertificationResponseJson { - readonly receipt?: IReceiptJson; readonly status: CertificationStatus; } -/** - * Receipt information for a successful certification request. - */ -export interface IReceiptJson { - readonly publicKey: string; - readonly signature: string; -} - -/** - * Receipt object returned by the aggregator on certification request. - */ -class Receipt { - public constructor( - private readonly _publicKey: Uint8Array, - public readonly signature: Signature, - ) {} - - public get publicKey(): Uint8Array { - return new Uint8Array(this._publicKey); - } - - /** - * Parse a receipt object from CBOR bytes. - * @param {Uint8Array} bytes CBOR-encoded receipt - * @returns {Receipt} Parsed receipt - */ - public static fromCBOR(bytes: Uint8Array): Receipt { - const data = CborDeserializer.decodeArray(bytes); - return new Receipt(CborDeserializer.decodeByteString(data[0]), Signature.fromCBOR(data[1])); - } - - /** - * Parse a receipt object from JSON. - * @param {unknown} data Raw receipt - * @returns {Receipt} Parsed receipt - * @throws {InvalidJsonStructureError} InvalidJsonStructureError if the data does not match the expected shape - */ - public static fromJSON(data: unknown): Receipt { - if (!Receipt.isJSON(data)) { - throw new InvalidJsonStructureError(); - } - - return new Receipt(HexConverter.decode(data.publicKey), Signature.fromJSON(data.signature)); - } - - /** - * Check if the given data is a valid JSON receipt object. - * @param {unknown} data Raw receipt - * @returns {boolean} True if the data is a valid JSON receipt object - */ - public static isJSON(data: unknown): data is IReceiptJson { - return ( - typeof data === 'object' && - data !== null && - 'publicKey' in data && - typeof data.publicKey === 'string' && - 'signature' in data && - typeof data.signature === 'string' - ); - } - - /** - * Convert the receipt to CBOR bytes. - * @returns {Uint8Array} CBOR-encoded receipt - */ - public toCBOR(): Uint8Array { - return CborSerializer.encodeArray(CborSerializer.encodeByteString(this._publicKey), this.signature.toCBOR()); - } - - /** - * Convert the receipt to a JSON object. - * @returns {IReceiptJson} JSON representation of the receipt - */ - public toJSON(): IReceiptJson { - return { - publicKey: HexConverter.encode(this._publicKey), - signature: this.signature.toJSON(), - }; - } -} - /** * Response object returned by the aggregator on certification request. */ export class CertificationResponse { - public constructor( - public readonly status: CertificationStatus, - public receipt: Receipt | null, - ) {} + public constructor(public readonly status: CertificationStatus) {} /** * Create a new certification response. @@ -137,27 +43,7 @@ export class CertificationResponse { * @returns {CertificationResponse} Created certification response */ public static create(status: CertificationStatus): CertificationResponse { - return new CertificationResponse(status, null); - } - - /** - * Create a new certification response. - * @param {ISigningService} signingService Aggregator signing service - * @param {CertificationResponse} certificationData Certification data - * @param {CertificationStatus} status Certification response status - * - * @returns {Promise} Created certification response - */ - public static async createWithReceipt( - signingService: ISigningService, - certificationData: CertificationData, - status: CertificationStatus, - ): Promise { - const signature = await signingService.sign( - await new DataHasher(HashAlgorithm.SHA256).update(certificationData.toCBOR()).digest(), - ); - - return new CertificationResponse(status, new Receipt(signingService.publicKey, signature)); + return new CertificationResponse(status); } /** @@ -172,7 +58,7 @@ export class CertificationResponse { throw new InvalidJsonStructureError(); } - return new CertificationResponse(data.status, data.receipt ? Receipt.fromJSON(data.receipt) : null); + return new CertificationResponse(data.status); } /** @@ -198,26 +84,7 @@ export class CertificationResponse { */ public toJSON(): ICertificationResponseJson { return { - receipt: this.receipt?.toJSON(), status: this.status, }; } - - /** - * Verify the receipt of the commitment. - * - * @returns {boolean} True if the receipt is valid, false otherwise - */ - public async verifyReceipt(certificationData: CertificationData): Promise { - if (!this.receipt) { - throw new Error('Receipt is not part of the response.'); - } - - return SigningService.verifyWithPublicKey( - // TODO: Implement whenever this is implemented in aggregator - await certificationData.calculateLeafValue(), - this.receipt.signature.bytes, - this.receipt.publicKey, - ); - } } diff --git a/src/api/IAggregatorClient.ts b/src/api/IAggregatorClient.ts index 3d92cb5..85c197b 100644 --- a/src/api/IAggregatorClient.ts +++ b/src/api/IAggregatorClient.ts @@ -19,8 +19,7 @@ export interface IAggregatorClient { * Submit a transaction commitment for inclusion in the ledger. * * @param {CertificationData} certificationData The certification data to submit - * @param {boolean} receipt Require a signed receipt of the commitment, default is false * @returns Result status from the aggregator */ - submitCertificationRequest(certificationData: CertificationData, receipt: boolean): Promise; + submitCertificationRequest(certificationData: CertificationData): Promise; } diff --git a/tests/unit/api/CertificationRequestTest.ts b/tests/unit/api/CertificationRequestTest.ts index c1f8c33..2359794 100644 --- a/tests/unit/api/CertificationRequestTest.ts +++ b/tests/unit/api/CertificationRequestTest.ts @@ -4,8 +4,8 @@ import { CborSerializer } from '../../../src/serialization/cbor/CborSerializer.j import { HexConverter } from '../../../src/serialization/HexConverter.js'; describe('CertificationRequest', () => { - it('should encode and decode CBOR to exactly same object', async () => { - let request = await CertificationRequest.create( + it('should encode object to expected CBOR bytes', async () => { + const request = await CertificationRequest.create( CertificationData.fromCBOR( CborSerializer.encodeArray( HexConverter.decode('8301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), @@ -21,27 +21,7 @@ describe('CertificationRequest', () => { ); expect(HexConverter.encode(request.toCBOR())).toEqual( - '8458207191bb9f044715f712ca5e77e91b585cf892eb5755ae4d77231ad429c53cf661848301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798582000000000000000000000000000000000000000000000000000000000000000005820000000000000000000000000000000000000000000000000000000000000000058418c3f91708445bf0ddec220f0821461bcf84860a8769275f9930e798d1f645d157bb6a2998c61941108b0993c5aed6a7b92ccf31d11b50fe80d9ff93da392336a01f400', - ); - - request = await CertificationRequest.create( - CertificationData.fromCBOR( - CborSerializer.encodeArray( - HexConverter.decode('8301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString( - HexConverter.decode( - '8c3f91708445bf0ddec220f0821461bcf84860a8769275f9930e798d1f645d157bb6a2998c61941108b0993c5aed6a7b92ccf31d11b50fe80d9ff93da392336a01', - ), - ), - ), - ), - true, - ); - - expect(HexConverter.encode(request.toCBOR())).toEqual( - '8458207191bb9f044715f712ca5e77e91b585cf892eb5755ae4d77231ad429c53cf661848301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798582000000000000000000000000000000000000000000000000000000000000000005820000000000000000000000000000000000000000000000000000000000000000058418c3f91708445bf0ddec220f0821461bcf84860a8769275f9930e798d1f645d157bb6a2998c61941108b0993c5aed6a7b92ccf31d11b50fe80d9ff93da392336a01f500', + '8358207191bb9f044715f712ca5e77e91b585cf892eb5755ae4d77231ad429c53cf661848301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798582000000000000000000000000000000000000000000000000000000000000000005820000000000000000000000000000000000000000000000000000000000000000058418c3f91708445bf0ddec220f0821461bcf84860a8769275f9930e798d1f645d157bb6a2998c61941108b0993c5aed6a7b92ccf31d11b50fe80d9ff93da392336a0100', ); }); }); diff --git a/tests/unit/api/CertificationResponseTest.ts b/tests/unit/api/CertificationResponseTest.ts index 63d71f2..499ad4e 100644 --- a/tests/unit/api/CertificationResponseTest.ts +++ b/tests/unit/api/CertificationResponseTest.ts @@ -1,17 +1,11 @@ -import { CertificationData } from '../../../src/api/CertificationData.js'; import { CertificationResponse, CertificationStatus } from '../../../src/api/CertificationResponse.js'; -import { SigningService } from '../../../src/crypto/secp256k1/SigningService.js'; import { InvalidJsonStructureError } from '../../../src/InvalidJsonStructureError.js'; -import { CborSerializer } from '../../../src/serialization/cbor/CborSerializer.js'; -import { HexConverter } from '../../../src/serialization/HexConverter.js'; describe('CertificationResponse', () => { - it('should encode and decode JSON to exactly same object', async () => { - // Test simple success response without receipt + it('should encode and decode JSON to exactly same object', () => { let response = CertificationResponse.fromJSON(CertificationResponse.create(CertificationStatus.SUCCESS).toJSON()); expect(response.status).toBe(CertificationStatus.SUCCESS); - expect(response.receipt).toBeNull(); // Test error response without receipt response = CertificationResponse.fromJSON( @@ -19,41 +13,6 @@ describe('CertificationResponse', () => { ); expect(response.status).toBe(CertificationStatus.INVALID_PUBLIC_KEY_FORMAT); - expect(response.receipt).toBeNull(); - - // Test response with all fields - const signingService = new SigningService( - new Uint8Array(HexConverter.decode('0000000000000000000000000000000000000000000000000000000000000001')), - ); - - response = await CertificationResponse.createWithReceipt( - signingService, - CertificationData.fromCBOR( - CborSerializer.encodeArray( - HexConverter.decode('8301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString( - HexConverter.decode( - '8c3f91708445bf0ddec220f0821461bcf84860a8769275f9930e798d1f645d157bb6a2998c61941108b0993c5aed6a7b92ccf31d11b50fe80d9ff93da392336a01', - ), - ), - ), - ), - CertificationStatus.SUCCESS, - ); - - const signature = response.receipt?.signature; - - response = CertificationResponse.fromJSON(response.toJSON()); - - expect(response.toJSON()).toEqual({ - receipt: { - publicKey: HexConverter.encode(signingService.publicKey), - signature: signature?.toJSON(), - }, - status: CertificationStatus.SUCCESS, - }); }); it('should validate JSON structure correctly', () => { @@ -72,56 +31,4 @@ describe('CertificationResponse', () => { expect(() => CertificationResponse.fromJSON(null)).toThrow(InvalidJsonStructureError); expect(() => CertificationResponse.fromJSON({ status: 123 })).toThrow(InvalidJsonStructureError); }); - - it('should verify receipt correctly', async () => { - const signingService = new SigningService( - new Uint8Array(HexConverter.decode('0000000000000000000000000000000000000000000000000000000000000001')), - ); - - const certificationData = CertificationData.fromCBOR( - CborSerializer.encodeArray( - HexConverter.decode('8301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString( - HexConverter.decode( - '8c3f91708445bf0ddec220f0821461bcf84860a8769275f9930e798d1f645d157bb6a2998c61941108b0993c5aed6a7b92ccf31d11b50fe80d9ff93da392336a01', - ), - ), - ), - ); - let response = await CertificationResponse.createWithReceipt( - signingService, - certificationData, - CertificationStatus.SUCCESS, - ); - - await expect(response.verifyReceipt(certificationData)).resolves.toBe(true); - - // Test that JSON serialization and deserialization preserves verification - response = CertificationResponse.fromJSON(response.toJSON()); - await expect(response.verifyReceipt(certificationData)).resolves.toBe(true); - - // Test with wrong signature should fail verification - const invalidCertificationData = CertificationData.fromCBOR( - CborSerializer.encodeArray( - HexConverter.decode('8301410158210279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString(new Uint8Array(32)), - CborSerializer.encodeByteString( - HexConverter.decode( - '8c3f91708445bf0ddec220f0821461bcf84860a8769275f9930e798d1f645d157bb6a2998c61941108b0993c5aed6a7b92ccf31d11b50fe80d9ff93da392336a00', - ), - ), - ), - ); - - await expect(response.verifyReceipt(invalidCertificationData)).resolves.toBe(false); - - // Test responses without receipt should fail verification - response = CertificationResponse.create(CertificationStatus.SUCCESS); - await expect(() => response.verifyReceipt(certificationData)).rejects.toThrow( - 'Receipt is not part of the response.', - ); - }); });