diff --git a/package-lock.json b/package-lock.json index a93a7751..fee99f43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -559,6 +559,36 @@ "@lezer/common": "^1.1.0" } }, + "node_modules/@codemirror/lang-css": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz", + "integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/common": "^1.0.2", + "@lezer/css": "^1.1.7" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.9.tgz", + "integrity": "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.17.0", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.0" + } + }, "node_modules/@codemirror/lang-javascript": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz", @@ -584,6 +614,21 @@ "@lezer/json": "^1.0.0" } }, + "node_modules/@codemirror/lang-markdown": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.3.1.tgz", + "integrity": "sha512-y3sSPuQjBKZQbQwe3ZJKrSW6Silyl9PnrU/Mf0m2OQgIlPoSYTtOvEL7xs94SVMkb8f4x+SQFnzXPdX4Wk2lsg==", + "license": "MIT", + "dependencies": { + "@codemirror/autocomplete": "^6.7.1", + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.2.1", + "@lezer/markdown": "^1.0.0" + } + }, "node_modules/@codemirror/lang-xml": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz", @@ -1512,12 +1557,29 @@ "url": "https://opencollective.com/js-sdsl" } }, + "node_modules/@juggle/resize-observer": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", + "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==", + "license": "Apache-2.0" + }, "node_modules/@lezer/common": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.2.tgz", "integrity": "sha512-Z+R3hN6kXbgBWAuejUNPihylAL1Z5CaFqnIe0nTX8Ej+XlIy3EGtXxn6WtLMO+os2hRkQvm2yvaGMYliUzlJaw==", "license": "MIT" }, + "node_modules/@lezer/css": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.9.tgz", + "integrity": "sha512-TYwgljcDv+YrV0MZFFvYFQHCfGgbPMR6nuqLabBdmZoFH3EP1gvw8t0vae326Ne3PszQkbXfVBjCnf3ZVCr0bA==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/@lezer/generator": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/@lezer/generator/-/generator-1.7.1.tgz", @@ -1541,6 +1603,17 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@lezer/html": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.10.tgz", + "integrity": "sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.2.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, "node_modules/@lezer/javascript": { "version": "1.4.19", "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.19.tgz", @@ -1572,6 +1645,16 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@lezer/markdown": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.3.2.tgz", + "integrity": "sha512-Wu7B6VnrKTbBEohqa63h5vxXjiC4pO5ZQJ/TDbhJxPQaaIoRD/6UVDhSDtVsCwVZV12vvN9KxuLL3ATMnlG0oQ==", + "license": "MIT", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, "node_modules/@lezer/xml": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.5.tgz", @@ -1775,17 +1858,31 @@ "react": ">=16.8" } }, - "node_modules/@react-hook/resize-observer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-2.0.2.tgz", - "integrity": "sha512-tzKKzxNpfE5TWmxuv+5Ae3IF58n0FQgQaWJmcbYkjXTRZATXxClnTprQ2uuYygYTpu1pqbBskpwMpj6jpT1djA==", + "node_modules/@react-hook/size": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@react-hook/size/-/size-2.1.2.tgz", + "integrity": "sha512-BmE5asyRDxSuQ9p14FUKJ0iBRgV9cROjqNG9jT/EjCM+xHha1HVqbPoT+14FQg1K7xIydabClCibUY4+1tw/iw==", "license": "MIT", "dependencies": { + "@react-hook/passive-layout-effect": "^1.2.0", + "@react-hook/resize-observer": "^1.2.1" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/@react-hook/size/node_modules/@react-hook/resize-observer": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-1.2.6.tgz", + "integrity": "sha512-DlBXtLSW0DqYYTW3Ft1/GQFZlTdKY5VAFIC4+km6IK5NiPPDFchGbEJm1j6pSgMqPRHbUQgHJX7RaR76ic1LWA==", + "license": "MIT", + "dependencies": { + "@juggle/resize-observer": "^3.3.1", "@react-hook/latest": "^1.0.2", "@react-hook/passive-layout-effect": "^1.2.0" }, "peerDependencies": { - "react": ">=18" + "react": ">=16.8" } }, "node_modules/@remix-run/router": { @@ -3000,13 +3097,39 @@ "@types/responselike": "^1.0.0" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, "license": "MIT" }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", @@ -3050,6 +3173,21 @@ "@types/node": "*" } }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", @@ -3087,14 +3225,12 @@ "version": "15.7.13", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "devOptional": true, "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.11", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", - "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -3121,6 +3257,12 @@ "@types/node": "*" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/@types/uuid": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", @@ -3340,7 +3482,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, "license": "ISC" }, "node_modules/@vitejs/plugin-react": { @@ -3881,6 +4022,16 @@ "node": ">= 0.4" } }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4392,6 +4543,16 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4409,6 +4570,46 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -4723,6 +4924,16 @@ "color-support": "bin.js" } }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -5083,7 +5294,6 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "devOptional": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -5106,6 +5316,19 @@ "node": ">=0.10.0" } }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/decompress": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", @@ -5410,6 +5633,19 @@ "license": "MIT", "optional": true }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -6385,6 +6621,16 @@ "node": ">=4.0" } }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -6458,6 +6704,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -7356,6 +7608,46 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", + "integrity": "sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -7372,6 +7664,16 @@ "dev": true, "license": "ISC" }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", @@ -7529,6 +7831,12 @@ "dev": true, "license": "ISC" }, + "node_modules/inline-style-parser": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==", + "license": "MIT" + }, "node_modules/inline-style-prefixer": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", @@ -7623,6 +7931,30 @@ "node": ">= 0.10" } }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-arguments": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", @@ -7795,6 +8127,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -7854,6 +8196,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-installed-globally": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", @@ -7986,6 +8338,18 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -8580,6 +8944,16 @@ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", "license": "Apache-2.0" }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -8662,6 +9036,16 @@ "url": "https://github.com/wojtekmaj/make-event-props?sponsor=1" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -8676,6 +9060,288 @@ "node": ">=10" } }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", @@ -8737,6 +9403,569 @@ "node": ">= 8" } }, + "node_modules/micromark": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.1.tgz", + "integrity": "sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz", + "integrity": "sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.3.tgz", + "integrity": "sha512-VXJJuNxYWSoYL6AJ6OQECCFGhIU2GGHMw8tahogePBrjkG8aCCas3ibkp7RnVOSTClg2is05/R7maAhF1XyQMg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", + "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -8902,7 +10131,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true, "license": "MIT" }, "node_modules/mz": { @@ -9826,6 +11054,31 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", "integrity": "sha512-RwBeO/B/vZR3dfKL1ye/vx8MHZ40ugzpyfeVG5GsiuGnrlMWe2o8wxBbLCpw9CsxV+wHuzYlCiWnybrIA0ling==" }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -10271,6 +11524,16 @@ "react-is": "^16.13.1" } }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/protobufjs": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", @@ -10832,6 +12095,32 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/react-markdown": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-9.0.1.tgz", + "integrity": "sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, "node_modules/react-pdf": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-9.1.1.tgz", @@ -11078,6 +12367,72 @@ "node": ">=0.10.0" } }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz", + "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11681,6 +13036,16 @@ "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -11961,6 +13326,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -12048,6 +13427,15 @@ "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", "license": "MIT" }, + "node_modules/style-to-object": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.4" + } + }, "node_modules/stylis": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", @@ -12577,6 +13965,26 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/truncate-utf8-bytes": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", @@ -12848,6 +14256,25 @@ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "license": "MIT" }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unique-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", @@ -12861,6 +14288,74 @@ "node": ">=4" } }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -13077,6 +14572,34 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "5.4.8", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", @@ -13713,6 +15236,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "plugin-runtime": { "name": "@yaakapp-internal/plugin-runtime", "dependencies": { @@ -13766,12 +15299,13 @@ "@codemirror/commands": "6.7.0", "@codemirror/lang-javascript": "^6.2.2", "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-markdown": "^6.3.1", "@codemirror/lang-xml": "^6.0.2", "@codemirror/language": "^6.6.0", "@codemirror/search": "^6.2.3", "@lezer/highlight": "^1.1.3", "@lezer/lr": "^1.3.3", - "@react-hook/resize-observer": "^2.0.2", + "@react-hook/size": "^2.1.2", "@tailwindcss/container-queries": "^0.1.1", "@tanstack/react-query": "^5.59.16", "@tanstack/react-virtual": "^3.10.8", @@ -13803,9 +15337,11 @@ "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", "react-helmet-async": "^2.0.5", + "react-markdown": "^9.0.1", "react-pdf": "^9.1.0", "react-router-dom": "^6.26.2", "react-use": "^17.5.1", + "remark-gfm": "^4.0.0", "slugify": "^1.6.6", "uuid": "^10.0.0", "whatwg-mimetype": "^4.0.0", diff --git a/src-tauri/migrations/20241217204951_docs.sql b/src-tauri/migrations/20241217204951_docs.sql new file mode 100644 index 00000000..5bedee7e --- /dev/null +++ b/src-tauri/migrations/20241217204951_docs.sql @@ -0,0 +1,8 @@ +ALTER TABLE http_requests + ADD COLUMN description TEXT DEFAULT '' NOT NULL; + +ALTER TABLE grpc_requests + ADD COLUMN description TEXT DEFAULT '' NOT NULL; + +ALTER TABLE folders + ADD COLUMN description TEXT DEFAULT '' NOT NULL; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 0f8793ef..6bd1eb1e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -903,7 +903,7 @@ async fn cmd_import_data( v.workspace_id = maybe_gen_id(v.workspace_id.as_str(), ModelType::TypeWorkspace, &mut id_map); v.folder_id = maybe_gen_id_opt(v.folder_id, ModelType::TypeFolder, &mut id_map); - let x = upsert_grpc_request(&window, &v).await.map_err(|e| e.to_string())?; + let x = upsert_grpc_request(&window, v).await.map_err(|e| e.to_string())?; imported_resources.grpc_requests.push(x.clone()); } info!("Imported {} grpc_requests", imported_resources.grpc_requests.len()); @@ -1225,7 +1225,7 @@ async fn cmd_create_grpc_request( ) -> Result { upsert_grpc_request( &w, - &GrpcRequest { + GrpcRequest { workspace_id: workspace_id.to_string(), name: name.to_string(), folder_id: folder_id.map(|s| s.to_string()), @@ -1273,7 +1273,7 @@ async fn cmd_update_grpc_request( request: GrpcRequest, w: WebviewWindow, ) -> Result { - upsert_grpc_request(&w, &request).await.map_err(|e| e.to_string()) + upsert_grpc_request(&w, request).await.map_err(|e| e.to_string()) } #[tauri::command] diff --git a/src-tauri/yaak_models/bindings/models.ts b/src-tauri/yaak_models/bindings/models.ts index f1afec54..3872c2ce 100644 --- a/src-tauri/yaak_models/bindings/models.ts +++ b/src-tauri/yaak_models/bindings/models.ts @@ -14,7 +14,7 @@ export type Environment = { model: "environment", id: string, workspaceId: strin export type EnvironmentVariable = { enabled?: boolean, name: string, value: string, }; -export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, sortPriority: number, }; +export type Folder = { model: "folder", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, name: string, description: string, sortPriority: number, }; export type GrpcConnection = { model: "grpc_connection", id: string, createdAt: string, updatedAt: string, workspaceId: string, requestId: string, elapsed: number, error: string | null, method: string, service: string, status: number, state: GrpcConnectionState, trailers: { [key in string]?: string }, url: string, }; @@ -26,9 +26,9 @@ export type GrpcEventType = "info" | "error" | "client_message" | "server_messag export type GrpcMetadataEntry = { enabled?: boolean, name: string, value: string, }; -export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; +export type GrpcRequest = { model: "grpc_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authenticationType: string | null, authentication: Record, description: string, message: string, metadata: Array, method: string | null, name: string, service: string | null, sortPriority: number, url: string, }; -export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, body: Record, bodyType: string | null, headers: Array, method: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; +export type HttpRequest = { model: "http_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record, authenticationType: string | null, body: Record, bodyType: string | null, description: string, headers: Array, method: string, name: string, sortPriority: number, url: string, urlParameters: Array, }; export type HttpRequestHeader = { enabled?: boolean, name: string, value: string, }; diff --git a/src-tauri/yaak_models/src/models.rs b/src-tauri/yaak_models/src/models.rs index 9382ba82..ac3ca348 100644 --- a/src-tauri/yaak_models/src/models.rs +++ b/src-tauri/yaak_models/src/models.rs @@ -310,6 +310,7 @@ pub struct Folder { pub folder_id: Option, pub name: String, + pub description: String, pub sort_priority: f32, } @@ -325,6 +326,7 @@ pub enum FolderIden { UpdatedAt, Name, + Description, SortPriority, } @@ -341,6 +343,7 @@ impl<'s> TryFrom<&Row<'s>> for Folder { updated_at: r.get("updated_at")?, folder_id: r.get("folder_id")?, name: r.get("name")?, + description: r.get("description")?, }) } } @@ -385,6 +388,7 @@ pub struct HttpRequest { #[ts(type = "Record")] pub body: BTreeMap, pub body_type: Option, + pub description: String, pub headers: Vec, #[serde(default = "default_http_request_method")] pub method: String, @@ -409,6 +413,7 @@ pub enum HttpRequestIden { AuthenticationType, Body, BodyType, + Description, Headers, Method, Name, @@ -437,6 +442,7 @@ impl<'s> TryFrom<&Row<'s>> for HttpRequest { method: r.get("method")?, body: serde_json::from_str(body.as_str()).unwrap_or_default(), body_type: r.get("body_type")?, + description: r.get("description")?, authentication: serde_json::from_str(authentication.as_str()).unwrap_or_default(), authentication_type: r.get("authentication_type")?, headers: serde_json::from_str(headers.as_str()).unwrap_or_default(), @@ -584,6 +590,7 @@ pub struct GrpcRequest { pub authentication_type: Option, #[ts(type = "Record")] pub authentication: BTreeMap, + pub description: String, pub message: String, pub metadata: Vec, pub method: Option, @@ -606,6 +613,7 @@ pub enum GrpcRequestIden { Authentication, AuthenticationType, + Description, Message, Metadata, Method, @@ -629,6 +637,7 @@ impl<'s> TryFrom<&Row<'s>> for GrpcRequest { updated_at: r.get("updated_at")?, folder_id: r.get("folder_id")?, name: r.get("name")?, + description: r.get("description")?, service: r.get("service")?, method: r.get("method")?, message: r.get("message")?, diff --git a/src-tauri/yaak_models/src/queries.rs b/src-tauri/yaak_models/src/queries.rs index af76682e..4128d49a 100644 --- a/src-tauri/yaak_models/src/queries.rs +++ b/src-tauri/yaak_models/src/queries.rs @@ -307,7 +307,7 @@ pub async fn duplicate_grpc_request( } }; request.id = "".to_string(); - upsert_grpc_request(window, &request).await + upsert_grpc_request(window, request).await } pub async fn delete_grpc_request( @@ -334,7 +334,7 @@ pub async fn delete_grpc_request( pub async fn upsert_grpc_request( window: &WebviewWindow, - request: &GrpcRequest, + request: GrpcRequest, ) -> Result { let id = match request.id.as_str() { "" => generate_model_id(ModelType::TypeGrpcRequest), @@ -351,6 +351,7 @@ pub async fn upsert_grpc_request( GrpcRequestIden::CreatedAt, GrpcRequestIden::UpdatedAt, GrpcRequestIden::Name, + GrpcRequestIden::Description, GrpcRequestIden::WorkspaceId, GrpcRequestIden::FolderId, GrpcRequestIden::SortPriority, @@ -363,17 +364,18 @@ pub async fn upsert_grpc_request( GrpcRequestIden::Metadata, ]) .values_panic([ - id.as_str().into(), + id.into(), CurrentTimestamp.into(), CurrentTimestamp.into(), trimmed_name.into(), - request.workspace_id.as_str().into(), + request.description.into(), + request.workspace_id.into(), request.folder_id.as_ref().map(|s| s.as_str()).into(), request.sort_priority.into(), - request.url.as_str().into(), + request.url.into(), request.service.as_ref().map(|s| s.as_str()).into(), request.method.as_ref().map(|s| s.as_str()).into(), - request.message.as_str().into(), + request.message.into(), request.authentication_type.as_ref().map(|s| s.as_str()).into(), serde_json::to_string(&request.authentication)?.into(), serde_json::to_string(&request.metadata)?.into(), @@ -384,6 +386,7 @@ pub async fn upsert_grpc_request( GrpcRequestIden::UpdatedAt, GrpcRequestIden::WorkspaceId, GrpcRequestIden::Name, + GrpcRequestIden::Description, GrpcRequestIden::FolderId, GrpcRequestIden::SortPriority, GrpcRequestIden::Url, @@ -1064,6 +1067,7 @@ pub async fn upsert_folder(window: &WebviewWindow, r: Folder) -> FolderIden::WorkspaceId, FolderIden::FolderId, FolderIden::Name, + FolderIden::Description, FolderIden::SortPriority, ]) .values_panic([ @@ -1073,6 +1077,7 @@ pub async fn upsert_folder(window: &WebviewWindow, r: Folder) -> r.workspace_id.as_str().into(), r.folder_id.as_ref().map(|s| s.as_str()).into(), trimmed_name.into(), + r.description.into(), r.sort_priority.into(), ]) .on_conflict( @@ -1080,6 +1085,7 @@ pub async fn upsert_folder(window: &WebviewWindow, r: Folder) -> .update_columns([ FolderIden::UpdatedAt, FolderIden::Name, + FolderIden::Description, FolderIden::FolderId, FolderIden::SortPriority, ]) @@ -1127,6 +1133,7 @@ pub async fn upsert_http_request( HttpRequestIden::WorkspaceId, HttpRequestIden::FolderId, HttpRequestIden::Name, + HttpRequestIden::Description, HttpRequestIden::Url, HttpRequestIden::UrlParameters, HttpRequestIden::Method, @@ -1141,12 +1148,13 @@ pub async fn upsert_http_request( id.as_str().into(), CurrentTimestamp.into(), CurrentTimestamp.into(), - r.workspace_id.as_str().into(), + r.workspace_id.into(), r.folder_id.as_ref().map(|s| s.as_str()).into(), trimmed_name.into(), - r.url.as_str().into(), + r.description.into(), + r.url.into(), serde_json::to_string(&r.url_parameters)?.into(), - r.method.as_str().into(), + r.method.into(), serde_json::to_string(&r.body)?.into(), r.body_type.as_ref().map(|s| s.as_str()).into(), serde_json::to_string(&r.authentication)?.into(), @@ -1160,6 +1168,7 @@ pub async fn upsert_http_request( HttpRequestIden::UpdatedAt, HttpRequestIden::WorkspaceId, HttpRequestIden::Name, + HttpRequestIden::Description, HttpRequestIden::FolderId, HttpRequestIden::Method, HttpRequestIden::Headers, diff --git a/src-web/components/FolderSettingsDialog.tsx b/src-web/components/FolderSettingsDialog.tsx new file mode 100644 index 00000000..e9f13e51 --- /dev/null +++ b/src-web/components/FolderSettingsDialog.tsx @@ -0,0 +1,46 @@ +import { useFolders } from '../hooks/useFolders'; +import { useUpdateAnyFolder } from '../hooks/useUpdateAnyFolder'; +import { Banner } from './core/Banner'; +import { PlainInput } from './core/PlainInput'; +import { VStack } from './core/Stacks'; +import { MarkdownEditor } from './MarkdownEditor'; + +interface Props { + folderId: string | null; +} + +export function FolderSettingsDialog({ folderId }: Props) { + const updateFolder = useUpdateAnyFolder(); + const folders = useFolders(); + const folder = folders.find((f) => f.id === folderId); + + if (folder == null) return null; + + return ( + + {updateFolder.error != null && {String(updateFolder.error)}} + { + if (folderId == null) return; + updateFolder.mutate({ id: folderId, update: (folder) => ({ ...folder, name }) }); + }} + /> + + { + if (folderId == null) return; + updateFolder.mutate({ + id: folderId, + update: (folder) => ({ ...folder, description }), + }); + }} + /> + + ); +} diff --git a/src-web/components/GrpcConnectionSetupPane.tsx b/src-web/components/GrpcConnectionSetupPane.tsx index c4a1838d..cb6a6ae1 100644 --- a/src-web/components/GrpcConnectionSetupPane.tsx +++ b/src-web/components/GrpcConnectionSetupPane.tsx @@ -1,9 +1,9 @@ -import useResizeObserver from '@react-hook/resize-observer'; +import useSize from '@react-hook/size'; import type { GrpcMetadataEntry, GrpcRequest } from '@yaakapp-internal/models'; import classNames from 'classnames'; import type { CSSProperties } from 'react'; -import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { createGlobalState } from 'react-use'; +import React, { useCallback, useMemo, useRef } from 'react'; +import { useLocalStorage } from 'react-use'; import type { ReflectResponseService } from '../hooks/useGrpc'; import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest'; @@ -11,6 +11,7 @@ import { AUTH_TYPE_BASIC, AUTH_TYPE_BEARER, AUTH_TYPE_NONE } from '../lib/model_ import { BasicAuth } from './BasicAuth'; import { BearerAuth } from './BearerAuth'; import { Button } from './core/Button'; +import { CountBadge } from './core/CountBadge'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; import { PairOrBulkEditor } from './core/PairOrBulkEditor'; @@ -20,6 +21,7 @@ import type { TabItem } from './core/Tabs/Tabs'; import { TabContent, Tabs } from './core/Tabs/Tabs'; import { EmptyStateText } from './EmptyStateText'; import { GrpcEditor } from './GrpcEditor'; +import { MarkdownEditor } from './MarkdownEditor'; import { UrlBar } from './UrlBar'; interface Props { @@ -44,7 +46,10 @@ interface Props { services: ReflectResponseService[] | null; } -const useActiveTab = createGlobalState('message'); +const TAB_MESSAGE = 'message'; +const TAB_METADATA = 'metadata'; +const TAB_AUTH = 'auth'; +const TAB_DESCRIPTION = 'description'; export function GrpcConnectionSetupPane({ style, @@ -61,14 +66,14 @@ export function GrpcConnectionSetupPane({ onSend, }: Props) { const updateRequest = useUpdateAnyGrpcRequest(); - const [activeTab, setActiveTab] = useActiveTab(); + const [activeTabs, setActiveTabs] = useLocalStorage>( + 'grpcRequestPaneActiveTabs', + {}, + ); const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null); - const [paneSize, setPaneSize] = useState(99999); const urlContainerEl = useRef(null); - useResizeObserver(urlContainerEl.current, (entry) => { - setPaneSize(entry.contentRect.width); - }); + const [paneWidth] = useSize(urlContainerEl.current); const handleChangeUrl = useCallback( (url: string) => updateRequest.mutateAsync({ id: activeRequest.id, update: { url } }), @@ -129,9 +134,18 @@ export function GrpcConnectionSetupPane({ const tabs: TabItem[] = useMemo( () => [ - { value: 'message', label: 'Message' }, { - value: 'auth', + value: TAB_DESCRIPTION, + label: ( +
+ Docs + {activeRequest.description && } +
+ ), + }, + { value: TAB_MESSAGE, label: 'Message' }, + { + value: TAB_AUTH, label: 'Auth', options: { value: activeRequest.authenticationType, @@ -160,29 +174,44 @@ export function GrpcConnectionSetupPane({ }, }, }, - { value: 'metadata', label: 'Metadata' }, + { value: TAB_METADATA, label: 'Metadata' }, ], [ activeRequest.authentication, activeRequest.authenticationType, + activeRequest.description, activeRequest.id, updateRequest, ], ); + const activeTab = activeTabs?.[activeRequest.id]; + const setActiveTab = useCallback( + (tab: string) => { + setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); + }, + [activeRequest.id, setActiveTabs], + ); + const handleMetadataChange = useCallback( (metadata: GrpcMetadataEntry[]) => updateRequest.mutate({ id: activeRequest.id, update: { metadata } }), [activeRequest.id, updateRequest], ); + const handleDescriptionChange = useCallback( + (description: string) => + updateRequest.mutate({ id: activeRequest.id, update: { description } }), + [activeRequest.id, updateRequest], + ); + return (
{select.options.find((o) => o.value === select.value)?.label ?? 'No Schema'} @@ -312,6 +341,14 @@ export function GrpcConnectionSetupPane({ forceUpdateKey={forceUpdateKey} /> + + + ); diff --git a/src-web/components/MarkdownEditor.tsx b/src-web/components/MarkdownEditor.tsx new file mode 100644 index 00000000..455b7c93 --- /dev/null +++ b/src-web/components/MarkdownEditor.tsx @@ -0,0 +1,137 @@ +import useSize from '@react-hook/size'; +import classNames from 'classnames'; +import { useRef } from 'react'; +import Markdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; +import { useKeyValue } from '../hooks/useKeyValue'; +import { Editor } from './core/Editor'; +import { IconButton } from './core/IconButton'; +import { SplitLayout } from './core/SplitLayout'; +import { VStack } from './core/Stacks'; +import { Prose } from './Prose'; + +interface Props { + placeholder: string; + className?: string; + defaultValue: string; + onChange: (value: string) => void; + name: string; +} + +export function MarkdownEditor({ className, defaultValue, onChange, name, placeholder }: Props) { + const containerRef = useRef(null); + + const [width] = useSize(containerRef.current); + const wideEnoughForSplit = width > 600; + + const { set: setViewMode, value: rawViewMode } = useKeyValue<'edit' | 'preview' | 'both'>({ + namespace: 'global', + key: ['md_view', name], + fallback: 'edit', + }); + + if (rawViewMode == null) return null; + + let viewMode = rawViewMode; + if (rawViewMode === 'both' && !wideEnoughForSplit) { + viewMode = 'edit'; + } + + const editor = ( + + ); + + const preview = + defaultValue.length === 0 ? ( +

No description

+ ) : ( + + { + if (href && !href.match(/https?:\/\//)) { + href = `http://${href}`; + } + return ( + + {children} + + ); + }, + }} + > + {defaultValue} + + + ); + + const contents = + viewMode === 'both' ? ( +
{editor}
} + secondSlot={({ style }) => ( +
+ {preview} +
+ )} + /> + ) : viewMode === 'preview' ? ( + preview + ) : ( + editor + ); + + return ( +
+
{contents}
+ + setViewMode('edit')} + /> + {wideEnoughForSplit && ( + setViewMode('both')} + /> + )} + setViewMode('preview')} + /> + +
+ ); +} diff --git a/src-web/components/Prose.css b/src-web/components/Prose.css new file mode 100644 index 00000000..64f35b7d --- /dev/null +++ b/src-web/components/Prose.css @@ -0,0 +1,201 @@ +.prose { + @apply text-text; + + & > :first-child { + @apply mt-0; + } + + img, + video, + p, + ul, + ol, + table, + blockquote, + hr, + h1, + h2, + h3, + h4, + h5, + h6 { + @apply my-5; + } + + h1, + h2, + h3, + h4, + h5, + h6 { + @apply mt-10 leading-tight text-balance; + } + + p { + @apply text-pretty; + } + + h1 { + @apply text-4xl font-bold; + } + + h2 { + @apply text-2xl font-bold; + } + + h3 { + @apply text-xl font-bold; + } + + em { + @apply italic; + } + + strong { + @apply font-bold; + } + + ul { + @apply list-disc; + + ul, ol { + @apply my-0; + } + } + + ol { + @apply list-decimal; + + ol, ul { + @apply my-0; + } + } + + ol, ul { + @apply pl-6; + + li p { + @apply inline-block my-0; + } + + li { + @apply pl-2; + } + + li::marker { + @apply text-success; + } + } + + a { + @apply text-notice hover:underline; + + * { + @apply text-notice !important; + } + } + + img, + video { + @apply max-h-[65vh]; + @apply w-auto mx-auto rounded-md; + } + + table code, + p code, + ol code, + ul code { + @apply text-xs bg-surface-active text-info font-normal whitespace-nowrap; + @apply px-1.5 py-0.5 rounded not-italic; + } + + pre { + @apply bg-surface-highlight text-text !important; + @apply px-4 py-3 rounded-md; + @apply overflow-auto whitespace-pre; + + code { + @apply text-xs font-normal; + } + } + + .banner { + @apply border border-dashed; + @apply border-border bg-surface-highlight text-text px-4 py-3 rounded text-base; + + &::before { + @apply block font-bold mb-1; + @apply text-text-subtlest; + + content: 'Note'; + } + + &.x-theme-banner--secondary::before { + content: 'Info'; + } + + &.x-theme-banner--success::before { + content: 'Tip'; + } + + &.x-theme-banner--notice::before { + content: 'Important'; + } + + &.x-theme-banner--warning::before { + content: 'Warning'; + } + + &.x-theme-banner--danger::before { + content: 'Caution'; + } + } + + blockquote { + @apply italic py-3 pl-5 pr-3 border-l-8 border-surface-active text-lg text-text bg-surface-highlight rounded shadow-lg; + + p { + @apply m-0; + } + } + + h2[id] > a .icon.icon-link { + @apply hidden w-4 h-4 bg-success ml-2; + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24' stroke='currentColor' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round' class='css-i6dzq1'%3E%3Cpath d='M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71'%3E%3C/path%3E%3Cpath d='M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71'%3E%3C/path%3E%3C/svg%3E"); + mask-size: contain; + mask-repeat: no-repeat; + + &:hover { + @apply bg-notice; + } + } + + h2[id]:hover { + .icon.icon-link { + @apply inline-block; + } + } + + hr { + @apply border-secondary border-dashed md:mx-[25%] my-10; + } + + figure { + img { + @apply mb-0; + } + + figcaption { + @apply relative pl-9 text-success text-sm pt-1; + + p { + @apply m-0; + } + } + + figcaption::before { + @apply border-info absolute left-2 top-0 h-3.5 w-6 rounded-bl border-l border-b border-dotted; + content: ''; + } + } +} diff --git a/src-web/components/Prose.tsx b/src-web/components/Prose.tsx new file mode 100644 index 00000000..ab8be45b --- /dev/null +++ b/src-web/components/Prose.tsx @@ -0,0 +1,12 @@ +import classNames from 'classnames'; +import type { ReactNode } from 'react'; +import './Prose.css'; + +interface Props { + children: ReactNode; + className?: string; +} + +export function Prose({ className, ...props }: Props) { + return
; +} diff --git a/src-web/components/RequestPane.tsx b/src-web/components/RequestPane.tsx index 2cbe8c9f..0fdf11ce 100644 --- a/src-web/components/RequestPane.tsx +++ b/src-web/components/RequestPane.tsx @@ -1,4 +1,4 @@ -import type { HttpRequest, HttpRequestHeader, HttpUrlParameter } from '@yaakapp-internal/models'; +import type { HttpRequest } from '@yaakapp-internal/models'; import classNames from 'classnames'; import type { CSSProperties } from 'react'; import React, { memo, useCallback, useMemo, useState } from 'react'; @@ -15,6 +15,7 @@ import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey'; import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest'; import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest'; import { languageFromContentType } from '../lib/contentType'; +import { fallbackRequestName } from '../lib/fallbackRequestName'; import { tryFormatJson } from '../lib/formatters'; import { AUTH_TYPE_BASIC, @@ -34,9 +35,13 @@ import { BearerAuth } from './BearerAuth'; import { BinaryFileEditor } from './BinaryFileEditor'; import { CountBadge } from './core/CountBadge'; import { Editor } from './core/Editor'; -import type { GenericCompletionOption } from './core/Editor/genericCompletion'; +import type { + GenericCompletionConfig, + GenericCompletionOption, +} from './core/Editor/genericCompletion'; import { InlineCode } from './core/InlineCode'; import type { Pair } from './core/PairEditor'; +import { PlainInput } from './core/PlainInput'; import type { TabItem } from './core/Tabs/Tabs'; import { TabContent, Tabs } from './core/Tabs/Tabs'; import { EmptyStateText } from './EmptyStateText'; @@ -44,6 +49,7 @@ import { FormMultipartEditor } from './FormMultipartEditor'; import { FormUrlencodedEditor } from './FormUrlencodedEditor'; import { GraphQLEditor } from './GraphQLEditor'; import { HeadersEditor } from './HeadersEditor'; +import { MarkdownEditor } from './MarkdownEditor'; import { useToast } from './ToastContext'; import { UrlBar } from './UrlBar'; import { UrlParametersEditor } from './UrlParameterEditor'; @@ -59,8 +65,7 @@ const TAB_BODY = 'body'; const TAB_PARAMS = 'params'; const TAB_HEADERS = 'headers'; const TAB_AUTH = 'auth'; - -const DEFAULT_TAB = TAB_BODY; +const TAB_DESCRIPTION = 'description'; export const RequestPane = memo(function RequestPane({ style, @@ -120,6 +125,15 @@ export const RequestPane = memo(function RequestPane({ const tabs: TabItem[] = useMemo( () => [ + { + value: TAB_DESCRIPTION, + label: ( +
+ Docs + {activeRequest.description && } +
+ ), + }, { value: TAB_BODY, options: { @@ -239,68 +253,36 @@ export const RequestPane = memo(function RequestPane({ activeRequest.authentication, activeRequest.authenticationType, activeRequest.bodyType, + activeRequest.description, activeRequest.headers, activeRequest.method, activeRequestId, handleContentTypeChange, toast, updateRequest, - urlParameterPairs, + urlParameterPairs.length, ], ); + const sendRequest = useSendAnyHttpRequest(); + const { activeResponse } = usePinnedHttpResponse(activeRequest); + const cancelResponse = useCancelHttpResponse(activeResponse?.id ?? null); + const isLoading = useIsResponseLoading(activeRequestId); + const { updateKey } = useRequestUpdateKey(activeRequestId); + const importCurl = useImportCurl(); + const importQuerystring = useImportQuerystring(activeRequestId); + const handleBodyChange = useCallback( (body: HttpRequest['body']) => updateRequest.mutate({ id: activeRequestId, update: { body } }), [activeRequestId, updateRequest], ); - const handleBinaryFileChange = useCallback( - (body: HttpRequest['body']) => { - updateRequest.mutate({ id: activeRequestId, update: { body } }); - }, - [activeRequestId, updateRequest], - ); const handleBodyTextChange = useCallback( (text: string) => updateRequest.mutate({ id: activeRequestId, update: { body: { text } } }), [activeRequestId, updateRequest], ); - const handleHeadersChange = useCallback( - (headers: HttpRequestHeader[]) => - updateRequest.mutate({ id: activeRequestId, update: { headers } }), - [activeRequestId, updateRequest], - ); - const handleUrlParametersChange = useCallback( - (urlParameters: HttpUrlParameter[]) => - updateRequest.mutate({ id: activeRequestId, update: { urlParameters } }), - [activeRequestId, updateRequest], - ); - const sendRequest = useSendAnyHttpRequest(); - const { activeResponse } = usePinnedHttpResponse(activeRequest); - const cancelResponse = useCancelHttpResponse(activeResponse?.id ?? null); - const handleSend = useCallback(async () => { - await sendRequest.mutateAsync(activeRequest.id ?? null); - }, [activeRequest.id, sendRequest]); - - const handleCancel = useCallback(async () => { - await cancelResponse.mutateAsync(); - }, [cancelResponse]); - - const handleMethodChange = useCallback( - (method: string) => updateRequest.mutate({ id: activeRequestId, update: { method } }), - [activeRequestId, updateRequest], - ); - const handleUrlChange = useCallback( - (url: string) => updateRequest.mutate({ id: activeRequestId, update: { url } }), - [activeRequestId, updateRequest], - ); - - const isLoading = useIsResponseLoading(activeRequestId); - const { updateKey } = useRequestUpdateKey(activeRequestId); - const importCurl = useImportCurl(); - const importQuerystring = useImportQuerystring(activeRequestId); - - const activeTab = activeTabs?.[activeRequestId] ?? DEFAULT_TAB; + const activeTab = activeTabs?.[activeRequestId]; const setActiveTab = useCallback( (tab: string) => { setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); @@ -312,6 +294,21 @@ export const RequestPane = memo(function RequestPane({ setActiveTab(TAB_PARAMS); }); + const autocomplete: GenericCompletionConfig = { + minMatch: 3, + options: + requests.length > 0 + ? [ + ...requests + .filter((r) => r.id !== activeRequestId) + .map((r): GenericCompletionOption => ({ type: 'constant', label: r.url })), + ] + : [ + { label: 'http://', type: 'constant' }, + { label: 'https://', type: 'constant' }, + ], + }; + return (
0 - ? [ - ...requests - .filter((r) => r.id !== activeRequestId) - .map( - (r) => - ({ - type: 'constant', - label: r.url, - }) as GenericCompletionOption, - ), - ] - : [ - { label: 'http://', type: 'constant' }, - { label: 'https://', type: 'constant' }, - ], - }} - onSend={handleSend} - onCancel={handleCancel} - onMethodChange={handleMethodChange} - onUrlChange={handleUrlChange} + autocomplete={autocomplete} + onSend={() => sendRequest.mutateAsync(activeRequest.id ?? null)} + onCancel={cancelResponse.mutate} + onMethodChange={(method) => + updateRequest.mutate({ id: activeRequestId, update: { method } }) + } + onUrlChange={(url: string) => + updateRequest.mutate({ id: activeRequestId, update: { url } }) + } forceUpdateKey={updateKey} isLoading={isLoading} /> @@ -382,14 +364,18 @@ export const RequestPane = memo(function RequestPane({ + updateRequest.mutate({ id: activeRequestId, update: { headers } }) + } /> + updateRequest.mutate({ id: activeRequestId, update: { urlParameters } }) + } /> @@ -440,7 +426,9 @@ export const RequestPane = memo(function RequestPane({ requestId={activeRequest.id} contentType={contentType} body={activeRequest.body} - onChange={handleBinaryFileChange} + onChange={(body) => + updateRequest.mutate({ id: activeRequestId, update: { body } }) + } onChangeContentType={handleContentTypeChange} /> ) : typeof activeRequest.bodyType === 'string' ? ( @@ -458,6 +446,26 @@ export const RequestPane = memo(function RequestPane({ Empty Body )} +
+ updateRequest.mutate({ id: activeRequestId, update: { name } })} + /> + + updateRequest.mutate({ id: activeRequestId, update: { description } }) + } + /> +
+
)} diff --git a/src-web/components/ResponsePane.tsx b/src-web/components/ResponsePane.tsx index e23f0e75..21dfedf8 100644 --- a/src-web/components/ResponsePane.tsx +++ b/src-web/components/ResponsePane.tsx @@ -38,7 +38,6 @@ interface Props { const TAB_BODY = 'body'; const TAB_HEADERS = 'headers'; const TAB_INFO = 'info'; -const DEFAULT_TAB = TAB_BODY; export const ResponsePane = memo(function ResponsePane({ style, className, activeRequest }: Props) { const { activeResponse, setPinnedResponseId, responses } = usePinnedHttpResponse(activeRequest); @@ -48,13 +47,6 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ {}, ); const contentType = useContentTypeFromHeaders(activeResponse?.headers ?? null); - const activeTab = activeTabs?.[activeRequest.id] ?? DEFAULT_TAB; - const setActiveTab = useCallback( - (tab: string) => { - setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); - }, - [activeRequest.id, setActiveTabs], - ); const tabs = useMemo( () => [ @@ -88,6 +80,13 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ ], [activeResponse?.headers, contentType, setViewMode, viewMode], ); + const activeTab = activeTabs?.[activeRequest.id]; + const setActiveTab = useCallback( + (tab: string) => { + setActiveTabs((r) => ({ ...r, [activeRequest.id]: tab })); + }, + [activeRequest.id, setActiveTabs], + ); const isLoading = isResponseLoading(activeResponse); diff --git a/src-web/components/Sidebar.tsx b/src-web/components/Sidebar.tsx index c01486d9..2ab5c68e 100644 --- a/src-web/components/Sidebar.tsx +++ b/src-web/components/Sidebar.tsx @@ -32,7 +32,6 @@ import { useHttpRequestActions } from '../hooks/useHttpRequestActions'; import { useHttpResponses } from '../hooks/useHttpResponses'; import { useKeyValue } from '../hooks/useKeyValue'; import { useMoveToWorkspace } from '../hooks/useMoveToWorkspace'; -import { usePrompt } from '../hooks/usePrompt'; import { useRenameRequest } from '../hooks/useRenameRequest'; import { useRequests } from '../hooks/useRequests'; import { useScrollIntoView } from '../hooks/useScrollIntoView'; @@ -50,10 +49,11 @@ import type { DropdownItem } from './core/Dropdown'; import { ContextMenu } from './core/Dropdown'; import { HttpMethodTag } from './core/HttpMethodTag'; import { Icon } from './core/Icon'; -import { InlineCode } from './core/InlineCode'; import { VStack } from './core/Stacks'; import { StatusTag } from './core/StatusTag'; +import { useDialog } from './DialogContext'; import { DropMarker } from './DropMarker'; +import { FolderSettingsDialog } from './FolderSettingsDialog'; interface Props { className?: string; @@ -694,6 +694,7 @@ function SidebarItem({ connectDrag(connectDrop(ref)); + const dialog = useDialog(); const activeRequest = useActiveRequest(); const deleteFolder = useDeleteFolder(itemId); const deleteRequest = useDeleteRequest(itemId); @@ -706,8 +707,6 @@ function SidebarItem({ const updateHttpRequest = useUpdateAnyHttpRequest(); const workspaces = useWorkspaces(); const updateGrpcRequest = useUpdateAnyGrpcRequest(); - const updateAnyFolder = useUpdateAnyFolder(); - const prompt = usePrompt(); const [editing, setEditing] = useState(false); const isActive = activeRequest?.id === itemId; const createDropdownItems = useCreateDropdownItems({ folderId: itemId }); @@ -786,35 +785,25 @@ function SidebarItem({ if (itemModel === 'folder') { return [ { - key: 'sendAll', + key: 'send-all', label: 'Send All', leftSlot: , onSelect: () => sendManyRequests.mutate(child.children.map((c) => c.item.id)), }, { - key: 'rename', - label: 'Rename', - leftSlot: , - onSelect: async () => { - const name = await prompt({ - id: 'rename-folder', - title: 'Rename Folder', - description: ( - <> - Enter a new name for {itemName} - - ), - confirmText: 'Save', - label: 'Name', - placeholder: 'New Name', - defaultValue: itemName, - }); - if (name == null) return; - updateAnyFolder.mutate({ id: itemId, update: (f) => ({ ...f, name }) }); - }, + key: 'folder-settings', + label: 'Settings', + leftSlot: , + onSelect: () => + dialog.show({ + id: 'folder-settings', + title: 'Folder Settings', + size: 'md', + render: () => , + }), }, { - key: 'deleteFolder', + key: 'delete-folder', label: 'Delete', variant: 'danger', leftSlot: , @@ -828,7 +817,7 @@ function SidebarItem({ itemModel === 'http_request' ? [ { - key: 'sendRequest', + key: 'send-request', label: 'Send', hotKeyAction: 'http_request.send', hotKeyLabelOnly: true, // Already bound in URL bar @@ -851,13 +840,13 @@ function SidebarItem({ return [ ...requestItems, { - key: 'renameRequest', + key: 'rename-request', label: 'Rename', leftSlot: , onSelect: renameRequest.mutate, }, { - key: 'duplicateRequest', + key: 'duplicate-request', label: 'Duplicate', hotKeyAction: 'http_request.duplicate', hotKeyLabelOnly: true, // Would trigger for every request (bad) @@ -868,14 +857,14 @@ function SidebarItem({ : duplicateGrpcRequest.mutate(), }, { - key: 'moveWorkspace', + key: 'move-workspace', label: 'Move', leftSlot: , hidden: workspaces.length <= 1, onSelect: moveToWorkspace.mutate, }, { - key: 'deleteRequest', + key: 'delete-request', variant: 'danger', label: 'Delete', leftSlot: , @@ -888,18 +877,16 @@ function SidebarItem({ createDropdownItems, deleteFolder, deleteRequest, + dialog, duplicateGrpcRequest, duplicateHttpRequest, httpRequestActions, itemId, itemModel, - itemName, moveToWorkspace.mutate, - prompt, renameRequest.mutate, sendManyRequests, sendRequest, - updateAnyFolder, workspaces.length, ]); diff --git a/src-web/components/UrlBar.tsx b/src-web/components/UrlBar.tsx index 829f68c3..20104e60 100644 --- a/src-web/components/UrlBar.tsx +++ b/src-web/components/UrlBar.tsx @@ -66,7 +66,7 @@ export const UrlBar = memo(function UrlBar({ +
+ +
) } rightSlot={ <> {rightSlot} {submitIcon !== null && ( - +
+ +
)} } diff --git a/src-web/components/WorkpaceSettingsDialog.tsx b/src-web/components/WorkpaceSettingsDialog.tsx new file mode 100644 index 00000000..dfabaebb --- /dev/null +++ b/src-web/components/WorkpaceSettingsDialog.tsx @@ -0,0 +1,39 @@ +import { useUpdateWorkspace } from '../hooks/useUpdateWorkspace'; +import { useWorkspaces } from '../hooks/useWorkspaces'; +import { Banner } from './core/Banner'; +import { PlainInput } from './core/PlainInput'; +import { VStack } from './core/Stacks'; +import { MarkdownEditor } from './MarkdownEditor'; + +interface Props { + workspaceId: string | null; +} + +export function WorkspaceSettingsDialog({ workspaceId }: Props) { + const updateWorkspace = useUpdateWorkspace(workspaceId ?? null); + const workspaces = useWorkspaces(); + const workspace = workspaces.find((w) => w.id === workspaceId); + + if (workspace == null) return null; + + return ( + + {updateWorkspace.error != null && ( + {String(updateWorkspace.error)} + )} + updateWorkspace.mutate({ name })} + /> + + updateWorkspace.mutate({ description })} + /> + + ); +} diff --git a/src-web/components/Workspace.tsx b/src-web/components/Workspace.tsx index 57f338e4..df320c63 100644 --- a/src-web/components/Workspace.tsx +++ b/src-web/components/Workspace.tsx @@ -2,7 +2,6 @@ import classNames from 'classnames'; import { motion } from 'framer-motion'; import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react'; import { useCallback, useMemo, useRef, useState } from 'react'; -import { useWindowSize } from 'react-use'; import { useActiveRequest } from '../hooks/useActiveRequest'; import { useActiveWorkspace } from '../hooks/useActiveWorkspace'; import { useFloatingSidebarHidden } from '../hooks/useFloatingSidebarHidden'; @@ -34,13 +33,13 @@ const drag = { gridArea: 'drag' }; export default function Workspace() { useSyncWorkspaceRequestTitle(); + const workspaces = useWorkspaces(); const activeWorkspace = useActiveWorkspace(); const { setWidth, width, resetWidth } = useSidebarWidth(); const [sidebarHidden, setSidebarHidden] = useSidebarHidden(); const [floatingSidebarHidden, setFloatingSidebarHidden] = useFloatingSidebarHidden(); const activeRequest = useActiveRequest(); - const windowSize = useWindowSize(); const importData = useImportData(); const floating = useShouldFloatSidebar(); const [isResizing, setIsResizing] = useState(false); @@ -103,14 +102,6 @@ export default function Workspace() { [sideWidth, floating], ); - if (windowSize.width <= 100) { - return ( -
- -
- ); - } - // We're loading still if (workspaces.length === 0) { return null; diff --git a/src-web/components/WorkspaceActionsDropdown.tsx b/src-web/components/WorkspaceActionsDropdown.tsx index f78730ab..576d71be 100644 --- a/src-web/components/WorkspaceActionsDropdown.tsx +++ b/src-web/components/WorkspaceActionsDropdown.tsx @@ -5,20 +5,18 @@ import { useCreateWorkspace } from '../hooks/useCreateWorkspace'; import { useDeleteSendHistory } from '../hooks/useDeleteSendHistory'; import { useDeleteWorkspace } from '../hooks/useDeleteWorkspace'; import { useOpenWorkspace } from '../hooks/useOpenWorkspace'; -import { usePrompt } from '../hooks/usePrompt'; import { useSettings } from '../hooks/useSettings'; -import { useUpdateWorkspace } from '../hooks/useUpdateWorkspace'; import { useWorkspaces } from '../hooks/useWorkspaces'; import { getWorkspace } from '../lib/store'; import type { ButtonProps } from './core/Button'; import { Button } from './core/Button'; import type { DropdownItem } from './core/Dropdown'; import { Icon } from './core/Icon'; -import { InlineCode } from './core/InlineCode'; import type { RadioDropdownItem } from './core/RadioDropdown'; import { RadioDropdown } from './core/RadioDropdown'; import { useDialog } from './DialogContext'; import { OpenWorkspaceDialog } from './OpenWorkspaceDialog'; +import { WorkspaceSettingsDialog } from './WorkpaceSettingsDialog'; type Props = Pick; @@ -29,11 +27,9 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ const workspaces = useWorkspaces(); const activeWorkspace = useActiveWorkspace(); const activeWorkspaceId = activeWorkspace?.id ?? null; - const updateWorkspace = useUpdateWorkspace(activeWorkspaceId); const deleteWorkspace = useDeleteWorkspace(activeWorkspace); const createWorkspace = useCreateWorkspace(); const dialog = useDialog(); - const prompt = usePrompt(); const settings = useSettings(); const openWorkspace = useOpenWorkspace(); const openWorkspaceNewWindow = settings?.openWorkspaceNewWindow ?? null; @@ -52,24 +48,16 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ const extraItems: DropdownItem[] = [ { - key: 'rename', - label: 'Rename', - leftSlot: , + key: 'workspace-settings', + label: 'Settings', + leftSlot: , onSelect: async () => { - const name = await prompt({ - id: 'rename-workspace', - title: 'Rename Workspace', - description: ( - <> - Enter a new name for {activeWorkspace?.name} - - ), - label: 'Name', - placeholder: 'New Name', - defaultValue: activeWorkspace?.name, + dialog.show({ + id: 'workspace-settings', + title: 'Workspace Settings', + size: 'md', + render: () => , }); - if (name == null) return; - updateWorkspace.mutate({ name }); }, }, { @@ -96,13 +84,12 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ return { workspaceItems, extraItems }; }, [ - activeWorkspace?.name, + activeWorkspace, activeWorkspaceId, createWorkspace.mutate, deleteSendHistory.mutate, deleteWorkspace.mutate, - prompt, - updateWorkspace, + dialog, workspaces, ]); diff --git a/src-web/components/WorkspaceHeader.tsx b/src-web/components/WorkspaceHeader.tsx index 45f4d97f..cf7fa074 100644 --- a/src-web/components/WorkspaceHeader.tsx +++ b/src-web/components/WorkspaceHeader.tsx @@ -45,6 +45,7 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop icon="search" title="Search or execute a command" size="sm" + event="search" onClick={togglePalette} /> diff --git a/src-web/components/core/CountBadge.tsx b/src-web/components/core/CountBadge.tsx index 95c7efd4..9f97ee22 100644 --- a/src-web/components/core/CountBadge.tsx +++ b/src-web/components/core/CountBadge.tsx @@ -1,7 +1,7 @@ import classNames from 'classnames'; interface Props { - count: number; + count: number | true; className?: string; } @@ -12,10 +12,11 @@ export function CountBadge({ count, className }: Props) { aria-hidden className={classNames( className, + 'flex items-center', 'opacity-70 border border-border-subtle text-4xs rounded mb-0.5 px-1 ml-1 h-4 font-mono', )} > - {count} + {count === true ?
: count}
); } diff --git a/src-web/components/core/Editor/Editor.css b/src-web/components/core/Editor/Editor.css index ec9a7508..5280f1c1 100644 --- a/src-web/components/core/Editor/Editor.css +++ b/src-web/components/core/Editor/Editor.css @@ -21,7 +21,7 @@ .cm-line { @apply w-full; /* Important! Ensure it spans the entire width */ - @apply w-full text-text pl-1 pr-1.5; + @apply w-full text-text px-0; } .cm-placeholder { @@ -51,7 +51,7 @@ /* Style gutters */ .cm-gutters { - @apply border-0 text-text-subtlest bg-surface; + @apply border-0 text-text-subtlest bg-surface pr-1.5; /* Not sure why, but there's a tiny gap left of the gutter that you can see text through. Move left slightly to fix that. */ @apply -left-[1px]; @@ -114,12 +114,6 @@ .cm-scroller { @apply font-mono text-editor; - /* - * Round corners or they'll stick out of the editor bounds of editor is rounded. - * Could potentially be pushed up from the editor like we do with bg color but this - * is probably fine. - */ - @apply rounded-lg; } } } diff --git a/src-web/components/core/Editor/Editor.tsx b/src-web/components/core/Editor/Editor.tsx index 454ac686..ddf90c5c 100644 --- a/src-web/components/core/Editor/Editor.tsx +++ b/src-web/components/core/Editor/Editor.tsx @@ -8,12 +8,12 @@ import classNames from 'classnames'; import { EditorView } from 'codemirror'; import type { MutableRefObject, ReactNode } from 'react'; import { - useEffect, Children, cloneElement, forwardRef, isValidElement, useCallback, + useEffect, useImperativeHandle, useMemo, useRef, @@ -45,7 +45,16 @@ export interface EditorProps { type?: 'text' | 'password'; className?: string; heightMode?: 'auto' | 'full'; - language?: 'javascript' | 'json' | 'html' | 'xml' | 'graphql' | 'url' | 'pairs' | 'text'; + language?: + | 'javascript' + | 'json' + | 'html' + | 'xml' + | 'graphql' + | 'url' + | 'pairs' + | 'text' + | 'markdown'; forceUpdateKey?: string | number; autoFocus?: boolean; autoSelect?: boolean; @@ -66,6 +75,7 @@ export interface EditorProps { autocompleteVariables?: boolean; extraExtensions?: Extension[]; actions?: ReactNode; + hideGutter?: boolean; } const emptyVariables: EnvironmentVariable[] = []; @@ -96,6 +106,7 @@ export const Editor = forwardRef(function E autocompleteVariables, actions, wrapLines, + hideGutter, }: EditorProps, ref, ) { @@ -310,6 +321,7 @@ export const Editor = forwardRef(function E container, readOnly, singleLine, + hideGutter, onChange: handleChange, onPaste: handlePaste, onPasteOverwrite: handlePasteOverwrite, @@ -374,7 +386,7 @@ export const Editor = forwardRef(function E const decoratedActions = useMemo(() => { const results = []; const actionClassName = classNames( - 'bg-surface transition-opacity opacity-0 group-hover:opacity-100 hover:!opacity-100 shadow', + 'bg-surface transition-opacity transform-gpu opacity-0 group-hover:opacity-100 hover:!opacity-100 shadow', ); if (format) { @@ -455,13 +467,14 @@ function getExtensions({ container, readOnly, singleLine, + hideGutter, onChange, onPaste, onPasteOverwrite, onFocus, onBlur, onKeyDown, -}: Pick & { +}: Pick & { container: HTMLDivElement | null; onChange: MutableRefObject; onPaste: MutableRefObject; @@ -499,7 +512,7 @@ function getExtensions({ tooltips({ parent }), keymap.of(singleLine ? defaultKeymap.filter((k) => k.key !== 'Enter') : defaultKeymap), ...(singleLine ? [singleLineExt()] : []), - ...(!singleLine ? [multiLineExtensions] : []), + ...(!singleLine ? [multiLineExtensions({ hideGutter })] : []), ...(readOnly ? [EditorState.readOnly.of(true), EditorView.contentAttributes.of({ tabindex: '-1' })] : []), diff --git a/src-web/components/core/Editor/extensions.ts b/src-web/components/core/Editor/extensions.ts index 6283405d..2d9c8947 100644 --- a/src-web/components/core/Editor/extensions.ts +++ b/src-web/components/core/Editor/extensions.ts @@ -6,6 +6,7 @@ import { } from '@codemirror/autocomplete'; import { history, historyKeymap, indentWithTab } from '@codemirror/commands'; import { javascript } from '@codemirror/lang-javascript'; +import { markdown } from '@codemirror/lang-markdown'; import { json } from '@codemirror/lang-json'; import { xml } from '@codemirror/lang-xml'; import type { LanguageSupport } from '@codemirror/language'; @@ -79,6 +80,7 @@ const syntaxExtensions: Record, LanguageSup url: url(), pairs: pairs(), text: text(), + markdown: markdown(), }; export function getLanguageExtension({ @@ -138,21 +140,25 @@ export const baseExtensions = [ keymap.of([...historyKeymap, ...completionKeymap]), ]; -export const multiLineExtensions = [ - lineNumbers(), - foldGutter({ - markerDOM: (open) => { - const el = document.createElement('div'); - el.classList.add('fold-gutter-icon'); - el.tabIndex = -1; - if (open) { - el.setAttribute('data-open', ''); - } - return el; - }, - }), +export const multiLineExtensions = ({ hideGutter }: { hideGutter?: boolean }) => [ + hideGutter + ? [] + : [ + lineNumbers(), + foldGutter({ + markerDOM: (open) => { + const el = document.createElement('div'); + el.classList.add('fold-gutter-icon'); + el.tabIndex = -1; + if (open) { + el.setAttribute('data-open', ''); + } + return el; + }, + }), + ], codeFolding({ - placeholderDOM(view, onclick, prepared) { + placeholderDOM(_view, onclick, prepared) { const el = document.createElement('span'); el.onclick = onclick; el.className = 'cm-foldPlaceholder'; diff --git a/src-web/components/core/Icon.tsx b/src-web/components/core/Icon.tsx index 6de0b20a..bd497ea5 100644 --- a/src-web/components/core/Icon.tsx +++ b/src-web/components/core/Icon.tsx @@ -30,6 +30,7 @@ const icons = { circle_alert: lucide.CircleAlertIcon, clock: lucide.ClockIcon, code: lucide.CodeIcon, + columns_2: lucide.Columns2Icon, cookie: lucide.CookieIcon, copy: lucide.CopyIcon, copy_check: lucide.CopyCheck, diff --git a/src-web/components/core/SplitLayout.tsx b/src-web/components/core/SplitLayout.tsx index 4533214a..97515c85 100644 --- a/src-web/components/core/SplitLayout.tsx +++ b/src-web/components/core/SplitLayout.tsx @@ -1,4 +1,4 @@ -import useResizeObserver from '@react-hook/resize-observer'; +import useSize from '@react-hook/size'; import classNames from 'classnames'; import type { CSSProperties, MouseEvent as ReactMouseEvent, ReactNode } from 'react'; import React, { useCallback, useMemo, useRef, useState } from 'react'; @@ -43,7 +43,6 @@ export function SplitLayout({ }: Props) { const containerRef = useRef(null); const activeWorkspace = useActiveWorkspace(); - const [verticalBasedOnSize, setVerticalBasedOnSize] = useState(false); const [widthRaw, setWidth] = useLocalStorage( `${name}_width::${activeWorkspace?.id ?? 'n/a'}`, ); @@ -62,10 +61,7 @@ export function SplitLayout({ minHeightPx = 0; } - useResizeObserver(containerRef.current, ({ contentRect }) => { - setVerticalBasedOnSize(contentRect.width < STACK_VERTICAL_WIDTH); - }); - + const verticalBasedOnSize = useSize(containerRef.current)[0] < STACK_VERTICAL_WIDTH; const vertical = layout !== 'horizontal' && (layout === 'vertical' || verticalBasedOnSize); const styles = useMemo(() => { diff --git a/src-web/components/core/Tabs/Tabs.tsx b/src-web/components/core/Tabs/Tabs.tsx index 870e439f..9d6dcc6b 100644 --- a/src-web/components/core/Tabs/Tabs.tsx +++ b/src-web/components/core/Tabs/Tabs.tsx @@ -40,6 +40,8 @@ export function Tabs({ }: Props) { const ref = useRef(null); + value = value ?? tabs[0]?.value; + // Update tabs when value changes useEffect(() => { const tabs = ref.current?.querySelectorAll(`[data-tab]`); @@ -61,7 +63,7 @@ export function Tabs({ return (
(null); - const [containerWidth, setContainerWidth] = useDebouncedState(0, 100); const [numPages, setNumPages] = useState(); - useResizeObserver(containerRef.current ?? null, (v) => { - setContainerWidth(v.contentRect.width); - }); + const [containerWidth] = useSize(containerRef.current); const onDocumentLoadSuccess = ({ numPages: nextNumPages }: PDFDocumentProxy): void => { setNumPages(nextNumPages); diff --git a/src-web/lib/theme/window.ts b/src-web/lib/theme/window.ts index e22e076b..596fd03e 100644 --- a/src-web/lib/theme/window.ts +++ b/src-web/lib/theme/window.ts @@ -69,7 +69,7 @@ function themeVariables(theme?: Partial, base?: CSSVariables): CSSVa theme?.shadow ?? YaakColor.black().translucify(isThemeDark(theme ?? ({} as Partial)) ? 0.7 : 0.93), primary: theme?.primary, - secondary: theme?.primary, + secondary: theme?.secondary, info: theme?.info, success: theme?.success, notice: theme?.notice, diff --git a/src-web/package.json b/src-web/package.json index 16b60eb7..3ebdbd55 100644 --- a/src-web/package.json +++ b/src-web/package.json @@ -12,12 +12,13 @@ "@codemirror/commands": "6.7.0", "@codemirror/lang-javascript": "^6.2.2", "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-markdown": "^6.3.1", "@codemirror/lang-xml": "^6.0.2", "@codemirror/language": "^6.6.0", "@codemirror/search": "^6.2.3", "@lezer/highlight": "^1.1.3", "@lezer/lr": "^1.3.3", - "@react-hook/resize-observer": "^2.0.2", + "@react-hook/size": "^2.1.2", "@tailwindcss/container-queries": "^0.1.1", "@tanstack/react-query": "^5.59.16", "@tanstack/react-virtual": "^3.10.8", @@ -49,9 +50,11 @@ "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", "react-helmet-async": "^2.0.5", + "react-markdown": "^9.0.1", "react-pdf": "^9.1.0", "react-router-dom": "^6.26.2", "react-use": "^17.5.1", + "remark-gfm": "^4.0.0", "slugify": "^1.6.6", "uuid": "^10.0.0", "whatwg-mimetype": "^4.0.0", diff --git a/src-web/tailwind.config.cjs b/src-web/tailwind.config.cjs index 277096a0..ee846525 100644 --- a/src-web/tailwind.config.cjs +++ b/src-web/tailwind.config.cjs @@ -4,7 +4,7 @@ const sizes = { '2xs': '1.4rem', xs: '1.8rem', sm: '2.0rem', - md: '2.5rem', + md: '2.3rem', }; /** @type {import("tailwindcss").Config} */