diff --git a/CHANGELOG.md b/CHANGELOG.md index 386b1c28..98200cf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## [1.7.15](https://github.com/Chia-Network/cadt/compare/1.7.14...1.7.15) (2024-05-13) +## [1.7.15](https://github.com/Chia-Network/cadt/compare/1.7.14...1.7.15) (2024-05-15) ### Bug Fixes @@ -8,6 +8,7 @@ * empty sync ([1a19a04](https://github.com/Chia-Network/cadt/commit/1a19a04907c11bd22f6b54b4d9c812df3a18d065)) * missing function ([4cf1159](https://github.com/Chia-Network/cadt/commit/4cf11598d008601bf248d39c31a522eeefcd1f13)) * missing function ([35230b9](https://github.com/Chia-Network/cadt/commit/35230b9d86c628487637009db0e975f3f97d2bf9)) +* null fix during sync ([2a28d13](https://github.com/Chia-Network/cadt/commit/2a28d138f3bd3956f57c4936159a52250148a972)) * registry id on sync status ([3678a9b](https://github.com/Chia-Network/cadt/commit/3678a9b161da6c9ffcb8d69feffc685f58beb9a2)) * sync status export ([61271c0](https://github.com/Chia-Network/cadt/commit/61271c00fb0ff8cdda4ec8223fe52e526aeac999)) * truncate staging only once ([2ff211d](https://github.com/Chia-Network/cadt/commit/2ff211dd98119f77fbc64494693315e9a558f470)) diff --git a/docs/cadt_rpc_api.md b/docs/cadt_rpc_api.md index 30f2b097..515befd5 100644 --- a/docs/cadt_rpc_api.md +++ b/docs/cadt_rpc_api.md @@ -126,7 +126,7 @@ POST Options: ```json // Request -curl --location -g --request POST 'localhost:31310/v1/organizations/' \ +curl --location -g --request POST 'localhost:31310/v1/organizations/create' \ --header 'Content-Type: application/json' \ --data-raw '{ "name": "Sample Org", diff --git a/package-lock.json b/package-lock.json index bb0c3988..8d742efc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cadt", - "version": "1.7.13", + "version": "1.7.15", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cadt", - "version": "1.7.13", + "version": "1.7.15", "dependencies": { "@babel/eslint-parser": "^7.23.10", "async-mutex": "^0.4.1", @@ -22,7 +22,7 @@ "lodash": "^4.17.21", "log-update": "^4.0.0", "multer": "^1.4.5-lts.1", - "mysql2": "^3.9.3", + "mysql2": "^3.9.7", "node-xlsx": "^0.23.0", "regenerator-runtime": "^0.13.11", "rxjs": "^7.8.1", @@ -64,14 +64,6 @@ "node": ">=16.13" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -85,9 +77,9 @@ } }, "node_modules/@babel/cli": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.24.1.tgz", - "integrity": "sha512-HbmrtxyFUr34LwAlV9jS+sSIjUp4FpdtIMGwgufY3AsxrIfsh/HxlMTywsONAZsU0RMYbZtbZFpUCrSGs7o0EA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.24.5.tgz", + "integrity": "sha512-2qg1mYtJRsOOWF6IUwLP5jI42P8Cc0hQ5TmnjLrik/4DKouO8dFJN80HEz81VmVeUs97yuuf3vQ/9j7Elrcjlg==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", @@ -134,20 +126,20 @@ } }, "node_modules/@babel/core": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz", - "integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz", + "integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.2", - "@babel/generator": "^7.24.4", + "@babel/generator": "^7.24.5", "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.4", - "@babel/parser": "^7.24.4", + "@babel/helper-module-transforms": "^7.24.5", + "@babel/helpers": "^7.24.5", + "@babel/parser": "^7.24.5", "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/traverse": "^7.24.5", + "@babel/types": "^7.24.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -171,9 +163,9 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.1.tgz", - "integrity": "sha512-d5guuzMlPeDfZIbpQ8+g1NaCNuAGBBGNECh0HVqz1sjOeVLh2CEaifuOysCH18URW6R7pqXINvf5PaR/dC6jLQ==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.5.tgz", + "integrity": "sha512-gsUcqS/fPlgAw1kOtpss7uhY6E9SFFANQ6EFX5GTvzUwaV0+sGaZWk6xq22MOdeT9wfxyokW3ceCUvOiRtZciQ==", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", @@ -184,7 +176,7 @@ }, "peerDependencies": { "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0" + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/@babel/eslint-parser/node_modules/semver": { @@ -196,11 +188,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz", - "integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz", + "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==", "dependencies": { - "@babel/types": "^7.24.0", + "@babel/types": "^7.24.5", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -257,19 +249,19 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz", - "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz", + "integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.24.5", "@babel/helper-optimise-call-expression": "^7.22.5", "@babel/helper-replace-supers": "^7.24.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-split-export-declaration": "^7.24.5", "semver": "^6.3.1" }, "engines": { @@ -315,9 +307,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz", - "integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -362,12 +354,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz", + "integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==", "dev": true, "dependencies": { - "@babel/types": "^7.23.0" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -385,15 +377,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz", + "integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.24.3", + "@babel/helper-simple-access": "^7.24.5", + "@babel/helper-split-export-declaration": "^7.24.5", + "@babel/helper-validator-identifier": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -415,9 +407,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", - "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz", + "integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==", "dev": true, "engines": { "node": ">=6.9.0" @@ -458,11 +450,11 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz", + "integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -481,11 +473,11 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz", + "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -500,9 +492,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz", + "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==", "engines": { "node": ">=6.9.0" } @@ -516,38 +508,38 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz", + "integrity": "sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" + "@babel/helper-function-name": "^7.23.0", + "@babel/template": "^7.24.0", + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz", - "integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz", + "integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==", "dependencies": { "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.1", - "@babel/types": "^7.24.0" + "@babel/traverse": "^7.24.5", + "@babel/types": "^7.24.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz", - "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz", + "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.5", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -557,9 +549,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz", - "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", + "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", "bin": { "parser": "bin/babel-parser.js" }, @@ -568,13 +560,13 @@ } }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz", - "integrity": "sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz", + "integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -944,12 +936,12 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz", - "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz", + "integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -992,18 +984,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz", - "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz", + "integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/helper-replace-supers": "^7.24.1", - "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-split-export-declaration": "^7.24.5", "globals": "^11.1.0" }, "engines": { @@ -1030,12 +1022,12 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz", - "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz", + "integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1349,15 +1341,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz", - "integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz", + "integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.24.1" + "@babel/plugin-transform-parameters": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1399,12 +1391,12 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz", - "integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz", + "integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, @@ -1416,12 +1408,12 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz", - "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz", + "integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1447,14 +1439,14 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz", - "integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz", + "integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==", "dev": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.24.1", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-create-class-features-plugin": "^7.24.5", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { @@ -1572,12 +1564,12 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz", - "integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz", + "integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.24.0" + "@babel/helper-plugin-utils": "^7.24.5" }, "engines": { "node": ">=6.9.0" @@ -1650,16 +1642,16 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.4.tgz", - "integrity": "sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz", + "integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.24.4", "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-plugin-utils": "^7.24.5", "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.4", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1", @@ -1686,12 +1678,12 @@ "@babel/plugin-transform-async-generator-functions": "^7.24.3", "@babel/plugin-transform-async-to-generator": "^7.24.1", "@babel/plugin-transform-block-scoped-functions": "^7.24.1", - "@babel/plugin-transform-block-scoping": "^7.24.4", + "@babel/plugin-transform-block-scoping": "^7.24.5", "@babel/plugin-transform-class-properties": "^7.24.1", "@babel/plugin-transform-class-static-block": "^7.24.4", - "@babel/plugin-transform-classes": "^7.24.1", + "@babel/plugin-transform-classes": "^7.24.5", "@babel/plugin-transform-computed-properties": "^7.24.1", - "@babel/plugin-transform-destructuring": "^7.24.1", + "@babel/plugin-transform-destructuring": "^7.24.5", "@babel/plugin-transform-dotall-regex": "^7.24.1", "@babel/plugin-transform-duplicate-keys": "^7.24.1", "@babel/plugin-transform-dynamic-import": "^7.24.1", @@ -1711,13 +1703,13 @@ "@babel/plugin-transform-new-target": "^7.24.1", "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1", "@babel/plugin-transform-numeric-separator": "^7.24.1", - "@babel/plugin-transform-object-rest-spread": "^7.24.1", + "@babel/plugin-transform-object-rest-spread": "^7.24.5", "@babel/plugin-transform-object-super": "^7.24.1", "@babel/plugin-transform-optional-catch-binding": "^7.24.1", - "@babel/plugin-transform-optional-chaining": "^7.24.1", - "@babel/plugin-transform-parameters": "^7.24.1", + "@babel/plugin-transform-optional-chaining": "^7.24.5", + "@babel/plugin-transform-parameters": "^7.24.5", "@babel/plugin-transform-private-methods": "^7.24.1", - "@babel/plugin-transform-private-property-in-object": "^7.24.1", + "@babel/plugin-transform-private-property-in-object": "^7.24.5", "@babel/plugin-transform-property-literals": "^7.24.1", "@babel/plugin-transform-regenerator": "^7.24.1", "@babel/plugin-transform-reserved-words": "^7.24.1", @@ -1725,7 +1717,7 @@ "@babel/plugin-transform-spread": "^7.24.1", "@babel/plugin-transform-sticky-regex": "^7.24.1", "@babel/plugin-transform-template-literals": "^7.24.1", - "@babel/plugin-transform-typeof-symbol": "^7.24.1", + "@babel/plugin-transform-typeof-symbol": "^7.24.5", "@babel/plugin-transform-unicode-escapes": "^7.24.1", "@babel/plugin-transform-unicode-property-regex": "^7.24.1", "@babel/plugin-transform-unicode-regex": "^7.24.1", @@ -1793,9 +1785,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", + "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", "dev": true, "dependencies": { "regenerator-runtime": "^0.14.0" @@ -1824,18 +1816,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz", - "integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz", + "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==", "dependencies": { - "@babel/code-frame": "^7.24.1", - "@babel/generator": "^7.24.1", + "@babel/code-frame": "^7.24.2", + "@babel/generator": "^7.24.5", "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.1", - "@babel/types": "^7.24.0", + "@babel/helper-split-export-declaration": "^7.24.5", + "@babel/parser": "^7.24.5", + "@babel/types": "^7.24.5", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1844,12 +1836,12 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.24.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz", + "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.1", + "@babel/helper-validator-identifier": "^7.24.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1865,13 +1857,13 @@ } }, "node_modules/@commitlint/cli": { - "version": "19.2.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.2.1.tgz", - "integrity": "sha512-cbkYUJsLqRomccNxvoJTyv5yn0bSy05BBizVyIcLACkRbVUqYorC351Diw/XFSWC/GtpwiwT2eOvQgFZa374bg==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.3.0.tgz", + "integrity": "sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==", "dev": true, "dependencies": { - "@commitlint/format": "^19.0.3", - "@commitlint/lint": "^19.1.0", + "@commitlint/format": "^19.3.0", + "@commitlint/lint": "^19.2.2", "@commitlint/load": "^19.2.0", "@commitlint/read": "^19.2.1", "@commitlint/types": "^19.0.3", @@ -1886,9 +1878,9 @@ } }, "node_modules/@commitlint/config-conventional": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.1.0.tgz", - "integrity": "sha512-KIKD2xrp6Uuk+dcZVj3++MlzIr/Su6zLE8crEDQCZNvWHNQSeeGbzOlNtsR32TUy6H3JbP7nWgduAHCaiGQ6EA==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", + "integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -1938,9 +1930,9 @@ } }, "node_modules/@commitlint/format": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.0.3.tgz", - "integrity": "sha512-QjjyGyoiVWzx1f5xOteKHNLFyhyweVifMgopozSgx1fGNrGV8+wp7k6n1t6StHdJ6maQJ+UUtO2TcEiBFRyR6Q==", + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.3.0.tgz", + "integrity": "sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -1963,9 +1955,9 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "19.0.3", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.0.3.tgz", - "integrity": "sha512-MqDrxJaRSVSzCbPsV6iOKG/Lt52Y+PVwFVexqImmYYFhe51iVJjK2hRhOG2jUAGiUHk4jpdFr0cZPzcBkSzXDQ==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.2.2.tgz", + "integrity": "sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==", "dev": true, "dependencies": { "@commitlint/types": "^19.0.3", @@ -1976,12 +1968,12 @@ } }, "node_modules/@commitlint/lint": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.1.0.tgz", - "integrity": "sha512-ESjaBmL/9cxm+eePyEr6SFlBUIYlYpI80n+Ltm7IA3MAcrmiP05UMhJdAD66sO8jvo8O4xdGn/1Mt2G5VzfZKw==", + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", + "integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^19.0.3", + "@commitlint/is-ignored": "^19.2.2", "@commitlint/parse": "^19.0.3", "@commitlint/rules": "^19.0.3", "@commitlint/types": "^19.0.3" @@ -2506,9 +2498,9 @@ "dev": true }, "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==" }, "node_modules/@tootallnate/once": { "version": "1.1.2", @@ -2520,9 +2512,9 @@ } }, "node_modules/@types/chai": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz", - "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==", + "version": "4.3.16", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz", + "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==", "dev": true }, "node_modules/@types/conventional-commits-parser": { @@ -2573,9 +2565,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.12.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.4.tgz", - "integrity": "sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==", + "version": "20.12.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz", + "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==", "dependencies": { "undici-types": "~5.26.4" } @@ -2607,9 +2599,9 @@ "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==" }, "node_modules/@types/validator": { - "version": "13.11.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", - "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" + "version": "13.11.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz", + "integrity": "sha512-e2PNXoXLr6Z+dbfx5zSh9TRlXJrELycxiaXznp4S5+D2M3b9bqJEitNHA5923jhnB2zzFiZHa2f0SI1HoIahpg==" }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", @@ -2697,15 +2689,15 @@ } }, "node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz", + "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "uri-js": "^4.4.1" }, "funding": { "type": "github", @@ -2871,19 +2863,16 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/babel-plugin-module-resolver": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.0.tgz", - "integrity": "sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.2.tgz", + "integrity": "sha512-9KtaCazHee2xc0ibfqsDeamwDps6FZNo5S0Q81dUqEuFzVwPhcT4J5jOqIVvgCA3Q/wO9hKYxN/Ds3tIsp5ygg==", "dev": true, "dependencies": { - "find-babel-config": "^2.0.0", - "glob": "^8.0.3", + "find-babel-config": "^2.1.1", + "glob": "^9.3.3", "pkg-up": "^3.1.0", "reselect": "^4.1.7", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">= 16" + "resolve": "^1.22.8" } }, "node_modules/babel-plugin-module-resolver/node_modules/brace-expansion": { @@ -2896,44 +2885,55 @@ } }, "node_modules/babel-plugin-module-resolver/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/babel-plugin-module-resolver/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/babel-plugin-module-resolver/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz", - "integrity": "sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.1", + "@babel/helper-define-polyfill-provider": "^0.6.2", "semver": "^6.3.1" }, "peerDependencies": { @@ -2963,12 +2963,12 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz", - "integrity": "sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.1" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -3319,9 +3319,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001606", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001606.tgz", - "integrity": "sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg==", + "version": "1.0.30001617", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz", + "integrity": "sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==", "funding": [ { "type": "opencollective", @@ -3338,13 +3338,13 @@ ] }, "node_modules/chai": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.0.tgz", - "integrity": "sha512-kDZ7MZyM6Q1DhR9jy7dalKohXQ2yrlXkk59CR52aRKxJrobmlBNqnFQxX9xOX8w+4mz8SYlKJa/7D7ddltFXCw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", + "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", "dev": true, "dependencies": { "assertion-error": "^2.0.1", - "check-error": "^2.0.0", + "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" @@ -3373,9 +3373,9 @@ } }, "node_modules/chai-http/node_modules/qs": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz", - "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", "dev": true, "dependencies": { "side-channel": "^1.0.6" @@ -3410,9 +3410,9 @@ } }, "node_modules/check-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.0.0.tgz", - "integrity": "sha512-tjLAOBHKVxtPoHe/SA7kNOMvhCRdCJ3vETdeY0RuAc9popf+hyaSV6ZEg9hr4cpWF7jmo/JSWEnLDrnijS9Tog==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "engines": { "node": ">= 16" @@ -4698,9 +4698,9 @@ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" }, "node_modules/core-js-compat": { - "version": "3.36.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.1.tgz", - "integrity": "sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA==", + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz", + "integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==", "dev": true, "dependencies": { "browserslist": "^4.23.0" @@ -5144,9 +5144,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.729", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.729.tgz", - "integrity": "sha512-bx7+5Saea/qu14kmPTDHQxkp2UnziG3iajUQu3BxFvCOnpAJdDbMV4rSl+EqFDkkpNNVUFlR1kDfpL59xfy1HA==" + "version": "1.4.764", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.764.tgz", + "integrity": "sha512-ZXbPV46Y4dNCA+k7YHB+BYlzcoMtZ1yH6V0tQ1ul0wmA7RiwJfS29LSdRlE1myWBXRzEgm/Lz6tryj5WVQiLmg==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -5382,9 +5382,9 @@ } }, "node_modules/eslint-plugin-mocha": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.1.tgz", - "integrity": "sha512-G85ALUgKaLzuEuHhoW3HVRgPTmia6njQC3qCG6CEvA8/Ja9PDZnRZOuzekMki+HaViEQXINuYsmhp5WR5/4MfA==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.3.tgz", + "integrity": "sha512-emc4TVjq5Ht0/upR+psftuz6IBG5q279p+1dSRDeHf+NS9aaerBi3lXKo1SEzwC29hFIW21gO89CEWSvRsi8IQ==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -6020,16 +6020,13 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/find-babel-config": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.0.0.tgz", - "integrity": "sha512-dOKT7jvF3hGzlW60Gc3ONox/0rRZ/tz7WCil0bqA1In/3I8f1BctpXahRnEKDySZqci7u+dqq93sZST9fOJpFw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.1.1.tgz", + "integrity": "sha512-5Ji+EAysHGe1OipH7GN4qDjok5Z1uw5KAwDCbicU/4wyTZY7CqOCzcWbG7J5ad9mazq67k89fXlbc1MuIfl9uA==", "dev": true, "dependencies": { - "json5": "^2.1.1", + "json5": "^2.2.3", "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" } }, "node_modules/find-cache-dir": { @@ -6996,9 +6993,9 @@ } }, "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "dev": true, "funding": { "type": "github", @@ -7286,9 +7283,9 @@ } }, "node_modules/joi": { - "version": "17.12.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.3.tgz", - "integrity": "sha512-2RRziagf555owrm9IRVtdKynOBeITiDpuZqIpgwqXShPncPKNiRQoiGsl/T8SQdq+8ugRzH2LqY67irr2y/d+g==", + "version": "17.13.1", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.1.tgz", + "integrity": "sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -7708,9 +7705,9 @@ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/loupe": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.0.tgz", - "integrity": "sha512-qKl+FrLXUhFuHUoDJG7f8P8gEMHq9NFS0c6ghXG1J0rldmZFQZoNVv/vyirE9qwCIhWZDsvEFd1sbFu3GvRQFg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", + "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", "dev": true, "dependencies": { "get-func-name": "^2.0.1" @@ -8407,9 +8404,9 @@ } }, "node_modules/mysql2": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.3.tgz", - "integrity": "sha512-+ZaoF0llESUy7BffccHG+urErHcWPZ/WuzYAA9TEeLaDYyke3/3D+VQDzK9xzRnXpd0eMtRf0WNOeo4Q1Baung==", + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.7.tgz", + "integrity": "sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw==", "dependencies": { "denque": "^2.1.0", "generate-function": "^2.3.1", @@ -8500,15 +8497,15 @@ } }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", "dev": true }, "node_modules/node-abi": { - "version": "3.57.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.57.0.tgz", - "integrity": "sha512-Dp+A9JWxRaKuHP35H77I4kCKesDy5HUDEmScia2FyncMTOXASMyg251F5PhFoDA5uqBrDDffiLpbqnrZmNXW+g==", + "version": "3.62.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.62.0.tgz", + "integrity": "sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==", "dependencies": { "semver": "^7.3.5" }, @@ -8715,16 +8712,16 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -8851,6 +8848,40 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "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==", + "dev": true, + "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.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz", + "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -9710,12 +9741,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "bin": { "semver": "bin/semver.js" }, @@ -9723,22 +9751,6 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -9786,9 +9798,9 @@ "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" }, "node_modules/sequelize": { - "version": "6.37.2", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.2.tgz", - "integrity": "sha512-bnb7swGANONXCTrVyebpOOZssLwQrVkYX2tcC6qOIvH+P+OhsoMBi7c3GXI5bC+Z4b4tOl+kQy6yeqLCZ1YQAQ==", + "version": "6.37.3", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.3.tgz", + "integrity": "sha512-V2FTqYpdZjPy3VQrZvjTPnOoLm0KudCRXfGWp48QwhyPPp2yW8z0p0sCYZd/em847Tl2dVxJJ1DR+hF+O77T7A==", "funding": [ { "type": "opencollective", @@ -10187,9 +10199,9 @@ } }, "node_modules/socks": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.1.tgz", - "integrity": "sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "optional": true, "dependencies": { "ip-address": "^9.0.5", @@ -10647,6 +10659,7 @@ "version": "8.1.2", "resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz", "integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==", + "deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net", "dependencies": { "component-emitter": "^1.3.0", "cookiejar": "^2.1.4", @@ -10968,9 +10981,9 @@ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" }, "node_modules/typescript": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz", - "integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "peer": true, "bin": { @@ -11078,9 +11091,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz", + "integrity": "sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==", "funding": [ { "type": "opencollective", @@ -11096,7 +11109,7 @@ } ], "dependencies": { - "escalade": "^3.1.1", + "escalade": "^3.1.2", "picocolors": "^1.0.0" }, "bin": { @@ -11155,9 +11168,9 @@ } }, "node_modules/validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", + "integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==", "engines": { "node": ">= 0.10" } @@ -11289,6 +11302,14 @@ "@types/node": "*" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", diff --git a/package.json b/package.json index 497b74ee..d069468d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cadt", - "version": "1.7.14", + "version": "1.7.15", "_comment": "DONT CHANGE MAJOR UNLESS DATAMODEL CHANGES: The major version corresponds to the datamodel version your using, so 2.0.0 means it'll use datamodel v2", "private": true, "bin": "build/server.js", @@ -45,7 +45,7 @@ "lodash": "^4.17.21", "log-update": "^4.0.0", "multer": "^1.4.5-lts.1", - "mysql2": "^3.9.3", + "mysql2": "^3.9.7", "node-xlsx": "^0.23.0", "regenerator-runtime": "^0.13.11", "rxjs": "^7.8.1", diff --git a/src/controllers/organization.controller.js b/src/controllers/organization.controller.js index e90c247f..b7c16486 100644 --- a/src/controllers/organization.controller.js +++ b/src/controllers/organization.controller.js @@ -27,6 +27,8 @@ export const homeOrgSyncStatus = async (req, res) => { where: { commited: true }, }); + const { sync_status } = await datalayer.getSyncStatus(homeOrg.orgUid); + return res.json({ ready: walletSynced && Boolean(homeOrg?.synced) && pendingCommitsCount === 0, @@ -34,6 +36,8 @@ export const homeOrgSyncStatus = async (req, res) => { wallet_synced: walletSynced, home_org_synced: Boolean(homeOrg?.synced), pending_commits: pendingCommitsCount, + home_org_profile_synced: + sync_status.target_root_hash === homeOrg.orgHash, }, success: true, }); diff --git a/src/datalayer/persistance.js b/src/datalayer/persistance.js index 9ece8832..1f1dd0dc 100644 --- a/src/datalayer/persistance.js +++ b/src/datalayer/persistance.js @@ -716,6 +716,34 @@ const cancelOffer = async (tradeId) => { } }; +const getSyncStatus = async (storeId) => { + const url = `${CONFIG.DATALAYER_URL}/get_sync_status`; + const { cert, key, timeout } = getBaseOptions(); + + try { + const response = await superagent + .post(url) + .key(key) + .cert(cert) + .timeout(timeout) + .send({ + id: storeId, + }); + + const data = response.body; + + // We just care that we got some response, not what the response is + if (Object.keys(data).includes('success')) { + return data; + } + + return false; + } catch (error) { + logger.error(error); + return false; + } +}; + export { addMirror, makeOffer, @@ -737,4 +765,5 @@ export { takeOffer, clearPendingRoots, getValue, + getSyncStatus, }; diff --git a/src/datalayer/writeService.js b/src/datalayer/writeService.js index bbe8d917..6ef7e76d 100644 --- a/src/datalayer/writeService.js +++ b/src/datalayer/writeService.js @@ -1,195 +1,200 @@ -import _ from 'lodash'; - -import * as dataLayer from './persistance'; -import wallet from './wallet'; -import * as simulator from './simulator'; -import { encodeHex, getMirrorUrl } from '../utils/datalayer-utils'; -import { getConfig } from '../utils/config-loader'; -import { logger } from '../config/logger.cjs'; -import { Organization } from '../models'; - -const { USE_SIMULATOR, AUTO_MIRROR_EXTERNAL_STORES } = getConfig().APP; - -const createDataLayerStore = async () => { - await wallet.waitForAllTransactionsToConfirm(); - - let storeId; - if (USE_SIMULATOR) { - storeId = await simulator.createDataLayerStore(); - } else { - storeId = await dataLayer.createDataLayerStore(); - - logger.info( - `Created storeId: ${storeId}, waiting for this to be confirmed on the blockchain.`, - ); - await waitForStoreToBeConfirmed(storeId); - await wallet.waitForAllTransactionsToConfirm(); - - // Default AUTO_MIRROR_EXTERNAL_STORES to true if it is null or undefined - // This make sure this runs by default even if the config param is missing - const shouldMirror = AUTO_MIRROR_EXTERNAL_STORES ?? true; - - if (shouldMirror) { - const mirrorUrl = await getMirrorUrl(); - await dataLayer.addMirror(storeId, mirrorUrl, true); - } - } - - return storeId; -}; - -const addMirror = async (storeId, url, force = false) => { - return dataLayer.addMirror(storeId, url, force); -}; - -const waitForStoreToBeConfirmed = async (storeId, retry = 0) => { - if (retry > 120) { - throw new Error( - `Creating storeId: ${storeId} timed out. Its possible the transaction is stuck.`, - ); - } - - const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId); - - if (!storeExistAndIsConfirmed) { - logger.info(`Still waiting for ${storeId} to confirm`); - await new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, 30000); - }); - return waitForStoreToBeConfirmed(storeId, retry + 1); - } - logger.info(`StoreId: ${storeId} has been confirmed. Congrats!`); -}; - -const syncDataLayer = async (storeId, data, failedCallback) => { - logger.info(`Syncing ${storeId}`); - const changeList = Object.keys(data).map((key) => { - return { - action: 'insert', - key: encodeHex(key), - value: encodeHex(data[key]), - }; - }); - - await pushChangesWhenStoreIsAvailable(storeId, changeList, failedCallback); -}; - -const upsertDataLayer = async (storeId, data) => { - logger.info(`Syncing ${storeId}`); - const homeOrg = await Organization.getHomeOrg(); - let changeList = Object.keys(data).map((key) => { - const change = []; - - if (homeOrg[key]) { - change.push({ - action: 'delete', - key: encodeHex(key), - }); - } - - change.push({ - action: 'insert', - key: encodeHex(key), - value: encodeHex(data[key]), - }); - return change; - }); - - const finalChangeList = _.uniqBy( - _.sortBy(_.flatten(_.values(changeList)), 'action'), - (v) => [v.action, v.key].join(), - ); - - await pushChangesWhenStoreIsAvailable(storeId, finalChangeList); -}; - -const retry = (storeId, changeList, failedCallback, retryAttempts) => { - logger.info(`Retrying pushing to store ${storeId}: ${retryAttempts}`); - if (retryAttempts >= 60) { - logger.info( - 'Could not push changelist to datalayer after retrying 10 times', - ); - failedCallback(); - return; - } - - setTimeout(async () => { - await pushChangesWhenStoreIsAvailable( - storeId, - changeList, - failedCallback, - retryAttempts + 1, - ); - }, 30000); -}; - -export const pushChangesWhenStoreIsAvailable = async ( - storeId, - changeList, - failedCallback = _.noop, - retryAttempts = 0, -) => { - if (USE_SIMULATOR) { - return simulator.pushChangeListToDataLayer(storeId, changeList); - } else { - const hasUnconfirmedTransactions = - await wallet.hasUnconfirmedTransactions(); - - const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId); - - if (!hasUnconfirmedTransactions && storeExistAndIsConfirmed) { - logger.info(`pushing to datalayer ${storeId}`); - - const success = await dataLayer.pushChangeListToDataLayer( - storeId, - changeList, - ); - - if (!success) { - logger.info( - `RPC failed when pushing to store ${storeId}, attempting retry.`, - ); - retry(storeId, changeList, failedCallback, retryAttempts); - } - } else { - retry(storeId, changeList, failedCallback, retryAttempts); - } - } -}; - -const pushDataLayerChangeList = (storeId, changeList, failedCallback) => { - pushChangesWhenStoreIsAvailable(storeId, changeList, failedCallback); -}; - -const dataLayerAvailable = async () => { - if (USE_SIMULATOR) { - return simulator.dataLayerAvailable(); - } else { - return dataLayer.dataLayerAvailable(); - } -}; - -const removeMirror = (storeId, coinId) => { - return dataLayer.removeMirror(storeId, coinId); -}; - -const getValue = async (storeId, key) => { - if (USE_SIMULATOR) { - return '7b22636f6d6d656e74223a2022227d'; - } else { - return dataLayer.getValue(storeId, key); - } -}; - -export default { - addMirror, - createDataLayerStore, - dataLayerAvailable, - pushDataLayerChangeList, - syncDataLayer, - upsertDataLayer, - removeMirror, - getValue, -}; +import _ from 'lodash'; + +import * as dataLayer from './persistance'; +import wallet from './wallet'; +import * as simulator from './simulator'; +import { encodeHex, getMirrorUrl } from '../utils/datalayer-utils'; +import { getConfig } from '../utils/config-loader'; +import { logger } from '../config/logger.cjs'; +import { Organization } from '../models'; + +const { USE_SIMULATOR, AUTO_MIRROR_EXTERNAL_STORES } = getConfig().APP; + +const createDataLayerStore = async () => { + await wallet.waitForAllTransactionsToConfirm(); + + let storeId; + if (USE_SIMULATOR) { + storeId = await simulator.createDataLayerStore(); + } else { + storeId = await dataLayer.createDataLayerStore(); + + logger.info( + `Created storeId: ${storeId}, waiting for this to be confirmed on the blockchain.`, + ); + await waitForStoreToBeConfirmed(storeId); + await wallet.waitForAllTransactionsToConfirm(); + + // Default AUTO_MIRROR_EXTERNAL_STORES to true if it is null or undefined + // This make sure this runs by default even if the config param is missing + const shouldMirror = AUTO_MIRROR_EXTERNAL_STORES ?? true; + + if (shouldMirror) { + const mirrorUrl = await getMirrorUrl(); + await dataLayer.addMirror(storeId, mirrorUrl, true); + } + } + + return storeId; +}; + +const addMirror = async (storeId, url, force = false) => { + return dataLayer.addMirror(storeId, url, force); +}; + +const waitForStoreToBeConfirmed = async (storeId, retry = 0) => { + if (retry > 120) { + throw new Error( + `Creating storeId: ${storeId} timed out. Its possible the transaction is stuck.`, + ); + } + + const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId); + + if (!storeExistAndIsConfirmed) { + logger.info(`Still waiting for ${storeId} to confirm`); + await new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, 30000); + }); + return waitForStoreToBeConfirmed(storeId, retry + 1); + } + logger.info(`StoreId: ${storeId} has been confirmed. Congrats!`); +}; + +const syncDataLayer = async (storeId, data, failedCallback) => { + logger.info(`Syncing ${storeId}`); + const changeList = Object.keys(data).map((key) => { + return { + action: 'insert', + key: encodeHex(key), + value: encodeHex(data[key]), + }; + }); + + await pushChangesWhenStoreIsAvailable(storeId, changeList, failedCallback); +}; + +const upsertDataLayer = async (storeId, data) => { + logger.info(`Syncing ${storeId}`); + const homeOrg = await Organization.getHomeOrg(); + let changeList = Object.keys(data).map((key) => { + const change = []; + + if (homeOrg[key]) { + change.push({ + action: 'delete', + key: encodeHex(key), + }); + } + + change.push({ + action: 'insert', + key: encodeHex(key), + value: encodeHex(data[key]), + }); + return change; + }); + + const finalChangeList = _.uniqBy( + _.sortBy(_.flatten(_.values(changeList)), 'action'), + (v) => [v.action, v.key].join(), + ); + + await pushChangesWhenStoreIsAvailable(storeId, finalChangeList); +}; + +const retry = (storeId, changeList, failedCallback, retryAttempts) => { + logger.info(`Retrying pushing to store ${storeId}: ${retryAttempts}`); + if (retryAttempts >= 60) { + logger.info( + 'Could not push changelist to datalayer after retrying 10 times', + ); + failedCallback(); + return; + } + + setTimeout(async () => { + await pushChangesWhenStoreIsAvailable( + storeId, + changeList, + failedCallback, + retryAttempts + 1, + ); + }, 30000); +}; + +export const pushChangesWhenStoreIsAvailable = async ( + storeId, + changeList, + failedCallback = _.noop, + retryAttempts = 0, +) => { + if (USE_SIMULATOR) { + return simulator.pushChangeListToDataLayer(storeId, changeList); + } else { + const hasUnconfirmedTransactions = + await wallet.hasUnconfirmedTransactions(); + + const storeExistAndIsConfirmed = await dataLayer.getRoot(storeId); + + if (!hasUnconfirmedTransactions && storeExistAndIsConfirmed) { + logger.info(`pushing to datalayer ${storeId}`); + + const success = await dataLayer.pushChangeListToDataLayer( + storeId, + changeList, + ); + + if (!success) { + logger.info( + `RPC failed when pushing to store ${storeId}, attempting retry.`, + ); + retry(storeId, changeList, failedCallback, retryAttempts); + } + } else { + retry(storeId, changeList, failedCallback, retryAttempts); + } + } +}; + +const pushDataLayerChangeList = (storeId, changeList, failedCallback) => { + pushChangesWhenStoreIsAvailable(storeId, changeList, failedCallback); +}; + +const dataLayerAvailable = async () => { + if (USE_SIMULATOR) { + return simulator.dataLayerAvailable(); + } else { + return dataLayer.dataLayerAvailable(); + } +}; + +const removeMirror = (storeId, coinId) => { + return dataLayer.removeMirror(storeId, coinId); +}; + +const getSyncStatus = (orgUid) => { + return dataLayer.getSyncStatus(orgUid); +}; + +const getValue = async (storeId, key) => { + if (USE_SIMULATOR) { + return '7b22636f6d6d656e74223a2022227d'; + } else { + return dataLayer.getValue(storeId, key); + } +}; + +export default { + addMirror, + createDataLayerStore, + dataLayerAvailable, + pushDataLayerChangeList, + syncDataLayer, + upsertDataLayer, + removeMirror, + getValue, + getSyncStatus, +}; diff --git a/src/tasks/sync-registries.js b/src/tasks/sync-registries.js index c67af761..11d251d4 100644 --- a/src/tasks/sync-registries.js +++ b/src/tasks/sync-registries.js @@ -138,6 +138,33 @@ const tryParseJSON = (jsonString, defaultValue) => { } }; +const truncateStaging = async () => { + logger.info(`ATTEMPTING TO TRUNCATE STAGING TABLE`); + + let success = false; + let attempts = 0; + const maxAttempts = 5; // Set a maximum number of attempts to avoid infinite loops + + while (!success && attempts < maxAttempts) { + try { + await Staging.truncate(); + success = true; // If truncate succeeds, set success to true to exit the loop + logger.info('STAGING TABLE TRUNCATED SUCCESSFULLY'); + } catch (error) { + attempts++; + logger.error( + `TRUNCATION FAILED ON ATTEMPT ${attempts}: ${error.message}`, + ); + if (attempts < maxAttempts) { + logger.info('WAITING 1 SECOND BEFORE RETRYING...'); + await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for 1 second + } else { + logger.error('MAXIMUM TRUNCATION ATTEMPTS REACHED, GIVING UP'); + } + } + } +}; + const syncOrganizationAudit = async (organization) => { try { let afterCommitCallbacks = []; @@ -250,6 +277,23 @@ const syncOrganizationAudit = async (organization) => { if (!CONFIG.USE_SIMULATOR) { await new Promise((resolve) => setTimeout(resolve, 30000)); + + const { sync_status } = await datalayer.getSyncStatus( + organization.registryId, + ); + + if (lastProcessedIndex > sync_status.generation) { + const warningMsg = [ + `No data found for ${organization.name} in the current datalayer generation.`, + `DataLayer not yet caught up to generation ${lastProcessedIndex}. The current processed generation is ${sync_status.generation}.`, + `This issue is often temporary and could be due to a lag in data propagation.`, + 'Syncing for this organization will be paused until this is resolved.', + 'For ongoing issues, please contact the organization.', + ].join(' '); + + logger.warn(warningMsg); + return; + } } logger.debug(`5 Last processed index: ${lastProcessedIndex}`); @@ -276,19 +320,6 @@ const syncOrganizationAudit = async (organization) => { root2.root_hash, ); - if (_.isEmpty(kvDiff)) { - const warningMsg = [ - `No data found for ${organization.name} in the current datalayer generation.`, - `Missing data for root hash: ${root2.root_hash}.`, - `This issue is often temporary and could be due to a lag in data propagation.`, - 'Syncing for this organization will be paused until this is resolved.', - 'For ongoing issues, please contact the organization.', - ].join(' '); - - logger.warn(warningMsg); - return; - } - const comment = kvDiff.filter( (diff) => (diff.key === encodeHex('comment') || @@ -312,91 +343,104 @@ const syncOrganizationAudit = async (organization) => { logger.info( `Syncing ${organization.name} generation ${toBeProcessedIndex}`, ); - for (const diff of optimizedKvDiff) { - const key = decodeHex(diff.key); - const modelKey = key.split('|')[0]; - + if (_.isEmpty(optimizedKvDiff)) { const auditData = { orgUid: organization.orgUid, registryId: organization.registryId, rootHash: root2.root_hash, - type: diff.type, - table: modelKey, - change: decodeHex(diff.value), + type: 'NO CHANGE', + table: null, + change: null, onchainConfirmationTimeStamp: root2.timestamp, generation: toBeProcessedIndex, - comment: _.get( - tryParseJSON( - decodeHex(_.get(comment, '[0].value', encodeHex('{}'))), + comment: '', + author: '', + }; + + await Audit.create(auditData, { transaction, mirrorTransaction }); + } else { + for (const diff of optimizedKvDiff) { + const key = decodeHex(diff.key); + const modelKey = key.split('|')[0]; + + const auditData = { + orgUid: organization.orgUid, + registryId: organization.registryId, + rootHash: root2.root_hash, + type: diff.type, + table: modelKey, + change: decodeHex(diff.value), + onchainConfirmationTimeStamp: root2.timestamp, + generation: toBeProcessedIndex, + comment: _.get( + tryParseJSON( + decodeHex(_.get(comment, '[0].value', encodeHex('{}'))), + ), + 'comment', + '', ), - 'comment', - '', - ), - author: _.get( - tryParseJSON( - decodeHex(_.get(author, '[0].value', encodeHex('{}'))), + author: _.get( + tryParseJSON( + decodeHex(_.get(author, '[0].value', encodeHex('{}'))), + ), + 'author', + '', ), - 'author', - '', - ), - }; + }; - if (modelKey && Object.keys(ModelKeys).includes(modelKey)) { - const record = JSON.parse(decodeHex(diff.value)); - const primaryKeyValue = - record[ModelKeys[modelKey].primaryKeyAttributes[0]]; + if (modelKey && Object.keys(ModelKeys).includes(modelKey)) { + const record = JSON.parse(decodeHex(diff.value)); + const primaryKeyValue = + record[ModelKeys[modelKey].primaryKeyAttributes[0]]; - if (diff.type === 'INSERT') { - logger.info(`UPSERTING: ${modelKey} - ${primaryKeyValue}`); - await ModelKeys[modelKey].upsert(record, { - transaction, - mirrorTransaction, - }); - } else if (diff.type === 'DELETE') { - logger.info(`DELETING: ${modelKey} - ${primaryKeyValue}`); - await ModelKeys[modelKey].destroy({ - where: { - [ModelKeys[modelKey].primaryKeyAttributes[0]]: primaryKeyValue, - }, - transaction, - mirrorTransaction, - }); - } + if (diff.type === 'INSERT') { + logger.info(`UPSERTING: ${modelKey} - ${primaryKeyValue}`); + + // Remove updatedAt fields if they exist + // This is because the db will update this field automatically and its not allowed to be null + delete record.updatedAt; + + // if createdAt is null, remove it, so that the db will update it automatically + // this field is also not allowed to be null + if (_.isNil(record.createdAt)) { + delete record.createdAt; + } - if (organization.orgUid === homeOrg?.orgUid) { - const stagingUuid = [ - 'unit', - 'project', - 'units', - 'projects', - ].includes(modelKey) - ? primaryKeyValue - : undefined; - - if (stagingUuid) { - afterCommitCallbacks.push(async () => { - logger.info(`DELETING STAGING: ${stagingUuid}`); - await Staging.destroy({ - where: { uuid: stagingUuid }, - }); + await ModelKeys[modelKey].upsert(record, { + transaction, + mirrorTransaction, + }); + } else if (diff.type === 'DELETE') { + logger.info(`DELETING: ${modelKey} - ${primaryKeyValue}`); + await ModelKeys[modelKey].destroy({ + where: { + [ModelKeys[modelKey].primaryKeyAttributes[0]]: + primaryKeyValue, + }, + transaction, + mirrorTransaction, }); } } - } - // Create the Audit record - await Audit.create(auditData, { transaction, mirrorTransaction }); - await Organization.update( - { registryHash: root2.root_hash }, - { - where: { orgUid: organization.orgUid }, - transaction, - mirrorTransaction, - }, - ); + // Create the Audit record + await Audit.create(auditData, { transaction, mirrorTransaction }); + await Organization.update( + { registryHash: root2.root_hash }, + { + where: { orgUid: organization.orgUid }, + transaction, + mirrorTransaction, + }, + ); + } } }; + if (organization.orgUid === homeOrg?.orgUid) { + afterCommitCallbacks.push(truncateStaging); + } + await createTransaction(updateTransaction, afterCommitCallbacks); } catch (error) { logger.error('Error syncing org audit', error); diff --git a/src/utils/data-assertions.js b/src/utils/data-assertions.js index d4d6b08a..fb9fc9b1 100644 --- a/src/utils/data-assertions.js +++ b/src/utils/data-assertions.js @@ -1,253 +1,245 @@ -'use strict'; - -import _ from 'lodash'; - -import { Organization, Unit, Project, Staging, Meta } from '../models'; -import datalayer from '../datalayer'; -import { formatModelAssociationName } from './model-utils.js'; -import { getConfig } from '../utils/config-loader'; - -const { IS_GOVERNANCE_BODY, READ_ONLY, USE_SIMULATOR, CHIA_NETWORK } = - getConfig().APP; - -export const assertChiaNetworkMatchInConfiguration = async () => { - if (!USE_SIMULATOR) { - const networkInfo = await datalayer.getActiveNetwork(); - const network = _.get(networkInfo, 'network_name', ''); - - if (!network.includes(CHIA_NETWORK)) { - throw new Error( - `Your node is on ${network} but your climate warehouse is set to ${CHIA_NETWORK}, please change your config so they match`, - ); - } - } -}; - -export const assertCanBeGovernanceBody = async () => { - if (!IS_GOVERNANCE_BODY) { - throw new Error( - 'You are not an governance body and can not use this functionality', - ); - } -}; - -export const assertIsActiveGovernanceBody = async () => { - const governanceBodyIsSetUp = Meta.findAll({ - where: { metaKey: 'governanceBodyId' }, - }); - - if (!governanceBodyIsSetUp) { - throw new Error( - 'You are not an governance body and can not use this functionality', - ); - } -}; - -export const assertDataLayerAvailable = async () => { - const isAvailable = await datalayer.dataLayerAvailable(); - - if (!isAvailable) { - throw new Error('Can not establish connection to Chia Datalayer'); - } -}; - -export const assertIfReadOnlyMode = async () => { - if (READ_ONLY) { - throw new Error('You can not use this API in read-only mode'); - } -}; - -export const assertNoPendingCommits = async () => { - if (USE_SIMULATOR) { - const pendingCommits = await Staging.findAll({ - where: { commited: true, failedCommit: false }, - raw: true, - }); - - if (pendingCommits.length > 0) { - throw new Error( - 'You currently have changes pending on the blockchain. Please wait for them to propagate before making more changes', - ); - } - } else { - if (await datalayer.hasUnconfirmedTransactions()) { - throw new Error( - 'You currently have changes pending on the blockchain. Please wait for them to propagate before making more changes', - ); - } - } -}; - -export const assertWalletIsSynced = async () => { - if (!USE_SIMULATOR) { - if (!(await datalayer.walletIsSynced())) { - throw new Error( - 'Your wallet is syncing, please wait for it to sync and try again', - ); - } - } -}; - -export const assertWalletIsAvailable = async () => { - if (!USE_SIMULATOR) { - if (!(await datalayer.walletIsAvailable())) { - throw new Error( - 'Your wallet is not available, please turn it on to continue using climate warehouse', - ); - } - } -}; - -export const assertRecordExistance = async (Model, pk) => { - const record = await Model.findByPk(pk); - if (!record) { - throw new Error(`${Model.name} does not have a record for ${pk}`); - } - - return record; -}; - -export const assertCanDeleteOrg = async (orgUid) => { - const homeOrg = await Organization.getHomeOrg(); - if (homeOrg.orgUid === orgUid) { - throw new Error(`Cant delete your own organization`); - } -}; - -export const assertHomeOrgExists = async () => { - const homeOrg = await Organization.getHomeOrg(); - if (!homeOrg) { - throw new Error( - `No Home organization found, please create an organization to write data`, - ); - } - - if (!homeOrg.subscribed) { - throw new Error( - `Your Home organization is still confirming, please wait a little longer for it to finished.`, - ); - } - - return homeOrg; -}; - -export const assertOrgUidIsValid = async (orgUid, fieldName) => { - const orgMap = await Organization.getOrgsMap(); - if (!orgMap[orgUid]) { - throw new Error( - `The orgUid: ${orgUid}, provided for '${fieldName}' is not in the list of subscribed organizations, either remove it or add it to your organizations and try again`, - ); - } - - return orgMap; -}; - -export const assertCsvFileInRequest = (req) => { - if (!req.file) { - throw new Error('Cannot find the required csv file in request'); - } - - return req.file; -}; - -export const assertOrgIsHomeOrg = async (orgUid) => { - const homeOrg = await Organization.getHomeOrg(); - - if (homeOrg.orgUid !== orgUid) { - throw new Error( - `Restricted data: can not modify this record with orgUid ${orgUid}`, - ); - } - - return orgUid; -}; - -export const assertUnitRecordExists = async ( - warehouseUnitId, - customMessage, -) => { - const record = await Unit.findByPk(warehouseUnitId, { - include: Unit.getAssociatedModels().map((association) => { - return { - model: association.model, - as: formatModelAssociationName(association), - }; - }), - }); - if (!record) { - throw new Error( - customMessage || - `The unit record for the warehouseUnitId: ${warehouseUnitId} does not exist.`, - ); - } - - return record.dataValues; -}; - -export const assertStagingTableNotEmpty = async () => { - const records = await Staging.findAll({ raw: true }); - - if (!records || records.length === 0) { - throw new Error(`Cant commit empty staging table`); - } -}; - -export const assertStagingRecordExists = async (stagingId) => { - const record = await Staging.findOne({ where: { uuid: stagingId } }); - - if (!record) { - throw new Error( - `The staging record for the staging ID: ${stagingId} does not exist.`, - ); - } - - return record.dataValues; -}; - -export const assertProjectRecordExists = async ( - warehouseProjectId, - customMessage, -) => { - const record = await Project.findByPk(warehouseProjectId, { - include: Project.getAssociatedModels().map( - (association) => association.model, - ), - }); - - if (!record) { - throw new Error( - customMessage || - `The project record for the warehouseProjectId: ${warehouseProjectId} does not exist.`, - ); - } - - return record.dataValues; -}; - -export const assertStagingTableIsEmpty = async (customMessage) => { - const count = await Staging.count({ raw: true }); - - if (count > 0) { - throw new Error(customMessage || `Staging table is not empty.`); - } -}; - -export const assertActiveOfferFile = async () => { - const activeOfferFile = await Meta.findOne({ - where: { metaKey: 'activeOffer' }, - }); - - if (!activeOfferFile) { - throw new Error(`There is no active offer pending`); - } -}; - -export const assertNoActiveOfferFile = async () => { - const activeOfferFile = await Meta.findOne({ - where: { metaKey: 'activeOffer' }, - }); - - if (activeOfferFile) { - throw new Error(`There is an active offer pending`); - } -}; +'use strict'; + +import _ from 'lodash'; + +import { Organization, Unit, Project, Staging, Meta } from '../models'; +import datalayer from '../datalayer'; +import { formatModelAssociationName } from './model-utils.js'; +import { getConfig } from '../utils/config-loader'; + +const { IS_GOVERNANCE_BODY, READ_ONLY, USE_SIMULATOR, CHIA_NETWORK } = + getConfig().APP; + +export const assertChiaNetworkMatchInConfiguration = async () => { + if (!USE_SIMULATOR) { + const networkInfo = await datalayer.getActiveNetwork(); + const network = _.get(networkInfo, 'network_name', ''); + + if (!network.includes(CHIA_NETWORK)) { + throw new Error( + `Your node is on ${network} but your climate warehouse is set to ${CHIA_NETWORK}, please change your config so they match`, + ); + } + } +}; + +export const assertCanBeGovernanceBody = async () => { + if (!IS_GOVERNANCE_BODY) { + throw new Error( + 'You are not an governance body and can not use this functionality', + ); + } +}; + +export const assertIsActiveGovernanceBody = async () => { + const governanceBodyIsSetUp = Meta.findAll({ + where: { metaKey: 'governanceBodyId' }, + }); + + if (!governanceBodyIsSetUp) { + throw new Error( + 'You are not an governance body and can not use this functionality', + ); + } +}; + +export const assertDataLayerAvailable = async () => { + const isAvailable = await datalayer.dataLayerAvailable(); + + if (!isAvailable) { + throw new Error('Can not establish connection to Chia Datalayer'); + } +}; + +export const assertIfReadOnlyMode = async () => { + if (READ_ONLY) { + throw new Error('You can not use this API in read-only mode'); + } +}; + +export const assertNoPendingCommits = async () => { + const pendingCommits = await Staging.findAll({ + where: { commited: true, failedCommit: false }, + raw: true, + }); + + if (pendingCommits.length > 0) { + throw new Error( + 'You currently have changes pending on the blockchain. Please wait for them to propagate before making more changes', + ); + } +}; + +export const assertWalletIsSynced = async () => { + if (!USE_SIMULATOR) { + if (!(await datalayer.walletIsSynced())) { + throw new Error( + 'Your wallet is syncing, please wait for it to sync and try again', + ); + } + } +}; + +export const assertWalletIsAvailable = async () => { + if (!USE_SIMULATOR) { + if (!(await datalayer.walletIsAvailable())) { + throw new Error( + 'Your wallet is not available, please turn it on to continue using climate warehouse', + ); + } + } +}; + +export const assertRecordExistance = async (Model, pk) => { + const record = await Model.findByPk(pk); + if (!record) { + throw new Error(`${Model.name} does not have a record for ${pk}`); + } + + return record; +}; + +export const assertCanDeleteOrg = async (orgUid) => { + const homeOrg = await Organization.getHomeOrg(); + if (homeOrg.orgUid === orgUid) { + throw new Error(`Cant delete your own organization`); + } +}; + +export const assertHomeOrgExists = async () => { + const homeOrg = await Organization.getHomeOrg(); + if (!homeOrg) { + throw new Error( + `No Home organization found, please create an organization to write data`, + ); + } + + if (!homeOrg.subscribed) { + throw new Error( + `Your Home organization is still confirming, please wait a little longer for it to finished.`, + ); + } + + return homeOrg; +}; + +export const assertOrgUidIsValid = async (orgUid, fieldName) => { + const orgMap = await Organization.getOrgsMap(); + if (!orgMap[orgUid]) { + throw new Error( + `The orgUid: ${orgUid}, provided for '${fieldName}' is not in the list of subscribed organizations, either remove it or add it to your organizations and try again`, + ); + } + + return orgMap; +}; + +export const assertCsvFileInRequest = (req) => { + if (!req.file) { + throw new Error('Cannot find the required csv file in request'); + } + + return req.file; +}; + +export const assertOrgIsHomeOrg = async (orgUid) => { + const homeOrg = await Organization.getHomeOrg(); + + if (homeOrg.orgUid !== orgUid) { + throw new Error( + `Restricted data: can not modify this record with orgUid ${orgUid}`, + ); + } + + return orgUid; +}; + +export const assertUnitRecordExists = async ( + warehouseUnitId, + customMessage, +) => { + const record = await Unit.findByPk(warehouseUnitId, { + include: Unit.getAssociatedModels().map((association) => { + return { + model: association.model, + as: formatModelAssociationName(association), + }; + }), + }); + if (!record) { + throw new Error( + customMessage || + `The unit record for the warehouseUnitId: ${warehouseUnitId} does not exist.`, + ); + } + + return record.dataValues; +}; + +export const assertStagingTableNotEmpty = async () => { + const records = await Staging.findAll({ raw: true }); + + if (!records || records.length === 0) { + throw new Error(`Cant commit empty staging table`); + } +}; + +export const assertStagingRecordExists = async (stagingId) => { + const record = await Staging.findOne({ where: { uuid: stagingId } }); + + if (!record) { + throw new Error( + `The staging record for the staging ID: ${stagingId} does not exist.`, + ); + } + + return record.dataValues; +}; + +export const assertProjectRecordExists = async ( + warehouseProjectId, + customMessage, +) => { + const record = await Project.findByPk(warehouseProjectId, { + include: Project.getAssociatedModels().map( + (association) => association.model, + ), + }); + + if (!record) { + throw new Error( + customMessage || + `The project record for the warehouseProjectId: ${warehouseProjectId} does not exist.`, + ); + } + + return record.dataValues; +}; + +export const assertStagingTableIsEmpty = async (customMessage) => { + const count = await Staging.count({ raw: true }); + + if (count > 0) { + throw new Error(customMessage || `Staging table is not empty.`); + } +}; + +export const assertActiveOfferFile = async () => { + const activeOfferFile = await Meta.findOne({ + where: { metaKey: 'activeOffer' }, + }); + + if (!activeOfferFile) { + throw new Error(`There is no active offer pending`); + } +}; + +export const assertNoActiveOfferFile = async () => { + const activeOfferFile = await Meta.findOne({ + where: { metaKey: 'activeOffer' }, + }); + + if (activeOfferFile) { + throw new Error(`There is an active offer pending`); + } +}; diff --git a/tests/integration/project.spec.js b/tests/integration/project.spec.js index df1296ff..9f6e8849 100644 --- a/tests/integration/project.spec.js +++ b/tests/integration/project.spec.js @@ -22,7 +22,7 @@ describe('Project Resource Integration Tests', function () { homeOrgUid = await testFixtures.getHomeOrgId(); }); - it.only('deletes a project end-to-end (with simulator)', async function () { + it('deletes a project end-to-end (with simulator)', async function () { /* Basic Idea for this test is that we are going to create a project and verify that the new project propagates through the data layer and into our db. Then we are going