diff --git a/.presetterrc.json b/.presetterrc.json index 1dc1e4b..7d080ea 100644 --- a/.presetterrc.json +++ b/.presetterrc.json @@ -5,7 +5,8 @@ "config": { "tsconfig": { "compilerOptions": { - "module": "nodenext" + "module": "nodenext", + "moduleResolution": "node" } } } diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 7b79b65..e679619 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -20,6 +20,7 @@ "devDependencies": { "@lumeweb/node-library-preset": "^0.2.7", "@types/ws": "^8.5.10", + "orval": "^6.24.0", "presetter": "*" } }, @@ -47,6 +48,117 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.6.tgz", + "integrity": "sha512-M3YgsLjI0lZxvrpeGVk9Ap032W6TPQkH6pRAZz81Ac3WUNF79VQooAFnp8umjvVzUmD93NkogxEwbSce7qMsUg==", + "dev": true, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "call-me-maybe": "^1.0.1", + "js-yaml": "^3.13.1" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==", + "dev": true + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-10.1.0.tgz", + "integrity": "sha512-9Kt7EuS/7WbMAUv2gSziqjvxwDbFSg3Xeyfuj5laUODX8o/k/CpsAKiQ8W7/R88eXFTMbJYg6+7uAmOWNKmwnw==", + "dev": true, + "dependencies": { + "@apidevtools/json-schema-ref-parser": "9.0.6", + "@apidevtools/openapi-schemas": "^2.1.0", + "@apidevtools/swagger-methods": "^3.0.2", + "@jsdevtools/ono": "^7.1.3", + "ajv": "^8.6.3", + "ajv-draft-04": "^1.0.0", + "call-me-maybe": "^1.0.1" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, + "node_modules/@apidevtools/swagger-parser/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@apidevtools/swagger-parser/node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@apidevtools/swagger-parser/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@asyncapi/specs": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-4.3.1.tgz", + "integrity": "sha512-EfexhJu/lwF8OdQDm28NKLJHFkx0Gb6O+rcezhZYLPIoNYKXJMh2J1vFGpwmfAcTTh+ffK44Oc2Hs1Q4sLBp+A==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.11" + } + }, "node_modules/@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", @@ -791,6 +903,22 @@ "node": ">=16" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", @@ -1225,6 +1353,12 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@exodus/schemasafe": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", + "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", + "dev": true + }, "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", @@ -1277,6 +1411,60 @@ "node": ">=6.9.0" } }, + "node_modules/@ibm-cloud/openapi-ruleset": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@ibm-cloud/openapi-ruleset/-/openapi-ruleset-1.15.2.tgz", + "integrity": "sha512-LePXcmEIQ9nYe8kNY/uQwacEtuMNM6CS8T4ugb7qqFDE6jU6TTdJITFZ5M3ECJERWe2wozuPM9/VfKH88pzNxQ==", + "dev": true, + "dependencies": { + "@ibm-cloud/openapi-ruleset-utilities": "1.3.0", + "@stoplight/spectral-formats": "^1.5.0", + "@stoplight/spectral-functions": "^1.7.2", + "@stoplight/spectral-rulesets": "^1.16.0", + "chalk": "^4.1.1", + "lodash": "^4.17.21", + "loglevel": "^1.8.1", + "loglevel-plugin-prefix": "0.8.4", + "minimatch": "^6.1.6", + "validator": "^13.7.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ibm-cloud/openapi-ruleset-utilities": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ibm-cloud/openapi-ruleset-utilities/-/openapi-ruleset-utilities-1.3.0.tgz", + "integrity": "sha512-CuG5u6+gSEbU8IKGZqKH+WsH4rFU9KMYriDzG6F+DJ8XbtEd3RTHWMQdAeO/ec2XiyPF2j4VxWEXMzVZJ05bAA==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@ibm-cloud/openapi-ruleset/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/@ibm-cloud/openapi-ruleset/node_modules/minimatch": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-6.2.0.tgz", + "integrity": "sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1789,6 +1977,36 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, + "node_modules/@jsep-plugin/regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz", + "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==", + "dev": true, + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, + "node_modules/@jsep-plugin/ternary": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.3.tgz", + "integrity": "sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==", + "dev": true, + "engines": { + "node": ">= 10.16.0" + }, + "peerDependencies": { + "jsep": "^0.4.0||^1.0.0" + } + }, "node_modules/@lumeweb/libs5": { "version": "0.1.0-develop.82", "resolved": "https://registry.npmjs.org/@lumeweb/libs5/-/libs5-0.1.0-develop.82.tgz", @@ -2460,6 +2678,505 @@ "@octokit/openapi-types": "^19.1.0" } }, + "node_modules/@orval/angular": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@orval/angular/-/angular-6.24.0.tgz", + "integrity": "sha512-ENnwxhbSdYo4d5J5eDspDqF9OrHnf1XYnWWouMGeIHs6l6NBq+AGb6uFEH5pzGPi7Erw5GvXIDbTWFv3W/0Vxw==", + "dev": true, + "dependencies": { + "@orval/core": "6.24.0" + } + }, + "node_modules/@orval/axios": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@orval/axios/-/axios-6.24.0.tgz", + "integrity": "sha512-VxQgwAo5Djxvpixs15BVY1gMjd49YmjqBfEeQB7PrrY1T1PvVyENgFkBr+hg2QoBdy2LmdMxXDfFig00FNoerQ==", + "dev": true, + "dependencies": { + "@orval/core": "6.24.0" + } + }, + "node_modules/@orval/core": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@orval/core/-/core-6.24.0.tgz", + "integrity": "sha512-8pfzviEPuP/hlxj0PGUKphKRjfIVYYKCkWamCiNqmUyVxrL+plQnIYvUf5I9Xol0d+oZ1lG2VNV2v4Gtt/zwXQ==", + "dev": true, + "dependencies": { + "@apidevtools/swagger-parser": "^10.1.0", + "@ibm-cloud/openapi-ruleset": "^1.14.2", + "acorn": "^8.11.2", + "ajv": "^8.12.0", + "chalk": "^4.1.2", + "compare-versions": "^6.1.0", + "debug": "^4.3.4", + "esbuild": "^0.19.11", + "esutils": "2.0.3", + "fs-extra": "^11.2.0", + "globby": "11.1.0", + "lodash.get": "^4.4.2", + "lodash.isempty": "^4.4.0", + "lodash.omit": "^4.5.0", + "lodash.uniq": "^4.5.0", + "lodash.uniqby": "^4.7.0", + "lodash.uniqwith": "^4.5.0", + "micromatch": "^4.0.5", + "openapi3-ts": "4.2.1", + "swagger2openapi": "^7.0.8" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@orval/core/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@orval/core/node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "node_modules/@orval/core/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@orval/mock": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@orval/mock/-/mock-6.24.0.tgz", + "integrity": "sha512-7U1Bpa2FmRqGdFZBIf6qAKJ+9z6aF/1LjxHabxkcdChP8jrPLVncCKK/mqwE0/8lntxA28/NR7q4l5NAE/GC8w==", + "dev": true, + "dependencies": { + "@orval/core": "6.24.0", + "lodash.get": "^4.4.2", + "lodash.omit": "^4.5.0", + "openapi3-ts": "^4.2.1" + } + }, + "node_modules/@orval/query": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@orval/query/-/query-6.24.0.tgz", + "integrity": "sha512-I0NCXBdcro7+kgu4UyCM4m/PZPwTBZHHUPiIfhkxkUUzqY2gX0k3Au2sZcHULyEZBB8A2+s42YPEWPGg1yjP7Q==", + "dev": true, + "dependencies": { + "@orval/core": "6.24.0", + "lodash.omitby": "^4.6.0" + } + }, + "node_modules/@orval/swr": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@orval/swr/-/swr-6.24.0.tgz", + "integrity": "sha512-13gGIiYE1hg7h/ps/z//ITUcZUQI6e6L7wFaE6+A0EoEuC6z2UXIx+4TV0t43G8S+E8Ow6ZUNjLzeR1GjiRmPA==", + "dev": true, + "dependencies": { + "@orval/core": "6.24.0" + } + }, + "node_modules/@orval/zod": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/@orval/zod/-/zod-6.24.0.tgz", + "integrity": "sha512-EknDRi9Toh635CwDXtyzvwB4bGWw2NvbVHpw0ne7/y7nWsUW7N5+RRi+OAk39q/psFlCZtsI1EJtfyQ6Zr5MzQ==", + "dev": true, + "dependencies": { + "@orval/core": "6.24.0", + "lodash.uniq": "^4.5.0" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -3319,6 +4036,430 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@stoplight/json": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.0.tgz", + "integrity": "sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==", + "dev": true, + "dependencies": { + "@stoplight/ordered-object-literal": "^1.0.3", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^13.6.0", + "jsonc-parser": "~2.2.1", + "lodash": "^4.17.21", + "safe-stable-stringify": "^1.1" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@stoplight/json-ref-readers": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@stoplight/json-ref-readers/-/json-ref-readers-1.2.2.tgz", + "integrity": "sha512-nty0tHUq2f1IKuFYsLM4CXLZGHdMn+X/IwEUIpeSOXt0QjMUbL0Em57iJUDzz+2MkWG83smIigNZ3fauGjqgdQ==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.0", + "tslib": "^1.14.1" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@stoplight/json-ref-readers/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@stoplight/json-ref-resolver": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@stoplight/json-ref-resolver/-/json-ref-resolver-3.1.6.tgz", + "integrity": "sha512-YNcWv3R3n3U6iQYBsFOiWSuRGE5su1tJSiX6pAPRVk7dP0L7lqCteXGzuVRQ0gMZqUl8v1P0+fAKxF6PLo9B5A==", + "dev": true, + "dependencies": { + "@stoplight/json": "^3.21.0", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^12.3.0 || ^13.0.0", + "@types/urijs": "^1.19.19", + "dependency-graph": "~0.11.0", + "fast-memoize": "^2.5.2", + "immer": "^9.0.6", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "urijs": "^1.19.11" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/@stoplight/ordered-object-literal": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.5.tgz", + "integrity": "sha512-COTiuCU5bgMUtbIFBuyyh2/yVVzlr5Om0v5utQDgBCuQUOPgU1DwoffkTfg4UBQOvByi5foF4w4T+H9CoRe5wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@stoplight/path": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz", + "integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@stoplight/spectral-core": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.18.3.tgz", + "integrity": "sha512-YY8x7X2SWJIhGTLPol+eFiQpWPz0D0mJdkK2i4A0QJG68KkNhypP6+JBC7/Kz3XWjqr0L/RqAd+N5cQLPOKZGQ==", + "dev": true, + "dependencies": { + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "~3.21.0", + "@stoplight/path": "1.3.2", + "@stoplight/spectral-parsers": "^1.0.0", + "@stoplight/spectral-ref-resolver": "^1.0.0", + "@stoplight/spectral-runtime": "^1.0.0", + "@stoplight/types": "~13.6.0", + "@types/es-aggregate-error": "^1.0.2", + "@types/json-schema": "^7.0.11", + "ajv": "^8.6.0", + "ajv-errors": "~3.0.0", + "ajv-formats": "~2.1.0", + "es-aggregate-error": "^1.0.7", + "jsonpath-plus": "7.1.0", + "lodash": "~4.17.21", + "lodash.topath": "^4.5.2", + "minimatch": "3.1.2", + "nimma": "0.2.2", + "pony-cause": "^1.0.0", + "simple-eval": "1.0.0", + "tslib": "^2.3.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/@stoplight/better-ajv-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", + "integrity": "sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==", + "dev": true, + "dependencies": { + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/@stoplight/types": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.6.0.tgz", + "integrity": "sha512-dzyuzvUjv3m1wmhPfq82lCVYGcXG0xUYgqnWfCq3PCVR4BKFhjdkHrnJ+jIDoMKvXb05AZP/ObQF6+NpDo29IQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/ajv-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", + "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, + "peerDependencies": { + "ajv": "^8.0.1" + } + }, + "node_modules/@stoplight/spectral-core/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@stoplight/spectral-formats": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.6.0.tgz", + "integrity": "sha512-X27qhUfNluiduH0u/QwJqhOd8Wk5YKdxVmKM03Aijlx0AH1H5mYt3l9r7t2L4iyJrsBaFPnMGt7UYJDGxszbNA==", + "dev": true, + "dependencies": { + "@stoplight/json": "^3.17.0", + "@stoplight/spectral-core": "^1.8.0", + "@types/json-schema": "^7.0.7", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-functions": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.2.tgz", + "integrity": "sha512-f+61/FtIkQeIo+a269CeaeqjpyRsgDyIk6DGr7iS4hyuk1PPk7Uf6MNRDs9FEIBh7CpdEJ+HSHbMLwgpymWTIw==", + "dev": true, + "dependencies": { + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "^3.17.1", + "@stoplight/spectral-core": "^1.7.0", + "@stoplight/spectral-formats": "^1.0.0", + "@stoplight/spectral-runtime": "^1.1.0", + "ajv": "^8.6.3", + "ajv-draft-04": "~1.0.0", + "ajv-errors": "~3.0.0", + "ajv-formats": "~2.1.0", + "lodash": "~4.17.21", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-functions/node_modules/@stoplight/better-ajv-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", + "integrity": "sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==", + "dev": true, + "dependencies": { + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/@stoplight/spectral-functions/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@stoplight/spectral-functions/node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@stoplight/spectral-functions/node_modules/ajv-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", + "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, + "peerDependencies": { + "ajv": "^8.0.1" + } + }, + "node_modules/@stoplight/spectral-functions/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@stoplight/spectral-parsers": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.3.tgz", + "integrity": "sha512-J0KW5Rh5cHWnJQ3yN+cr/ijNFVirPSR0pkQbdrNX30VboEl083UEDrQ3yov9kjLVIWEk9t9kKE7Eo3QT/k4JLA==", + "dev": true, + "dependencies": { + "@stoplight/json": "~3.21.0", + "@stoplight/types": "^13.6.0", + "@stoplight/yaml": "~4.2.3", + "tslib": "^2.3.1" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/spectral-ref-resolver": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.4.tgz", + "integrity": "sha512-5baQIYL0NJTSVy8v6RxOR4U51xOUYM8wJri1YvlAT6bPN8m0EIxMwfVYi0xUZEMVeHcWx869nIkoqyWmOutF2A==", + "dev": true, + "dependencies": { + "@stoplight/json-ref-readers": "1.2.2", + "@stoplight/json-ref-resolver": "~3.1.6", + "@stoplight/spectral-runtime": "^1.1.2", + "dependency-graph": "0.11.0", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-rulesets": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.18.1.tgz", + "integrity": "sha512-buLzYi4rHjZOG2d5LC/s3YpySrCGrwR4irKDyrxLlbbqmB8BDOsrdO+7G9UGvRCJwAy/xs1VWcjokzGnG68K+Q==", + "dev": true, + "dependencies": { + "@asyncapi/specs": "^4.1.0", + "@stoplight/better-ajv-errors": "1.0.3", + "@stoplight/json": "^3.17.0", + "@stoplight/spectral-core": "^1.8.1", + "@stoplight/spectral-formats": "^1.5.0", + "@stoplight/spectral-functions": "^1.5.1", + "@stoplight/spectral-runtime": "^1.1.1", + "@stoplight/types": "^13.6.0", + "@types/json-schema": "^7.0.7", + "ajv": "^8.8.2", + "ajv-formats": "~2.1.0", + "json-schema-traverse": "^1.0.0", + "lodash": "~4.17.21", + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-rulesets/node_modules/@stoplight/better-ajv-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz", + "integrity": "sha512-0p9uXkuB22qGdNfy3VeEhxkU5uwvp/KrBTAbrLBURv6ilxIVwanKwjMc41lQfIVgPGcOkmLbTolfFrSsueu7zA==", + "dev": true, + "dependencies": { + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": "^12.20 || >= 14.13" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/@stoplight/spectral-rulesets/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@stoplight/spectral-rulesets/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@stoplight/spectral-runtime": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.2.tgz", + "integrity": "sha512-fr5zRceXI+hrl82yAVoME+4GvJie8v3wmOe9tU+ZLRRNonizthy8qDi0Z/z4olE+vGreSDcuDOZ7JjRxFW5kTw==", + "dev": true, + "dependencies": { + "@stoplight/json": "^3.17.0", + "@stoplight/path": "^1.3.2", + "@stoplight/types": "^12.3.0", + "abort-controller": "^3.0.0", + "lodash": "^4.17.21", + "node-fetch": "^2.6.7", + "tslib": "^2.3.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stoplight/spectral-runtime/node_modules/@stoplight/types": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz", + "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@stoplight/types": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-13.20.0.tgz", + "integrity": "sha512-2FNTv05If7ib79VPDA/r9eUet76jewXFH2y2K5vuge6SXbRHtWBhcaRmu+6QpF4/WRNoJj5XYRSwLGXDxysBGA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "utility-types": "^3.10.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + } + }, + "node_modules/@stoplight/yaml": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-4.2.3.tgz", + "integrity": "sha512-Mx01wjRAR9C7yLMUyYFTfbUf5DimEpHMkRDQ1PKLe9dfNILbgdxyrncsOXM3vCpsQ1Hfj4bPiGl+u4u6e9Akqw==", + "dev": true, + "dependencies": { + "@stoplight/ordered-object-literal": "^1.0.1", + "@stoplight/types": "^13.0.0", + "@stoplight/yaml-ast-parser": "0.0.48", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=10.8" + } + }, + "node_modules/@stoplight/yaml-ast-parser": { + "version": "0.0.48", + "resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.48.tgz", + "integrity": "sha512-sV+51I7WYnLJnKPn2EMWgS4EUfoP4iWEbrWwbXsj0MZCB/xOK8j6+C9fntIdOM50kpx45ZLC3s6kwKivWuqvyg==", + "dev": true + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -3447,6 +4588,15 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/es-aggregate-error": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.6.tgz", + "integrity": "sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -3499,8 +4649,7 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/json5": { "version": "0.0.29", @@ -3564,6 +4713,12 @@ "dev": true, "peer": true }, + "node_modules/@types/urijs": { + "version": "1.19.25", + "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.25.tgz", + "integrity": "sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.10", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", @@ -3837,7 +4992,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3926,6 +5080,54 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -3990,7 +5192,6 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, - "peer": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4052,7 +5253,6 @@ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "is-array-buffer": "^3.0.1" @@ -4092,7 +5292,6 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -4121,7 +5320,6 @@ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "call-bind": "^1.0.2", @@ -4147,6 +5345,15 @@ "node": ">=0.10.0" } }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "dev": true, + "bin": { + "astring": "bin/astring" + } + }, "node_modules/async": { "version": "3.2.5", "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", @@ -4164,7 +5371,6 @@ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -4381,7 +5587,6 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -4531,6 +5736,15 @@ "semver": "^7.0.0" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/cacache": { "version": "17.1.4", "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.4.tgz", @@ -4614,7 +5828,6 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, - "peer": true, "dependencies": { "function-bind": "^1.1.2", "get-intrinsic": "^1.2.1", @@ -4624,6 +5837,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "node_modules/callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", @@ -4801,7 +6020,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4834,7 +6052,6 @@ "url": "https://paulmillr.com/funding/" } ], - "peer": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4856,7 +6073,6 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "peer": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -5180,6 +6396,12 @@ "dot-prop": "^5.1.0" } }, + "node_modules/compare-versions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6202,7 +7424,6 @@ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.2.1", "gopd": "^1.0.1", @@ -6217,7 +7438,6 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "peer": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -6244,6 +7464,15 @@ "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", "dev": true }, + "node_modules/dependency-graph": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", @@ -6548,6 +7777,19 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/env-ci": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-9.1.1.tgz", @@ -6707,7 +7949,6 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, - "peer": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", @@ -6756,12 +7997,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-aggregate-error": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/es-aggregate-error/-/es-aggregate-error-1.0.12.tgz", + "integrity": "sha512-j0PupcmELoVbYS2NNrsn5zcLLEsryQwP02x8fRawh7c2eEaPHwJFAxltZsqV7HJjsF57+SMpYyVRWgbVLfOagg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "function-bind": "^1.1.2", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.1", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.2.2", "has-tostringtag": "^1.0.0", @@ -6786,7 +8057,6 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "peer": true, "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -6799,6 +8069,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, "node_modules/esbuild": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", @@ -7277,7 +8553,6 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -7366,8 +8641,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/fast-glob": { "version": "3.3.2", @@ -7411,6 +8685,18 @@ "dev": true, "peer": true }, + "node_modules/fast-memoize": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz", + "integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==", + "dev": true + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -7488,7 +8774,6 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -7561,7 +8846,6 @@ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "peer": true, "dependencies": { "is-callable": "^1.1.3" } @@ -7695,7 +8979,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -7714,7 +8997,6 @@ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -7733,7 +9015,6 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7822,7 +9103,6 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, - "peer": true, "dependencies": { "function-bind": "^1.1.2", "has-proto": "^1.0.1", @@ -8016,7 +9296,6 @@ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.1" @@ -8241,7 +9520,6 @@ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, - "peer": true, "dependencies": { "define-properties": "^1.1.3" }, @@ -8257,7 +9535,6 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "peer": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -8278,7 +9555,6 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -8343,7 +9619,6 @@ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -8362,7 +9637,6 @@ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.2.2" }, @@ -8375,7 +9649,6 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -8388,7 +9661,6 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -8401,7 +9673,6 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, - "peer": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -8578,6 +9849,12 @@ "node": ">= 6" } }, + "node_modules/http2-client": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", + "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", + "dev": true + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -8702,6 +9979,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -8804,7 +10091,6 @@ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dev": true, - "peer": true, "dependencies": { "get-intrinsic": "^1.2.2", "hasown": "^2.0.0", @@ -8851,7 +10137,6 @@ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.0", @@ -8872,7 +10157,6 @@ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "peer": true, "dependencies": { "has-bigints": "^1.0.1" }, @@ -8885,7 +10169,6 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "peer": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -8898,7 +10181,6 @@ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -8953,7 +10235,6 @@ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -8978,7 +10259,6 @@ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -9049,7 +10329,6 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" }, @@ -9071,7 +10350,6 @@ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -9115,7 +10393,6 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" @@ -9132,7 +10409,6 @@ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -9156,7 +10432,6 @@ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "peer": true, "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -9172,7 +10447,6 @@ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "peer": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -9200,7 +10474,6 @@ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dev": true, - "peer": true, "dependencies": { "which-typed-array": "^1.1.11" }, @@ -9234,7 +10507,6 @@ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2" }, @@ -9246,8 +10518,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -9993,6 +11264,15 @@ "node": ">=12.0.0" } }, + "node_modules/jsep": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz", + "integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==", + "dev": true, + "engines": { + "node": ">= 10.16.0" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -10077,6 +11357,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz", + "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -10098,6 +11384,24 @@ "node >= 0.2.0" ] }, + "node_modules/jsonpath-plus": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.1.0.tgz", + "integrity": "sha512-gTaNRsPWO/K2KY6MrqaUFClF9kmuM6MFH5Dhg1VYDODgFbByw1yb7xu3hrViE/sz+dGOeMWgCzwUwQtAnCTE9g==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -10298,7 +11602,6 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -10569,7 +11872,6 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -10644,6 +11946,18 @@ "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg==", + "dev": true + }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -10676,17 +11990,47 @@ "dev": true, "peer": true }, + "node_modules/lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", + "dev": true + }, + "node_modules/lodash.omitby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.omitby/-/lodash.omitby-4.6.0.tgz", + "integrity": "sha512-5OrRcIVR75M288p4nbI2WLAf3ndw2GD9fyNv3Bc15+WCxJDdZ4lYndSxGd7hnG6PVjiJTeJE2dHEGhIuKGicIQ==", + "dev": true + }, "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" }, + "node_modules/lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha512-1/W4dM+35DwvE/iEd1M9ekewOSTlpFekhw9mhAtrwjVqUr83/ilQiyAvmg4tVX7Unkcfl1KC+i9WdaT4B6aQcg==", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true + }, "node_modules/lodash.uniqby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", "dev": true }, + "node_modules/lodash.uniqwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniqwith/-/lodash.uniqwith-4.5.0.tgz", + "integrity": "sha512-7lYL8bLopMoy4CTICbxygAUq6CdRJ36vFc80DucPueUee+d5NBRxz3FdT9Pes/HEx5mPoT9jwnsEJWz1N7uq7Q==", + "dev": true + }, "node_modules/log-symbols": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", @@ -10790,6 +12134,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/loglevel": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", + "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "dev": true + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -11750,6 +13113,35 @@ "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", "dev": true }, + "node_modules/nimma": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/nimma/-/nimma-0.2.2.tgz", + "integrity": "sha512-V52MLl7BU+tH2Np9tDrIXK8bql3MVUadnMIl/0/oZSGC9keuro0O9UUv9QKp0aMvtN8HRew4G7byY7H4eWsxaQ==", + "dev": true, + "dependencies": { + "@jsep-plugin/regex": "^1.0.1", + "@jsep-plugin/ternary": "^1.0.2", + "astring": "^1.8.1", + "jsep": "^1.2.0" + }, + "engines": { + "node": "^12.20 || >=14.13" + }, + "optionalDependencies": { + "jsonpath-plus": "^6.0.1", + "lodash.topath": "^4.5.2" + } + }, + "node_modules/nimma/node_modules/jsonpath-plus": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-6.0.1.tgz", + "integrity": "sha512-EvGovdvau6FyLexFH2OeXfIITlgIbgZoAZe3usiySeaIDm5QS+A10DKNpaPBBqqRSZr2HN6HVNXxtwUAr2apEw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/node-emoji": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", @@ -11759,6 +13151,38 @@ "lodash": "^4.17.21" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-h2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", + "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", + "dev": true, + "dependencies": { + "http2-client": "^1.2.5" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/node-gyp": { "version": "9.4.1", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", @@ -11912,6 +13336,15 @@ "dev": true, "peer": true }, + "node_modules/node-readfiles": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", + "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", + "dev": true, + "dependencies": { + "es6-promise": "^3.2.1" + } + }, "node_modules/node-releases": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", @@ -11954,7 +13387,6 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -15309,12 +16741,108 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/oas-kit-common": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", + "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", + "dev": true, + "dependencies": { + "fast-safe-stringify": "^2.0.7" + } + }, + "node_modules/oas-linter": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", + "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", + "dev": true, + "dependencies": { + "@exodus/schemasafe": "^1.0.0-rc.2", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-linter/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-resolver": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", + "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", + "dev": true, + "dependencies": { + "node-fetch-h2": "^2.3.0", + "oas-kit-common": "^1.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "resolve": "resolve.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-resolver/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/oas-schema-walker": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", + "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", + "dev": true, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-validator": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", + "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", + "dev": true, + "dependencies": { + "call-me-maybe": "^1.0.1", + "oas-kit-common": "^1.0.8", + "oas-linter": "^3.2.2", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "reftools": "^1.1.9", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-validator/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -15324,7 +16852,6 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, - "peer": true, "engines": { "node": ">= 0.4" } @@ -15334,7 +16861,6 @@ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -15390,6 +16916,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "dev": true, + "peer": true + }, + "node_modules/openapi3-ts": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-4.2.1.tgz", + "integrity": "sha512-KL1mKwkZii5ce+tb24KCUmQHyWB/oanG5fzUY35UB+wenWJv4Kr/IWBntpn5R8ODiJcxx13ZDophcpHnLGeIOw==", + "dev": true, + "dependencies": { + "yaml": "^2.3.4" + } + }, + "node_modules/openapi3-ts/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/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -15408,6 +16959,59 @@ "node": ">= 0.8.0" } }, + "node_modules/orval": { + "version": "6.24.0", + "resolved": "https://registry.npmjs.org/orval/-/orval-6.24.0.tgz", + "integrity": "sha512-UH7fyEdFyy7twSH0WR02TL4q2obFjIxv3Q1lQu9jfj+XHm06Hn60nMjd0Qgb4G+RhqqSWQtjTEXAhlFm8fiZlQ==", + "dev": true, + "dependencies": { + "@apidevtools/swagger-parser": "^10.1.0", + "@orval/angular": "6.24.0", + "@orval/axios": "6.24.0", + "@orval/core": "6.24.0", + "@orval/mock": "6.24.0", + "@orval/query": "6.24.0", + "@orval/swr": "6.24.0", + "@orval/zod": "6.24.0", + "ajv": "^8.12.0", + "cac": "^6.7.14", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "enquirer": "^2.4.1", + "execa": "^5.1.1", + "find-up": "5.0.0", + "fs-extra": "^11.2.0", + "lodash.uniq": "^4.5.0", + "openapi3-ts": "4.2.1", + "string-argv": "^0.3.2", + "tsconfck": "^2.0.1" + }, + "bin": { + "orval": "dist/bin/orval.js" + } + }, + "node_modules/orval/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/orval/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/p-defer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.0.tgz", @@ -15530,7 +17134,6 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -15546,7 +17149,6 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -15985,6 +17587,15 @@ "node": ">=12" } }, + "node_modules/pony-cause": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-1.1.1.tgz", + "integrity": "sha512-PxkIc/2ZpLiEzQXu5YRDOUgBlfGYBY8156HY5ZcRAwwonMk5W/MrJP2LLkG/hF7GEQzaHo2aS7ho6ZLCOvf+6g==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/postcss-selector-parser": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", @@ -16397,7 +18008,6 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -16936,7 +18546,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "peer": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -16979,12 +18588,20 @@ "esprima": "~4.0.0" } }, + "node_modules/reftools": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", + "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", + "dev": true, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -17018,6 +18635,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -17218,7 +18844,6 @@ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -17257,7 +18882,6 @@ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", @@ -17267,6 +18891,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==", + "dev": true + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -17738,7 +19368,6 @@ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", "dev": true, - "peer": true, "dependencies": { "define-data-property": "^1.1.1", "get-intrinsic": "^1.2.1", @@ -17754,7 +19383,6 @@ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", "dev": true, - "peer": true, "dependencies": { "define-data-property": "^1.0.1", "functions-have-names": "^1.2.3", @@ -17803,6 +19431,60 @@ "node": ">=4" } }, + "node_modules/should": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", + "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", + "dev": true, + "dependencies": { + "should-equal": "^2.0.0", + "should-format": "^3.0.3", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" + } + }, + "node_modules/should-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", + "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "dev": true, + "dependencies": { + "should-type": "^1.4.0" + } + }, + "node_modules/should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", + "dev": true, + "dependencies": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" + } + }, + "node_modules/should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", + "dev": true + }, + "node_modules/should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, + "dependencies": { + "should-type": "^1.3.0", + "should-util": "^1.0.0" + } + }, + "node_modules/should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", + "dev": true + }, "node_modules/shx": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", @@ -17825,7 +19507,6 @@ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -18026,6 +19707,18 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/simple-eval": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-eval/-/simple-eval-1.0.0.tgz", + "integrity": "sha512-kpKJR+bqTscgC0xuAl2xHN6bB12lHjC2DCUfqjAx19bQyO3R2EVLOurm3H9AUltv/uFVcSCVNc6faegR+8NYLw==", + "dev": true, + "dependencies": { + "jsep": "^1.1.2" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -18038,7 +19731,6 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "peer": true, "engines": { "node": ">=8" } @@ -18218,8 +19910,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "peer": true + "dev": true }, "node_modules/ssri": { "version": "10.0.5", @@ -18572,7 +20263,6 @@ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "peer": true, "engines": { "node": ">=0.6.19" } @@ -18670,7 +20360,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -18688,7 +20377,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -18703,7 +20391,6 @@ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", @@ -18827,6 +20514,42 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger2openapi": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", + "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", + "dev": true, + "dependencies": { + "call-me-maybe": "^1.0.1", + "node-fetch": "^2.6.1", + "node-fetch-h2": "^2.3.0", + "node-readfiles": "^0.2.0", + "oas-kit-common": "^1.0.8", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "oas-validator": "^5.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "boast": "boast.js", + "oas-validate": "oas-validate.js", + "swagger2openapi": "swagger2openapi.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/swagger2openapi/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/tar": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", @@ -19049,6 +20772,12 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "node_modules/traverse": { "version": "0.6.7", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", @@ -19319,6 +21048,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/tsconfck": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-2.1.2.tgz", + "integrity": "sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==", + "dev": true, + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^14.13.1 || ^16 || >=18" + }, + "peerDependencies": { + "typescript": "^4.3.5 || ^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/tsconfig": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", @@ -19381,8 +21130,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/tsx": { "version": "3.14.0", @@ -19555,7 +21303,6 @@ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "get-intrinsic": "^1.2.1", @@ -19570,7 +21317,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -19589,7 +21335,6 @@ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", "dev": true, - "peer": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", @@ -19609,7 +21354,6 @@ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "for-each": "^0.3.3", @@ -19667,7 +21411,6 @@ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "peer": true, "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", @@ -19786,11 +21529,16 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "peer": true, "dependencies": { "punycode": "^2.1.0" } }, + "node_modules/urijs": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", + "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==", + "dev": true + }, "node_modules/url-join": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", @@ -19814,6 +21562,15 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -19858,6 +21615,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/walk-up-path": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", @@ -19874,6 +21640,22 @@ "makeerror": "1.0.12" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -19894,7 +21676,6 @@ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "peer": true, "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -19911,7 +21692,6 @@ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dev": true, - "peer": true, "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.4", @@ -20299,7 +22079,6 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "peer": true, "engines": { "node": ">=10" }, diff --git a/orval.config.ts b/orval.config.ts new file mode 100644 index 0000000..4944826 --- /dev/null +++ b/orval.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from "orval"; + +export default defineConfig({ + s5: { + input: "./swagger.yaml", + output: { + mode: "split", + workspace: "./src/generated", + target: "openapi.ts", + override: { + mutator: { + path: "../axios.ts", + name: "customInstance", + }, + }, + }, + }, +}); diff --git a/package.json b/package.json index 684344c..af594fd 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "devDependencies": { "@lumeweb/node-library-preset": "^0.2.7", "@types/ws": "^8.5.10", + "orval": "^6.24.0", "presetter": "*" }, "readme": "ERROR: No README data found!", diff --git a/src/axios.ts b/src/axios.ts new file mode 100644 index 0000000..14defd5 --- /dev/null +++ b/src/axios.ts @@ -0,0 +1,31 @@ +import Axios, { AxiosRequestConfig } from "axios"; + +export const customInstance = ( + config: AxiosRequestConfig, + options?: AxiosRequestConfig, +): Promise => { + const source = Axios.CancelToken.source(); + + /* + Hack to ensure that the data is passed to the request as an option. + */ + if (options?.data) { + config = config || {}; + config.data = options.data; + delete config.data; + } + + const instance = Axios.create({ baseURL: options?.baseURL }); + const promise = instance({ + ...config, + ...options, + cancelToken: source.token, + }).then(({ data }) => data); + + // @ts-ignore + promise.cancel = () => { + source.cancel("Query was cancelled"); + }; + + return promise; +}; diff --git a/src/client.ts b/src/client.ts index a46b6be..d9b8385 100644 --- a/src/client.ts +++ b/src/client.ts @@ -23,294 +23,74 @@ import { getMetadata, } from "./methods/download.js"; -import { defaultPortalUrl, ensureUrl } from "./utils/url.js"; +import { ensureUrl } from "./utils/url.js"; -import { - buildRequestHeaders, - buildRequestUrl, - ExecuteRequestError, - Headers, -} from "./request.js"; import { createEntry, getEntry, publishEntry, subscribeToEntry, } from "./methods/registry.js"; - -/** - * Custom client options. - * - * @property [APIKey] - Authentication password to use for a single S5 node. - * @property [s5ApiKey] - Authentication API key to use for a S5 portal (sets the "S5-Api-Key" header). - * @property [customUserAgent] - Custom user agent header to set. - * @property [customCookie] - Custom cookie header to set. WARNING: the Cookie header cannot be set in browsers. This is meant for usage in server contexts. - * @property [onDownloadProgress] - Optional callback to track download progress. - * @property [onUploadProgress] - Optional callback to track upload progress. - * @property [loginFn] - A function that, if set, is called when a 401 is returned from the request before re-trying the request. - */ -export type CustomClientOptions = { - APIKey?: string; - s5ApiKey?: string; - customUserAgent?: string; - customCookie?: string; - onDownloadProgress?: (progress: number, event: ProgressEvent) => void; - onUploadProgress?: (progress: number, event: ProgressEvent) => void; - loginFn?: (config?: RequestConfig) => Promise; -}; - -/** - * Config options for a single request. - * - * @property endpointPath - The endpoint to contact. - * @property [data] - The data for a POST request. - * @property [url] - The full url to contact. Will be computed from the portalUrl and endpointPath if not provided. - * @property [method] - The request method. - * @property [headers] - Any request headers to set. - * @property [subdomain] - An optional subdomain to add to the URL. - * @property [query] - Query parameters. - * @property [extraPath] - An additional path to append to the URL, e.g. a 46-character cid. - * @property [responseType] - The response type. - * @property [transformRequest] - A function that allows manually transforming the request. - * @property [transformResponse] - A function that allows manually transforming the response. - */ -export type RequestConfig = CustomClientOptions & { - endpointPath?: string; - data?: FormData | Record; - url?: string; - method?: Method; - headers?: Headers; - subdomain?: string; - query?: { [key: string]: string | undefined }; - extraPath?: string; - responseType?: ResponseType; - transformRequest?: (data: unknown) => string; - transformResponse?: (data: string) => Record; -}; +import { CustomClientOptions } from "#utils/options.js"; +import { throwValidationError } from "#utils/validation.js"; /** * The S5 Client which can be used to access S5-net. */ export class S5Client { - customOptions: CustomClientOptions; - private httpClient = axios.create(); - - // The initial portal URL, the value of `defaultPortalUrl()` if `new - // S5Client` is called without a given portal. This initial URL is used to - // resolve the final portal URL. - protected initialPortalUrl: string; - // The resolved API portal URL. The request won't be made until needed, or - // `initPortalUrl()` is called. The request is only made once, for all S5 - // Clients. - protected static resolvedPortalUrl?: Promise; - // The custom portal URL, if one was passed in to `new S5Client()`. - protected customPortalUrl?: string; - - // Set methods (defined in other files). - // Upload - uploadFile = uploadFile; - protected uploadSmallFile = uploadSmallFile; - protected uploadSmallFileRequest = uploadSmallFileRequest; - protected uploadLargeFile = uploadLargeFile; - protected uploadLargeFileRequest = uploadLargeFileRequest; uploadDirectory = uploadDirectory; - protected uploadDirectoryRequest = uploadDirectoryRequest; - protected uploadWebappRequest = uploadWebappRequest; + // Set methods (defined in other files). uploadWebapp = uploadWebapp; - // Download - downloadFile = downloadFile; downloadData = downloadData; getCidUrl = getCidUrl; getMetadata = getMetadata; - // Registry subscribeToEntry = subscribeToEntry; publishEntry = publishEntry; createEntry = createEntry; getEntry = getEntry; + // Download + protected uploadSmallFile = uploadSmallFile; + protected uploadSmallFileRequest = uploadSmallFileRequest; + protected uploadLargeFile = uploadLargeFile; + protected uploadLargeFileRequest = uploadLargeFileRequest; + protected uploadDirectoryRequest = uploadDirectoryRequest; + protected uploadWebappRequest = uploadWebappRequest; /** * The S5 Client which can be used to access S5-net. * * @class - * @param [initialPortalUrl] The initial portal URL to use to access S5, if specified. A request will be made to this URL to get the actual portal URL. To use the default portal while passing custom options, pass "". + * @param [portalUrl] The initial portal URL to use to access S5, if specified. A request will be made to this URL to get the actual portal URL. To use the default portal while passing custom options, pass "". * @param [customOptions] Configuration for the client. */ - constructor(initialPortalUrl = "", customOptions: CustomClientOptions = {}) { - if (initialPortalUrl === "") { - // Portal was not given, use the default portal URL. We'll still make a request for the resolved portal URL. - initialPortalUrl = defaultPortalUrl(); - } else { - // Portal was given, don't make the request for the resolved portal URL. - this.customPortalUrl = ensureUrl(initialPortalUrl); - } - this.initialPortalUrl = initialPortalUrl; - this.customOptions = customOptions; - - // Add a response interceptor so that we always return an error of type - // `ExecuteResponseError`. - this.httpClient.interceptors.response.use( - function (response) { - // Any status code that lie within the range of 2xx cause this function to trigger. - // Do something with response data. - return response; - }, - function (error) { - // Any status codes that falls outside the range of 2xx cause this function to trigger - // Do something with response error. - return Promise.reject(ExecuteRequestError.From(error as AxiosError)); - }, - ); - } - - /* istanbul ignore next */ - /** - * Make the request for the API portal URL. - * - * @returns - A promise that resolves when the request is complete. - */ - async initPortalUrl(): Promise { - if (this.customPortalUrl) { - // Tried to make a request for the API portal URL when a custom URL was already provided. - return; - } - - // Try to resolve the portal URL again if it's never been called or if it - // previously failed. - if (!S5Client.resolvedPortalUrl) { - S5Client.resolvedPortalUrl = this.resolvePortalUrl(); - } else { - try { - await S5Client.resolvedPortalUrl; - } catch (e) { - S5Client.resolvedPortalUrl = this.resolvePortalUrl(); - } - } - - // Wait on the promise and throw if it fails. - await S5Client.resolvedPortalUrl; - return; - } - - /* istanbul ignore next */ - /** - * Returns the API portal URL. Makes the request to get it if not done so already. - * - * @returns - the portal URL. - */ - async portalUrl(): Promise { - if (this.customPortalUrl) { - return this.customPortalUrl; - } - - // Make the request if needed and not done so. - await this.initPortalUrl(); - - return await S5Client.resolvedPortalUrl!; // eslint-disable-line - } - - /** - * Creates and executes a request. - * - * @param config - Configuration for the request. - * @returns - The response from axios. - * @throws - Will throw `ExecuteRequestError` if the request fails. This error contains the original Axios error. - */ - async executeRequest(config: RequestConfig): Promise { - const params = { - method: config.method, - data: config.data, - responseType: config.responseType, - transformRequest: config.transformRequest, - transformResponse: config.transformResponse, - - maxContentLength: Infinity, - maxBodyLength: Infinity, - // Allow cross-site cookies. - withCredentials: true, - } as AxiosRequestConfig; - - params["url"] = await buildRequestUrl(this, { - baseUrl: config.url, - endpointPath: config.endpointPath, - subdomain: config.subdomain, - extraPath: config.extraPath, - query: config.query, - }); - - // Build headers. - params["headers"] = buildRequestHeaders( - config.headers, - config.customUserAgent, - config.customCookie, - config.s5ApiKey, - ); - - params["auth"] = config.APIKey - ? { username: "", password: config.APIKey } - : undefined; - - if (config.onDownloadProgress) { - params.onDownloadProgress = function (event: AxiosProgressEvent) { - // Avoid NaN for 0-byte file. - /* istanbul ignore next: Empty file test doesn't work yet. */ - const progress = event.total ? event.loaded / event.total : 1; - // @ts-expect-error TS complains even though we've ensured this is defined. - config.onDownloadProgress(progress, event); - }; - } - if (config.onUploadProgress) { - params.onUploadProgress = function (event: AxiosProgressEvent) { - // Avoid NaN for 0-byte file. - /* istanbul ignore next: event.total is always 0 in Node. */ - const progress = event.total ? event.loaded / event.total : 1; - // @ts-expect-error TS complains even though we've ensured this is defined. - config.onUploadProgress(progress, event); - }; - } - - // NOTE: The error type is `ExecuteRequestError`. We set up a response - // interceptor above that does the conversion from `AxiosError`. - try { - return await this.httpClient.request(params); - } catch (e) { - // If `loginFn` is set and we get an Unauthorized response... - if (config.loginFn && (e as ExecuteRequestError).responseStatus === 401) { - // Try logging in again. - await config.loginFn(config); - // Unset the login function on the recursive call so that we don't try - // to login again, avoiding infinite loops. - return await this.executeRequest({ ...config, loginFn: undefined }); - } - - throw e; - } - } - - /** - * Make a request to resolve the provided `initialPortalUrl`. - * - * @returns - The portal URL. - */ - protected async resolvePortalUrl(): Promise { - const response = await this.executeRequest({ - ...this.customOptions, - method: "head", - url: this.initialPortalUrl, - }); - - if (!response.headers) { - throw new Error( - "Did not get 'headers' in response despite a successful request. Please try again and report this issue to the devs if it persists.", - ); - } - const portalUrl = response.headers["s5-portal-api"]; + constructor(portalUrl: string, customOptions: CustomClientOptions = {}) { if (!portalUrl) { - throw new Error("Could not get portal URL for the given portal"); + throwValidationError("portalUrl", portalUrl, "parameter", "string"); } - return portalUrl; + this._portalUrl = ensureUrl(portalUrl); + this._customOptions = customOptions; + } + + private _customOptions: CustomClientOptions; + + get customOptions(): CustomClientOptions { + return this._customOptions; + } + + private _portalUrl: string; + + get portalUrl(): string { + return this._portalUrl; + } + + public static create( + portalUrl: string, + customOptions: CustomClientOptions = {}, + ) { + return new S5Client(portalUrl, customOptions); } } diff --git a/src/methods/download.ts b/src/methods/download.ts index b69448a..a10c917 100644 --- a/src/methods/download.ts +++ b/src/methods/download.ts @@ -1,8 +1,10 @@ import { ResponseType } from "axios"; import { S5Client } from "../client.js"; -import { BaseCustomOptions, DEFAULT_BASE_OPTIONS } from "../utils/options.js"; +import { CustomClientOptions, optionsToConfig } from "../utils/options.js"; import path from "path"; +import { DEFAULT_UPLOAD_OPTIONS } from "#methods/upload.js"; +import { getS5DownloadCid, getS5MetadataCid } from "#generated/index.js"; /** * Custom download options. @@ -14,18 +16,13 @@ import path from "path"; * @property [responseType] - The response type. * @property [subdomain=false] - Whether to return the final cid in subdomain format. */ -export type CustomDownloadOptions = BaseCustomOptions & { - endpointDownload?: string; - download?: boolean; +export type CustomDownloadOptions = CustomClientOptions & { path?: string; range?: string; responseType?: ResponseType; - subdomain?: string; }; -export type CustomGetMetadataOptions = BaseCustomOptions & { - endpointGetMetadata?: string; -}; +export type CustomGetMetadataOptions = CustomClientOptions & {}; /** * The response for a get metadata request. @@ -34,24 +31,17 @@ export type CustomGetMetadataOptions = BaseCustomOptions & { * @property portalUrl - The URL of the portal. * @property cid - 46-character cid. */ -export type GetMetadataResponse = { +export type MetadataResult = { metadata: Record; }; export const DEFAULT_DOWNLOAD_OPTIONS = { - ...DEFAULT_BASE_OPTIONS, - endpointDownload: "/", - download: false, - path: undefined, range: undefined, responseType: undefined, subdomain: "", }; -const DEFAULT_GET_METADATA_OPTIONS = { - ...DEFAULT_BASE_OPTIONS, - endpointGetMetadata: "/s5/metadata", -}; +const DEFAULT_GET_METADATA_OPTIONS = {}; /** * Initiates a download of the content of the cid within the browser. @@ -68,14 +58,7 @@ export async function downloadFile( cid: string, customOptions?: CustomDownloadOptions, ): Promise { - const opts = { - ...DEFAULT_DOWNLOAD_OPTIONS, - ...this.customOptions, - ...customOptions, - download: true, - }; - - const url = await this.getCidUrl(cid, opts); + const url = await this.getCidUrl(cid, customOptions); // Download the url. window.location.assign(url); @@ -96,18 +79,9 @@ export async function downloadFile( export async function getCidUrl( this: S5Client, cid: string, - customOptions?: CustomDownloadOptions, + customOptions: CustomDownloadOptions = {}, ): Promise { - const opts = { - ...DEFAULT_DOWNLOAD_OPTIONS, - ...this.customOptions, - ...customOptions, - }; - console.log(opts); - - const portalUrl = await this.portalUrl(); - - return path.join(portalUrl, cid); + return path.join(this.portalUrl, cid); } /** @@ -123,35 +97,30 @@ export async function getCidUrl( export async function getMetadata( this: S5Client, cid: string, - customOptions?: CustomGetMetadataOptions, -): Promise { - const opts = { - ...DEFAULT_GET_METADATA_OPTIONS, - ...this.customOptions, - ...customOptions, - }; + customOptions: CustomGetMetadataOptions = {}, +): Promise { + const config = optionsToConfig( + this, + DEFAULT_GET_METADATA_OPTIONS, + customOptions, + ); - const response = await this.executeRequest({ - ...opts, - method: "get", - endpointPath: opts.endpointGetMetadata, - extraPath: cid, - }); + const response = await getS5MetadataCid(cid, config); - return { metadata: response.data }; + return { metadata: response }; } /** * Downloads in-memory data from a S5 cid. * @param this - S5Client - * @param cid - 46-character cid, or a valid cid URL. Can be followed by a path. Note that the cid will not be encoded, so if your path might contain special characters, consider using `customOptions.path`. + * @param cid - 46-character cid, or a valid cid URL. * @param [customOptions] - Additional settings that can optionally be set. * @returns - The data */ export async function downloadData( this: S5Client, cid: string, - customOptions?: CustomDownloadOptions, + customOptions: CustomDownloadOptions = {}, ): Promise { const opts = { ...DEFAULT_DOWNLOAD_OPTIONS, @@ -160,12 +129,12 @@ export async function downloadData( download: true, }; - const response = await this.executeRequest({ - ...opts, - method: "get", - extraPath: cid, - responseType: "arraybuffer", - }); + const config = optionsToConfig(this, DEFAULT_UPLOAD_OPTIONS, customOptions); - return response.data; + return await ( + await getS5DownloadCid(cid, { + ...config, + responseType: "arraybuffer", + }) + ).arrayBuffer(); } diff --git a/src/methods/registry.ts b/src/methods/registry.ts index 93ffaef..7b673ff 100644 --- a/src/methods/registry.ts +++ b/src/methods/registry.ts @@ -1,9 +1,7 @@ -import { DEFAULT_BASE_OPTIONS } from "../utils/options.js"; -import { CustomClientOptions, S5Client } from "../client.js"; +import { S5Client } from "../client.js"; import { ensureBytes, equalBytes } from "@noble/curves/abstract/utils"; import WS from "isomorphic-ws"; -import { buildRequestUrl, ExecuteRequestError } from "#request.js"; import { CID, createKeyPair, @@ -22,27 +20,29 @@ import { throwValidationError } from "../utils/validation.js"; import { base64url } from "multiformats/bases/base64"; import { concatBytes } from "@noble/hashes/utils"; import { CID_HASH_TYPES } from "@lumeweb/libs5/lib/constants.js"; +import { CustomClientOptions, optionsToConfig } from "#utils/options.js"; +import { buildRequestUrl } from "#request.js"; +import { + getS5Registry, + postS5Registry, + type RegistrySetRequest, +} from "#generated/index.js"; +import { DEFAULT_UPLOAD_OPTIONS } from "#methods/upload.js"; +import { AxiosError } from "axios"; -export const DEFAULT_GET_ENTRY_OPTIONS = { - ...DEFAULT_BASE_OPTIONS, - endpointGetEntry: "/s5/registry", -}; +export const DEFAULT_GET_ENTRY_OPTIONS = {}; export const DEFAULT_SET_ENTRY_OPTIONS = { - ...DEFAULT_BASE_OPTIONS, endpointSetEntry: "/s5/registry", - deleteForever: false, }; export const DEFAULT_SUBSCRIBE_ENTRY_OPTIONS = { - ...DEFAULT_BASE_OPTIONS, endpointSubscribeEntry: "/s5/registry/subscription", -}; +} as CustomRegistryOptions; export const DEFAULT_PUBLISH_ENTRY_OPTIONS = { - ...DEFAULT_BASE_OPTIONS, endpointPublishEntry: "/s5/registry", -}; +} as CustomRegistryOptions; export type BaseCustomOptions = CustomClientOptions; @@ -54,7 +54,7 @@ export type CustomRegistryOptions = BaseCustomOptions & { export async function subscribeToEntry( this: S5Client, publicKey: Uint8Array, - customOptions?: CustomRegistryOptions, + customOptions: CustomRegistryOptions = {}, ) { const opts = { ...DEFAULT_SUBSCRIBE_ENTRY_OPTIONS, @@ -66,7 +66,7 @@ export async function subscribeToEntry( publicKey = concatBytes(Uint8Array.from([CID_HASH_TYPES.ED25519]), publicKey); const url = await buildRequestUrl(this, { - baseUrl: await this.portalUrl(), + baseUrl: await this.portalUrl, endpointPath: opts.endpointSubscribeEntry, }); @@ -104,13 +104,13 @@ const base64urlDecode = (d: string) => base64url.decode(`u${d}`); export async function publishEntry( this: S5Client, signedEntry: SignedRegistryEntry, - customOptions?: CustomRegistryOptions, + customOptions: CustomRegistryOptions = {}, ) { - const opts = { - ...DEFAULT_PUBLISH_ENTRY_OPTIONS, - ...this.customOptions, - ...customOptions, - }; + const config = optionsToConfig( + this, + DEFAULT_PUBLISH_ENTRY_OPTIONS, + customOptions, + ); if (!verifyRegistryEntry(signedEntry)) { throwValidationError( @@ -121,17 +121,15 @@ export async function publishEntry( ); } - return await this.executeRequest({ - ...opts, - endpointPath: opts.endpointPublishEntry, - method: "post", - data: { + return postS5Registry( + { pk: base64urlEncode(signedEntry.pk), revision: signedEntry.revision, data: base64urlEncode(signedEntry.data), signature: base64urlEncode(signedEntry.signature), }, - }); + config, + ); } export async function createEntry( @@ -188,29 +186,27 @@ export async function createEntry( export async function getEntry( this: S5Client, publicKey: Uint8Array, - customOptions?: CustomRegistryOptions, + customOptions: CustomRegistryOptions = {}, ) { - const opts = { - ...DEFAULT_GET_ENTRY_OPTIONS, - ...this.customOptions, - ...customOptions, - }; + const config = optionsToConfig( + this, + DEFAULT_GET_ENTRY_OPTIONS, + customOptions, + ); try { - const ret = await this.executeRequest({ - ...opts, - endpointPath: opts.endpointGetEntry, - method: "get", - query: { + const ret = await getS5Registry( + { pk: base64urlEncode(publicKey), }, - }); + config, + ); const signedEntry = { - pk: base64urlDecode(ret.data.pk), - revision: ret.data.revision, - data: base64urlDecode(ret.data.data), - signature: base64urlDecode(ret.data.signature), + pk: base64urlDecode(ret.pk), + revision: ret.revision, + data: base64urlDecode(ret.data), + signature: base64urlDecode(ret.signature), } as SignedRegistryEntry; if (!verifyRegistryEntry(signedEntry)) { @@ -224,7 +220,7 @@ export async function getEntry( return signedEntry; } catch (e) { - if ((e as ExecuteRequestError).responseStatus === 404) { + if ((e as AxiosError).response?.status === 404) { return undefined; } diff --git a/src/methods/upload.ts b/src/methods/upload.ts index 0a45f95..97f1305 100644 --- a/src/methods/upload.ts +++ b/src/methods/upload.ts @@ -5,11 +5,18 @@ import { blake3 } from "@noble/hashes/blake3"; import { Buffer } from "buffer"; import { getFileMimeType } from "../utils/file.js"; -import { BaseCustomOptions, DEFAULT_BASE_OPTIONS } from "../utils/options.js"; import { S5Client } from "../client.js"; -import type { JsonData } from "../utils/types.js"; -import { buildRequestHeaders, buildRequestUrl } from "../request.js"; import { CID, CID_HASH_TYPES, CID_TYPES } from "@lumeweb/libs5"; +import { + type BasicUploadResponse, + postS5Upload, + postS5UploadDirectory, + PostS5UploadDirectoryParams, + PostS5UploadResult, +} from "#generated/index.js"; +import { BaseCustomOptions } from "#methods/registry.js"; +import { optionsToConfig } from "#utils/options.js"; +import { buildRequestUrl } from "#request.js"; /** * The tus chunk size is (4MiB - encryptionOverhead) * dataPieces, set as default. @@ -27,25 +34,18 @@ const DEFAULT_TUS_RETRY_DELAYS = [0, 5_000, 15_000, 60_000, 300_000, 600_000]; */ const PORTAL_FILE_FIELD_NAME = "file"; +const TUS_ENDPOINT = "/s5/upload/tus"; + /** * Custom upload options. * - * @property [endpointUpload] - The relative URL path of the portal endpoint to contact. - * @property [endpointDirectoryUpload] - The relative URL path of the portal endpoint to contact for Directorys. - * @property [endpointLargeUpload] - The relative URL path of the portal endpoint to contact for large uploads. - * @property [customFilename] - The custom filename to use when uploading files. * @property [largeFileSize=32943040] - The size at which files are considered "large" and will be uploaded using the tus resumable upload protocol. This is the size of one chunk by default (32 mib). Note that this does not affect the actual size of chunks used by the protocol. * @property [errorPages] - Defines a mapping of error codes and subfiles which are to be served in case we are serving the respective error code. All subfiles referred like this must be defined with absolute paths and must exist. * @property [retryDelays=[0, 5_000, 15_000, 60_000, 300_000, 600_000]] - An array or undefined, indicating how many milliseconds should pass before the next attempt to uploading will be started after the transfer has been interrupted. The array's length indicates the maximum number of attempts. * @property [tryFiles] - Allows us to set a list of potential subfiles to return in case the requested one does not exist or is a directory. Those subfiles might be listed with relative or absolute paths. If the path is absolute the file must exist. */ export type CustomUploadOptions = BaseCustomOptions & { - endpointUpload?: string; - endpointDirectoryUpload: string; - endpointLargeUpload?: string; - - customFilename?: string; - errorPages?: JsonData; + errorPages?: Record; tryFiles?: string[]; // Large files. @@ -53,39 +53,18 @@ export type CustomUploadOptions = BaseCustomOptions & { retryDelays?: number[]; }; -/** - * The response to an upload request. - * - * @property cid - 46-character cid. - */ -export type UploadRequestResponse = { - cid: CID; -}; - -/** - * The response to an upload request. - * - * @property cid - 46-character cid. - */ -export type UploadTusRequestResponse = { - data: { cid: CID }; -}; - export const DEFAULT_UPLOAD_OPTIONS = { - ...DEFAULT_BASE_OPTIONS, - - endpointUpload: "/s5/upload", - endpointDirectoryUpload: "/s5/upload/directory", - endpointLargeUpload: "/s5/upload/tus", - - customFilename: "", errorPages: { 404: "/404.html" }, tryFiles: ["index.html"], // Large files. largeFileSize: TUS_CHUNK_SIZE, retryDelays: DEFAULT_TUS_RETRY_DELAYS, -}; +} as CustomUploadOptions; + +export interface UploadResult { + cid: CID; +} /** * Uploads a file to S5-net. @@ -93,24 +72,21 @@ export const DEFAULT_UPLOAD_OPTIONS = { * @param this - S5Client * @param file - The file to upload. * @param [customOptions] - Additional settings that can optionally be set. - * @param [customOptions.endpointUpload="/s5/upload"] - The relative URL path of the portal endpoint to contact for small uploads. - * @param [customOptions.endpointDirectoryUpload="/s5/upload/directory"] - The relative URL path of the portal endpoint to contact for Directory uploads. - * @param [customOptions.endpointLargeUpload="/s5/upload/tus"] - The relative URL path of the portal endpoint to contact for large uploads. * @returns - The returned cid. * @throws - Will throw if the request is successful but the upload response does not contain a complete response. */ export async function uploadFile( this: S5Client, file: File, - customOptions?: CustomUploadOptions, -): Promise { + customOptions: CustomUploadOptions = {}, +): Promise { const opts = { ...DEFAULT_UPLOAD_OPTIONS, ...this.customOptions, ...customOptions, - }; + } as CustomUploadOptions; - if (file.size < opts.largeFileSize) { + if (file.size < opts?.largeFileSize) { return this.uploadSmallFile(file, opts); } else { return this.uploadLargeFile(file, opts); @@ -123,18 +99,18 @@ export async function uploadFile( * @param this - S5Client * @param file - The file to upload. * @param [customOptions] - Additional settings that can optionally be set. - * @param [customOptions.endpointUpload="/s5/upload"] - The relative URL path of the portal endpoint to contact. - * @returns - The returned cid. + + * @returns UploadResult - The returned cid. * @throws - Will throw if the request is successful but the upload response does not contain a complete response. */ export async function uploadSmallFile( this: S5Client, file: File, customOptions: CustomUploadOptions, -): Promise { +): Promise { const response = await this.uploadSmallFileRequest(file, customOptions); - return { cid: CID.decode(response.data.cid) }; + return { cid: CID.decode(response.CID) }; } /** @@ -143,34 +119,24 @@ export async function uploadSmallFile( * @param this - S5Client * @param file - The file to upload. * @param [customOptions] - Additional settings that can optionally be set. - * @param [customOptions.endpointPath="/s5/upload"] - The relative URL path of the portal endpoint to contact. - * @returns - The upload response. + + * @returns PostS5UploadResult - The upload response. */ export async function uploadSmallFileRequest( this: S5Client, file: File, - customOptions?: CustomUploadOptions, -): Promise { - const opts = { - ...DEFAULT_UPLOAD_OPTIONS, - ...this.customOptions, - ...customOptions, - }; - const formData = new FormData(); + customOptions: CustomUploadOptions = {}, +): Promise { + const config = optionsToConfig(this, DEFAULT_UPLOAD_OPTIONS, customOptions); file = ensureFileObjectConsistency(file); - if (opts.customFilename) { - formData.append(PORTAL_FILE_FIELD_NAME, file, opts.customFilename); - } else { - formData.append(PORTAL_FILE_FIELD_NAME, file); - } - return await this.executeRequest({ - ...opts, - endpointPath: opts.endpointUpload, - method: "post", - data: formData, - }); + return postS5Upload( + { + file: file, + }, + config, + ); } /* istanbul ignore next */ @@ -187,11 +153,9 @@ export async function uploadSmallFileRequest( export async function uploadLargeFile( this: S5Client, file: File, - customOptions?: CustomUploadOptions, -): Promise { - const response = await this.uploadLargeFileRequest(file, customOptions); - - return response.data; + customOptions: CustomUploadOptions = {}, +): Promise { + return await this.uploadLargeFileRequest(file, customOptions); } /* istanbul ignore next */ @@ -201,44 +165,32 @@ export async function uploadLargeFile( * @param this - S5Client * @param file - The file to upload. * @param [customOptions] - Additional settings that can optionally be set. - * @param [customOptions.endpointLargeUpload="/s5/upload/tus"] - The relative URL path of the portal endpoint to contact. * @returns - The upload response. */ export async function uploadLargeFileRequest( this: S5Client, file: File, - customOptions?: CustomUploadOptions, -): Promise { - const opts = { - ...DEFAULT_UPLOAD_OPTIONS, - ...this.customOptions, - ...customOptions, - }; + customOptions: CustomUploadOptions = {}, +): Promise { + const config = optionsToConfig(this, DEFAULT_UPLOAD_OPTIONS, customOptions); // Validation. const url = await buildRequestUrl(this, { - endpointPath: opts.endpointLargeUpload, + endpointPath: TUS_ENDPOINT, }); - const headers = buildRequestHeaders( - undefined, - opts.customUserAgent, - opts.customCookie, - opts.s5ApiKey, - ); file = ensureFileObjectConsistency(file); - let filename = file.name; - if (opts.customFilename) { - filename = opts.customFilename; - } const onProgress = - opts.onUploadProgress && + config.onUploadProgress && function (bytesSent: number, bytesTotal: number) { const progress = bytesSent / bytesTotal; // @ts-expect-error TS complains. - opts.onUploadProgress(progress, { loaded: bytesSent, total: bytesTotal }); + config.onUploadProgress(progress, { + loaded: bytesSent, + total: bytesTotal, + }); }; const hasher = blake3.create({}); @@ -282,19 +234,21 @@ export async function uploadLargeFileRequest( } return new Promise((resolve, reject) => { + const filename = hash + .toString("base64") + .replace(/\+/g, "-") + .replace(/\//g, "_") + .replace("=", ""); + const tusOpts = { endpoint: url, // retryDelays: opts.retryDelays, metadata: { - hash: hash - .toString("base64") - .replace(/\+/g, "-") - .replace(/\//g, "_") - .replace("=", ""), - filename, + hash: filename, + filename: filename, filetype: file.type, }, - headers, + config: config.headers, onProgress, onBeforeRequest: function (req: HttpRequest) { const xhr = req.getUnderlyingObject(); @@ -311,7 +265,6 @@ export async function uploadLargeFileRequest( reject(new Error("'upload.url' was not set")); return; } - const resCid = "u" + cid @@ -319,8 +272,7 @@ export async function uploadLargeFileRequest( .replace(/\+/g, "-") .replace(/\//g, "_") .replace("=", ""); - const resolveData = { data: { cid: CID.decode(resCid) } }; - resolve(resolveData); + resolve({ cid: CID.decode(resCid) }); }, }; @@ -344,15 +296,15 @@ export async function uploadDirectory( this: S5Client, directory: Record, filename: string, - customOptions?: CustomUploadOptions, -): Promise { + customOptions: CustomUploadOptions = {}, +): Promise { const response = await this.uploadDirectoryRequest( directory, filename, customOptions, ); - return { cid: CID.decode(response.data.cid) }; + return { cid: CID.decode(response.CID) }; } /** @@ -362,7 +314,6 @@ export async function uploadDirectory( * @param directory - File objects to upload, indexed by their path strings. * @param filename - The name of the directory. * @param [customOptions] - Additional settings that can optionally be set. - * @param [customOptions.endpointPath="/s5/upload/directory"] - The relative URL path of the portal endpoint to contact. * @returns - The upload response. * @throws - Will throw if the input filename is not a string. */ @@ -370,45 +321,44 @@ export async function uploadDirectoryRequest( this: S5Client, directory: Record, filename: string, - customOptions?: CustomUploadOptions, -): Promise { - const opts = { - ...DEFAULT_UPLOAD_OPTIONS, - ...this.customOptions, - ...customOptions, - }; + customOptions: CustomUploadOptions = {}, +): Promise { + const config = optionsToConfig(this, DEFAULT_UPLOAD_OPTIONS, customOptions); const formData = new FormData(); - Object.entries(directory).forEach(([path, file]) => { - file = ensureFileObjectConsistency(file as File); - formData.append(path, file as File, path); - }); - const query: { [key: string]: string | undefined } = { filename }; - if (opts.tryFiles) { - query.tryfiles = JSON.stringify(opts.tryFiles); - } - if (opts.errorPages) { - query.errorpages = JSON.stringify(opts.errorPages); + for (const entry in directory) { + const file = ensureFileObjectConsistency(directory[entry]); + formData.append(entry, file, entry); } - return await this.executeRequest({ - ...opts, - endpointPath: opts.endpointDirectoryUpload, - method: "post", - data: formData, - query, - }); + const params = {} as PostS5UploadDirectoryParams; + + if (customOptions.tryFiles) { + params.tryFiles = customOptions.tryFiles; + } + if (customOptions.errorPages) { + params.errorPages = customOptions.errorPages; + } + + params.name = filename; + + /* + Hack to pass the data right since OpenAPI doesn't support variable file inputs without knowing the names ahead of time. + */ + config.data = formData; + + return postS5UploadDirectory({}, params, config); } export async function uploadWebapp( this: S5Client, directory: Record, - customOptions?: CustomUploadOptions, -): Promise { + customOptions: CustomUploadOptions = {}, +): Promise { const response = await this.uploadWebappRequest(directory, customOptions); - return { cid: CID.decode(response.data.cid) }; + return { cid: CID.decode(response.CID) }; } /** @@ -423,40 +373,9 @@ export async function uploadWebapp( export async function uploadWebappRequest( this: S5Client, directory: Record, - customOptions?: CustomUploadOptions, -): Promise { - const opts = { - ...DEFAULT_UPLOAD_OPTIONS, - ...this.customOptions, - ...customOptions, - }; - - const formData = new FormData(); - Object.entries(directory).forEach(([path, file]) => { - file = ensureFileObjectConsistency(file as File); - formData.append(path, file as File, path); - }); - - const query: { [key: string]: string | undefined } = { name: "" }; - if (opts.tryFiles) { - query.tryfiles = JSON.stringify(opts.tryFiles); - } else { - query.tryfiles = JSON.stringify(["index.html"]); - } - - if (opts.errorPages) { - query.errorpages = JSON.stringify(opts.errorPages); - } else { - query.errorpages = JSON.stringify({ 404: "/404.html" }); - } - - return await this.executeRequest({ - ...opts, - endpointPath: opts.endpointDirectoryUpload, - method: "post", - data: formData, - query, - }); + customOptions: CustomUploadOptions = {}, +): Promise { + return this.uploadDirectoryRequest(directory, "webapp", customOptions); } /** diff --git a/src/request.ts b/src/request.ts index cccd790..a743ad6 100644 --- a/src/request.ts +++ b/src/request.ts @@ -10,35 +10,6 @@ import { export type Headers = { [key: string]: string }; -/** - * Helper function that builds the request headers. - * - * @param [baseHeaders] - Any base headers. - * @param [customUserAgent] - A custom user agent to set. - * @param [customCookie] - A custom cookie. - * @param [s5ApiKey] - Authentication key to use for a S5 portal. - * @returns - The built headers. - */ -export function buildRequestHeaders( - baseHeaders?: Headers, - customUserAgent?: string, - customCookie?: string, - s5ApiKey?: string, -): Headers { - const returnHeaders = { ...baseHeaders }; - // Set some headers from common options. - if (customUserAgent) { - returnHeaders["User-Agent"] = customUserAgent; - } - if (customCookie) { - returnHeaders["Cookie"] = customCookie; - } - if (s5ApiKey) { - returnHeaders["S5-Api-Key"] = s5ApiKey; - } - return returnHeaders; -} - /** * Helper function that builds the request URL. Ensures that the final URL * always has a protocol prefix for consistency. @@ -66,7 +37,7 @@ export async function buildRequestUrl( // Get the base URL, if not passed in. if (!parts.baseUrl) { - url = await client.portalUrl(); + url = await client.portalUrl; } else { url = parts.baseUrl; } @@ -89,139 +60,3 @@ export async function buildRequestUrl( return url; } - -/** - * The error type returned by the SDK whenever it makes a network request - * (internally, this happens in `executeRequest`). It implements, so is - * compatible with, `AxiosError`. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export class ExecuteRequestError - extends Error - implements AxiosError -{ - originalError: AxiosError; - responseStatus: number | null; - responseMessage: string | null; - - // Properties required by `AxiosError`. - - config: InternalAxiosRequestConfig; - code?: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - request?: any; - response?: AxiosResponse; - isAxiosError: boolean; - // eslint-disable-next-line @typescript-eslint/ban-types - toJSON: () => object; - - /** - * Creates an `ExecuteRequestError`. - * - * @param message - The error message. - * @param axiosError - The original Axios error. - * @param responseStatus - The response status, if found in the original error. - * @param responseMessage - The response message, if found in the original error. - */ - constructor( - message: string, - axiosError: AxiosError, - responseStatus: number | null, - responseMessage: string | null, - ) { - // Include this check since `ExecuteRequestError` implements `AxiosError`, - // but we only expect original errors from Axios here. Anything else - // indicates a likely developer/logic bug. - if (axiosError instanceof ExecuteRequestError) { - throw new Error( - "Could not instantiate an `ExecuteRequestError` from an `ExecuteRequestError`, an original error from axios was expected", - ); - } - - // Set `Error` fields. - super(message); - this.name = "ExecuteRequestError"; - - // Set `ExecuteRequestError` fields. - this.originalError = axiosError; - this.responseStatus = responseStatus; - this.responseMessage = responseMessage; - - // Set properties required by `AxiosError`. - // - // NOTE: `Object.assign` doesn't work because Typescript can't detect that - // required fields are set in this constructor. - if (!axiosError.config) { - throw new Error("axiosError.config is undefined"); - } - this.config = axiosError.config; - this.code = axiosError.code; - this.request = axiosError.request; - this.response = axiosError.response; - this.isAxiosError = axiosError.isAxiosError; - this.toJSON = axiosError.toJSON; - - // Required for `instanceof` to work. - Object.setPrototypeOf(this, ExecuteRequestError.prototype); - } - - /** - * Gets the full, descriptive error response returned from the portal. - * - * @param err - The Axios error. - * @returns - A new error if the error response is malformed, or the error message otherwise. - */ - static From( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - err: AxiosError, - ): ExecuteRequestError { - /* istanbul ignore next */ - if (!err.response) { - return new ExecuteRequestError( - `Error response did not contain expected field 'response'.`, - err, - null, - null, - ); - } - /* istanbul ignore next */ - if (!err.response.status) { - return new ExecuteRequestError( - `Error response did not contain expected field 'response.status'.`, - err, - null, - null, - ); - } - - const status = err.response.status; - - // If we don't get an error message, just return the status code. - /* istanbul ignore next */ - if (!err.response.data) { - return new ExecuteRequestError( - `Request failed with status code ${status}`, - err, - status, - null, - ); - } - /* istanbul ignore next */ - if (!err.response.data.message) { - return new ExecuteRequestError( - `Request failed with status code ${status}`, - err, - status, - null, - ); - } - - // Return the error message. Pass along the original Axios error. - return new ExecuteRequestError( - `Request failed with status code ${err.response.status}: ${err.response.data.message}`, - err, - status, - err.response.data.message, - ); - } -} diff --git a/src/utils/options.ts b/src/utils/options.ts index 3c8c613..19bba68 100644 --- a/src/utils/options.ts +++ b/src/utils/options.ts @@ -1,21 +1,80 @@ -import { CustomClientOptions } from "../client.js"; +import { AxiosProgressEvent, AxiosRequestConfig } from "axios"; +import { S5Client } from "../client.js"; -// TODO: Unnecessary, remove. /** - * Base custom options for methods hitting the API. + * Custom client options. + * + * @property [ApiKey] - Authentication password to use for a single S5 node/portal. + * @property [customUserAgent] - Custom user agent header to set. + * @property [customCookie] - Custom cookie header to set. WARNING: the Cookie header cannot be set in browsers. This is meant for usage in server contexts. + * @property [onDownloadProgress] - Optional callback to track download progress. + * @property [onUploadProgress] - Optional callback to track upload progress. */ -export type BaseCustomOptions = CustomClientOptions; -// TODO: Move to client.ts. -/** - * The default base custom options. - */ -export const DEFAULT_BASE_OPTIONS = { - APIKey: "", - s5ApiKey: "", - customUserAgent: "", - customCookie: "", - onDownloadProgress: undefined, - onUploadProgress: undefined, - loginFn: undefined, +export type CustomClientOptions = { + ApiKey?: string; + customUserAgent?: string; + customCookie?: string; + onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void; + onUploadProgress?: (progressEvent: AxiosProgressEvent) => void; }; + +export function optionsToConfig( + client: S5Client, + def: CustomClientOptions, + ...options: CustomClientOptions[] +): AxiosRequestConfig { + const config: AxiosRequestConfig = {}; + + config.baseURL = client.portalUrl; + + const extraOptions = options.reduce((acc, val) => { + return { + ...acc, + ...val, + }; + }, options); + + const finalOptions = { + ...def, + ...client.customOptions, + ...extraOptions, + }; + + if (finalOptions?.onDownloadProgress) { + config.onDownloadProgress = finalOptions?.onDownloadProgress; + } + + if (finalOptions?.onUploadProgress) { + config.onUploadProgress = finalOptions?.onUploadProgress; + } + + if (finalOptions?.customCookie) { + config.headers = { + Cookie: finalOptions?.customCookie, + }; + } + + if (finalOptions?.customUserAgent) { + config.headers = { + ...config.headers, + "User-Agent": finalOptions?.customUserAgent, + }; + } + + if (finalOptions?.ApiKey) { + config.headers = { + ...config.headers, + Authorization: `Bearer ${finalOptions?.ApiKey}`, + }; + + config.withCredentials = true; + + config.params = { + ...config.params, + auth_token: finalOptions?.ApiKey, + }; + } + + return config; +} diff --git a/src/utils/types.ts b/src/utils/types.ts deleted file mode 100644 index 0d06e50..0000000 --- a/src/utils/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type JsonData = Record; diff --git a/src/utils/url.ts b/src/utils/url.ts index 8799b32..197f94c 100644 --- a/src/utils/url.ts +++ b/src/utils/url.ts @@ -4,31 +4,8 @@ import parse from "url-parse"; import { trimSuffix } from "./string.js"; import { throwValidationError } from "./validation.js"; -export const DEFAULT_S5_PORTAL_URL = "https://localhost:5522"; - -/** - * @deprecated please use DEFAULT_S5_PORTAL_URL. - */ -export const defaultS5PortalUrl = DEFAULT_S5_PORTAL_URL; - export const URI_S5_PREFIX = "s5://"; -/** - * @deprecated please use URI_S5_PREFIX. - */ -export const uriS5Prefix = URI_S5_PREFIX; - -/** - * Returns the default portal URL. - * - * @returns - The portal URL. - */ -export function defaultPortalUrl(): string { - /* istanbul ignore next */ - if (typeof window === "undefined") return "/"; // default to path root on ssr - return window.location.origin; -} - /** * Adds a subdomain to the given URL. * diff --git a/swagger.yaml b/swagger.yaml new file mode 100644 index 0000000..790c63e --- /dev/null +++ b/swagger.yaml @@ -0,0 +1,1003 @@ +openapi: 3.0.0 +info: + title: S5 Storage API + version: "1.0" +paths: + # Account API + /s5/account/register: + get: + summary: Initiate account registration + tags: + - account + security: [] + parameters: + - name: pubKey + description: Public key of the account + in: query + required: true + schema: + type: string + responses: + '200': + description: Registration challenge + post: + summary: Complete account registration + tags: + - account + security: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccountRegisterRequest' + responses: + '201': + description: Account created + /s5/account/login: + get: + summary: Initiate account login + tags: + - account + security: [] + parameters: + - name: pubKey + description: Public key of the account + in: query + required: true + schema: + type: string + responses: + '200': + description: Login challenge + post: + summary: Complete account login + tags: + - account + security: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AccountLoginRequest' + responses: + '200': + description: Login successful + /s5/account: + get: + summary: Retrieve account information + tags: + - account + responses: + '200': + description: Account information + /s5/account/stats: + get: + summary: Retrieve account statistics + tags: + - account + responses: + '200': + description: Account statistics + content: + application/json: + schema: + $ref: "#/components/schemas/AccountStatsResponse" + /s5/account/pins.bin: + get: + summary: Retrieve account pins + tags: + - account + responses: + '200': + description: Account pins + + # Upload API + /s5/upload: + post: + summary: Upload a small file + tags: + - upload + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + file: + type: string + format: binary + application/octet-stream: + schema: + type: string + format: binary + responses: + '200': + description: File uploaded + content: + application/json: + schema: + $ref: '#/components/schemas/BasicUploadResponse' + '500': + description: Error uploading file + /s5/upload/directory: + post: + summary: Upload a directory + tags: + - upload + description: > + This endpoint accepts multiple files in a multipart/form-data request. + Each file can be uploaded under its own field name, which the server will process dynamically. + The endpoint also accepts additional query parameters such as `tryfiles` and `errorpages` to configure the upload behavior. + parameters: + - name: tryFiles + in: query + required: true + schema: + $ref: '#/components/schemas/UploadRequestTryFiles' + - name: errorPages + in: query + required: true + schema: + $ref: '#/components/schemas/UploadRequestErrorPages' + - name: name + in: query + required: true + schema: + type: string + requestBody: + content: + multipart/form-data: + schema: + type: object + additionalProperties: + type: string + format: binary + + responses: + '201': + description: Directory uploaded + content: + application/json: + schema: + $ref: '#/components/schemas/BasicUploadResponse' + + # Tus API + /s5/upload/tus: + post: + summary: TUS Upload + tags: + - upload + - tus + description: > + An empty POST request is used to create a new upload resource. The + Upload-Length header indicates the size of the entire upload in bytes. + If the Creation With Upload extension is available, the Client MAY include + parts of the upload in the initial Creation request + parameters: + - name: Content-Length + in: header + description: Must be 0 for creation extension. May be a positive number for + Creation With Upload extension. + schema: + type: integer + - name: Upload-Length + in: header + schema: + $ref: "#/components/schemas/Upload-Length" + - name: Tus-Resumable + in: header + schema: + $ref: "#/components/schemas/Tus-Resumable" + - name: Upload-Metadata + in: header + description: Added by the Creation extension. The Upload-Metadata request + and response header MUST consist of one or more comma-separated key-value + pairs. The key and value MUST be separated by a space. The key MUST NOT + contain spaces and commas and MUST NOT be empty. The key SHOULD be ASCII + encoded and the value MUST be Base64 encoded. All keys MUST be unique. The + value MAY be empty. In these cases, the space, which would normally separate + the key and the value, MAY be left out. Since metadata can contain arbitrary + binary values, Servers SHOULD carefully validate metadata values or sanitize + them before using them as header values to avoid header smuggling. + schema: + type: string + - name: Upload-Concat + in: header + description: Added by the Concatenation extension. The Upload-Concat request + and response header MUST be set in both partial and final upload creation + requests. It indicates whether the upload is either a partial or final upload. + If the upload is a partial one, the header value MUST be partial. In the + case of a final upload, its value MUST be final followed by a semicolon + and a space-separated list of partial upload URLs that will be concatenated. + The partial uploads URLs MAY be absolute or relative and MUST NOT contain + spaces as defined in RFC 3986. + schema: + type: string + - name: Upload-Defer-Length + in: header + description: Added by the Creation Defer Length extension. The Upload-Defer-Length + request and response header indicates that the size of the upload is not + known currently and will be transferred later. Its value MUST be 1. If the + length of an upload is not deferred, this header MUST be omitted. + schema: + type: integer + enum: + - 1 + - name: Upload-Offset + in: header + schema: + $ref: "#/components/schemas/Upload-Offset" + - name: Upload-Checksum + in: header + schema: + $ref: "#/components/schemas/Upload-Checksum" + requestBody: + description: (Possibly partial) content of the file. Required if Content-Length > 0. + required: false + content: + application/offset+octet-stream: + schema: + type: string + format: binary + responses: + 201: + description: Created + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Upload-Offset: + schema: + $ref: "#/components/schemas/Upload-Offset" + Upload-Expires: + description: Added by the Creation With Upload Extension in combination + with the expiration extension. The Upload-Expires response header + indicates the time after which the unfinished upload expires. A Server + MAY wish to remove incomplete uploads after a given period of time + to prevent abandoned uploads from taking up extra storage. The Client + SHOULD use this header to determine if an upload is still valid before + attempting to resume the upload. This header MUST be included in every + PATCH response if the upload is going to expire. If the expiration + is known at the creation, the Upload-Expires header MUST be included + in the response to the initial POST request. Its value MAY change + over time. If a Client does attempt to resume an upload which has + since been removed by the Server, the Server SHOULD respond with the + 404 Not Found or 410 Gone status. The latter one SHOULD be used if + the Server is keeping track of expired uploads. In both cases the + Client SHOULD start a new upload. The value of the Upload-Expires + header MUST be in RFC 7231 datetime format. + schema: + type: string + Location: + description: Url of the created resource. + schema: + type: string + 400: + description: Added by the Creation With Upload Extension in combination + with the checksum extension. The checksum algorithm is not supported by + the server + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 412: + description: Precondition Failed + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Tus-Version: + schema: + $ref: "#/components/schemas/Tus-Version" + 413: + description: If the length of the upload exceeds the maximum, which MAY + be specified using the Tus-Max-Size header, the Server MUST respond with + the 413 Request Entity Too Large status. + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 415: + description: Added by the Creation With Upload Extension. Content-Type was + not application/offset+octet-stream + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 460: + description: Added by the Creation With Upload Extension in combination + with the checksum extension. Checksums mismatch + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + options: + summary: Request to gather information about the Server's current configuration + description: An OPTIONS request MAY be used to gather information about the + Server's current configuration. A successful response indicated by the 204 + No Content or 200 OK status MUST contain the Tus-Version header. It MAY include + the Tus-Extension and Tus-Max-Size headers. + responses: + 200: + description: Success + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Tus-Checksum-Algorithm: + schema: + $ref: "#/components/schemas/Tus-Checksum-Algorithm" + Tus-Version: + schema: + $ref: "#/components/schemas/Tus-Version" + Tus-Max-Size: + schema: + $ref: "#/components/schemas/Tus-Max-Size" + Tus-Extension: + schema: + $ref: "#/components/schemas/Tus-Extension" + 204: + description: Success + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Tus-Checksum-Algorithm: + schema: + $ref: "#/components/schemas/Tus-Checksum-Algorithm" + Tus-Version: + schema: + $ref: "#/components/schemas/Tus-Version" + Tus-Max-Size: + schema: + $ref: "#/components/schemas/Tus-Max-Size" + Tus-Extension: + schema: + $ref: "#/components/schemas/Tus-Extension" + /s5/upload/tus/{id}: + delete: + summary: Added by the Termination extension. + tags: + - upload + - tus + description: When receiving a DELETE request for an existing upload the Server + SHOULD free associated resources and MUST respond with the 204 No Content + status confirming that the upload was terminated. For all future requests + to this URL, the Server SHOULD respond with the 404 Not Found or 410 Gone + status. + operationId: FilesDelete + parameters: + - name: id + in: path + required: true + schema: + type: string + - name: Tus-Resumable + in: header + required: true + schema: + $ref: "#/components/schemas/Tus-Resumable" + responses: + 204: + description: Upload was terminated + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 412: + description: Precondition Failed + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Tus-Version: + schema: + $ref: "#/components/schemas/Tus-Version" + head: + summary: Used to determine the offset at which the upload should be continued. + tags: + - upload + - tus + description: Used to determine the offset at which the upload should be continued. + operationId: FilesHead + parameters: + - name: id + in: path + required: true + schema: + type: string + - name: Tus-Resumable + in: header + required: true + schema: + $ref: "#/components/schemas/Tus-Resumable" + responses: + 200: + description: Returns offset + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Cache-Control: + schema: + type: string + enum: + - no-store + Upload-Offset: + schema: + $ref: "#/components/schemas/Upload-Offset" + Upload-Length: + schema: + $ref: "#/components/schemas/Upload-Length" + 403: + description: If the resource is not found, the Server SHOULD return either + the 404 Not Found, 410 Gone or 403 Forbidden status without the Upload-Offset + header. + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 404: + description: If the resource is not found, the Server SHOULD return either + the 404 Not Found, 410 Gone or 403 Forbidden status without the Upload-Offset + header. + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 410: + description: If the resource is not found, the Server SHOULD return either + the 404 Not Found, 410 Gone or 403 Forbidden status without the Upload-Offset + header. + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 412: + description: Precondition Failed + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Tus-Version: + schema: + $ref: "#/components/schemas/Tus-Version" + patch: + summary: Used to resume the upload + tags: + - upload + - tus + description: 'The Server SHOULD accept PATCH requests against any upload URL + and apply the bytes contained in the message at the given offset specified + by the Upload-Offset header. All PATCH requests MUST use Content-Type: application/offset+octet-stream, + otherwise the server SHOULD return a 415 Unsupported Media Type status.' + operationId: FilePatch + parameters: + - name: id + in: path + required: true + schema: + type: string + - name: Tus-Resumable + in: header + required: true + schema: + $ref: "#/components/schemas/Tus-Resumable" + - name: Content-Length + in: header + description: Length of the body of this request + required: true + schema: + type: integer + - name: Upload-Offset + in: header + required: true + schema: + $ref: "#/components/schemas/Upload-Offset" + - name: Upload-Checksum + in: header + schema: + $ref: "#/components/schemas/Upload-Checksum" + requestBody: + description: Remaining (possibly partial) content of the file. Required if Content-Length > 0. + required: false + content: + application/offset+octet-stream: + schema: + type: string + format: binary + responses: + 204: + description: Upload offset was updated + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Upload-Offset: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Upload-Expires: + description: Added by the expiration extension. The Upload-Expires response + header indicates the time after which the unfinished upload expires. + A Server MAY wish to remove incomplete uploads after a given period + of time to prevent abandoned uploads from taking up extra storage. + The Client SHOULD use this header to determine if an upload is still + valid before attempting to resume the upload. This header MUST be + included in every PATCH response if the upload is going to expire. + If the expiration is known at the creation, the Upload-Expires header + MUST be included in the response to the initial POST request. Its + value MAY change over time. If a Client does attempt to resume an + upload which has since been removed by the Server, the Server SHOULD + respond with the 404 Not Found or 410 Gone status. The latter one + SHOULD be used if the Server is keeping track of expired uploads. + In both cases the Client SHOULD start a new upload. The value of the + Upload-Expires header MUST be in RFC 7231 datetime format. + schema: + type: string + 400: + description: Added by the checksum extension. The checksum algorithm is + not supported by the server + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 403: + description: In the concatenation extension, the Server MUST respond with + the 403 Forbidden status to PATCH requests against a final upload URL + and MUST NOT modify the final or its partial uploads. + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 404: + description: PATCH request against a non-existent resource + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 409: + description: PATCH request with Upload-Offset unequal to the offset of the resource on the server. The Upload-Offset header's value MUST be equal to the current offset of the resource. + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 410: + description: PATCH request against a non-existent resource + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 412: + description: Precondition Failed + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + Tus-Version: + schema: + $ref: "#/components/schemas/Tus-Version" + 415: + description: Content-Type was not application/offset+octet-stream + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + 460: + description: Added by the checksum extension. Checksums mismatch + headers: + Tus-Resumable: + schema: + $ref: "#/components/schemas/Tus-Resumable" + + # Download API + /s5/blob/{cid}: + get: + summary: Retrieve a blob + tags: + - download + parameters: + - name: cid + in: path + required: true + schema: + type: string + responses: + '302': + description: Redirecting to discovered blob url + /s5/metadata/{cid}: + get: + summary: Retrieve file metadata + tags: + - download + parameters: + - name: cid + in: path + required: true + schema: + type: string + description: > + * Resolvers are currently not supported + + * Raw files don't have metadata + responses: + '200': + description: File metadata + content: + application/json: + schema: + type: object + /s5/download/{cid}: + get: + summary: Download a file + tags: + - download + parameters: + - name: cid + in: path + required: true + schema: + type: string + responses: + '200': + description: File content + content: + application/octet-stream: + schema: + type: string + format: binary + + # Pins API + /s5/pin/{cid}: + post: + summary: Pin a file + tags: + - pin + parameters: + - name: cid + in: path + required: true + schema: + type: string + responses: + '204': + description: File pinned + /s5/delete/{cid}: + delete: + summary: Delete a file. This will only unpin it from the account, and potentially delete it later if there are no more global pins. + tags: + - pin + parameters: + - name: cid + in: path + required: true + schema: + type: string + responses: + '204': + description: File deleted + + # Debug API + /s5/debug/download_urls/{cid}: + get: + summary: Retrieve download URLs + tags: + - debug + parameters: + - name: cid + in: path + required: true + schema: + type: string + - name: hash + in: query + required: true + schema: + type: string + description: This is base64 url encoded + - name: kinds + in: query + required: false + schema: + type: string + description: This is a comma separated list of kinds, which are integer identifiers. + responses: + '200': + description: Download URLs + content: + text/plain: + schema: + type: string + /s5/debug/storage_locations/{hash}: + get: + summary: Retrieve storage locations + tags: + - debug + parameters: + - name: hash + in: path + required: true + schema: + type: string + description: This is base64 url encoded + responses: + '200': + description: Storage locations + content: + application/json: + schema: + $ref: '#/components/schemas/DebugStorageLocationsResponse' + # Registry API + /s5/registry: + get: + summary: Retrieve a registry entry + tags: + - registry + parameters: + - name: pk + description: Public key of the registry entry + in: query + required: true + schema: + type: string + responses: + '200': + description: Registry entry + content: + application/json: + schema: + $ref: '#/components/schemas/RegistryQueryResponse' + post: + summary: Create or update a registry entry + tags: + - registry + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegistrySetRequest' + responses: + '200': + description: Registry entry set + /s5/registry/subscription: + post: + summary: Listen for websocket updates for a given registry entry + tags: + - registry + requestBody: + content: + text/plain: + schema: + nullable: true + responses: + '200': + description: Success +components: + schemas: + AccountRegisterChallengeResponse: + type: object + properties: + challenge: + type: string + AccountRegisterRequest: + type: object + properties: + pubkey: + type: string + description: This is base64 url encoded + response: + type: string + description: This is base64 url encoded + signature: + type: string + description: This is base64 url encoded + email: + type: string + required: + - pubkey + - response + - signature + AccountLoginChallengeResponse: + type: object + properties: + challenge: + type: string + description: This is base64 url encoded + AccountLoginRequest: + type: object + properties: + pubkey: + type: string + description: This is base64 url encoded + response: + type: string + description: This is base64 url encoded + signature: + type: string + description: This is base64 url encoded + required: + - pubkey + - response + - signature + BasicUploadResponse: + type: object + properties: + CID: + type: string + UploadRequestTryFiles: + type: array + items: + type: string + UploadRequestErrorPages: + type: object + additionalProperties: + type: string + description: > + Object keys are expected to be string representations of integers (e.g., "404", "500"), + with their values being strings. Due to limitations in the OpenAPI Specification, + this pattern cannot be enforced through the schema and should be validated at runtime. + AccountStats: + type: object + properties: + total: + $ref: '#/components/schemas/AccountStatsTotal' + AccountStatsTotal: + type: object + properties: + usedStorage: + type: integer + AccountTier: + type: object + properties: + id: + type: integer + name: + type: string + uploadBandwidth: + type: integer + storageLimit: + type: integer + scopes: + type: array + items: + type: object + AccountInfoResponse: + type: object + properties: + email: + type: string + quotaExceeded: + type: boolean + emailConfirmed: + type: boolean + isRestricted: + type: boolean + tier: + $ref: '#/components/schemas/AccountTier' + AccountStatsResponse: + allOf: + - $ref: "#/components/schemas/AccountInfoResponse" + - type: object + properties: + stats: + $ref: "#/components/schemas/AccountStats" + RegistryQueryResponse: + type: object + properties: + pk: + type: string + revision: + type: integer + data: + type: string + signature: + type: string + RegistrySetRequest: + type: object + properties: + pk: + type: string + revision: + type: integer + data: + type: string + signature: + type: string + DebugStorageLocationsResponse: + type: object + properties: + locations: + type: array + items: + $ref: '#/components/schemas/DebugStorageLocation' + DebugStorageLocation: + type: object + properties: + location: + type: integer + parts: + type: array + items: + type: string + expiry: + type: integer + nodeId: + type: string + score: + type: integer + Tus-Resumable: + type: string + enum: + - 1.0.0 + description: Protocol version + Tus-Version: + description: The Tus-Version response header MUST be a comma-separated + list of protocol versions supported by the Server. The list MUST be + sorted by Server's preference where the first one is the most preferred + one. + type: string + Tus-Extension: + description: The Tus-Extension response header MUST be a comma-separated + list of the extensions supported by the Server. If no extensions are + supported, the Tus-Extension header MUST be omitted. + type: string + Tus-Max-Size: + description: The Tus-Max-Size response header MUST be a non-negative + integer indicating the maximum allowed size of an entire upload in + bytes. The Server SHOULD set this header if there is a known hard + limit. + type: integer + Upload-Length: + description: The Upload-Length request and response header indicates the size + of the entire upload in bytes. The value MUST be a non-negative integer. + In the concatenation extension, the Client MUST NOT include the Upload-Length + header in the final upload creation + type: integer + Upload-Offset: + description: The Upload-Offset request and response header indicates + a byte offset within a resource. The value MUST be a non-negative + integer. + type: integer + + Tus-Checksum-Algorithm: + description: Added by the checksum extension. The Tus-Checksum-Algorithm + response header MUST be a comma-separated list of the checksum algorithms + supported by the server. + type: string + Upload-Checksum: + description: Added by the checksum extension. The Upload-Checksum request + header contains information about the checksum of the current body payload. + The header MUST consist of the name of the used checksum algorithm and the + Base64 encoded checksum separated by a space. + type: string + securitySchemes: + BearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + CookieAuth: + type: apiKey + in: cookie + name: s5-auth-token + QueryAuth: + type: apiKey + in: query + name: s5-auth-token +security: + - BearerAuth: [] + - CookieAuth: [] + - QueryAuth: [] +tags: + - name: account + description: Account API + - name: upload + description: Upload API + - name: tus + description: TUS API + - name: download + description: Download API + - name: pin + description: Pins API + - name: debug + description: Debug API + - name: registry + description: Registry API