diff --git a/CONFIGURATION.md b/CONFIGURATION.md index adcc4de6..4edec215 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -112,6 +112,3 @@ Running `nostream` for the first time creates the settings file in ` lastPercentage) { + console.log(`${new Date().toLocaleString()} Migration progress: ${currentPercentage}%`); + lastPercentage = currentPercentage; + } + } +}; + +exports.down = function (knex) { + return knex.schema.dropTable('event_tags'); +}; \ No newline at end of file diff --git a/migrations/20240111204900_remove_delegator_from_events_table.js b/migrations/20240111204900_remove_delegator_from_events_table.js deleted file mode 100644 index b5a7310c..00000000 --- a/migrations/20240111204900_remove_delegator_from_events_table.js +++ /dev/null @@ -1,18 +0,0 @@ -exports.up = async function (knex) { - await knex.schema - .raw('DROP INDEX IF EXISTS pubkey_delegator_kind_idx;') - await knex.schema.alterTable('events', function (table) { - table.dropColumn('event_delegator') - }) -} - -exports.down = async function (knex) { - await knex.schema.alterTable('events', function (table) { - table.binary('event_delegator').nullable().index() - }) - await knex.schema - .raw( - `CREATE UNIQUE INDEX pubkey_delegator_kind_idx - ON events ( event_pubkey, event_delegator, event_kind );`, - ) -} diff --git a/package-lock.json b/package-lock.json index cbd38ec3..224a44c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "nostream", - "version": "2.0.0", + "version": "1.25.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "nostream", - "version": "2.0.0", + "version": "1.25.2", "license": "MIT", "dependencies": { "@noble/secp256k1": "1.7.1", - "axios": "1.6.5", + "axios": "1.2.6", "bech32": "2.0.0", "body-parser": "1.20.1", "debug": "4.3.4", @@ -32,7 +32,7 @@ "devDependencies": { "@commitlint/cli": "17.2.0", "@commitlint/config-conventional": "17.2.0", - "@cucumber/cucumber": "10.2.1", + "@cucumber/cucumber": "8.7.0", "@cucumber/pretty-formatter": "1.0.0", "@semantic-release/commit-analyzer": "9.0.2", "@semantic-release/git": "10.0.1", @@ -88,89 +88,17 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { "version": "7.18.8", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz", @@ -220,14 +148,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz", + "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==", "dev": true, "dependencies": { - "@babel/types": "^7.23.6", + "@babel/types": "^7.18.10", "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -276,34 +203,34 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", "dev": true, "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -353,30 +280,30 @@ } }, "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.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "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.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true, "engines": { "node": ">=6.9.0" @@ -406,13 +333,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "engines": { @@ -491,9 +418,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.11.tgz", + "integrity": "sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -502,35 +429,47 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", + "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@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.23.6", - "@babel/types": "^7.23.6", - "debug": "^4.3.1", + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.11.tgz", + "integrity": "sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.11", + "@babel/types": "^7.18.10", + "debug": "^4.1.0", "globals": "^11.1.0" }, "engines": { @@ -547,13 +486,13 @@ } }, "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", + "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", "to-fast-properties": "^2.0.0" }, "engines": { @@ -929,35 +868,37 @@ } }, "node_modules/@cucumber/ci-environment": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-10.0.0.tgz", - "integrity": "sha512-lRkiehckosIOdc7p1L44nZsttO5dVHFjpwKKWZ07x8SeoAdV/sPuGe1PISe0AmAowFGza62nMOgG4KaroGzwFQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-9.1.0.tgz", + "integrity": "sha512-jdnF6APXP3GawMue8kdMxhu6TBhyRUO4KDRxTowf06NtclLjIw2Ybpo9IcIOMvE8kHukvJyM00uxWX+CfS7JgQ==", "dev": true }, "node_modules/@cucumber/cucumber": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-10.2.1.tgz", - "integrity": "sha512-jpJPhngRDHkPkTYQ4dtDHM30dhyM7OJJTMqp0ZoImeX2t7zwlVErfhPD5NlVnXL2yor6AJG6QFe/GwwI7IXc2w==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-8.7.0.tgz", + "integrity": "sha512-RYhobk+W73UVhd7fRHiKsAchjMl1h3Ic5VSSPwY6KyKw8t0wsfZM+U/a0xcUO/xflABeA0A8J+PupTNB4z9O3Q==", "dev": true, "dependencies": { - "@cucumber/ci-environment": "10.0.0", - "@cucumber/cucumber-expressions": "17.0.1", - "@cucumber/gherkin": "27.0.0", + "@cspotcode/source-map-support": "^0.8.0", + "@cucumber/ci-environment": "9.1.0", + "@cucumber/cucumber-expressions": "16.0.0", + "@cucumber/gherkin": "24.0.0", "@cucumber/gherkin-streams": "5.0.1", - "@cucumber/gherkin-utils": "8.0.5", - "@cucumber/html-formatter": "21.2.0", + "@cucumber/gherkin-utils": "8.0.0", + "@cucumber/html-formatter": "20.1.0", "@cucumber/message-streams": "4.0.1", - "@cucumber/messages": "24.0.1", - "@cucumber/tag-expressions": "6.0.0", + "@cucumber/messages": "19.1.4", + "@cucumber/tag-expressions": "4.1.0", "assertion-error-formatter": "^3.0.0", "capital-case": "^1.0.4", "chalk": "^4.1.2", "cli-table3": "0.6.3", - "commander": "^10.0.0", + "commander": "^9.0.0", "debug": "^4.3.4", - "error-stack-parser": "^2.1.4", + "duration": "^0.2.2", + "durations": "^3.4.2", "figures": "^3.2.0", - "glob": "^10.3.10", + "glob": "^7.1.6", "has-ansi": "^4.0.1", "indent-string": "^4.0.0", "is-installed-globally": "^0.4.0", @@ -965,176 +906,35 @@ "knuth-shuffle-seeded": "^1.0.6", "lodash.merge": "^4.6.2", "lodash.mergewith": "^4.6.2", - "luxon": "3.2.1", - "mkdirp": "^2.1.5", "mz": "^2.7.0", "progress": "^2.0.3", - "read-pkg-up": "^7.0.1", "resolve-pkg": "^2.0.0", - "semver": "7.5.3", - "string-argv": "0.3.1", + "semver": "7.3.7", + "stack-chain": "^2.0.0", + "string-argv": "^0.3.1", "strip-ansi": "6.0.1", "supports-color": "^8.1.1", "tmp": "^0.2.1", - "type-fest": "^4.8.3", "util-arity": "^1.1.0", - "xmlbuilder": "^15.1.1", - "yaml": "^2.2.2", - "yup": "1.2.0" + "verror": "^1.10.0", + "yup": "^0.32.11" }, "bin": { "cucumber-js": "bin/cucumber.js" }, "engines": { - "node": "18 || >=20" + "node": "12 || 14 || >=16" } }, "node_modules/@cucumber/cucumber-expressions": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-17.0.1.tgz", - "integrity": "sha512-reR7/sNRmDWgdz8BtFuHEwpksPnAkHty7gxUC2n0iaUPmckv9G5I5i+Vonc6xwUHDb/hmHPz/DyUL+Iv4Ao96w==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-16.0.0.tgz", + "integrity": "sha512-HTh+Pg7oQ5aLuCkSbD2Q6jBaE40M3R/XaLEz+UqD5d9dZRu6P38W4LTooV5bV6dZgBunlMLK8+6ug2ziYvRddw==", "dev": true, "dependencies": { "regexp-match-indices": "1.0.2" } }, - "node_modules/@cucumber/cucumber/node_modules/@cucumber/messages": { - "version": "24.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-24.0.1.tgz", - "integrity": "sha512-dKfNkvgc6stSQIyeHk7p/221iqEZe1BP+e/Js8XKtSmc0sS8khKMvbSBwYVeonn/67/vYKiAyo6Eo0SzXd5Plw==", - "dev": true, - "dependencies": { - "@types/uuid": "9.0.7", - "class-transformer": "0.5.1", - "reflect-metadata": "0.2.1", - "uuid": "9.0.1" - } - }, - "node_modules/@cucumber/cucumber/node_modules/@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", - "dev": true - }, - "node_modules/@cucumber/cucumber/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@cucumber/cucumber/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@cucumber/cucumber/node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@cucumber/cucumber/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@cucumber/cucumber/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@cucumber/cucumber/node_modules/mkdirp": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", - "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", - "dev": true, - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@cucumber/cucumber/node_modules/reflect-metadata": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", - "dev": true - }, - "node_modules/@cucumber/cucumber/node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@cucumber/cucumber/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@cucumber/cucumber/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -1150,47 +950,13 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@cucumber/cucumber/node_modules/type-fest": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.9.0.tgz", - "integrity": "sha512-KS/6lh/ynPGiHD/LnAobrEFq3Ad4pBzOlJ1wAnJx9N4EYoqFhMfLIBjUT2UEx4wg5ZE+cC1ob6DCSpppVo+rtg==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@cucumber/cucumber/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/@cucumber/cucumber/node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, "node_modules/@cucumber/gherkin": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-27.0.0.tgz", - "integrity": "sha512-j5rCsjqzRiC3iVTier3sa0kzyNbkcAmF7xr7jKnyO7qDeK3Z8Ye1P3KSVpeQRMY+KCDJ3WbTDdyxH0FwfA/fIw==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-24.0.0.tgz", + "integrity": "sha512-b7OsnvX1B8myDAKMc+RAiUX9bzgtNdjGsiMj10O13xu2HBWIOQ19EqBJ4xLO5CFG/lGk1J/+L0lANQVowxLVBg==", "dev": true, "dependencies": { - "@cucumber/messages": ">=19.1.4 <=22" + "@cucumber/messages": "^19.0.0" } }, "node_modules/@cucumber/gherkin-streams": { @@ -1221,43 +987,23 @@ } }, "node_modules/@cucumber/gherkin-utils": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-8.0.5.tgz", - "integrity": "sha512-kxM1OCDjYddF26VKc892PF0GokW4wUIl1PUz3TIXsPZgS39ExM1pF8oww8mlGFD2B0+4op/cSE3SSIME5H3aNw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-8.0.0.tgz", + "integrity": "sha512-8uIZInEe3cO1cASmy3BA0PbVFUI+xWBnZAxmICbVOPsZaMB85MtESZLafzErgfRQPsHf6uYbVagP7MIjNPM5Jw==", "dev": true, "dependencies": { - "@cucumber/gherkin": "^26.0.0", - "@cucumber/messages": "^22.0.0", - "@teppeis/multimaps": "3.0.0", - "commander": "10.0.1", - "source-map-support": "^0.5.21" + "@cucumber/messages": "^19.0.0", + "@teppeis/multimaps": "2.0.0", + "commander": "9.3.0" }, "bin": { "gherkin-utils": "bin/gherkin-utils" } }, - "node_modules/@cucumber/gherkin-utils/node_modules/@cucumber/gherkin": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-26.2.0.tgz", - "integrity": "sha512-iRSiK8YAIHAmLrn/mUfpAx7OXZ7LyNlh1zT89RoziSVCbqSVDxJS6ckEzW8loxs+EEXl0dKPQOXiDmbHV+C/fA==", - "dev": true, - "dependencies": { - "@cucumber/messages": ">=19.1.4 <=22" - } - }, - "node_modules/@cucumber/gherkin-utils/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@cucumber/html-formatter": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-21.2.0.tgz", - "integrity": "sha512-4OcSa12Y0v5e4ySDl67+QFTxCG/Y9fxGSkFqvm98ggpTvS7b75whwzupu+lM2lMBw+h3H6P8ZURQr0xQIAwE2A==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-20.1.0.tgz", + "integrity": "sha512-bu2shjZuVGfAtKaw8ebCBxhgu3Eiaz/P7ZuSxrw9YCa6rOyxMX5zO+4f2FUBTK/AV0b9O5cAB/xitYBrGhlYKg==", "dev": true, "peerDependencies": { "@cucumber/messages": ">=18" @@ -1273,12 +1019,12 @@ } }, "node_modules/@cucumber/messages": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-22.0.0.tgz", - "integrity": "sha512-EuaUtYte9ilkxcKmfqGF9pJsHRUU0jwie5ukuZ/1NPTuHS1LxHPsGEODK17RPRbZHOFhqybNzG2rHAwThxEymg==", + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-19.1.4.tgz", + "integrity": "sha512-Pksl0pnDz2l1+L5Ug85NlG6LWrrklN9qkMxN5Mv+1XZ3T6u580dnE6mVaxjJRdcOq4tR17Pc0RqIDZMyVY1FlA==", "dev": true, "dependencies": { - "@types/uuid": "9.0.1", + "@types/uuid": "8.3.4", "class-transformer": "0.5.1", "reflect-metadata": "0.1.13", "uuid": "9.0.0" @@ -1322,9 +1068,9 @@ } }, "node_modules/@cucumber/tag-expressions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-6.0.0.tgz", - "integrity": "sha512-JbNb/254Wn6b8cfrIJoqR0NekHXvoB/eMvSY4RK11H8k+YZfm7mZesu/3yVX67nkW+Y+PGjZFcgTMcfjwFRsRw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-4.1.0.tgz", + "integrity": "sha512-chTnjxV3vryL75N90wJIMdMafXmZoO2JgNJLYpsfcALL2/IQrRiny3vM9DgD5RDCSt1LNloMtb7rGey9YWxCsA==", "dev": true }, "node_modules/@dinero.js/calculator-number": { @@ -1401,102 +1147,6 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1652,13 +1302,13 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "node_modules/@noble/secp256k1": { @@ -1861,19 +1511,9 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-8.0.0.tgz", "integrity": "sha512-65/TPpOJP1i3K4lBJMnWqPUJ6zuOtzhtagDvydAWbEXpbFYA0oMKKyLb95NFZZP0lSh/4b6K+DQlzvYQJQQePg==", - "dev": true, - "dependencies": { - "@octokit/openapi-types": "^14.0.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^14.0.0" } }, "node_modules/@redis/bloom": { @@ -2117,12 +1757,12 @@ "dev": true }, "node_modules/@teppeis/multimaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-3.0.0.tgz", - "integrity": "sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-2.0.0.tgz", + "integrity": "sha512-TL1adzq1HdxUf9WYduLcQ/DNGYiz71U31QRgbnr0Ef1cPyOUOsBojxHVWpFeOSUucB6Lrs0LxFRA14ntgtkc9w==", "dev": true, "engines": { - "node": ">=14" + "node": ">=10.17" } }, "node_modules/@tootallnate/once": { @@ -2236,6 +1876,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.186", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.186.tgz", + "integrity": "sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==", + "dev": true + }, "node_modules/@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -2379,9 +2025,9 @@ "dev": true }, "node_modules/@types/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, "node_modules/@types/ws": { @@ -2868,6 +2514,15 @@ "node": ">=0.10.0" } }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -2909,11 +2564,11 @@ } }, "node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz", + "integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==", "dependencies": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.0", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -4086,6 +3741,16 @@ "node": ">=4" } }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -4390,6 +4055,25 @@ "readable-stream": "^2.0.2" } }, + "node_modules/duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.46" + } + }, + "node_modules/durations": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/durations/-/durations-3.4.2.tgz", + "integrity": "sha512-V/lf7y33dGaypZZetVI1eu7BmvkbC4dItq12OElLRpKuaU5JxQstV2zHwLv8P7cNbQ+KL1WD80zMCTx5dNC4dg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/dynamic-dedupe": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", @@ -4399,12 +4083,6 @@ "xtend": "^4.0.0" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4462,13 +4140,19 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "dev": true, + "hasInstallScript": true, "dependencies": { - "stackframe": "^1.3.4" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" } }, "node_modules/es6-error": { @@ -4477,6 +4161,27 @@ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -4822,6 +4527,21 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4854,6 +4574,15 @@ "node": ">=0.6.0" } }, + "node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5095,9 +4824,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", @@ -6380,24 +6109,6 @@ "node": ">=8" } }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/java-properties": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", @@ -6688,6 +6399,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, "node_modules/lodash.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", @@ -6869,15 +6586,6 @@ "node": ">=10" } }, - "node_modules/luxon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz", - "integrity": "sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -7193,15 +6901,6 @@ "node": ">=0.10.0" } }, - "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -7442,6 +7141,12 @@ "thenify-all": "^1.0.0" } }, + "node_modules/nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==", + "dev": true + }, "node_modules/nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", @@ -7480,6 +7185,12 @@ "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", "dev": true }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "node_modules/nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -10728,31 +10439,6 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -11127,9 +10813,9 @@ } }, "node_modules/property-expr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", - "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==", "dev": true }, "node_modules/protocols": { @@ -11564,6 +11250,12 @@ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", "dev": true }, + "node_modules/regenerator-runtime": { + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", + "dev": true + }, "node_modules/regexp-match-indices": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", @@ -11574,9 +11266,9 @@ } }, "node_modules/regexp-tree": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", - "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", "dev": true, "bin": { "regexp-tree": "bin/regexp-tree" @@ -12390,10 +12082,10 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "node_modules/stack-chain": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz", + "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==", "dev": true }, "node_modules/statuses": { @@ -12452,21 +12144,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -12479,19 +12156,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -12750,12 +12414,6 @@ "node": ">=8" } }, - "node_modules/tiny-case": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", - "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", - "dev": true - }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -13023,6 +12681,12 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -13293,6 +12957,20 @@ "node": ">= 0.8" } }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/vfile": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", @@ -13370,9 +13048,9 @@ "dev": true }, "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -13407,24 +13085,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -13463,15 +13123,6 @@ } } }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "engines": { - "node": ">=8.0" - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -13567,27 +13218,21 @@ } }, "node_modules/yup": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/yup/-/yup-1.2.0.tgz", - "integrity": "sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ==", + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", "dev": true, "dependencies": { - "property-expr": "^2.0.5", - "tiny-case": "^1.0.3", - "toposort": "^2.0.2", - "type-fest": "^2.19.0" - } - }, - "node_modules/yup/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "engines": { - "node": ">=12.20" + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, "node_modules/zip-stream": { @@ -13631,71 +13276,12 @@ } }, "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@babel/highlight": "^7.18.6" } }, "@babel/compat-data": { @@ -13736,14 +13322,13 @@ } }, "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.18.12", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz", + "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==", "dev": true, "requires": { - "@babel/types": "^7.23.6", + "@babel/types": "^7.18.10", "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -13781,28 +13366,28 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true }, "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", "dev": true, "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" } }, "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-imports": { @@ -13840,24 +13425,24 @@ } }, "@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.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "requires": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.18.6" } }, "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", "dev": true }, "@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.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true }, "@babel/helper-validator-option": { @@ -13878,13 +13463,13 @@ } }, "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "dependencies": { @@ -13947,37 +13532,46 @@ } }, "@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.11.tgz", + "integrity": "sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==", "dev": true }, + "@babel/runtime": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", + "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", - "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@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.23.6", - "@babel/types": "^7.23.6", - "debug": "^4.3.1", + "version": "7.18.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.11.tgz", + "integrity": "sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.10", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.11", + "@babel/types": "^7.18.10", + "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { @@ -13990,13 +13584,13 @@ } }, "@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz", + "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", "to-fast-properties": "^2.0.0" } }, @@ -14297,35 +13891,37 @@ } }, "@cucumber/ci-environment": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-10.0.0.tgz", - "integrity": "sha512-lRkiehckosIOdc7p1L44nZsttO5dVHFjpwKKWZ07x8SeoAdV/sPuGe1PISe0AmAowFGza62nMOgG4KaroGzwFQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-9.1.0.tgz", + "integrity": "sha512-jdnF6APXP3GawMue8kdMxhu6TBhyRUO4KDRxTowf06NtclLjIw2Ybpo9IcIOMvE8kHukvJyM00uxWX+CfS7JgQ==", "dev": true }, "@cucumber/cucumber": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-10.2.1.tgz", - "integrity": "sha512-jpJPhngRDHkPkTYQ4dtDHM30dhyM7OJJTMqp0ZoImeX2t7zwlVErfhPD5NlVnXL2yor6AJG6QFe/GwwI7IXc2w==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber/-/cucumber-8.7.0.tgz", + "integrity": "sha512-RYhobk+W73UVhd7fRHiKsAchjMl1h3Ic5VSSPwY6KyKw8t0wsfZM+U/a0xcUO/xflABeA0A8J+PupTNB4z9O3Q==", "dev": true, "requires": { - "@cucumber/ci-environment": "10.0.0", - "@cucumber/cucumber-expressions": "17.0.1", - "@cucumber/gherkin": "27.0.0", + "@cspotcode/source-map-support": "^0.8.0", + "@cucumber/ci-environment": "9.1.0", + "@cucumber/cucumber-expressions": "16.0.0", + "@cucumber/gherkin": "24.0.0", "@cucumber/gherkin-streams": "5.0.1", - "@cucumber/gherkin-utils": "8.0.5", - "@cucumber/html-formatter": "21.2.0", + "@cucumber/gherkin-utils": "8.0.0", + "@cucumber/html-formatter": "20.1.0", "@cucumber/message-streams": "4.0.1", - "@cucumber/messages": "24.0.1", - "@cucumber/tag-expressions": "6.0.0", + "@cucumber/messages": "19.1.4", + "@cucumber/tag-expressions": "4.1.0", "assertion-error-formatter": "^3.0.0", "capital-case": "^1.0.4", "chalk": "^4.1.2", "cli-table3": "0.6.3", - "commander": "^10.0.0", + "commander": "^9.0.0", "debug": "^4.3.4", - "error-stack-parser": "^2.1.4", + "duration": "^0.2.2", + "durations": "^3.4.2", "figures": "^3.2.0", - "glob": "^10.3.10", + "glob": "^7.1.6", "has-ansi": "^4.0.1", "indent-string": "^4.0.0", "is-installed-globally": "^0.4.0", @@ -14333,116 +13929,20 @@ "knuth-shuffle-seeded": "^1.0.6", "lodash.merge": "^4.6.2", "lodash.mergewith": "^4.6.2", - "luxon": "3.2.1", - "mkdirp": "^2.1.5", "mz": "^2.7.0", "progress": "^2.0.3", - "read-pkg-up": "^7.0.1", "resolve-pkg": "^2.0.0", - "semver": "7.5.3", - "string-argv": "0.3.1", + "semver": "7.3.7", + "stack-chain": "^2.0.0", + "string-argv": "^0.3.1", "strip-ansi": "6.0.1", "supports-color": "^8.1.1", "tmp": "^0.2.1", - "type-fest": "^4.8.3", "util-arity": "^1.1.0", - "xmlbuilder": "^15.1.1", - "yaml": "^2.2.2", - "yup": "1.2.0" + "verror": "^1.10.0", + "yup": "^0.32.11" }, "dependencies": { - "@cucumber/messages": { - "version": "24.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-24.0.1.tgz", - "integrity": "sha512-dKfNkvgc6stSQIyeHk7p/221iqEZe1BP+e/Js8XKtSmc0sS8khKMvbSBwYVeonn/67/vYKiAyo6Eo0SzXd5Plw==", - "dev": true, - "requires": { - "@types/uuid": "9.0.7", - "class-transformer": "0.5.1", - "reflect-metadata": "0.2.1", - "uuid": "9.0.1" - } - }, - "@types/uuid": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", - "integrity": "sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g==", - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true - }, - "foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - } - }, - "glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "mkdirp": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", - "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", - "dev": true - }, - "reflect-metadata": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==", - "dev": true - }, - "semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -14451,43 +13951,25 @@ "requires": { "has-flag": "^4.0.0" } - }, - "type-fest": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.9.0.tgz", - "integrity": "sha512-KS/6lh/ynPGiHD/LnAobrEFq3Ad4pBzOlJ1wAnJx9N4EYoqFhMfLIBjUT2UEx4wg5ZE+cC1ob6DCSpppVo+rtg==", - "dev": true - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true - }, - "yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", - "dev": true } } }, "@cucumber/cucumber-expressions": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-17.0.1.tgz", - "integrity": "sha512-reR7/sNRmDWgdz8BtFuHEwpksPnAkHty7gxUC2n0iaUPmckv9G5I5i+Vonc6xwUHDb/hmHPz/DyUL+Iv4Ao96w==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-16.0.0.tgz", + "integrity": "sha512-HTh+Pg7oQ5aLuCkSbD2Q6jBaE40M3R/XaLEz+UqD5d9dZRu6P38W4LTooV5bV6dZgBunlMLK8+6ug2ziYvRddw==", "dev": true, "requires": { "regexp-match-indices": "1.0.2" } }, "@cucumber/gherkin": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-27.0.0.tgz", - "integrity": "sha512-j5rCsjqzRiC3iVTier3sa0kzyNbkcAmF7xr7jKnyO7qDeK3Z8Ye1P3KSVpeQRMY+KCDJ3WbTDdyxH0FwfA/fIw==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-24.0.0.tgz", + "integrity": "sha512-b7OsnvX1B8myDAKMc+RAiUX9bzgtNdjGsiMj10O13xu2HBWIOQ19EqBJ4xLO5CFG/lGk1J/+L0lANQVowxLVBg==", "dev": true, "requires": { - "@cucumber/messages": ">=19.1.4 <=22" + "@cucumber/messages": "^19.0.0" } }, "@cucumber/gherkin-streams": { @@ -14509,39 +13991,20 @@ } }, "@cucumber/gherkin-utils": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-8.0.5.tgz", - "integrity": "sha512-kxM1OCDjYddF26VKc892PF0GokW4wUIl1PUz3TIXsPZgS39ExM1pF8oww8mlGFD2B0+4op/cSE3SSIME5H3aNw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin-utils/-/gherkin-utils-8.0.0.tgz", + "integrity": "sha512-8uIZInEe3cO1cASmy3BA0PbVFUI+xWBnZAxmICbVOPsZaMB85MtESZLafzErgfRQPsHf6uYbVagP7MIjNPM5Jw==", "dev": true, "requires": { - "@cucumber/gherkin": "^26.0.0", - "@cucumber/messages": "^22.0.0", - "@teppeis/multimaps": "3.0.0", - "commander": "10.0.1", - "source-map-support": "^0.5.21" - }, - "dependencies": { - "@cucumber/gherkin": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-26.2.0.tgz", - "integrity": "sha512-iRSiK8YAIHAmLrn/mUfpAx7OXZ7LyNlh1zT89RoziSVCbqSVDxJS6ckEzW8loxs+EEXl0dKPQOXiDmbHV+C/fA==", - "dev": true, - "requires": { - "@cucumber/messages": ">=19.1.4 <=22" - } - }, - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true - } + "@cucumber/messages": "^19.0.0", + "@teppeis/multimaps": "2.0.0", + "commander": "9.3.0" } }, "@cucumber/html-formatter": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-21.2.0.tgz", - "integrity": "sha512-4OcSa12Y0v5e4ySDl67+QFTxCG/Y9fxGSkFqvm98ggpTvS7b75whwzupu+lM2lMBw+h3H6P8ZURQr0xQIAwE2A==", + "version": "20.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-20.1.0.tgz", + "integrity": "sha512-bu2shjZuVGfAtKaw8ebCBxhgu3Eiaz/P7ZuSxrw9YCa6rOyxMX5zO+4f2FUBTK/AV0b9O5cAB/xitYBrGhlYKg==", "dev": true, "requires": {} }, @@ -14553,12 +14016,12 @@ "requires": {} }, "@cucumber/messages": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-22.0.0.tgz", - "integrity": "sha512-EuaUtYte9ilkxcKmfqGF9pJsHRUU0jwie5ukuZ/1NPTuHS1LxHPsGEODK17RPRbZHOFhqybNzG2rHAwThxEymg==", + "version": "19.1.4", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-19.1.4.tgz", + "integrity": "sha512-Pksl0pnDz2l1+L5Ug85NlG6LWrrklN9qkMxN5Mv+1XZ3T6u580dnE6mVaxjJRdcOq4tR17Pc0RqIDZMyVY1FlA==", "dev": true, "requires": { - "@types/uuid": "9.0.1", + "@types/uuid": "8.3.4", "class-transformer": "0.5.1", "reflect-metadata": "0.1.13", "uuid": "9.0.0" @@ -14593,9 +14056,9 @@ } }, "@cucumber/tag-expressions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-6.0.0.tgz", - "integrity": "sha512-JbNb/254Wn6b8cfrIJoqR0NekHXvoB/eMvSY4RK11H8k+YZfm7mZesu/3yVX67nkW+Y+PGjZFcgTMcfjwFRsRw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cucumber/tag-expressions/-/tag-expressions-4.1.0.tgz", + "integrity": "sha512-chTnjxV3vryL75N90wJIMdMafXmZoO2JgNJLYpsfcALL2/IQrRiny3vM9DgD5RDCSt1LNloMtb7rGey9YWxCsA==", "dev": true }, "@dinero.js/calculator-number": { @@ -14666,71 +14129,6 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - } - } - } - }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -14849,13 +14247,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, "@noble/secp256k1": { @@ -15013,13 +14411,6 @@ "@octokit/openapi-types": "^14.0.0" } }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, "@redis/bloom": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.1.0.tgz", @@ -15215,9 +14606,9 @@ "dev": true }, "@teppeis/multimaps": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-3.0.0.tgz", - "integrity": "sha512-ID7fosbc50TbT0MK0EG12O+gAP3W3Aa/Pz4DaTtQtEvlc9Odaqi0de+xuZ7Li2GtK4HzEX7IuRWS/JmZLksR3Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@teppeis/multimaps/-/multimaps-2.0.0.tgz", + "integrity": "sha512-TL1adzq1HdxUf9WYduLcQ/DNGYiz71U31QRgbnr0Ef1cPyOUOsBojxHVWpFeOSUucB6Lrs0LxFRA14ntgtkc9w==", "dev": true }, "@tootallnate/once": { @@ -15328,6 +14719,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "@types/lodash": { + "version": "4.14.186", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.186.tgz", + "integrity": "sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==", + "dev": true + }, "@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -15471,9 +14868,9 @@ "dev": true }, "@types/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", + "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", "dev": true }, "@types/ws": { @@ -15806,6 +15203,12 @@ "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true + }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -15841,11 +15244,11 @@ "dev": true }, "axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.6.tgz", + "integrity": "sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==", "requires": { - "follow-redirects": "^1.15.4", + "follow-redirects": "^1.15.0", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -16737,6 +16140,16 @@ } } }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -16957,6 +16370,22 @@ "readable-stream": "^2.0.2" } }, + "duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.46" + } + }, + "durations": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/durations/-/durations-3.4.2.tgz", + "integrity": "sha512-V/lf7y33dGaypZZetVI1eu7BmvkbC4dItq12OElLRpKuaU5JxQstV2zHwLv8P7cNbQ+KL1WD80zMCTx5dNC4dg==", + "dev": true + }, "dynamic-dedupe": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", @@ -16966,12 +16395,6 @@ "xtend": "^4.0.0" } }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -17023,13 +16446,15 @@ "is-arrayish": "^0.2.1" } }, - "error-stack-parser": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", - "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", "dev": true, "requires": { - "stackframe": "^1.3.4" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" } }, "es6-error": { @@ -17038,6 +16463,27 @@ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -17305,6 +16751,23 @@ } } }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "requires": { + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -17333,6 +16796,12 @@ } } }, + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -17529,9 +16998,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==" + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==" }, "foreground-child": { "version": "2.0.0", @@ -18444,16 +17913,6 @@ "istanbul-lib-report": "^3.0.0" } }, - "jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, "java-properties": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", @@ -18666,6 +18125,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, "lodash.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", @@ -18834,12 +18299,6 @@ "yallist": "^4.0.0" } }, - "luxon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz", - "integrity": "sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==", - "dev": true - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -19061,12 +18520,6 @@ } } }, - "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true - }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -19257,6 +18710,12 @@ "thenify-all": "^1.0.0" } }, + "nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==", + "dev": true + }, "nanoid": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", @@ -19286,6 +18745,12 @@ "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", "dev": true }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -21592,24 +21057,6 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", - "dev": true - } - } - }, "path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -21891,9 +21338,9 @@ } }, "property-expr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", - "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==", "dev": true }, "protocols": { @@ -22240,6 +21687,12 @@ "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", "dev": true }, + "regenerator-runtime": { + "version": "0.13.10", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz", + "integrity": "sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==", + "dev": true + }, "regexp-match-indices": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz", @@ -22250,9 +21703,9 @@ } }, "regexp-tree": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", - "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", "dev": true }, "regexpp": { @@ -22884,10 +22337,10 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "stack-chain": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stack-chain/-/stack-chain-2.0.0.tgz", + "integrity": "sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==", "dev": true }, "statuses": { @@ -22939,17 +22392,6 @@ "strip-ansi": "^6.0.1" } }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -22959,15 +22401,6 @@ "ansi-regex": "^5.0.1" } }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -23166,12 +22599,6 @@ "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==" }, - "tiny-case": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", - "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", - "dev": true - }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -23353,6 +22780,12 @@ "tslib": "^1.8.1" } }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -23552,6 +22985,17 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, + "verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, "vfile": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", @@ -23615,9 +23059,9 @@ "dev": true }, "word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wordwrap": { @@ -23643,17 +23087,6 @@ "strip-ansi": "^6.0.0" } }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -23678,12 +23111,6 @@ "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", "requires": {} }, - "xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -23752,23 +23179,18 @@ "dev": true }, "yup": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/yup/-/yup-1.2.0.tgz", - "integrity": "sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ==", + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", "dev": true, "requires": { - "property-expr": "^2.0.5", - "tiny-case": "^1.0.3", - "toposort": "^2.0.2", - "type-fest": "^2.19.0" - }, - "dependencies": { - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true - } + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" } }, "zip-stream": { diff --git a/package.json b/package.json index eebe5622..4b229979 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nostream", - "version": "2.0.0", + "version": "1.25.2", "description": "A Nostr relay written in Typescript.", "supportedNips": [ 1, @@ -13,6 +13,7 @@ 16, 20, 22, + 26, 28, 33, 40 @@ -72,7 +73,7 @@ "devDependencies": { "@commitlint/cli": "17.2.0", "@commitlint/config-conventional": "17.2.0", - "@cucumber/cucumber": "10.2.1", + "@cucumber/cucumber": "8.7.0", "@cucumber/pretty-formatter": "1.0.0", "@semantic-release/commit-analyzer": "9.0.2", "@semantic-release/git": "10.0.1", @@ -115,7 +116,7 @@ }, "dependencies": { "@noble/secp256k1": "1.7.1", - "axios": "1.6.5", + "axios": "1.2.6", "bech32": "2.0.0", "body-parser": "1.20.1", "debug": "4.3.4", diff --git a/postgresql-trigger.sql b/postgresql-trigger.sql new file mode 100644 index 00000000..3c2a0258 --- /dev/null +++ b/postgresql-trigger.sql @@ -0,0 +1,148 @@ +CREATE TABLE IF NOT EXISTS public.event_tags +( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + event_id bytea NOT NULL, + tag_name text COLLATE pg_catalog."default" NOT NULL, + tag_value text COLLATE pg_catalog."default" NOT NULL, + CONSTRAINT event_tags_pkey PRIMARY KEY (id) +) +TABLESPACE pg_default; + +ALTER TABLE IF EXISTS public.event_tags + OWNER to nostr_ts_relay; + +CREATE INDEX IF NOT EXISTS event_tags_tag_name_tag_value_index + ON public.event_tags USING btree + (tag_name COLLATE pg_catalog."default" ASC NULLS LAST, tag_value COLLATE pg_catalog."default" ASC NULLS LAST) + TABLESPACE pg_default; + +CREATE INDEX IF NOT EXISTS event_tags_tag_name_tag_value_hash_index + ON public.event_tags USING btree + (tag_name COLLATE pg_catalog."default" ASC NULLS LAST, md5(tag_value) COLLATE pg_catalog."default" ASC NULLS LAST) + TABLESPACE pg_default; + +CREATE INDEX IF NOT EXISTS event_tags_event_id_index + ON public.event_tags USING btree + (event_id ASC NULLS LAST) + WITH (deduplicate_items=True) + TABLESPACE pg_default; + +CREATE OR REPLACE FUNCTION process_event_tags() RETURNS TRIGGER AS $$ +DECLARE + tag_element jsonb; + tag_name text; + tag_value text; +BEGIN + DELETE FROM event_tags WHERE event_id = OLD.event_id; + + IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN + FOR tag_element IN SELECT jsonb_array_elements(NEW.event_tags) + LOOP + tag_name := trim((tag_element->0)::text, '"'); + tag_value := trim((tag_element->1)::text, '"'); + IF length(tag_name) = 1 AND tag_value IS NOT NULL AND tag_value <> '' THEN + INSERT INTO event_tags (event_id, tag_name, tag_value) VALUES (NEW.event_id, tag_name, tag_value); + END IF; + END LOOP; + END IF; + + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER insert_event_tags +AFTER INSERT OR UPDATE OR DELETE ON events +FOR EACH ROW +EXECUTE FUNCTION process_event_tags(); + + +CREATE OR REPLACE FUNCTION process_event_tags_direct(event_row events) RETURNS VOID AS $$ +DECLARE + tag_element jsonb; + tag_name text; + tag_value text; +BEGIN + DELETE FROM event_tags WHERE event_id = event_row.event_id; + + FOR tag_element IN SELECT jsonb_array_elements(event_row.event_tags) + LOOP + tag_name := trim((tag_element->0)::text, '"'); + tag_value := trim((tag_element->1)::text, '"'); + IF length(tag_name) = 1 AND tag_value IS NOT NULL AND tag_value <> '' THEN + INSERT INTO event_tags (event_id, tag_name, tag_value) VALUES (event_row.event_id, tag_name, tag_value); + END IF; + END LOOP; +END; +$$ LANGUAGE plpgsql; + + +DO $$ +DECLARE + cur CURSOR FOR SELECT * FROM events ORDER BY event_id; + row events%ROWTYPE; + total_rows int; + processed_rows int := 0; +BEGIN + -- 全行数を取得 + SELECT count(*) INTO total_rows FROM events; + + OPEN cur; + + WHILE processed_rows < total_rows LOOP + FOR i IN 1..100 LOOP + FETCH NEXT FROM cur INTO row; + EXIT WHEN NOT FOUND; + + -- process_event_tagsを直接呼び出す + PERFORM process_event_tags_direct(row); + + processed_rows := processed_rows + 1; + END LOOP; + + -- 進捗%を出力 + RAISE NOTICE 'Processed: %, Total: %, Remaining: %, Percentage: %', processed_rows, total_rows, total_rows - processed_rows, (processed_rows::float / total_rows::float * 100); + -- 1秒待機 + PERFORM pg_sleep(0.1); + END LOOP; + + CLOSE cur; +END $$; + + + + + + + + + + + + + + + + +CREATE OR REPLACE FUNCTION process_event_tags_direct(event_row events) RETURNS VOID AS $$ +DECLARE + tag_element jsonb; + tag_name text; + tag_value text; + exists_flag boolean; +BEGIN + -- 既に処理されたevent_idがあればスキップ + SELECT EXISTS(SELECT 1 FROM event_tags WHERE event_id = event_row.event_id) INTO exists_flag; + IF exists_flag THEN + RETURN; + END IF; + + FOR tag_element IN SELECT jsonb_array_elements(event_row.event_tags) + LOOP + tag_name := trim((tag_element->0)::text, '"'); + tag_value := trim((tag_element->1)::text, '"'); + IF length(tag_name) = 1 AND tag_value IS NOT NULL AND tag_value <> '' THEN + INSERT INTO event_tags (event_id, tag_name, tag_value) VALUES (event_row.event_id, tag_name, tag_value); + END IF; + END LOOP; +END; +$$ LANGUAGE plpgsql; diff --git a/postgresql.conf b/postgresql.conf index 702d370c..0c49d29e 100644 --- a/postgresql.conf +++ b/postgresql.conf @@ -510,7 +510,7 @@ default_statistics_target = 100 # range 1-10000 # fatal # panic (effectively off) -#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements +log_min_duration_statement = 30000 # -1 is disabled, 0 logs all statements # and their durations, > 0 logs only # statements running at least this number # of milliseconds diff --git a/resources/default-settings.yaml b/resources/default-settings.yaml index 058b7786..4f137e48 100755 --- a/resources/default-settings.yaml +++ b/resources/default-settings.yaml @@ -56,15 +56,6 @@ limits: - "::1" - "10.10.10.1" - "::ffff:10.10.10.1" - admissionCheck: - rateLimits: - - description: 30 admission checks/min or 1 check every 2 seconds - period: 60000 - rate: 30 - ipWhitelist: - - "::1" - - "10.10.10.1" - - "::ffff:10.10.10.1" connection: rateLimits: - period: 1000 diff --git a/src/@types/event.ts b/src/@types/event.ts index cc9241d4..52194560 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -1,5 +1,5 @@ import { ContextMetadata, EventId, Pubkey, Tag } from './base' -import { ContextMetadataKey, EventDeduplicationMetadataKey, EventExpirationTimeMetadataKey, EventKinds } from '../constants/base' +import { ContextMetadataKey, EventDeduplicationMetadataKey, EventDelegatorMetadataKey, EventExpirationTimeMetadataKey, EventKinds } from '../constants/base' export interface BaseEvent { id: EventId @@ -21,6 +21,10 @@ export type UnsignedEvent = Omit export type UnidentifiedEvent = Omit +export interface DelegatedEvent extends Event { + [EventDelegatorMetadataKey]?: Pubkey +} + export interface ExpiringEvent extends Event { [EventExpirationTimeMetadataKey]?: number } @@ -38,6 +42,7 @@ export interface DBEvent { event_content: string event_tags: Tag[] event_signature: Buffer + event_delegator?: Buffer | null event_deduplication?: string | null first_seen: Date deleted_at?: Date diff --git a/src/@types/repositories.ts b/src/@types/repositories.ts index 671dfaee..98d05cd3 100644 --- a/src/@types/repositories.ts +++ b/src/@types/repositories.ts @@ -16,6 +16,7 @@ export interface IEventRepository { create(event: Event): Promise upsert(event: Event): Promise findByFilters(filters: SubscriptionFilter[]): IQueryResult + insertStubs(pubkey: string, eventIdsToDelete: EventId[]): Promise deleteByPubkeyAndIds(pubkey: Pubkey, ids: EventId[]): Promise } diff --git a/src/@types/settings.ts b/src/@types/settings.ts index 3717fbe5..5255fb63 100644 --- a/src/@types/settings.ts +++ b/src/@types/settings.ts @@ -112,14 +112,8 @@ export interface InvoiceLimits { ipWhitelist?: string[] } -export interface AdmissionCheckLimits { - rateLimits: RateLimit[] - ipWhitelist?: string[] -} - export interface Limits { invoice?: InvoiceLimits - admissionCheck?: AdmissionCheckLimits connection?: ConnectionLimits client?: ClientLimits event?: EventLimits diff --git a/src/@types/subscription.ts b/src/@types/subscription.ts index 265506d5..e78efb2b 100644 --- a/src/@types/subscription.ts +++ b/src/@types/subscription.ts @@ -5,7 +5,7 @@ export type SubscriptionId = string export interface SubscriptionFilter { ids?: EventId[] - kinds?: (EventKinds | number)[] + kinds?: EventKinds[] since?: number until?: number authors?: Pubkey[] diff --git a/src/constants/base.ts b/src/constants/base.ts index 8b9adca8..fd6b2a9a 100644 --- a/src/constants/base.ts +++ b/src/constants/base.ts @@ -37,6 +37,7 @@ export enum EventTags { Event = 'e', Pubkey = 'p', // Multicast = 'm', + Delegation = 'delegation', Deduplication = 'd', Expiration = 'expiration', Invoice = 'bolt11', @@ -48,6 +49,7 @@ export enum PaymentsProcessors { LNBITS = 'lnbits', } +export const EventDelegatorMetadataKey = Symbol('Delegator') export const EventDeduplicationMetadataKey = Symbol('Deduplication') export const ContextMetadataKey = Symbol('Context') export const EventExpirationTimeMetadataKey = Symbol('Expiration') diff --git a/src/controllers/admission/get-admission-check-controller.ts b/src/controllers/admission/get-admission-check-controller.ts deleted file mode 100644 index 5900643a..00000000 --- a/src/controllers/admission/get-admission-check-controller.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Request, Response } from 'express' -import { createLogger } from '../../factories/logger-factory' -import { getRemoteAddress } from '../../utils/http' -import { IController } from '../../@types/controllers' -import { IRateLimiter } from '../../@types/utils' -import { IUserRepository } from '../../@types/repositories' -import { path } from 'ramda' -import { Settings } from '../../@types/settings' - -const debug = createLogger('get-admission-check-controller') - -export class GetSubmissionCheckController implements IController { - public constructor( - private readonly userRepository: IUserRepository, - private readonly settings: () => Settings, - private readonly rateLimiter: () => IRateLimiter, - ){} - - public async handleRequest(request: Request, response: Response): Promise { - const currentSettings = this.settings() - - const limited = await this.isRateLimited(request, currentSettings) - if (limited) { - response - .status(429) - .setHeader('content-type', 'text/plain; charset=utf8') - .send('Too many requests') - return - } - - const pubkey = request.params.pubkey - const user = await this.userRepository.findByPubkey(pubkey) - - let userAdmitted = false - - const minBalance = currentSettings.limits?.event?.pubkey?.minBalance - if (user && user.isAdmitted && (!minBalance || user.balance >= minBalance)) { - userAdmitted = true - } - - response - .status(200) - .setHeader('content-type', 'application/json; charset=utf8') - .send({ userAdmitted }) - - return - } - - public async isRateLimited(request: Request, settings: Settings) { - const rateLimits = path(['limits', 'admissionCheck', 'rateLimits'], settings) - if (!Array.isArray(rateLimits) || !rateLimits.length) { - return false - } - - const ipWhitelist = path(['limits', 'admissionCheck', 'ipWhitelist'], settings) - const remoteAddress = getRemoteAddress(request, settings) - - let limited = false - if (Array.isArray(ipWhitelist) && !ipWhitelist.includes(remoteAddress)) { - const rateLimiter = this.rateLimiter() - for (const { rate, period } of rateLimits) { - if (await rateLimiter.hit(`${remoteAddress}:admission-check:${period}`, 1, { period, rate })) { - debug('rate limited %s: %d in %d milliseconds', remoteAddress, rate, period) - limited = true - } - } - } - return limited - } -} \ No newline at end of file diff --git a/src/factories/controllers/get-admission-check-controller-factory.ts b/src/factories/controllers/get-admission-check-controller-factory.ts deleted file mode 100644 index c7d2d47e..00000000 --- a/src/factories/controllers/get-admission-check-controller-factory.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { createSettings } from '../settings-factory' -import { getMasterDbClient } from '../../database/client' -import { GetSubmissionCheckController } from '../../controllers/admission/get-admission-check-controller' -import { slidingWindowRateLimiterFactory } from '../rate-limiter-factory' -import { UserRepository } from '../../repositories/user-repository' - -export const createGetAdmissionCheckController = () => { - const dbClient = getMasterDbClient() - const userRepository = new UserRepository(dbClient) - - return new GetSubmissionCheckController( - userRepository, - createSettings, - slidingWindowRateLimiterFactory - ) -} diff --git a/src/factories/delegated-event-strategy-factory.ts b/src/factories/delegated-event-strategy-factory.ts new file mode 100644 index 00000000..1f828a9c --- /dev/null +++ b/src/factories/delegated-event-strategy-factory.ts @@ -0,0 +1,21 @@ +import { isDeleteEvent, isEphemeralEvent, isReplaceableEvent } from '../utils/event' +import { DefaultEventStrategy } from '../handlers/event-strategies/default-event-strategy' +import { EphemeralEventStrategy } from '../handlers/event-strategies/ephemeral-event-strategy' +import { Event } from '../@types/event' +import { Factory } from '../@types/base' +import { IEventRepository } from '../@types/repositories' +import { IEventStrategy } from '../@types/message-handlers' +import { IWebSocketAdapter } from '../@types/adapters' + +export const delegatedEventStrategyFactory = ( + eventRepository: IEventRepository, +): Factory>, [Event, IWebSocketAdapter]> => + ([event, adapter]: [Event, IWebSocketAdapter]) => { + if (isEphemeralEvent(event)) { + return new EphemeralEventStrategy(adapter) + } else if (isReplaceableEvent(event) || isDeleteEvent(event)) { + return + } + + return new DefaultEventStrategy(adapter, eventRepository) + } diff --git a/src/factories/message-handler-factory.ts b/src/factories/message-handler-factory.ts index b1c11e9c..a3123ce2 100644 --- a/src/factories/message-handler-factory.ts +++ b/src/factories/message-handler-factory.ts @@ -1,8 +1,11 @@ import { IEventRepository, IUserRepository } from '../@types/repositories' import { IncomingMessage, MessageType } from '../@types/messages' import { createSettings } from './settings-factory' +import { DelegatedEventMessageHandler } from '../handlers/delegated-event-message-handler' +import { delegatedEventStrategyFactory } from './delegated-event-strategy-factory' import { EventMessageHandler } from '../handlers/event-message-handler' import { eventStrategyFactory } from './event-strategy-factory' +import { isDelegatedEvent } from '../utils/event' import { IWebSocketAdapter } from '../@types/adapters' import { slidingWindowRateLimiterFactory } from './rate-limiter-factory' import { SubscribeMessageHandler } from '../handlers/subscribe-message-handler' @@ -15,6 +18,16 @@ export const messageHandlerFactory = ( switch (message[0]) { case MessageType.EVENT: { + if (isDelegatedEvent(message[1])) { + return new DelegatedEventMessageHandler( + adapter, + delegatedEventStrategyFactory(eventRepository), + userRepository, + createSettings, + slidingWindowRateLimiterFactory, + ) + } + return new EventMessageHandler( adapter, eventStrategyFactory(eventRepository), @@ -26,7 +39,7 @@ export const messageHandlerFactory = ( case MessageType.REQ: return new SubscribeMessageHandler(adapter, eventRepository, createSettings) case MessageType.CLOSE: - return new UnsubscribeMessageHandler(adapter) + return new UnsubscribeMessageHandler(adapter,) default: throw new Error(`Unknown message type: ${String(message[0]).substring(0, 64)}`) } diff --git a/src/handlers/delegated-event-message-handler.ts b/src/handlers/delegated-event-message-handler.ts new file mode 100644 index 00000000..13ede1f2 --- /dev/null +++ b/src/handlers/delegated-event-message-handler.ts @@ -0,0 +1,75 @@ +import { EventDelegatorMetadataKey, EventTags } from '../constants/base' +import { createCommandResult } from '../utils/messages' +import { createLogger } from '../factories/logger-factory' +import { DelegatedEvent } from '../@types/event' +import { EventMessageHandler } from './event-message-handler' +import { IMessageHandler } from '../@types/message-handlers' +import { IncomingEventMessage } from '../@types/messages' +import { isDelegatedEventValid } from '../utils/event' +import { WebSocketAdapterEvent } from '../constants/adapter' + +const debug = createLogger('delegated-event-message-handler') + +export class DelegatedEventMessageHandler extends EventMessageHandler implements IMessageHandler { + public async handleMessage(message: IncomingEventMessage): Promise { + const [, event] = message + + let reason = await this.isEventValid(event) + if (reason) { + debug('event %s rejected: %s', event.id, reason) + this.webSocket.emit(WebSocketAdapterEvent.Message, createCommandResult(event.id, false, reason)) + return + } + + if (await this.isRateLimited(event)) { + debug('event %s rejected: rate-limited') + this.webSocket.emit(WebSocketAdapterEvent.Message, createCommandResult(event.id, false, 'rate-limited: slow down')) + return + } + + reason = this.canAcceptEvent(event) + if (reason) { + debug('event %s rejected: %s', event.id, reason) + this.webSocket.emit(WebSocketAdapterEvent.Message, createCommandResult(event.id, false, reason)) + return + } + + reason = await this.isUserAdmitted(event) + if (reason) { + debug('event %s rejected: %s', event.id, reason) + this.webSocket.emit(WebSocketAdapterEvent.Message, createCommandResult(event.id, false, reason)) + return + } + + const [, delegator] = event.tags.find((tag) => tag.length === 4 && tag[0] === EventTags.Delegation) + const delegatedEvent: DelegatedEvent = { + ...event, + [EventDelegatorMetadataKey]: delegator, + } + + const strategy = this.strategyFactory([delegatedEvent, this.webSocket]) + + if (typeof strategy?.execute !== 'function') { + this.webSocket.emit(WebSocketAdapterEvent.Message, createCommandResult(event.id, false, 'error: event not supported')) + return + } + + try { + await strategy.execute(delegatedEvent) + } catch (error) { + console.error('error handling message', message, error) + this.webSocket.emit(WebSocketAdapterEvent.Message, createCommandResult(event.id, false, 'error: unable to process event')) + } + } + + protected async isEventValid(event: DelegatedEvent): Promise { + const reason = await super.isEventValid(event) + if (reason) { + return reason + } + + if (!await isDelegatedEventValid(event)) { + return 'invalid: delegation verification failed' + } + } +} diff --git a/src/handlers/event-strategies/delete-event-strategy.ts b/src/handlers/event-strategies/delete-event-strategy.ts index c25a3b6b..c03479ff 100644 --- a/src/handlers/event-strategies/delete-event-strategy.ts +++ b/src/handlers/event-strategies/delete-event-strategy.ts @@ -32,10 +32,16 @@ export class DeleteEventStrategy implements IEventStrategy> ) if (eventIdsToDelete.length) { - await this.eventRepository.deleteByPubkeyAndIds( + const count = await this.eventRepository.deleteByPubkeyAndIds( event.pubkey, eventIdsToDelete ) + if (!count) { + await this.eventRepository.insertStubs( + event.pubkey, + eventIdsToDelete, + ) + } } const count = await this.eventRepository.create(event) diff --git a/src/handlers/request-handlers/nodeinfo-handler.ts b/src/handlers/request-handlers/nodeinfo-handler.ts deleted file mode 100644 index 0a2ebf73..00000000 --- a/src/handlers/request-handlers/nodeinfo-handler.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { NextFunction, Request, Response } from 'express' -import packageJson from '../../../package.json' - -export const nodeinfoHandler = (req: Request, res: Response, next: NextFunction) => { - res.json({ - links: [{ - rel: 'http://nodeinfo.diaspora.software/ns/schema/2.0', - href: `https://${req.hostname}/nodeinfo/2.0`, - }, { - rel: 'http://nodeinfo.diaspora.software/ns/schema/2.1', - href: `https://${req.hostname}/nodeinfo/2.1`, - }], - }).send() - next() -} - -export const nodeinfo21Handler = (_req: Request, res: Response, next: NextFunction) => { - res.json({ - version: '2.1', - software: { - name: 'nostream', - version: packageJson.version, - repository: packageJson.repository.url, - homepage: packageJson.homepage, - }, - protocols: ['nostr'], - services: { - inbound: [], - outbound: [], - }, - openRegistrations: true, - usage: { - users: {}, - }, - metadata: { - features: ['nostr_relay'], - }, - }).send() - next() -} \ No newline at end of file diff --git a/src/handlers/request-handlers/root-request-handler.ts b/src/handlers/request-handlers/root-request-handler.ts index 0e88bb8d..d9450334 100644 --- a/src/handlers/request-handlers/root-request-handler.ts +++ b/src/handlers/request-handlers/root-request-handler.ts @@ -3,7 +3,6 @@ import { path } from 'ramda' import { createSettings } from '../../factories/settings-factory' import { FeeSchedule } from '../../@types/settings' -import { fromBech32 } from '../../utils/transform' import packageJson from '../../../package.json' export const rootRequestHandler = (request: Request, response: Response, next: NextFunction) => { @@ -11,7 +10,7 @@ export const rootRequestHandler = (request: Request, response: Response, next: N if (request.header('accept') === 'application/nostr+json') { const { - info: { name, description, pubkey: rawPubkey, contact, relay_url }, + info: { name, description, pubkey, contact, relay_url }, } = settings const paymentsUrl = new URL(relay_url) @@ -20,10 +19,6 @@ export const rootRequestHandler = (request: Request, response: Response, next: N const content = settings.limits?.event?.content - const pubkey = rawPubkey.startsWith('npub1') - ? fromBech32(rawPubkey) - : rawPubkey - const relayInformationDocument = { name, description, diff --git a/src/repositories/event-repository.ts b/src/repositories/event-repository.ts index 9c645b8a..d4f0a8ac 100644 --- a/src/repositories/event-repository.ts +++ b/src/repositories/event-repository.ts @@ -10,6 +10,7 @@ import { forEach, forEachObjIndexed, groupBy, + identity, ifElse, invoker, is, @@ -28,8 +29,8 @@ import { toPairs, } from 'ramda' -import { ContextMetadataKey, EventDeduplicationMetadataKey, EventExpirationTimeMetadataKey } from '../constants/base' -import { DatabaseClient, EventId } from '../@types/base' +import { ContextMetadataKey, EventDeduplicationMetadataKey, EventDelegatorMetadataKey, EventExpirationTimeMetadataKey } from '../constants/base' +import { DatabaseClient, EventId, Tag } from '../@types/base' import { DBEvent, Event } from '../@types/event' import { IEventRepository, IQueryResult } from '../@types/repositories' import { toBuffer, toJSON } from '../utils/transform' @@ -65,6 +66,8 @@ export class EventRepository implements IEventRepository { } const queries = filters.map((currentFilter) => { const builder = this.readReplicaDbClient('events') + .leftJoin('event_tags', 'events.event_id', 'event_tags.event_id') + .select('events.*', 'event_tags.event_id as event_tags_event_id') forEachObjIndexed((tableFields: string[], filterName: string | number) => { builder.andWhere((bd) => { @@ -105,8 +108,8 @@ export class EventRepository implements IEventRepository { ])(currentFilter[filterName] as string[]) }) })({ - authors: ['event_pubkey'], - ids: ['event_id'], + authors: ['event_pubkey', 'event_delegator'], + ids: ['events.event_id'], }) if (Array.isArray(currentFilter.kinds)) { @@ -170,7 +173,7 @@ export class EventRepository implements IEventRepository { return this.insert(event).then(prop('rowCount') as () => number, () => 0) } - private insert(event: Event) { + private async insert(event: Event) { debug('inserting event: %o', event) const row = applySpec({ event_id: pipe(prop('id'), toBuffer), @@ -180,6 +183,11 @@ export class EventRepository implements IEventRepository { event_tags: pipe(prop('tags'), toJSON), event_content: prop('content'), event_signature: pipe(prop('sig'), toBuffer), + event_delegator: ifElse( + propSatisfies(is(String), EventDelegatorMetadataKey), + pipe(prop(EventDelegatorMetadataKey as any), toBuffer), + always(null), + ), remote_address: path([ContextMetadataKey as any, 'remoteAddress', 'address']), expires_at: ifElse( propSatisfies(is(Number), EventExpirationTimeMetadataKey), @@ -188,13 +196,15 @@ export class EventRepository implements IEventRepository { ), })(event) + await this.insertEventTags(row.event_id, event.tags) + return this.masterDbClient('events') .insert(row) .onConflict() .ignore() } - public upsert(event: Event): Promise { + public async upsert(event: Event): Promise { debug('upserting event: %o', event) const toJSON = (input: any) => JSON.stringify(input) @@ -207,6 +217,11 @@ export class EventRepository implements IEventRepository { event_tags: pipe(prop('tags'), toJSON), event_content: prop('content'), event_signature: pipe(prop('sig'), toBuffer), + event_delegator: ifElse( + propSatisfies(is(String), EventDelegatorMetadataKey), + pipe(prop(EventDelegatorMetadataKey as any), toBuffer), + always(null), + ), event_deduplication: ifElse( propSatisfies(isNil, EventDeduplicationMetadataKey), pipe(paths([['pubkey'], ['kind']]), toJSON), @@ -218,7 +233,6 @@ export class EventRepository implements IEventRepository { prop(EventExpirationTimeMetadataKey as any), always(null), ), - deleted_at: always(null), })(event) const query = this.masterDbClient('events') @@ -233,6 +247,9 @@ export class EventRepository implements IEventRepository { .merge(omit(['event_pubkey', 'event_kind', 'event_deduplication'])(row)) .where('events.event_created_at', '<', row.event_created_at) + await this.removeEventTagsByEventId(event.id); + await this.insertEventTags(event.id, event.tags); + return { then: (onfulfilled: (value: number) => T1 | PromiseLike, onrejected: (reason: any) => T2 | PromiseLike) => query.then(prop('rowCount') as () => number).then(onfulfilled, onrejected), catch: (onrejected: (reason: any) => T | PromiseLike) => query.catch(onrejected), @@ -240,9 +257,37 @@ export class EventRepository implements IEventRepository { } as Promise } - public deleteByPubkeyAndIds(pubkey: string, eventIdsToDelete: EventId[]): Promise { + public async insertStubs(pubkey: string, eventIdsToDelete: EventId[]): Promise { + debug('inserting stubs for %s: %o', pubkey, eventIdsToDelete) + const date = new Date() + await this.removeEventTagsByEventIds(eventIdsToDelete); + + return this.masterDbClient('events').insert( + eventIdsToDelete.map( + applySpec({ + event_id: pipe(identity, toBuffer), + event_pubkey: pipe(always(pubkey), toBuffer), + event_created_at: always(Math.floor(date.getTime() / 1000)), + event_kind: always(5), + event_tags: always('[]'), + event_content: always(''), + event_signature: pipe(always(''), toBuffer), + event_delegator: always(null), + event_deduplication: pipe(always([pubkey, 5]), toJSON), + expires_at: always(null), + deleted_at: always(date.toISOString()), + }) + ) + ) + .onConflict() + .ignore() as Promise + } + + public async deleteByPubkeyAndIds(pubkey: string, eventIdsToDelete: EventId[]): Promise { debug('deleting events from %s: %o', pubkey, eventIdsToDelete) + await this.removeEventTagsByEventIds(eventIdsToDelete); + return this.masterDbClient('events') .where('event_pubkey', toBuffer(pubkey)) .whereIn('event_id', map(toBuffer)(eventIdsToDelete)) @@ -251,4 +296,28 @@ export class EventRepository implements IEventRepository { deleted_at: this.masterDbClient.raw('now()'), }) } + + private async insertEventTags(event_id: any, tags: Tag[]): Promise { + for (const [tag_name, tag_value] of tags) { + if (tag_name.length === 1 && tag_value) { + await this.masterDbClient('event_tags').insert({ + event_id: event_id, + tag_name, + tag_value + }); + } + } + } + + private async removeEventTagsByEventId(event_id: string): Promise { + await this.masterDbClient('event_tags') + .where('event_id', event_id) + .delete() + } + + private async removeEventTagsByEventIds(eventIdsToDelete: string[]): Promise { + await this.masterDbClient('event_tags') + .whereIn('event_id', map(toBuffer)(eventIdsToDelete)) + .delete() + } } diff --git a/src/routes/admissions/index.ts b/src/routes/admissions/index.ts deleted file mode 100644 index 8e63fb89..00000000 --- a/src/routes/admissions/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createGetAdmissionCheckController } from '../../factories/controllers/get-admission-check-controller-factory' -import { Router } from 'express' -import { withController } from '../../handlers/request-handlers/with-controller-request-handler' - -const admissionRouter = Router() - -admissionRouter - .get('/check/:pubkey', withController(createGetAdmissionCheckController)) - -export default admissionRouter \ No newline at end of file diff --git a/src/routes/index.ts b/src/routes/index.ts index 0e291f94..2c1e963f 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,7 +1,5 @@ import express from 'express' -import { nodeinfo21Handler, nodeinfoHandler } from '../handlers/request-handlers/nodeinfo-handler' -import admissionRouter from './admissions' import callbacksRouter from './callbacks' import { getHealthRequestHandler } from '../handlers/request-handlers/get-health-request-handler' import { getTermsRequestHandler } from '../handlers/request-handlers/get-terms-request-handler' @@ -15,12 +13,7 @@ router.get('/', rootRequestHandler) router.get('/healthz', getHealthRequestHandler) router.get('/terms', getTermsRequestHandler) -router.get('/.well-known/nodeinfo', nodeinfoHandler) -router.get('/nodeinfo/2.1', nodeinfo21Handler) -router.get('/nodeinfo/2.0', nodeinfo21Handler) - router.use('/invoices', rateLimiterMiddleware, invoiceRouter) -router.use('/admissions', rateLimiterMiddleware, admissionRouter) router.use('/callbacks', rateLimiterMiddleware, callbacksRouter) export default router diff --git a/src/routes/invoices/index.ts b/src/routes/invoices/index.ts index beefa741..5592d964 100644 --- a/src/routes/invoices/index.ts +++ b/src/routes/invoices/index.ts @@ -12,4 +12,4 @@ invoiceRouter .get('/:invoiceId/status', withController(createGetInvoiceStatusController)) .post('/', urlencoded({ extended: true }), withController(createPostInvoiceController)) -export default invoiceRouter \ No newline at end of file +export default invoiceRouter diff --git a/src/utils/event.ts b/src/utils/event.ts index 9c4bafd5..53ccedc0 100644 --- a/src/utils/event.ts +++ b/src/utils/event.ts @@ -1,6 +1,6 @@ import * as secp256k1 from '@noble/secp256k1' -import { applySpec, pipe, prop } from 'ramda' +import { applySpec, converge, curry, mergeLeft, nth, omit, pipe, prop, reduceBy } from 'ramda' import { CanonicalEvent, DBEvent, Event, UnidentifiedEvent, UnsignedEvent } from '../@types/event' import { createCipheriv, getRandomValues } from 'crypto' import { EventId, Pubkey, Tag } from '../@types/base' @@ -12,6 +12,7 @@ import { EventKindsRange } from '../@types/settings' import { fromBuffer } from './transform' import { getLeadingZeroBits } from './proof-of-work' import { isGenericTagQuery } from './filter' +import { RuneLike } from './runes/rune-like' import { SubscriptionFilter } from '../@types/subscription' import { WebSocketServerAdapterEvent } from '../constants/adapter' @@ -67,7 +68,18 @@ export const isEventMatchingFilter = (filter: SubscriptionFilter) => (event: Eve if ( !filter.authors.some(startsWith(event.pubkey)) ) { - return false + if (isDelegatedEvent(event)) { + const delegation = event.tags.find((tag) => tag[0] === EventTags.Delegation) + if (typeof delegation === 'undefined') { + return false + } + + if (!filter.authors.some(startsWith(delegation[1]))) { + return false + } + } else { + return false + } } } @@ -104,6 +116,51 @@ export const isEventMatchingFilter = (filter: SubscriptionFilter) => (event: Eve return true } +export const isDelegatedEvent = (event: Event): boolean => { + return event.tags.some((tag) => tag.length === 4 && tag[0] === EventTags.Delegation) +} + +export const isDelegatedEventValid = async (event: Event): Promise => { + const delegation = event.tags.find((tag) => tag.length === 4 && tag[0] === EventTags.Delegation) + if (!delegation) { + return false + } + + + // Validate rune + const runifiedEvent = (converge( + curry(mergeLeft), + [ + omit(['tags']), + pipe( + prop('tags') as any, + reduceBy( + (acc, tag) => ([...acc, tag[1]]), + [], + nth(0) as any, + ), + ), + ], + ) as any)(event) + + let result: boolean + try { + [result] = RuneLike.from(delegation[2]).test(runifiedEvent) + } catch (error) { + result = false + } + + if (!result) { + return false + } + + const serializedDelegationTag = `nostr:${delegation[0]}:${event.pubkey}:${delegation[2]}` + + const token = await secp256k1.utils.sha256(Buffer.from(serializedDelegationTag)) + + return secp256k1.schnorr.verify(delegation[3], token, delegation[1]) +} + export const getEventHash = async (event: Event | UnidentifiedEvent | UnsignedEvent): Promise => { const id = await secp256k1.utils.sha256(Buffer.from(JSON.stringify(serializeEvent(event)))) diff --git a/test/integration/features/nip-09/nip-09.feature b/test/integration/features/nip-09/nip-09.feature index 1bc53233..663724ff 100644 --- a/test/integration/features/nip-09/nip-09.feature +++ b/test/integration/features/nip-09/nip-09.feature @@ -21,10 +21,14 @@ Feature: NIP-09 And Alice drafts a text_note event with content "Twitter > Nostr" When Alice sends a delete event for their last event And Alice sends their last draft event successfully + And Alice subscribes to author Alice + Then Alice receives 1 delete event from Alice and EOSE Scenario: Alice sends a delete before deleted set_metadata Given someone called Alice And someone called Bob And Alice drafts a set_metadata event When Alice sends a delete event for their last event - Then Alice sends their last draft event successfully + And Alice sends their last draft event unsuccessfully + And Alice subscribes to author Alice + Then Alice receives 1 delete event from Alice and EOSE diff --git a/test/integration/features/nip-33/nip-33.feature b/test/integration/features/nip-33/nip-33.feature index dc669c61..855149db 100644 --- a/test/integration/features/nip-33/nip-33.feature +++ b/test/integration/features/nip-33/nip-33.feature @@ -30,24 +30,3 @@ Feature: NIP-33 Parameterized replaceable events And Alice sends a parameterized_replaceable_event_1 event with content "third" and tag d containing "friends" And Bob subscribes to author Alice Then Bob receives a parameterized_replaceable_event_1 event from Alice with content "third" and tag d containing "friends" - - Scenario: Alice deletes a parameterized replaceable event - Given someone called Alice - When Alice sends a parameterized_replaceable_event_1 event with content "exercise" and tag d containing "2023-resolutions" - And Alice sends a delete event for their last event - And Alice subscribes to author Alice - Then Alice receives 1 delete event from Alice and EOSE - - Scenario: Alice deletes and replaces a parameterized replaceable event - Given someone called Alice - And Alice sends a parameterized_replaceable_event_1 event with content "gym" and tag d containing "2024-resolutions" - And Alice sends a delete event for their last event - When Alice sends a parameterized_replaceable_event_1 event with content "exercise" and tag d containing "2024-resolutions" - And Alice subscribes to parameterized_replaceable_event_1 events from Alice - Then Alice receives a parameterized_replaceable_event_1 event from Alice with content "exercise" and tag d containing "2024-resolutions" - - Scenario: Alice deletes before sending parameterized replaceable event - Given someone called Alice - And Alice drafts a parameterized_replaceable_event_2 event with content "don't worry about it" and tag d containing "topsycrets" - When Alice sends a delete event for their last event - And Alice sends their last draft event successfully \ No newline at end of file diff --git a/test/integration/features/nip-33/nip-33.feature.ts b/test/integration/features/nip-33/nip-33.feature.ts index cba37160..9c421ebf 100644 --- a/test/integration/features/nip-33/nip-33.feature.ts +++ b/test/integration/features/nip-33/nip-33.feature.ts @@ -1,11 +1,10 @@ -import { Then, When, World } from '@cucumber/cucumber' +import { Then, When } from '@cucumber/cucumber' import { expect } from 'chai' import WebSocket from 'ws' -import { createEvent, createSubscription, sendEvent, waitForEventCount, waitForNextEvent } from '../helpers' +import { createEvent, sendEvent, waitForEventCount, waitForNextEvent } from '../helpers' import { EventKinds, EventTags } from '../../../../src/constants/base' import { Event } from '../../../../src/@types/event' -import { isDraft } from '../shared' When(/^(\w+) sends a parameterized_replaceable_event_0 event with content "([^"]+)" and tag (\w) containing "([^"]+)"$/, async function( name: string, @@ -109,40 +108,3 @@ Then(/(\w+) receives (\d+) parameterized_replaceable_event_0 events? from (\w+) expect(events[0].pubkey).to.equal(this.parameters.identities[author].pubkey) expect(events[0].content).to.equal(content) }) - -When(/^(\w+) subscribes to parameterized_replaceable_event_1 events from (\w+)$/, async function (this: World>, name: string, author: string) { - const ws = this.parameters.clients[name] as WebSocket - const authorPubkey = this.parameters.identities[author].pubkey - const subscription = { - name: `test-${Math.random()}`, - filters: [ - { kinds: [EventKinds.PARAMETERIZED_REPLACEABLE_FIRST + 1], authors: [authorPubkey] }, - ], - } - this.parameters.subscriptions[name].push(subscription) - - await createSubscription(ws, subscription.name, subscription.filters) -}) - - -Then(/^(\w+) drafts a parameterized_replaceable_event_2 event with content "([^"]+?)" and tag (\w+) containing "([^"]+?)"$/, async function ( - name: string, - content: string, - tagName: string, - tagValue: string, -) { - const { pubkey, privkey } = this.parameters.identities[name] - - const event: Event = await createEvent({ - pubkey, - kind: EventKinds.PARAMETERIZED_REPLACEABLE_FIRST + 2, - content, - tags: [ - [tagName, tagValue], - ], - }, privkey) - - event[isDraft] = true - - this.parameters.events[name].push(event) -}) \ No newline at end of file diff --git a/test/integration/features/shared.ts b/test/integration/features/shared.ts index d515d00f..2759b3f7 100644 --- a/test/integration/features/shared.ts +++ b/test/integration/features/shared.ts @@ -16,10 +16,8 @@ import Sinon from 'sinon' import { connect, createIdentity, createSubscription, sendEvent } from './helpers' import { getMasterDbClient, getReadReplicaDbClient } from '../../../src/database/client' import { AppWorker } from '../../../src/app/worker' -import { CacheClient } from '../../../src/@types/cache' import { DatabaseClient } from '../../../src/@types/base' import { Event } from '../../../src/@types/event' -import { getCacheClient } from '../../../src/cache/client' import { SettingsStatic } from '../../../src/utils/settings' import { workerFactory } from '../../../src/factories/worker-factory' @@ -29,7 +27,6 @@ let worker: AppWorker let dbClient: DatabaseClient let rrDbClient: DatabaseClient -let cacheClient: CacheClient export const streams = new WeakMap>() @@ -38,9 +35,7 @@ BeforeAll({ timeout: 1000 }, async function () { process.env.SECRET = Math.random().toString().repeat(6) dbClient = getMasterDbClient() rrDbClient = getReadReplicaDbClient() - cacheClient = getCacheClient() await dbClient.raw('SELECT 1=1') - await rrDbClient.raw('SELECT 1=1') Sinon.stub(SettingsStatic, 'watchSettings') const settings = SettingsStatic.createSettings() @@ -59,11 +54,7 @@ BeforeAll({ timeout: 1000 }, async function () { AfterAll(async function() { worker.close(async () => { - await Promise.all([ - dbClient.destroy(), - rrDbClient.destroy(), - cacheClient.disconnect(), - ]) + await Promise.all([dbClient.destroy(), rrDbClient.destroy()]) }) }) @@ -84,6 +75,8 @@ After(async function () { } this.parameters.clients = {} + const dbClient = getMasterDbClient() + await dbClient('events') .whereIn('event_pubkey', Object .values(this.parameters.identities as Record) diff --git a/test/unit/factories/delegated-event-strategy-factory.spec.ts b/test/unit/factories/delegated-event-strategy-factory.spec.ts new file mode 100644 index 00000000..9cc4e0cb --- /dev/null +++ b/test/unit/factories/delegated-event-strategy-factory.spec.ts @@ -0,0 +1,46 @@ +import { expect } from 'chai' + +import { DefaultEventStrategy } from '../../../src/handlers/event-strategies/default-event-strategy' +import { delegatedEventStrategyFactory } from '../../../src/factories/delegated-event-strategy-factory' +import { EphemeralEventStrategy } from '../../../src/handlers/event-strategies/ephemeral-event-strategy' +import { Event } from '../../../src/@types/event' +import { EventKinds } from '../../../src/constants/base' +import { Factory } from '../../../src/@types/base' +import { IEventRepository } from '../../../src/@types/repositories' +import { IEventStrategy } from '../../../src/@types/message-handlers' +import { IWebSocketAdapter } from '../../../src/@types/adapters' + +describe('delegatedEventStrategyFactory', () => { + let eventRepository: IEventRepository + let event: Event + let adapter: IWebSocketAdapter + let factory: Factory>, [Event, IWebSocketAdapter]> + + beforeEach(() => { + eventRepository = {} as any + event = {} as any + adapter = {} as any + + factory = delegatedEventStrategyFactory(eventRepository) + }) + + it('returns EphemeralEventStrategy given a set_metadata event', () => { + event.kind = EventKinds.EPHEMERAL_FIRST + expect(factory([event, adapter])).to.be.an.instanceOf(EphemeralEventStrategy) + }) + + it('returns DefaultEventStrategy given a text_note event', () => { + event.kind = EventKinds.TEXT_NOTE + expect(factory([event, adapter])).to.be.an.instanceOf(DefaultEventStrategy) + }) + + it('returns undefined given a replaceable event', () => { + event.kind = EventKinds.REPLACEABLE_FIRST + expect(factory([event, adapter])).to.be.undefined + }) + + it('returns undefined given a delete event', () => { + event.kind = EventKinds.DELETE + expect(factory([event, adapter])).to.be.undefined + }) +}) diff --git a/test/unit/factories/message-handler-factory.spec.ts b/test/unit/factories/message-handler-factory.spec.ts index 4c5299ff..b44c1ce7 100644 --- a/test/unit/factories/message-handler-factory.spec.ts +++ b/test/unit/factories/message-handler-factory.spec.ts @@ -2,8 +2,10 @@ import { expect } from 'chai' import { IEventRepository, IUserRepository } from '../../../src/@types/repositories' import { IncomingMessage, MessageType } from '../../../src/@types/messages' +import { DelegatedEventMessageHandler } from '../../../src/handlers/delegated-event-message-handler' import { Event } from '../../../src/@types/event' import { EventMessageHandler } from '../../../src/handlers/event-message-handler' +import { EventTags } from '../../../src/constants/base' import { IWebSocketAdapter } from '../../../src/@types/adapters' import { messageHandlerFactory } from '../../../src/factories/message-handler-factory' import { SubscribeMessageHandler } from '../../../src/handlers/subscribe-message-handler' @@ -36,6 +38,18 @@ describe('messageHandlerFactory', () => { expect(factory([message, adapter])).to.be.an.instanceOf(EventMessageHandler) }) + it('returns DelegatedEventMessageHandler when given an EVENT message with delegated event', () => { + event.tags = [ + [EventTags.Delegation, '', '', ''], + ] + message = [ + MessageType.EVENT, + event, + ] + + expect(factory([message, adapter])).to.be.an.instanceOf(DelegatedEventMessageHandler) + }) + it('returns SubscribeMessageHandler when given a REQ message', () => { message = [ MessageType.REQ, diff --git a/test/unit/handlers/delegated-event-message-handler.spec.ts b/test/unit/handlers/delegated-event-message-handler.spec.ts new file mode 100644 index 00000000..a965bbe8 --- /dev/null +++ b/test/unit/handlers/delegated-event-message-handler.spec.ts @@ -0,0 +1,229 @@ +import chai from 'chai' +import chaiAsPromised from 'chai-as-promised' +import EventEmitter from 'events' +import Sinon from 'sinon' +import sinonChai from 'sinon-chai' + +chai.use(sinonChai) +chai.use(chaiAsPromised) + +import { IncomingEventMessage, MessageType } from '../../../src/@types/messages' +import { DelegatedEventMessageHandler } from '../../../src/handlers/delegated-event-message-handler' +import { Event } from '../../../src/@types/event' +import { EventMessageHandler } from '../../../src/handlers/event-message-handler' +import { EventTags } from '../../../src/constants/base' +import { IUserRepository } from '../../../src/@types/repositories' +import { WebSocketAdapterEvent } from '../../../src/constants/adapter' + +const { expect } = chai + +describe('DelegatedEventMessageHandler', () => { + let webSocket: EventEmitter + let handler: DelegatedEventMessageHandler + let userRepository: IUserRepository + let event: Event + let message: IncomingEventMessage + let sandbox: Sinon.SinonSandbox + + let originalConsoleWarn: any = undefined + + beforeEach(() => { + sandbox = Sinon.createSandbox() + originalConsoleWarn = console.warn + console.warn = () => undefined + event = { + content: 'hello', + created_at: 1665546189, + id: 'f'.repeat(64), + kind: 1, + pubkey: 'f'.repeat(64), + sig: 'f'.repeat(128), + tags: [ + [EventTags.Delegation, 'delegator', 'rune', 'signature'], + ], + } + }) + + afterEach(() => { + console.warn = originalConsoleWarn + sandbox.restore() + }) + + describe('handleMessage', () => { + let canAcceptEventStub: Sinon.SinonStub + let isEventValidStub: Sinon.SinonStub + let strategyFactoryStub: Sinon.SinonStub + let onMessageSpy: Sinon.SinonSpy + let strategyExecuteStub: Sinon.SinonStub + let isRateLimitedStub: Sinon.SinonStub + let isUserAdmitted: Sinon.SinonStub + + beforeEach(() => { + canAcceptEventStub = sandbox.stub(DelegatedEventMessageHandler.prototype, 'canAcceptEvent' as any) + isEventValidStub = sandbox.stub(DelegatedEventMessageHandler.prototype, 'isEventValid' as any) + isUserAdmitted = sandbox.stub(EventMessageHandler.prototype, 'isUserAdmitted' as any) + strategyExecuteStub = sandbox.stub() + strategyFactoryStub = sandbox.stub().returns({ + execute: strategyExecuteStub, + }) + onMessageSpy = sandbox.fake.returns(undefined) + webSocket = new EventEmitter() + webSocket.on(WebSocketAdapterEvent.Message, onMessageSpy) + message = [MessageType.EVENT, event] + isRateLimitedStub = sandbox.stub(EventMessageHandler.prototype, 'isRateLimited' as any) + handler = new DelegatedEventMessageHandler( + webSocket as any, + strategyFactoryStub, + userRepository, + () => ({}) as any, + () => ({ hit: async () => false }), + ) + }) + + afterEach(() => { + isEventValidStub.restore() + canAcceptEventStub.restore() + webSocket.removeAllListeners() + }) + + it('rejects event if it can\'t be accepted', async () => { + canAcceptEventStub.returns('reason') + + await handler.handleMessage(message) + + expect(canAcceptEventStub).to.have.been.calledOnceWithExactly(event) + expect(onMessageSpy).to.have.been.calledOnceWithExactly( + [ + MessageType.OK, + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + false, + 'reason', + ], + ) + expect(strategyFactoryStub).not.to.have.been.called + }) + + it('rejects event if invalid', async () => { + isEventValidStub.returns('reason') + + await handler.handleMessage(message) + + expect(isEventValidStub).to.have.been.calledOnceWithExactly(event) + expect(onMessageSpy).not.to.have.been.calledOnceWithExactly() + expect(strategyFactoryStub).not.to.have.been.called + }) + + it('rejects event if rate-limited', async () => { + isRateLimitedStub.resolves(true) + + await handler.handleMessage(message) + + expect(isRateLimitedStub).to.have.been.calledOnceWithExactly(event) + expect(onMessageSpy).to.have.been.calledOnceWithExactly( + [MessageType.OK, event.id, false, 'rate-limited: slow down'], + ) + expect(strategyFactoryStub).not.to.have.been.called + }) + + it('rejects event is user is not admitted', async () => { + isUserAdmitted.resolves('not admitted') + + await handler.handleMessage(message) + + expect(isRateLimitedStub).to.have.been.calledOnceWithExactly(event) + expect(isUserAdmitted).to.have.been.calledOnceWithExactly(event) + expect(onMessageSpy).to.have.been.calledOnceWithExactly([ + MessageType.OK, + event.id, + false, + 'not admitted', + ]) + }) + + it('does not call strategy if none given', async () => { + isEventValidStub.returns(undefined) + canAcceptEventStub.returns(undefined) + strategyFactoryStub.returns(undefined) + + await handler.handleMessage(message) + + expect(isEventValidStub).to.have.been.calledOnceWithExactly(event) + expect(onMessageSpy).not.to.have.been.calledOnceWithExactly() + expect(strategyFactoryStub).to.have.been.calledOnceWithExactly([ + event, + webSocket, + ]) + expect(strategyExecuteStub).not.to.have.been.called + }) + + it('calls strategy with event', async () => { + isEventValidStub.returns(undefined) + canAcceptEventStub.returns(undefined) + + await handler.handleMessage(message) + + expect(isEventValidStub).to.have.been.calledOnceWithExactly(event) + expect(onMessageSpy).not.to.have.been.calledOnceWithExactly() + expect(strategyFactoryStub).to.have.been.calledOnceWithExactly([ + event, + webSocket, + ]) + expect(strategyExecuteStub).to.have.been.calledOnceWithExactly(event) + }) + + it('does not reject if strategy rejects', async () => { + const error = new Error('mistakes were made') + isEventValidStub.returns(undefined) + canAcceptEventStub.returns(undefined) + strategyExecuteStub.rejects(error) + + return expect(handler.handleMessage(message)).to.eventually.be.fulfilled + }) + }) + + describe('isEventValid', () => { + let parentIsEventValidStub: Sinon.SinonStub + + beforeEach(() => { + parentIsEventValidStub = Sinon.stub(EventMessageHandler.prototype, 'isEventValid' as any) + event = { + 'id': 'a080fd288b60ac2225ff2e2d815291bd730911e583e177302cc949a15dc2b2dc', + 'pubkey': '62903b1ff41559daf9ee98ef1ae67cc52f301bb5ce26d14baba3052f649c3f49', + 'created_at': 1660896109, + 'kind': 1, + 'tags': [ + [ + EventTags.Delegation, + '86f0689bd48dcd19c67a19d994f938ee34f251d8c39976290955ff585f2db42e', + 'kind=1&created_at>1640995200', + 'c33c88ba78ec3c760e49db591ac5f7b129e3887c8af7729795e85a0588007e5ac89b46549232d8f918eefd73e726cb450135314bfda419c030d0b6affe401ec1', + ], + ], + 'content': 'Hello world', + 'sig': 'cd4a3cd20dc61dcbc98324de561a07fd23b3d9702115920c0814b5fb822cc5b7c5bcdaf3fa326d24ed50c5b9c8214d66c75bae34e3a84c25e4d122afccb66eb6', + } + }) + + afterEach(() => { + parentIsEventValidStub.restore() + }) + + it('returns undefined if event and delegate tag is valid', async () => { + parentIsEventValidStub.resolves(undefined) + + expect(await (handler as any).isEventValid(event)).to.be.undefined + }) + + it('returns reason if event is not valid', () => { + parentIsEventValidStub.resolves('reason') + return expect((handler as any).isEventValid(event)).to.eventually.equal('reason') + }) + + it('returns reason if delegate signature is not valid', () => { + parentIsEventValidStub.resolves(undefined) + + event.tags[0][3] = 'wrong sig' + return expect((handler as any).isEventValid(event)).to.eventually.equal('invalid: delegation verification failed') + }) + }) +}) diff --git a/test/unit/handlers/event-strategies/delete-event-strategy.spec.ts b/test/unit/handlers/event-strategies/delete-event-strategy.spec.ts index b2c5fc63..0d632a8c 100644 --- a/test/unit/handlers/event-strategies/delete-event-strategy.spec.ts +++ b/test/unit/handlers/event-strategies/delete-event-strategy.spec.ts @@ -32,6 +32,7 @@ describe('DeleteEventStrategy', () => { let webSocketEmitStub: Sinon.SinonStub let eventRepositoryCreateStub: Sinon.SinonStub let eventRepositoryDeleteByPubkeyAndIdsStub: Sinon.SinonStub + let eventRepositoryInsertStubsStub: Sinon.SinonStub let strategy: IEventStrategy> @@ -42,6 +43,7 @@ describe('DeleteEventStrategy', () => { eventRepositoryCreateStub = sandbox.stub(EventRepository.prototype, 'create') eventRepositoryDeleteByPubkeyAndIdsStub = sandbox.stub(EventRepository.prototype, 'deleteByPubkeyAndIds') + eventRepositoryInsertStubsStub = sandbox.stub(EventRepository.prototype, 'insertStubs') webSocketEmitStub = sandbox.stub() webSocket = { @@ -65,6 +67,18 @@ describe('DeleteEventStrategy', () => { expect(eventRepositoryCreateStub).to.have.been.calledOnceWithExactly(event) }) + it('inserts stubs', async () => { + await strategy.execute(event) + + expect(eventRepositoryInsertStubsStub).to.have.been.calledOnceWithExactly( + event.pubkey, + [ + '0000000000000000000000000000000000000000000000000000000000000000', + 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + ] + ) + }) + it('deletes events if it has e tags', async () => { await strategy.execute(event) @@ -121,6 +135,7 @@ describe('DeleteEventStrategy', () => { expect(eventRepositoryCreateStub).to.have.been.calledOnceWithExactly(event) expect(eventRepositoryDeleteByPubkeyAndIdsStub).not.to.have.been.called + expect(eventRepositoryInsertStubsStub).to.not.have.been.called expect(webSocketEmitStub).not.to.have.been.called }) }) diff --git a/test/unit/repositories/event-repository.spec.ts b/test/unit/repositories/event-repository.spec.ts index abe026f9..c235c3d5 100644 --- a/test/unit/repositories/event-repository.spec.ts +++ b/test/unit/repositories/event-repository.spec.ts @@ -74,7 +74,7 @@ describe('EventRepository', () => { const query = repository.findByFilters(filters).toString() - expect(query).to.equal('select * from "events" where ("event_pubkey" in (X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\')) order by "event_created_at" asc limit 500') + expect(query).to.equal('select * from "events" where ("event_pubkey" in (X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\') or "event_delegator" in (X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\')) order by "event_created_at" asc limit 500') }) it('selects events by two authors', () => { @@ -89,7 +89,7 @@ describe('EventRepository', () => { const query = repository.findByFilters(filters).toString() - expect(query).to.equal('select * from "events" where ("event_pubkey" in (X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\', X\'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245\')) order by "event_created_at" asc limit 500') + expect(query).to.equal('select * from "events" where ("event_pubkey" in (X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\', X\'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245\') or "event_delegator" in (X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\', X\'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245\')) order by "event_created_at" asc limit 500') }) it('selects events by one author prefix (even length)', () => { @@ -103,7 +103,7 @@ describe('EventRepository', () => { const query = repository.findByFilters(filters).toString() - expect(query).to.equal('select * from "events" where (substring("event_pubkey" from 1 for 3) = X\'22e804\') order by "event_created_at" asc limit 500') + expect(query).to.equal('select * from "events" where (substring("event_pubkey" from 1 for 3) = X\'22e804\' or substring("event_delegator" from 1 for 3) = X\'22e804\') order by "event_created_at" asc limit 500') }) it('selects events by one author prefix (odd length)', () => { @@ -117,7 +117,7 @@ describe('EventRepository', () => { const query = repository.findByFilters(filters).toString() - expect(query).to.equal('select * from "events" where (substring("event_pubkey" from 1 for 4) BETWEEN E\'\\\\x22e804f0\' AND E\'\\\\x22e804ff\') order by "event_created_at" asc limit 500') + expect(query).to.equal('select * from "events" where (substring("event_pubkey" from 1 for 4) BETWEEN E\'\\\\x22e804f0\' AND E\'\\\\x22e804ff\' or substring("event_delegator" from 1 for 4) BETWEEN E\'\\\\x22e804f0\' AND E\'\\\\x22e804ff\') order by "event_created_at" asc limit 500') }) it('selects events by two author prefix (first even, second odd)', () => { @@ -132,7 +132,7 @@ describe('EventRepository', () => { const query = repository.findByFilters(filters).toString() - expect(query).to.equal('select * from "events" where (substring("event_pubkey" from 1 for 3) = X\'22e804\' or substring("event_pubkey" from 1 for 4) BETWEEN E\'\\\\x32e18270\' AND E\'\\\\x32e1827f\') order by "event_created_at" asc limit 500') + expect(query).to.equal('select * from "events" where (substring("event_pubkey" from 1 for 3) = X\'22e804\' or substring("event_delegator" from 1 for 3) = X\'22e804\' or substring("event_pubkey" from 1 for 4) BETWEEN E\'\\\\x32e18270\' AND E\'\\\\x32e1827f\' or substring("event_delegator" from 1 for 4) BETWEEN E\'\\\\x32e18270\' AND E\'\\\\x32e1827f\') order by "event_created_at" asc limit 500') }) }) @@ -363,7 +363,7 @@ describe('EventRepository', () => { const query = repository.findByFilters(filters).toString() - expect(query).to.equal('(select * from "events" where "event_kind" in (1)) union (select * from "events" where (substring("event_id" from 1 for 3) BETWEEN E\'\\\\xaaaaa0\' AND E\'\\\\xaaaaaf\') order by "event_created_at" asc limit 500) union (select * from "events" where (substring("event_pubkey" from 1 for 3) BETWEEN E\'\\\\xbbbbb0\' AND E\'\\\\xbbbbbf\') order by "event_created_at" asc limit 500) union (select * from "events" where "event_created_at" >= 1000 order by "event_created_at" asc limit 500) union (select * from "events" where "event_created_at" <= 1000 order by "event_created_at" asc limit 500) union (select * from "events" order by "event_created_at" DESC limit 1000) order by "event_created_at" asc limit 500') + expect(query).to.equal('(select * from "events" where "event_kind" in (1)) union (select * from "events" where (substring("event_id" from 1 for 3) BETWEEN E\'\\\\xaaaaa0\' AND E\'\\\\xaaaaaf\') order by "event_created_at" asc limit 500) union (select * from "events" where (substring("event_pubkey" from 1 for 3) BETWEEN E\'\\\\xbbbbb0\' AND E\'\\\\xbbbbbf\' or substring("event_delegator" from 1 for 3) BETWEEN E\'\\\\xbbbbb0\' AND E\'\\\\xbbbbbf\') order by "event_created_at" asc limit 500) union (select * from "events" where "event_created_at" >= 1000 order by "event_created_at" asc limit 500) union (select * from "events" where "event_created_at" <= 1000 order by "event_created_at" asc limit 500) union (select * from "events" order by "event_created_at" DESC limit 1000) order by "event_created_at" asc limit 500') }) }) }) @@ -435,7 +435,25 @@ describe('EventRepository', () => { const query = (repository as any).insert(event).toString() - expect(query).to.equal('insert into "events" ("event_content", "event_created_at", "event_id", "event_kind", "event_pubkey", "event_signature", "event_tags", "expires_at", "remote_address") values (\'I\'\'ve set up mirroring between relays: https://i.imgur.com/HxCDipB.png\', 1648351380, X\'6b3cdd0302ded8068ad3f0269c74423ca4fee460f800f3d90103b63f14400407\', 1, X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\', X\'b37adfed0e6398546d623536f9ddc92b95b7dc71927e1123266332659253ecd0ffa91ddf2c0a82a8426c5b363139d28534d6cac893b8a810149557a3f6d36768\', \'[["p","8355095016fddbe31fcf1453b26f613553e9758cf2263e190eac8fd96a3d3de9","wss://nostr-pub.wellorder.net"],["e","7377fa81fc6c7ae7f7f4ef8938d4a603f7bf98183b35ab128235cc92d4bebf96","wss://nostr-relay.untethr.me"]]\', NULL, \'::1\') on conflict do nothing') + expect(query).to.equal('insert into "events" ("event_content", "event_created_at", "event_delegator", "event_id", "event_kind", "event_pubkey", "event_signature", "event_tags", "expires_at", "remote_address") values (\'I\'\'ve set up mirroring between relays: https://i.imgur.com/HxCDipB.png\', 1648351380, NULL, X\'6b3cdd0302ded8068ad3f0269c74423ca4fee460f800f3d90103b63f14400407\', 1, X\'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793\', X\'b37adfed0e6398546d623536f9ddc92b95b7dc71927e1123266332659253ecd0ffa91ddf2c0a82a8426c5b363139d28534d6cac893b8a810149557a3f6d36768\', \'[["p","8355095016fddbe31fcf1453b26f613553e9758cf2263e190eac8fd96a3d3de9","wss://nostr-pub.wellorder.net"],["e","7377fa81fc6c7ae7f7f4ef8938d4a603f7bf98183b35ab128235cc92d4bebf96","wss://nostr-relay.untethr.me"]]\', NULL, \'::1\') on conflict do nothing') + }) + }) + + describe('insertStubs', () => { + let clock: sinon.SinonFakeTimers + + beforeEach(() => { + clock = sinon.useFakeTimers(1673835425) + }) + + afterEach(() => { + clock.restore() + }) + + it('insert stubs by pubkey & event ids', () => { + const query = repository.insertStubs('001122', ['aabbcc', 'ddeeff']).toString() + + expect(query).to.equal('insert into "events" ("deleted_at", "event_content", "event_created_at", "event_deduplication", "event_delegator", "event_id", "event_kind", "event_pubkey", "event_signature", "event_tags", "expires_at") values (\'1970-01-20T08:57:15.425Z\', \'\', 1673835, \'["001122",5]\', NULL, X\'aabbcc\', 5, X\'001122\', X\'\', \'[]\', NULL), (\'1970-01-20T08:57:15.425Z\', \'\', 1673835, \'["001122",5]\', NULL, X\'ddeeff\', 5, X\'001122\', X\'\', \'[]\', NULL) on conflict do nothing') }) }) @@ -462,7 +480,7 @@ describe('EventRepository', () => { const query = repository.upsert(event).toString() - expect(query).to.equal('insert into "events" ("deleted_at", "event_content", "event_created_at", "event_deduplication", "event_id", "event_kind", "event_pubkey", "event_signature", "event_tags", "expires_at", "remote_address") values (NULL, \'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\', 1564498626, \'["55b702c167c85eb1c2d5ab35d68bedd1a35b94c01147364d2395c2f66f35a503",0]\', X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\', 0, X\'55b702c167c85eb1c2d5ab35d68bedd1a35b94c01147364d2395c2f66f35a503\', X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\', \'[]\', NULL, \'::1\') on conflict (event_pubkey, event_kind, event_deduplication) WHERE (event_kind = 0 OR event_kind = 3 OR event_kind = 41 OR (event_kind >= 10000 AND event_kind < 20000)) OR (event_kind >= 30000 AND event_kind < 40000) do update set "event_id" = X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\',"event_created_at" = 1564498626,"event_tags" = \'[]\',"event_content" = \'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\',"event_signature" = X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\',"remote_address" = \'::1\',"expires_at" = NULL,"deleted_at" = NULL where "events"."event_created_at" < 1564498626') + expect(query).to.equal('insert into "events" ("event_content", "event_created_at", "event_deduplication", "event_delegator", "event_id", "event_kind", "event_pubkey", "event_signature", "event_tags", "expires_at", "remote_address") values (\'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\', 1564498626, \'["55b702c167c85eb1c2d5ab35d68bedd1a35b94c01147364d2395c2f66f35a503",0]\', NULL, X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\', 0, X\'55b702c167c85eb1c2d5ab35d68bedd1a35b94c01147364d2395c2f66f35a503\', X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\', \'[]\', NULL, \'::1\') on conflict (event_pubkey, event_kind, event_deduplication) WHERE (event_kind = 0 OR event_kind = 3 OR event_kind = 41 OR (event_kind >= 10000 AND event_kind < 20000)) OR (event_kind >= 30000 AND event_kind < 40000) do update set "event_id" = X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\',"event_created_at" = 1564498626,"event_tags" = \'[]\',"event_content" = \'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\',"event_signature" = X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\',"event_delegator" = NULL,"remote_address" = \'::1\',"expires_at" = NULL where "events"."event_created_at" < 1564498626') }) it('replaces event based on event_pubkey, event_kind and event_deduplication', () => { @@ -480,7 +498,7 @@ describe('EventRepository', () => { const query = repository.upsert(event).toString() - expect(query).to.equal('insert into "events" ("deleted_at", "event_content", "event_created_at", "event_deduplication", "event_id", "event_kind", "event_pubkey", "event_signature", "event_tags", "expires_at", "remote_address") values (NULL, \'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\', 1564498626, \'["deduplication"]\', X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\', 0, X\'55b702c167c85eb1c2d5ab35d68bedd1a35b94c01147364d2395c2f66f35a503\', X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\', \'[]\', NULL, \'::1\') on conflict (event_pubkey, event_kind, event_deduplication) WHERE (event_kind = 0 OR event_kind = 3 OR event_kind = 41 OR (event_kind >= 10000 AND event_kind < 20000)) OR (event_kind >= 30000 AND event_kind < 40000) do update set "event_id" = X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\',"event_created_at" = 1564498626,"event_tags" = \'[]\',"event_content" = \'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\',"event_signature" = X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\',"remote_address" = \'::1\',"expires_at" = NULL,"deleted_at" = NULL where "events"."event_created_at" < 1564498626') + expect(query).to.equal('insert into "events" ("event_content", "event_created_at", "event_deduplication", "event_delegator", "event_id", "event_kind", "event_pubkey", "event_signature", "event_tags", "expires_at", "remote_address") values (\'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\', 1564498626, \'["deduplication"]\', NULL, X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\', 0, X\'55b702c167c85eb1c2d5ab35d68bedd1a35b94c01147364d2395c2f66f35a503\', X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\', \'[]\', NULL, \'::1\') on conflict (event_pubkey, event_kind, event_deduplication) WHERE (event_kind = 0 OR event_kind = 3 OR event_kind = 41 OR (event_kind >= 10000 AND event_kind < 20000)) OR (event_kind >= 30000 AND event_kind < 40000) do update set "event_id" = X\'e527fe8b0f64a38c6877f943a9e8841074056ba72aceb31a4c85e6d10b27095a\',"event_created_at" = 1564498626,"event_tags" = \'[]\',"event_content" = \'{"name":"ottman@minds.io","about":"","picture":"https://feat-2311-nostr.minds.io/icon/1002952989368913934/medium/1564498626/1564498626/1653379539"}\',"event_signature" = X\'d1de98733de2b412549aa64454722d9b66ab3c68e9e0d0f9c5d42e7bd54c30a06174364b683d2c8dbb386ff47f31e6cb7e2f3c3498d8819ee80421216c8309a9\',"event_delegator" = NULL,"remote_address" = \'::1\',"expires_at" = NULL where "events"."event_created_at" < 1564498626') }) }) }) diff --git a/test/unit/utils/event.spec.ts b/test/unit/utils/event.spec.ts index f845b5a5..0009decb 100644 --- a/test/unit/utils/event.spec.ts +++ b/test/unit/utils/event.spec.ts @@ -3,6 +3,8 @@ import { expect } from 'chai' import { CanonicalEvent, Event } from '../../../src/@types/event' import { getEventExpiration, + isDelegatedEvent, + isDelegatedEventValid, isDeleteEvent, isEphemeralEvent, isEventIdValid, @@ -398,6 +400,75 @@ describe('NIP-16', () => { // }) // }) +describe('NIP-26', () => { + let event: Event + beforeEach(() => { + event = { + 'id': 'a080fd288b60ac2225ff2e2d815291bd730911e583e177302cc949a15dc2b2dc', + 'pubkey': '62903b1ff41559daf9ee98ef1ae67cc52f301bb5ce26d14baba3052f649c3f49', + 'created_at': 1660896109, + 'kind': 1, + 'tags': [ + [ + 'delegation', + '86f0689bd48dcd19c67a19d994f938ee34f251d8c39976290955ff585f2db42e', + 'kind=1&created_at>1640995200', + 'c33c88ba78ec3c760e49db591ac5f7b129e3887c8af7729795e85a0588007e5ac89b46549232d8f918eefd73e726cb450135314bfda419c030d0b6affe401ec1', + ], + ], + 'content': 'Hello world', + 'sig': 'cd4a3cd20dc61dcbc98324de561a07fd23b3d9702115920c0814b5fb822cc5b7c5bcdaf3fa326d24ed50c5b9c8214d66c75bae34e3a84c25e4d122afccb66eb6', + } + }) + + describe('isDelegatedEvent', () => { + it('returns true if event contains delegation tag', () => { + expect(isDelegatedEvent(event)).to.be.true + }) + }) + + describe('isDelegatedEventValid', () => { + it('resolves with true if delegated event is valid', async () => { + expect(await isDelegatedEventValid(event)).to.be.true + }) + + it('resolves with false if no delegation tag is found', async () => { + event.tags = [] + expect(await isDelegatedEventValid(event)).to.be.false + }) + + it('resolves with false if delegation signature is invalid', async () => { + event.tags[0][3] = 'f' + expect(await isDelegatedEventValid(event)).to.be.false + }) + + it('resolves with false if delegation rule is not a valid rune', async () => { + event.tags[0][2] = '@' + expect(await isDelegatedEventValid(event)).to.be.false + }) + + + it('resolves with false if no delegation rule does not match', async () => { + event.tags[0][2] = 'a=1' + expect(await isDelegatedEventValid(event)).to.be.false + }) + }) + + describe('isEventMatchingFilter', () => { + it('returns true if author is delegator', () => { + expect( + isEventMatchingFilter({ authors: ['86f0689bd48dcd19c67a19d994f938ee34f251d8c39976290955ff585f2db42e'] })(event) + ).to.be.true + }) + + it('returns false if author is not delegator', () => { + expect( + isEventMatchingFilter({ authors: ['e8b487c079b0f67c695ae6c4c2552a47f38adfa2533cc5926bd2c102942fdcb7'] })(event) + ).to.be.false + }) + }) +}) + describe('NIP-09', () => { describe('isDeleteEvent', () => { it('returns true if event is kind 5', () => {