diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 4a35a0b724f7..421689e0c5b5 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -1034,7 +1034,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.0.6.tgz", "integrity": "sha512-yktiFZoWPtEW8QKS65eqKwA5MTKp88CyiL8q72WynrBs/73SAaxlSWlA2zW/DZlywZ5hX1OYzrCC0wFdvO9c2w==", - "dev": true, "license": "MIT", "dependencies": { "@jsdevtools/ono": "^7.1.3", @@ -1050,10 +1049,9 @@ } }, "node_modules/@hey-api/openapi-ts": { - "version": "0.71.1", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.71.1.tgz", - "integrity": "sha512-LZhHH1CngE2vRgMdZGRI4UrxJ/JHvcsAy4Qjsbiu9BGWyZIraIqWLMsQgqB3TU5yJTrblFo9DA7RI5LIUol0yg==", - "dev": true, + "version": "0.81.1", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.81.1.tgz", + "integrity": "sha512-DdLEMbfQRMRDd+cOxG91G7Ro7vUUtt/zYlBGiYTahVO/4rn1HHnYl/WHL+to5I7CTX3sVVsVrxHWcJd0Fue7wg==", "license": "MIT", "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", @@ -1061,7 +1059,10 @@ "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", - "handlebars": "4.7.8" + "handlebars": "4.7.8", + "js-yaml": "4.1.0", + "open": "10.1.2", + "semver": "7.7.2" }, "bin": { "openapi-ts": "bin/index.cjs" @@ -1076,6 +1077,63 @@ "typescript": "^5.5.3" } }, + "node_modules/@hey-api/openapi-ts/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hey-api/openapi-ts/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hey-api/openapi-ts/node_modules/open": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", + "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@hey-api/openapi-ts/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1214,7 +1272,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true, "license": "MIT" }, "node_modules/@lit-labs/ssr-dom-shim": { @@ -2985,7 +3042,6 @@ "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, "license": "MIT" }, "node_modules/@types/json5": { @@ -5081,7 +5137,6 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -5144,7 +5199,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5768,6 +5822,21 @@ "node": "*" } }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -5782,7 +5851,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz", "integrity": "sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==", - "dev": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.1", @@ -6031,7 +6099,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, "license": "MIT", "dependencies": { "readdirp": "^4.0.1" @@ -6047,7 +6114,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -6090,7 +6156,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", - "dev": true, "license": "MIT", "dependencies": { "consola": "^3.2.3" @@ -6227,7 +6292,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, "license": "ISC", "bin": { "color-support": "bin.js" @@ -6295,7 +6359,6 @@ "version": "13.0.0", "resolved": "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz", "integrity": "sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6329,14 +6392,12 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, "license": "MIT" }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "dev": true, "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" @@ -6782,6 +6843,34 @@ "node": ">=0.10.0" } }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/default-gateway": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", @@ -6868,7 +6957,6 @@ "version": "6.1.4", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "dev": true, "license": "MIT" }, "node_modules/degenerator": { @@ -6956,7 +7044,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "dev": true, "license": "MIT" }, "node_modules/destroy": { @@ -7247,7 +7334,6 @@ "version": "16.6.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -8452,7 +8538,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, "license": "ISC", "dependencies": { "minipass": "^3.0.0" @@ -8465,7 +8550,6 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -8478,7 +8562,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, "license": "ISC" }, "node_modules/fs.realpath": { @@ -8687,7 +8770,6 @@ "version": "1.2.5", "resolved": "https://registry.npmjs.org/giget/-/giget-1.2.5.tgz", "integrity": "sha512-r1ekGw/Bgpi3HLV3h1MRBIlSAdHoIMklpaQ3OQLFcRw9PwAj2rqigvIbg+dBUI51OxVI2jsEtDywDBjSiuf7Ug==", - "dev": true, "license": "MIT", "dependencies": { "citty": "^0.1.6", @@ -8706,7 +8788,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/glob": { @@ -8866,7 +8947,6 @@ "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, "license": "MIT", "dependencies": { "minimist": "^1.2.5", @@ -8888,7 +8968,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -9538,6 +9617,39 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container/node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-interactive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", @@ -9952,7 +10064,6 @@ "version": "2.5.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", - "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -9986,7 +10097,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -10314,7 +10424,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, "license": "MIT" }, "node_modules/lodash.camelcase": { @@ -11493,7 +11602,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -11503,7 +11611,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, "license": "ISC", "engines": { "node": ">=8" @@ -11513,7 +11620,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, "license": "MIT", "dependencies": { "minipass": "^3.0.0", @@ -11527,7 +11633,6 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -11540,7 +11645,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, "license": "ISC" }, "node_modules/mitt": { @@ -11554,7 +11658,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" @@ -11567,7 +11670,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", - "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.14.0", @@ -11580,7 +11682,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/module-definition": { @@ -11821,7 +11922,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, "license": "MIT" }, "node_modules/netmask": { @@ -11858,7 +11958,6 @@ "version": "1.6.7", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", - "dev": true, "license": "MIT" }, "node_modules/node-fetch/node_modules/tr46": { @@ -11943,7 +12042,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.5.4.tgz", "integrity": "sha512-X0SNNrZiGU8/e/zAB7sCTtdxWTMSIO73q+xuKgglm2Yvzwlo8UoC5FNySQFCvl84uPaeADkqHUZUkWy4aH4xOA==", - "dev": true, "license": "MIT", "dependencies": { "citty": "^0.1.6", @@ -11964,7 +12062,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/object-inspect": { @@ -12068,7 +12165,6 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.6.tgz", "integrity": "sha512-TBu7PtV8YkAZn0tSxobKY2n2aAQva936lhRrj6957aDaCf9IEtqsKbgMzXE/F/sjqYOwmrukeORHNLe5glk7Cg==", - "dev": true, "license": "MIT" }, "node_modules/on-finished": { @@ -12457,7 +12553,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, "license": "MIT" }, "node_modules/pathval": { @@ -12481,7 +12576,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "dev": true, "license": "MIT" }, "node_modules/picocolors": { @@ -12518,7 +12612,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.1.8", @@ -12530,7 +12623,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, "license": "MIT" }, "node_modules/playwright": { @@ -13954,7 +14046,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", - "dev": true, "license": "MIT", "dependencies": { "defu": "^6.1.4", @@ -14013,7 +14104,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 14.18.0" @@ -14393,6 +14483,18 @@ "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", "license": "MIT" }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -15318,7 +15420,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, "license": "ISC", "dependencies": { "chownr": "^2.0.0", @@ -15363,7 +15464,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, "license": "ISC" }, "node_modules/text-decoder": { @@ -15412,7 +15512,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, "license": "MIT" }, "node_modules/tinyglobby": { @@ -16086,14 +16185,12 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "dev": true, "license": "MIT" }, "node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, "license": "BSD-2-Clause", "optional": true, "bin": { @@ -16803,7 +16900,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, "license": "MIT" }, "node_modules/wordwrapjs": { @@ -17070,23 +17166,10 @@ "src/packages/core": { "name": "@umbraco-backoffice/core", "dependencies": { - "@hey-api/client-fetch": "^0.12.0", + "@hey-api/openapi-ts": "0.81.1", "@types/diff": "^7.0.2", "diff": "^7.0.0", "uuid": "^11.1.0" - }, - "devDependencies": { - "@hey-api/openapi-ts": "^0.71.0" - } - }, - "src/packages/core/node_modules/@hey-api/client-fetch": { - "version": "0.12.0", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/hey-api" - }, - "peerDependencies": { - "@hey-api/openapi-ts": "< 2" } }, "src/packages/core/node_modules/diff": { diff --git a/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts b/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts index b638c1d94eb6..500922d9abfa 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/installer/installer.context.ts @@ -1,8 +1,5 @@ import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; -import type { - InstallSettingsResponseModel, - InstallRequestModelReadable, -} from '@umbraco-cms/backoffice/external/backend-api'; +import type { InstallSettingsResponseModel, InstallRequestModel } from '@umbraco-cms/backoffice/external/backend-api'; import { InstallService, TelemetryLevelModel } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecute, UmbApiError, type UmbProblemDetails } from '@umbraco-cms/backoffice/resources'; import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; @@ -15,7 +12,7 @@ import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; * @class UmbInstallerContext */ export class UmbInstallerContext extends UmbContextBase { - private _data = new UmbObjectState({ + private _data = new UmbObjectState({ user: { name: '', email: '', password: '', subscribeToNewsletter: false }, database: { id: '', providerName: '', useIntegratedAuthentication: false, trustServerCertificate: false }, telemetryLevel: TelemetryLevelModel.DETAILED, @@ -90,7 +87,7 @@ export class UmbInstallerContext extends UmbContextBase { * @param {Partial} data The data to set * @memberof UmbInstallerContext */ - public appendData(data: Partial): void { + public appendData(data: Partial): void { this._data.setValue({ ...this.getData(), ...data }); } @@ -100,7 +97,7 @@ export class UmbInstallerContext extends UmbContextBase { * @returns {*} {PostInstallRequest} * @memberof UmbInstallerContext */ - public getData(): InstallRequestModelReadable { + public getData(): InstallRequestModel { return this._data.getValue(); } diff --git a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts index 21fc60d6db91..8ea5de214722 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader-view.element.ts @@ -1,6 +1,6 @@ import type { CSSResultGroup } from '@umbraco-cms/backoffice/external/lit'; import { css, html, LitElement, customElement, property, ifDefined } from '@umbraco-cms/backoffice/external/lit'; -import type { UpgradeSettingsResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; /** * @element umb-upgrader-view @@ -18,7 +18,7 @@ export class UmbUpgraderViewElement extends LitElement { errorMessage = ''; @property({ type: Object, reflect: true }) - settings?: UpgradeSettingsResponseModelReadable; + settings?: UpgradeSettingsResponseModel; private _renderLayout() { return html` diff --git a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts index fa1b105c484c..5107af5c8d80 100644 --- a/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts +++ b/src/Umbraco.Web.UI.Client/src/apps/upgrader/upgrader.element.ts @@ -1,5 +1,5 @@ import { html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; -import type { UpgradeSettingsResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UpgradeService } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecute, UmbApiError } from '@umbraco-cms/backoffice/resources'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -13,7 +13,7 @@ import './upgrader-view.element.js'; @customElement('umb-upgrader') export class UmbUpgraderElement extends UmbLitElement { @state() - private _upgradeSettings?: UpgradeSettingsResponseModelReadable; + private _upgradeSettings?: UpgradeSettingsResponseModel; @state() private _fetching = true; diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts index 4c04edc1ea08..d63908540775 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/examine.data.ts @@ -1,7 +1,7 @@ import type { IndexResponseModel, PagedIndexResponseModel, - SearchResultResponseModelReadable, + SearchResultResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; import { HealthStatusModel } from '@umbraco-cms/backoffice/external/backend-api'; @@ -19,7 +19,7 @@ export function getIndexByName(indexName: string) { /** * */ -export function getSearchResultsMockData(): SearchResultResponseModelReadable[] { +export function getSearchResultsMockData(): SearchResultResponseModel[] { return searchResultMockData; } @@ -91,7 +91,7 @@ export const PagedIndexers: PagedIndexResponseModel = { total: 0, }; -export const searchResultMockData: SearchResultResponseModelReadable[] = [ +export const searchResultMockData: SearchResultResponseModel[] = [ { id: '1', score: 1, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts index be5d35b4604d..11a9228118fe 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.data.ts @@ -1,9 +1,6 @@ -import type { - RelationResponseModelReadable, - RelationReferenceModel, -} from '@umbraco-cms/backoffice/external/backend-api'; +import type { RelationResponseModel, RelationReferenceModel } from '@umbraco-cms/backoffice/external/backend-api'; -export type UmbMockRelationModel = RelationResponseModelReadable; +export type UmbMockRelationModel = RelationResponseModel; export type UmbMockRelationReferenceModel = RelationReferenceModel; export const data: Array = [ diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts index d885a524af3c..122b1506cbac 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/relation/relation.db.ts @@ -2,7 +2,7 @@ import { UmbMockEntityDetailManager } from '../utils/entity/entity-detail.manage import { UmbEntityMockDbBase } from '../utils/entity/entity-base.js'; import type { UmbMockRelationModel } from './relation.data.js'; import { data } from './relation.data.js'; -import type { RelationResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { RelationResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; class UmbRelationMockDB extends UmbEntityMockDbBase { item = new UmbMockEntityDetailManager(this, itemResponseMapper, createDetailMockMapper); @@ -16,7 +16,7 @@ const createDetailMockMapper = (): UmbMockRelationModel => { throw new Error('Not possible to create a relation'); }; -const itemResponseMapper = (item: UmbMockRelationModel): RelationResponseModelReadable => { +const itemResponseMapper = (item: UmbMockRelationModel): RelationResponseModel => { return { id: item.id, child: item.child, diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts index feb5d83ac5f3..51fca662e2e3 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/examine-management.handlers.ts @@ -6,7 +6,7 @@ import type { IndexResponseModel, PagedIndexResponseModel, PagedSearcherResponseModel, - PagedSearchResultResponseModelReadable, + PagedSearchResultResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; export const handlers = [ @@ -65,7 +65,7 @@ export const handlers = [ if (searcherName) { return res( ctx.status(200), - ctx.json({ + ctx.json({ total: 0, items: searchResultMockData, }), diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts index 01b96ab3aa8b..8a259c12f40d 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/install.handlers.ts @@ -1,7 +1,7 @@ const { rest } = window.MockServiceWorker; import type { DatabaseInstallRequestModel, - InstallRequestModelReadable, + InstallRequestModel, InstallSettingsResponseModel, ProblemDetails, } from '@umbraco-cms/backoffice/external/backend-api'; @@ -99,7 +99,7 @@ export const handlers = [ }), rest.post(umbracoPath('/install/setup'), async (req, res, ctx) => { - const body = await req.json(); + const body = await req.json(); if (body.database?.name === 'fail') { return res( diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts index a58cb2b86a7e..144a1f38488b 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/package.handlers.ts @@ -6,8 +6,8 @@ import type { PagedPackageMigrationStatusResponseModel, CreatePackageRequestModel, GetPackageConfigurationResponse, - PagedPackageDefinitionResponseModelReadable, - PackageDefinitionResponseModelReadable, + PagedPackageDefinitionResponseModel, + PackageDefinitionResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; export const handlers = [ @@ -55,7 +55,7 @@ export const handlers = [ // read all return res( ctx.status(200), - ctx.json({ + ctx.json({ total: packageArray.length, items: packageArray, }), @@ -65,9 +65,9 @@ export const handlers = [ rest.post(umbracoPath('/package/created'), async (_req, res, ctx) => { //save const data: CreatePackageRequestModel = await _req.json(); - const newPackage: PackageDefinitionResponseModelReadable = { ...data, id: UmbId.new(), packagePath: '' }; + const newPackage: PackageDefinitionResponseModel = { ...data, id: UmbId.new(), packagePath: '' }; packageArray.push(newPackage); - return res(ctx.status(200), ctx.json(newPackage)); + return res(ctx.status(200), ctx.json(newPackage)); }), rest.get(umbracoPath('/package/created/:id'), (_req, res, ctx) => { @@ -76,12 +76,12 @@ export const handlers = [ if (!id) return res(ctx.status(404)); const found = packageArray.find((p) => p.id == id); if (!found) return res(ctx.status(404)); - return res(ctx.status(200), ctx.json(found)); + return res(ctx.status(200), ctx.json(found)); }), rest.put(umbracoPath('/package/created/:id'), async (_req, res, ctx) => { //update - const data: PackageDefinitionResponseModelReadable = await _req.json(); + const data: PackageDefinitionResponseModel = await _req.json(); if (!data.id) return; const index = packageArray.findIndex((x) => x.id === data.id); packageArray[index] = data; @@ -104,7 +104,7 @@ export const handlers = [ }), ]; -const packageArray: PackageDefinitionResponseModelReadable[] = [ +const packageArray: PackageDefinitionResponseModel[] = [ { id: '2a0181ec-244b-4068-a1d7-2f95ed7e6da6', packagePath: '', diff --git a/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts b/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts index 61031c5ae793..6c733ed23fab 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/handlers/upgrade.handlers.ts @@ -1,14 +1,14 @@ const { rest } = window.MockServiceWorker; import { umbracoPath } from '@umbraco-cms/backoffice/utils'; -import type { UpgradeSettingsResponseModelReadable } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UpgradeSettingsResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; export const handlers = [ rest.get(umbracoPath('/upgrade/settings'), (_req, res, ctx) => { return res( // Respond with a 200 status code ctx.status(200), - ctx.json({ + ctx.json({ currentState: '2b20c6e7', newState: '2b20c6e8', oldVersion: '13.0.0', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts index fd97b4b69e6c..ee0c0bd98e9b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import type { ClientOptions } from './types.gen'; -import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from '@hey-api/client-fetch'; +import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from './client'; /** * The `createClientConfig()` function will be called on client initialization diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/client.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/client.gen.ts new file mode 100644 index 000000000000..0c60a9ab77ec --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/client.gen.ts @@ -0,0 +1,240 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import type { + Client, + Config, + RequestOptions, + ResolvedRequestOptions, +} from './types.gen'; +import { + buildUrl, + createConfig, + createInterceptors, + getParseAs, + mergeConfigs, + mergeHeaders, + setAuthParams, +} from './utils.gen'; + +type ReqInit = Omit & { + body?: any; + headers: ReturnType; +}; + +export const createClient = (config: Config = {}): Client => { + let _config = mergeConfigs(createConfig(), config); + + const getConfig = (): Config => ({ ..._config }); + + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + return getConfig(); + }; + + const interceptors = createInterceptors< + Request, + Response, + unknown, + ResolvedRequestOptions + >(); + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, + headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined, + }; + + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); + } + + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body && opts.bodySerializer) { + opts.serializedBody = opts.bodySerializer(opts.body); + } + + // remove Content-Type header if body is empty to avoid sending invalid requests + if (opts.serializedBody === undefined || opts.serializedBody === '') { + opts.headers.delete('Content-Type'); + } + + const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + const requestInit: ReqInit = { + redirect: 'follow', + ...opts, + body: opts.serializedBody, + }; + + let request = new Request(url, requestInit); + + for (const fn of interceptors.request._fns) { + if (fn) { + request = await fn(request, opts); + } + } + + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = opts.fetch!; + let response = await _fetch(request); + + for (const fn of interceptors.response._fns) { + if (fn) { + response = await fn(response, request, opts); + } + } + + const result = { + request, + response, + }; + + if (response.ok) { + if ( + response.status === 204 || + response.headers.get('Content-Length') === '0' + ) { + return opts.responseStyle === 'data' + ? {} + : { + data: {}, + ...result, + }; + } + + const parseAs = + (opts.parseAs === 'auto' + ? getParseAs(response.headers.get('Content-Type')) + : opts.parseAs) ?? 'json'; + + let data: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'formData': + case 'json': + case 'text': + data = await response[parseAs](); + break; + case 'stream': + return opts.responseStyle === 'data' + ? response.body + : { + data: response.body, + ...result, + }; + } + + if (parseAs === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return opts.responseStyle === 'data' + ? data + : { + data, + ...result, + }; + } + + const textError = await response.text(); + let jsonError: unknown; + + try { + jsonError = JSON.parse(textError); + } catch { + // noop + } + + const error = jsonError ?? textError; + let finalError = error; + + for (const fn of interceptors.error._fns) { + if (fn) { + finalError = (await fn(error, response, request, opts)) as string; + } + } + + finalError = finalError || ({} as string); + + if (opts.throwOnError) { + throw finalError; + } + + // TODO: we probably want to return error and improve types + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + ...result, + }; + }; + + const makeMethodFn = + (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = + (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + url, + }); + }; + + return { + buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + interceptors, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/index.ts new file mode 100644 index 000000000000..318a84b6a800 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/index.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from '../core/auth.gen'; +export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from '../core/bodySerializer.gen'; +export { buildClientParams } from '../core/params.gen'; +export { createClient } from './client.gen'; +export type { + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + OptionsLegacyParser, + RequestOptions, + RequestResult, + ResolvedRequestOptions, + ResponseStyle, + TDataShape, +} from './types.gen'; +export { createConfig, mergeHeaders } from './utils.gen'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/types.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/types.gen.ts new file mode 100644 index 000000000000..5bde93851e76 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/types.gen.ts @@ -0,0 +1,268 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; +import type { + Client as CoreClient, + Config as CoreConfig, +} from '../core/types.gen'; +import type { Middleware } from './utils.gen'; + +export type ResponseStyle = 'data' | 'fields'; + +export interface Config + extends Omit, + CoreConfig { + /** + * Base URL for all requests made by this client. + */ + baseUrl?: T['baseUrl']; + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: (request: Request) => ReturnType; + /** + * Please don't use the Fetch client for Next.js applications. The `next` + * options won't have any effect. + * + * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. + */ + next?: never; + /** + * Return the response data parsed in a specified format. By default, `auto` + * will infer the appropriate method from the `Content-Type` response header. + * You can override this behavior with any of the {@link Body} methods. + * Select `stream` if you don't want to parse response data at all. + * + * @default 'auto' + */ + parseAs?: + | 'arrayBuffer' + | 'auto' + | 'blob' + | 'formData' + | 'json' + | 'stream' + | 'text'; + /** + * Should we return only data or multiple fields (data, error, response, etc.)? + * + * @default 'fields' + */ + responseStyle?: ResponseStyle; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; +} + +export interface RequestOptions< + TData = unknown, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends Config<{ + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record; + query?: Record; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; +} + +export interface ResolvedRequestOptions< + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends RequestOptions { + serializedBody?: string; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = ThrowOnError extends true + ? Promise< + TResponseStyle extends 'data' + ? TData extends Record + ? TData[keyof TData] + : TData + : { + data: TData extends Record + ? TData[keyof TData] + : TData; + request: Request; + response: Response; + } + > + : Promise< + TResponseStyle extends 'data' + ? + | (TData extends Record + ? TData[keyof TData] + : TData) + | undefined + : ( + | { + data: TData extends Record + ? TData[keyof TData] + : TData; + error: undefined; + } + | { + data: undefined; + error: TError extends Record + ? TError[keyof TError] + : TError; + } + ) & { + request: Request; + response: Response; + } + >; + +export interface ClientOptions { + baseUrl?: string; + responseStyle?: ResponseStyle; + throwOnError?: boolean; +} + +type MethodFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => RequestResult; + +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + +type RequestFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'> & + Pick< + Required>, + 'method' + >, +) => RequestResult; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + }, +>( + options: Pick & Options, +) => string; + +export type Client = CoreClient< + RequestFn, + Config, + MethodFn, + BuildUrlFn, + SseFn +> & { + interceptors: Middleware; +}; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = ( + override?: Config, +) => Config & T>; + +export interface TDataShape { + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; +} + +type OmitKeys = Pick>; + +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, + TResponseStyle extends ResponseStyle = 'fields', +> = OmitKeys< + RequestOptions, + 'body' | 'path' | 'query' | 'url' +> & + Omit; + +export type OptionsLegacyParser< + TData = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'body' | 'headers' | 'url' + > & + TData + : OmitKeys< + RequestOptions, + 'body' | 'url' + > & + TData & + Pick, 'headers'> + : TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'headers' | 'url' + > & + TData & + Pick, 'body'> + : OmitKeys, 'url'> & + TData; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/utils.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/utils.gen.ts new file mode 100644 index 000000000000..a47509522bc5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/client/utils.gen.ts @@ -0,0 +1,327 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { getAuthToken } from '../core/auth.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +import { jsonBodySerializer } from '../core/bodySerializer.gen'; +import { + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; +import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; + +export const createQuerySerializer = ({ + allowReserved, + array, + object, +}: QuerySerializerOptions = {}) => { + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved, + explode: true, + name, + style: 'form', + value, + ...array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record, + ...object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } + } + return search.join('&'); + }; + return querySerializer; +}; + +/** + * Infers parseAs value from provided Content-Type header. + */ +export const getParseAs = ( + contentType: string | null, +): Exclude => { + if (!contentType) { + // If no Content-Type header is provided, the best we can do is return the raw response body, + // which is effectively the same as the 'stream' option. + return 'stream'; + } + + const cleanContent = contentType.split(';')[0]?.trim(); + + if (!cleanContent) { + return; + } + + if ( + cleanContent.startsWith('application/json') || + cleanContent.endsWith('+json') + ) { + return 'json'; + } + + if (cleanContent === 'multipart/form-data') { + return 'formData'; + } + + if ( + ['application/', 'audio/', 'image/', 'video/'].some((type) => + cleanContent.startsWith(type), + ) + ) { + return 'blob'; + } + + if (cleanContent.startsWith('text/')) { + return 'text'; + } + + return; +}; + +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + +export const setAuthParams = async ({ + security, + ...options +}: Pick, 'security'> & + Pick & { + headers: Headers; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + + const token = await getAuthToken(auth, options.auth); + + if (!token) { + continue; + } + + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': + options.headers.append('Cookie', `${name}=${token}`); + break; + case 'header': + default: + options.headers.set(name, token); + break; + } + } +}; + +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ + baseUrl: options.baseUrl as string, + path: options.path, + query: options.query, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); + +export const mergeConfigs = (a: Config, b: Config): Config => { + const config = { ...a, ...b }; + if (config.baseUrl?.endsWith('/')) { + config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); + } + config.headers = mergeHeaders(a.headers, b.headers); + return config; +}; + +export const mergeHeaders = ( + ...headers: Array['headers'] | undefined> +): Headers => { + const mergedHeaders = new Headers(); + for (const header of headers) { + if (!header || typeof header !== 'object') { + continue; + } + + const iterator = + header instanceof Headers ? header.entries() : Object.entries(header); + + for (const [key, value] of iterator) { + if (value === null) { + mergedHeaders.delete(key); + } else if (Array.isArray(value)) { + for (const v of value) { + mergedHeaders.append(key, v as string); + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders.set( + key, + typeof value === 'object' ? JSON.stringify(value) : (value as string), + ); + } + } + } + return mergedHeaders; +}; + +type ErrInterceptor = ( + error: Err, + response: Res, + request: Req, + options: Options, +) => Err | Promise; + +type ReqInterceptor = ( + request: Req, + options: Options, +) => Req | Promise; + +type ResInterceptor = ( + response: Res, + request: Req, + options: Options, +) => Res | Promise; + +class Interceptors { + _fns: (Interceptor | null)[]; + + constructor() { + this._fns = []; + } + + clear() { + this._fns = []; + } + + getInterceptorIndex(id: number | Interceptor): number { + if (typeof id === 'number') { + return this._fns[id] ? id : -1; + } else { + return this._fns.indexOf(id); + } + } + exists(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + return !!this._fns[index]; + } + + eject(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = null; + } + } + + update(id: number | Interceptor, fn: Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = fn; + return id; + } else { + return false; + } + } + + use(fn: Interceptor) { + this._fns = [...this._fns, fn]; + return this._fns.length - 1; + } +} + +// `createInterceptors()` response, meant for external use as it does not +// expose internals +export interface Middleware { + error: Pick< + Interceptors>, + 'eject' | 'use' + >; + request: Pick>, 'eject' | 'use'>; + response: Pick< + Interceptors>, + 'eject' | 'use' + >; +} + +// do not add `Middleware` as return type so we can use _fns internally +export const createInterceptors = () => ({ + error: new Interceptors>(), + request: new Interceptors>(), + response: new Interceptors>(), +}); + +const defaultQuerySerializer = createQuerySerializer({ + allowReserved: false, + array: { + explode: true, + style: 'form', + }, + object: { + explode: true, + style: 'deepObject', + }, +}); + +const defaultHeaders = { + 'Content-Type': 'application/json', +}; + +export const createConfig = ( + override: Config & T> = {}, +): Config & T> => ({ + ...jsonBodySerializer, + headers: defaultHeaders, + parseAs: 'auto', + querySerializer: defaultQuerySerializer, + ...override, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/auth.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/auth.gen.ts new file mode 100644 index 000000000000..f8a73266f934 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/auth.gen.ts @@ -0,0 +1,42 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AuthToken = string | undefined; + +export interface Auth { + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; +} + +export const getAuthToken = async ( + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, +): Promise => { + const token = + typeof callback === 'function' ? await callback(auth) : callback; + + if (!token) { + return; + } + + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } + + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } + + return token; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/bodySerializer.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/bodySerializer.gen.ts new file mode 100644 index 000000000000..49cd8925e3bd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/bodySerializer.gen.ts @@ -0,0 +1,92 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { + ArrayStyle, + ObjectStyle, + SerializerOptions, +} from './pathSerializer.gen'; + +export type QuerySerializer = (query: Record) => string; + +export type BodySerializer = (body: any) => any; + +export interface QuerySerializerOptions { + allowReserved?: boolean; + array?: SerializerOptions; + object?: SerializerOptions; +} + +const serializeFormDataPair = ( + data: FormData, + key: string, + value: unknown, +): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +const serializeUrlSearchParamsPair = ( + data: URLSearchParams, + key: string, + value: unknown, +): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +export const formDataBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): FormData => { + const data = new FormData(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); + + return data; + }, +}; + +export const jsonBodySerializer = { + bodySerializer: (body: T): string => + JSON.stringify(body, (_key, value) => + typeof value === 'bigint' ? value.toString() : value, + ), +}; + +export const urlSearchParamsBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): string => { + const data = new URLSearchParams(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); + + return data.toString(); + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/params.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/params.gen.ts new file mode 100644 index 000000000000..71c88e852b72 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/params.gen.ts @@ -0,0 +1,153 @@ +// This file is auto-generated by @hey-api/openapi-ts + +type Slot = 'body' | 'headers' | 'path' | 'query'; + +export type Field = + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + }; + +export interface Fields { + allowExtra?: Partial>; + args?: ReadonlyArray; +} + +export type FieldsConfig = ReadonlyArray; + +const extraPrefixesMap: Record = { + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query', +}; +const extraPrefixes = Object.entries(extraPrefixesMap); + +type KeyMap = Map< + string, + { + in: Slot; + map?: string; + } +>; + +const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; +}; + +interface Params { + body: unknown; + headers: Record; + path: Record; + query: Record; +} + +const stripEmptySlots = (params: Params) => { + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === 'object' && !Object.keys(value).length) { + delete params[slot as Slot]; + } + } +}; + +export const buildClientParams = ( + args: ReadonlyArray, + fields: FieldsConfig, +) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; + + const map = buildKeyMap(fields); + + let config: FieldsConfig[number] | undefined; + + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + (params[field.in] as Record)[name] = arg; + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + const name = field.map || key; + (params[field.in] as Record)[name] = value; + } else { + const extra = extraPrefixes.find(([prefix]) => + key.startsWith(prefix), + ); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[ + key.slice(prefix.length) + ] = value; + } else { + for (const [slot, allowed] of Object.entries( + config.allowExtra ?? {}, + )) { + if (allowed) { + (params[slot as Slot] as Record)[key] = value; + break; + } + } + } + } + } + } + } + + stripEmptySlots(params); + + return params; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/pathSerializer.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/pathSerializer.gen.ts new file mode 100644 index 000000000000..8d9993104743 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/pathSerializer.gen.ts @@ -0,0 +1,181 @@ +// This file is auto-generated by @hey-api/openapi-ts + +interface SerializeOptions + extends SerializePrimitiveOptions, + SerializerOptions {} + +interface SerializePrimitiveOptions { + allowReserved?: boolean; + name: string; +} + +export interface SerializerOptions { + /** + * @default true + */ + explode: boolean; + style: T; +} + +export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; +type MatrixStyle = 'label' | 'matrix' | 'simple'; +export type ObjectStyle = 'form' | 'deepObject'; +type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; + +interface SerializePrimitiveParam extends SerializePrimitiveOptions { + value: string; +} + +export const separatorArrayExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } +}; + +export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const serializeArrayParam = ({ + allowReserved, + explode, + name, + style, + value, +}: SerializeOptions & { + value: unknown[]; +}) => { + if (!explode) { + const joinedValues = ( + allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } + } + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; + +export const serializePrimitiveParam = ({ + allowReserved, + name, + value, +}: SerializePrimitiveParam) => { + if (value === undefined || value === null) { + return ''; + } + + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', + ); + } + + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; +}; + +export const serializeObjectParam = ({ + allowReserved, + explode, + name, + style, + value, + valueOnly, +}: SerializeOptions & { + value: Record | Date; + valueOnly?: boolean; +}) => { + if (value instanceof Date) { + return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; + } + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [ + ...values, + key, + allowReserved ? (v as string) : encodeURIComponent(v as string), + ]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string, + }), + ) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/serverSentEvents.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/serverSentEvents.gen.ts new file mode 100644 index 000000000000..01b5818fdf12 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/serverSentEvents.gen.ts @@ -0,0 +1,237 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit< + RequestInit, + 'method' +> & + Pick & { + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult< + TData = unknown, + TReturn = void, + TNext = unknown, +> = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = + sseSleepFn ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const response = await fetch(url, { ...options, headers, signal }); + + if (!response.ok) + throw new Error( + `SSE failed: ${response.status} ${response.statusText}`, + ); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body + .pipeThrough(new TextDecoderStream()) + .getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt( + line.replace(/^retry:\s*/, ''), + 10, + ); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if ( + sseMaxRetryAttempts !== undefined && + attempt >= sseMaxRetryAttempts + ) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min( + retryDelay * 2 ** (attempt - 1), + sseMaxRetryDelay ?? 30000, + ); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/types.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/types.gen.ts new file mode 100644 index 000000000000..643c070c9d29 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/types.gen.ts @@ -0,0 +1,118 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from './auth.gen'; +import type { + BodySerializer, + QuerySerializer, + QuerySerializerOptions, +} from './bodySerializer.gen'; + +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never, +> = { + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] + ? { sse?: never } + : { sse: { [K in HttpMethod]: SseFn } }); + +export interface Config { + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + | string + | number + | boolean + | (string | number | boolean)[] + | null + | undefined + | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; +} + +type IsExactlyNeverOrNeverUndefined = [T] extends [never] + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; + +export type OmitNever> = { + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true + ? never + : K]: T[K]; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/utils.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/utils.gen.ts new file mode 100644 index 000000000000..ac31396feaad --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/core/utils.gen.ts @@ -0,0 +1,114 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }), + ); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts index 62ef1c6b2358..5e723adbf222 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/sdk.gen.ts @@ -1,6 +1,6 @@ // This file is auto-generated by @hey-api/openapi-ts -import { type Options as ClientOptions, type TDataShape, type Client, formDataBodySerializer } from '@hey-api/client-fetch'; +import { type Options as ClientOptions, type TDataShape, type Client, formDataBodySerializer } from './client'; import type { GetCultureData, GetCultureResponses, GetCultureErrors, PostDataTypeData, PostDataTypeResponses, PostDataTypeErrors, DeleteDataTypeByIdData, DeleteDataTypeByIdResponses, DeleteDataTypeByIdErrors, GetDataTypeByIdData, GetDataTypeByIdResponses, GetDataTypeByIdErrors, PutDataTypeByIdData, PutDataTypeByIdResponses, PutDataTypeByIdErrors, PostDataTypeByIdCopyData, PostDataTypeByIdCopyResponses, PostDataTypeByIdCopyErrors, GetDataTypeByIdIsUsedData, GetDataTypeByIdIsUsedResponses, GetDataTypeByIdIsUsedErrors, PutDataTypeByIdMoveData, PutDataTypeByIdMoveResponses, PutDataTypeByIdMoveErrors, GetDataTypeByIdReferencedByData, GetDataTypeByIdReferencedByResponses, GetDataTypeByIdReferencedByErrors, GetDataTypeByIdReferencesData, GetDataTypeByIdReferencesResponses, GetDataTypeByIdReferencesErrors, GetDataTypeConfigurationData, GetDataTypeConfigurationResponses, GetDataTypeConfigurationErrors, PostDataTypeFolderData, PostDataTypeFolderResponses, PostDataTypeFolderErrors, DeleteDataTypeFolderByIdData, DeleteDataTypeFolderByIdResponses, DeleteDataTypeFolderByIdErrors, GetDataTypeFolderByIdData, GetDataTypeFolderByIdResponses, GetDataTypeFolderByIdErrors, PutDataTypeFolderByIdData, PutDataTypeFolderByIdResponses, PutDataTypeFolderByIdErrors, GetFilterDataTypeData, GetFilterDataTypeResponses, GetFilterDataTypeErrors, GetItemDataTypeData, GetItemDataTypeResponses, GetItemDataTypeErrors, GetItemDataTypeSearchData, GetItemDataTypeSearchResponses, GetItemDataTypeSearchErrors, GetTreeDataTypeAncestorsData, GetTreeDataTypeAncestorsResponses, GetTreeDataTypeAncestorsErrors, GetTreeDataTypeChildrenData, GetTreeDataTypeChildrenResponses, GetTreeDataTypeChildrenErrors, GetTreeDataTypeRootData, GetTreeDataTypeRootResponses, GetTreeDataTypeRootErrors, GetTreeDataTypeSiblingsData, GetTreeDataTypeSiblingsResponses, GetTreeDataTypeSiblingsErrors, GetDictionaryData, GetDictionaryResponses, GetDictionaryErrors, PostDictionaryData, PostDictionaryResponses, PostDictionaryErrors, DeleteDictionaryByIdData, DeleteDictionaryByIdResponses, DeleteDictionaryByIdErrors, GetDictionaryByIdData, GetDictionaryByIdResponses, GetDictionaryByIdErrors, PutDictionaryByIdData, PutDictionaryByIdResponses, PutDictionaryByIdErrors, GetDictionaryByIdExportData, GetDictionaryByIdExportResponses, GetDictionaryByIdExportErrors, PutDictionaryByIdMoveData, PutDictionaryByIdMoveResponses, PutDictionaryByIdMoveErrors, PostDictionaryImportData, PostDictionaryImportResponses, PostDictionaryImportErrors, GetItemDictionaryData, GetItemDictionaryResponses, GetItemDictionaryErrors, GetTreeDictionaryAncestorsData, GetTreeDictionaryAncestorsResponses, GetTreeDictionaryAncestorsErrors, GetTreeDictionaryChildrenData, GetTreeDictionaryChildrenResponses, GetTreeDictionaryChildrenErrors, GetTreeDictionaryRootData, GetTreeDictionaryRootResponses, GetTreeDictionaryRootErrors, PostDocumentBlueprintData, PostDocumentBlueprintResponses, PostDocumentBlueprintErrors, DeleteDocumentBlueprintByIdData, DeleteDocumentBlueprintByIdResponses, DeleteDocumentBlueprintByIdErrors, GetDocumentBlueprintByIdData, GetDocumentBlueprintByIdResponses, GetDocumentBlueprintByIdErrors, PutDocumentBlueprintByIdData, PutDocumentBlueprintByIdResponses, PutDocumentBlueprintByIdErrors, PutDocumentBlueprintByIdMoveData, PutDocumentBlueprintByIdMoveResponses, PutDocumentBlueprintByIdMoveErrors, GetDocumentBlueprintByIdScaffoldData, GetDocumentBlueprintByIdScaffoldResponses, GetDocumentBlueprintByIdScaffoldErrors, PostDocumentBlueprintFolderData, PostDocumentBlueprintFolderResponses, PostDocumentBlueprintFolderErrors, DeleteDocumentBlueprintFolderByIdData, DeleteDocumentBlueprintFolderByIdResponses, DeleteDocumentBlueprintFolderByIdErrors, GetDocumentBlueprintFolderByIdData, GetDocumentBlueprintFolderByIdResponses, GetDocumentBlueprintFolderByIdErrors, PutDocumentBlueprintFolderByIdData, PutDocumentBlueprintFolderByIdResponses, PutDocumentBlueprintFolderByIdErrors, PostDocumentBlueprintFromDocumentData, PostDocumentBlueprintFromDocumentResponses, PostDocumentBlueprintFromDocumentErrors, GetItemDocumentBlueprintData, GetItemDocumentBlueprintResponses, GetItemDocumentBlueprintErrors, GetTreeDocumentBlueprintAncestorsData, GetTreeDocumentBlueprintAncestorsResponses, GetTreeDocumentBlueprintAncestorsErrors, GetTreeDocumentBlueprintChildrenData, GetTreeDocumentBlueprintChildrenResponses, GetTreeDocumentBlueprintChildrenErrors, GetTreeDocumentBlueprintRootData, GetTreeDocumentBlueprintRootResponses, GetTreeDocumentBlueprintRootErrors, GetTreeDocumentBlueprintSiblingsData, GetTreeDocumentBlueprintSiblingsResponses, GetTreeDocumentBlueprintSiblingsErrors, PostDocumentTypeData, PostDocumentTypeResponses, PostDocumentTypeErrors, DeleteDocumentTypeByIdData, DeleteDocumentTypeByIdResponses, DeleteDocumentTypeByIdErrors, GetDocumentTypeByIdData, GetDocumentTypeByIdResponses, GetDocumentTypeByIdErrors, PutDocumentTypeByIdData, PutDocumentTypeByIdResponses, PutDocumentTypeByIdErrors, GetDocumentTypeByIdAllowedChildrenData, GetDocumentTypeByIdAllowedChildrenResponses, GetDocumentTypeByIdAllowedChildrenErrors, GetDocumentTypeByIdBlueprintData, GetDocumentTypeByIdBlueprintResponses, GetDocumentTypeByIdBlueprintErrors, GetDocumentTypeByIdCompositionReferencesData, GetDocumentTypeByIdCompositionReferencesResponses, GetDocumentTypeByIdCompositionReferencesErrors, PostDocumentTypeByIdCopyData, PostDocumentTypeByIdCopyResponses, PostDocumentTypeByIdCopyErrors, GetDocumentTypeByIdExportData, GetDocumentTypeByIdExportResponses, GetDocumentTypeByIdExportErrors, PutDocumentTypeByIdImportData, PutDocumentTypeByIdImportResponses, PutDocumentTypeByIdImportErrors, PutDocumentTypeByIdMoveData, PutDocumentTypeByIdMoveResponses, PutDocumentTypeByIdMoveErrors, GetDocumentTypeAllowedAtRootData, GetDocumentTypeAllowedAtRootResponses, GetDocumentTypeAllowedAtRootErrors, PostDocumentTypeAvailableCompositionsData, PostDocumentTypeAvailableCompositionsResponses, PostDocumentTypeAvailableCompositionsErrors, GetDocumentTypeConfigurationData, GetDocumentTypeConfigurationResponses, GetDocumentTypeConfigurationErrors, PostDocumentTypeFolderData, PostDocumentTypeFolderResponses, PostDocumentTypeFolderErrors, DeleteDocumentTypeFolderByIdData, DeleteDocumentTypeFolderByIdResponses, DeleteDocumentTypeFolderByIdErrors, GetDocumentTypeFolderByIdData, GetDocumentTypeFolderByIdResponses, GetDocumentTypeFolderByIdErrors, PutDocumentTypeFolderByIdData, PutDocumentTypeFolderByIdResponses, PutDocumentTypeFolderByIdErrors, PostDocumentTypeImportData, PostDocumentTypeImportResponses, PostDocumentTypeImportErrors, GetItemDocumentTypeData, GetItemDocumentTypeResponses, GetItemDocumentTypeErrors, GetItemDocumentTypeSearchData, GetItemDocumentTypeSearchResponses, GetItemDocumentTypeSearchErrors, GetTreeDocumentTypeAncestorsData, GetTreeDocumentTypeAncestorsResponses, GetTreeDocumentTypeAncestorsErrors, GetTreeDocumentTypeChildrenData, GetTreeDocumentTypeChildrenResponses, GetTreeDocumentTypeChildrenErrors, GetTreeDocumentTypeRootData, GetTreeDocumentTypeRootResponses, GetTreeDocumentTypeRootErrors, GetTreeDocumentTypeSiblingsData, GetTreeDocumentTypeSiblingsResponses, GetTreeDocumentTypeSiblingsErrors, GetDocumentVersionData, GetDocumentVersionResponses, GetDocumentVersionErrors, GetDocumentVersionByIdData, GetDocumentVersionByIdResponses, GetDocumentVersionByIdErrors, PutDocumentVersionByIdPreventCleanupData, PutDocumentVersionByIdPreventCleanupResponses, PutDocumentVersionByIdPreventCleanupErrors, PostDocumentVersionByIdRollbackData, PostDocumentVersionByIdRollbackResponses, PostDocumentVersionByIdRollbackErrors, GetCollectionDocumentByIdData, GetCollectionDocumentByIdResponses, GetCollectionDocumentByIdErrors, PostDocumentData, PostDocumentResponses, PostDocumentErrors, DeleteDocumentByIdData, DeleteDocumentByIdResponses, DeleteDocumentByIdErrors, GetDocumentByIdData, GetDocumentByIdResponses, GetDocumentByIdErrors, PutDocumentByIdData, PutDocumentByIdResponses, PutDocumentByIdErrors, GetDocumentByIdAuditLogData, GetDocumentByIdAuditLogResponses, GetDocumentByIdAuditLogErrors, PostDocumentByIdCopyData, PostDocumentByIdCopyResponses, PostDocumentByIdCopyErrors, GetDocumentByIdDomainsData, GetDocumentByIdDomainsResponses, GetDocumentByIdDomainsErrors, PutDocumentByIdDomainsData, PutDocumentByIdDomainsResponses, PutDocumentByIdDomainsErrors, PutDocumentByIdMoveData, PutDocumentByIdMoveResponses, PutDocumentByIdMoveErrors, PutDocumentByIdMoveToRecycleBinData, PutDocumentByIdMoveToRecycleBinResponses, PutDocumentByIdMoveToRecycleBinErrors, GetDocumentByIdNotificationsData, GetDocumentByIdNotificationsResponses, GetDocumentByIdNotificationsErrors, PutDocumentByIdNotificationsData, PutDocumentByIdNotificationsResponses, PutDocumentByIdNotificationsErrors, DeleteDocumentByIdPublicAccessData, DeleteDocumentByIdPublicAccessResponses, DeleteDocumentByIdPublicAccessErrors, GetDocumentByIdPublicAccessData, GetDocumentByIdPublicAccessResponses, GetDocumentByIdPublicAccessErrors, PostDocumentByIdPublicAccessData, PostDocumentByIdPublicAccessResponses, PostDocumentByIdPublicAccessErrors, PutDocumentByIdPublicAccessData, PutDocumentByIdPublicAccessResponses, PutDocumentByIdPublicAccessErrors, PutDocumentByIdPublishData, PutDocumentByIdPublishResponses, PutDocumentByIdPublishErrors, PutDocumentByIdPublishWithDescendantsData, PutDocumentByIdPublishWithDescendantsResponses, PutDocumentByIdPublishWithDescendantsErrors, GetDocumentByIdPublishWithDescendantsResultByTaskIdData, GetDocumentByIdPublishWithDescendantsResultByTaskIdResponses, GetDocumentByIdPublishWithDescendantsResultByTaskIdErrors, GetDocumentByIdPublishedData, GetDocumentByIdPublishedResponses, GetDocumentByIdPublishedErrors, GetDocumentByIdReferencedByData, GetDocumentByIdReferencedByResponses, GetDocumentByIdReferencedByErrors, GetDocumentByIdReferencedDescendantsData, GetDocumentByIdReferencedDescendantsResponses, GetDocumentByIdReferencedDescendantsErrors, PutDocumentByIdUnpublishData, PutDocumentByIdUnpublishResponses, PutDocumentByIdUnpublishErrors, PutUmbracoManagementApiV11DocumentByIdValidate11Data, PutUmbracoManagementApiV11DocumentByIdValidate11Responses, PutUmbracoManagementApiV11DocumentByIdValidate11Errors, GetDocumentAreReferencedData, GetDocumentAreReferencedResponses, GetDocumentAreReferencedErrors, GetDocumentConfigurationData, GetDocumentConfigurationResponses, GetDocumentConfigurationErrors, PutDocumentSortData, PutDocumentSortResponses, PutDocumentSortErrors, GetDocumentUrlsData, GetDocumentUrlsResponses, GetDocumentUrlsErrors, PostDocumentValidateData, PostDocumentValidateResponses, PostDocumentValidateErrors, GetItemDocumentData, GetItemDocumentResponses, GetItemDocumentErrors, GetItemDocumentSearchData, GetItemDocumentSearchResponses, GetItemDocumentSearchErrors, DeleteRecycleBinDocumentData, DeleteRecycleBinDocumentResponses, DeleteRecycleBinDocumentErrors, DeleteRecycleBinDocumentByIdData, DeleteRecycleBinDocumentByIdResponses, DeleteRecycleBinDocumentByIdErrors, GetRecycleBinDocumentByIdOriginalParentData, GetRecycleBinDocumentByIdOriginalParentResponses, GetRecycleBinDocumentByIdOriginalParentErrors, PutRecycleBinDocumentByIdRestoreData, PutRecycleBinDocumentByIdRestoreResponses, PutRecycleBinDocumentByIdRestoreErrors, GetRecycleBinDocumentChildrenData, GetRecycleBinDocumentChildrenResponses, GetRecycleBinDocumentChildrenErrors, GetRecycleBinDocumentReferencedByData, GetRecycleBinDocumentReferencedByResponses, GetRecycleBinDocumentReferencedByErrors, GetRecycleBinDocumentRootData, GetRecycleBinDocumentRootResponses, GetRecycleBinDocumentRootErrors, GetTreeDocumentAncestorsData, GetTreeDocumentAncestorsResponses, GetTreeDocumentAncestorsErrors, GetTreeDocumentChildrenData, GetTreeDocumentChildrenResponses, GetTreeDocumentChildrenErrors, GetTreeDocumentRootData, GetTreeDocumentRootResponses, GetTreeDocumentRootErrors, GetTreeDocumentSiblingsData, GetTreeDocumentSiblingsResponses, GetTreeDocumentSiblingsErrors, PostDynamicRootQueryData, PostDynamicRootQueryResponses, PostDynamicRootQueryErrors, GetDynamicRootStepsData, GetDynamicRootStepsResponses, GetDynamicRootStepsErrors, GetHealthCheckGroupData, GetHealthCheckGroupResponses, GetHealthCheckGroupErrors, GetHealthCheckGroupByNameData, GetHealthCheckGroupByNameResponses, GetHealthCheckGroupByNameErrors, PostHealthCheckGroupByNameCheckData, PostHealthCheckGroupByNameCheckResponses, PostHealthCheckGroupByNameCheckErrors, PostHealthCheckExecuteActionData, PostHealthCheckExecuteActionResponses, PostHealthCheckExecuteActionErrors, GetHelpData, GetHelpResponses, GetHelpErrors, GetImagingResizeUrlsData, GetImagingResizeUrlsResponses, GetImagingResizeUrlsErrors, GetImportAnalyzeData, GetImportAnalyzeResponses, GetImportAnalyzeErrors, GetIndexerData, GetIndexerResponses, GetIndexerErrors, GetIndexerByIndexNameData, GetIndexerByIndexNameResponses, GetIndexerByIndexNameErrors, PostIndexerByIndexNameRebuildData, PostIndexerByIndexNameRebuildResponses, PostIndexerByIndexNameRebuildErrors, GetInstallSettingsData, GetInstallSettingsResponses, GetInstallSettingsErrors, PostInstallSetupData, PostInstallSetupResponses, PostInstallSetupErrors, PostInstallValidateDatabaseData, PostInstallValidateDatabaseResponses, PostInstallValidateDatabaseErrors, GetItemLanguageData, GetItemLanguageResponses, GetItemLanguageErrors, GetItemLanguageDefaultData, GetItemLanguageDefaultResponses, GetItemLanguageDefaultErrors, GetLanguageData, GetLanguageResponses, GetLanguageErrors, PostLanguageData, PostLanguageResponses, PostLanguageErrors, DeleteLanguageByIsoCodeData, DeleteLanguageByIsoCodeResponses, DeleteLanguageByIsoCodeErrors, GetLanguageByIsoCodeData, GetLanguageByIsoCodeResponses, GetLanguageByIsoCodeErrors, PutLanguageByIsoCodeData, PutLanguageByIsoCodeResponses, PutLanguageByIsoCodeErrors, GetLogViewerLevelData, GetLogViewerLevelResponses, GetLogViewerLevelErrors, GetLogViewerLevelCountData, GetLogViewerLevelCountResponses, GetLogViewerLevelCountErrors, GetLogViewerLogData, GetLogViewerLogResponses, GetLogViewerLogErrors, GetLogViewerMessageTemplateData, GetLogViewerMessageTemplateResponses, GetLogViewerMessageTemplateErrors, GetLogViewerSavedSearchData, GetLogViewerSavedSearchResponses, GetLogViewerSavedSearchErrors, PostLogViewerSavedSearchData, PostLogViewerSavedSearchResponses, PostLogViewerSavedSearchErrors, DeleteLogViewerSavedSearchByNameData, DeleteLogViewerSavedSearchByNameResponses, DeleteLogViewerSavedSearchByNameErrors, GetLogViewerSavedSearchByNameData, GetLogViewerSavedSearchByNameResponses, GetLogViewerSavedSearchByNameErrors, GetLogViewerValidateLogsSizeData, GetLogViewerValidateLogsSizeResponses, GetLogViewerValidateLogsSizeErrors, GetManifestManifestData, GetManifestManifestResponses, GetManifestManifestErrors, GetManifestManifestPrivateData, GetManifestManifestPrivateResponses, GetManifestManifestPrivateErrors, GetManifestManifestPublicData, GetManifestManifestPublicResponses, GetItemMediaTypeData, GetItemMediaTypeResponses, GetItemMediaTypeErrors, GetItemMediaTypeAllowedData, GetItemMediaTypeAllowedResponses, GetItemMediaTypeAllowedErrors, GetItemMediaTypeFoldersData, GetItemMediaTypeFoldersResponses, GetItemMediaTypeFoldersErrors, GetItemMediaTypeSearchData, GetItemMediaTypeSearchResponses, GetItemMediaTypeSearchErrors, PostMediaTypeData, PostMediaTypeResponses, PostMediaTypeErrors, DeleteMediaTypeByIdData, DeleteMediaTypeByIdResponses, DeleteMediaTypeByIdErrors, GetMediaTypeByIdData, GetMediaTypeByIdResponses, GetMediaTypeByIdErrors, PutMediaTypeByIdData, PutMediaTypeByIdResponses, PutMediaTypeByIdErrors, GetMediaTypeByIdAllowedChildrenData, GetMediaTypeByIdAllowedChildrenResponses, GetMediaTypeByIdAllowedChildrenErrors, GetMediaTypeByIdCompositionReferencesData, GetMediaTypeByIdCompositionReferencesResponses, GetMediaTypeByIdCompositionReferencesErrors, PostMediaTypeByIdCopyData, PostMediaTypeByIdCopyResponses, PostMediaTypeByIdCopyErrors, GetMediaTypeByIdExportData, GetMediaTypeByIdExportResponses, GetMediaTypeByIdExportErrors, PutMediaTypeByIdImportData, PutMediaTypeByIdImportResponses, PutMediaTypeByIdImportErrors, PutMediaTypeByIdMoveData, PutMediaTypeByIdMoveResponses, PutMediaTypeByIdMoveErrors, GetMediaTypeAllowedAtRootData, GetMediaTypeAllowedAtRootResponses, GetMediaTypeAllowedAtRootErrors, PostMediaTypeAvailableCompositionsData, PostMediaTypeAvailableCompositionsResponses, PostMediaTypeAvailableCompositionsErrors, GetMediaTypeConfigurationData, GetMediaTypeConfigurationResponses, GetMediaTypeConfigurationErrors, PostMediaTypeFolderData, PostMediaTypeFolderResponses, PostMediaTypeFolderErrors, DeleteMediaTypeFolderByIdData, DeleteMediaTypeFolderByIdResponses, DeleteMediaTypeFolderByIdErrors, GetMediaTypeFolderByIdData, GetMediaTypeFolderByIdResponses, GetMediaTypeFolderByIdErrors, PutMediaTypeFolderByIdData, PutMediaTypeFolderByIdResponses, PutMediaTypeFolderByIdErrors, PostMediaTypeImportData, PostMediaTypeImportResponses, PostMediaTypeImportErrors, GetTreeMediaTypeAncestorsData, GetTreeMediaTypeAncestorsResponses, GetTreeMediaTypeAncestorsErrors, GetTreeMediaTypeChildrenData, GetTreeMediaTypeChildrenResponses, GetTreeMediaTypeChildrenErrors, GetTreeMediaTypeRootData, GetTreeMediaTypeRootResponses, GetTreeMediaTypeRootErrors, GetTreeMediaTypeSiblingsData, GetTreeMediaTypeSiblingsResponses, GetTreeMediaTypeSiblingsErrors, GetCollectionMediaData, GetCollectionMediaResponses, GetCollectionMediaErrors, GetItemMediaData, GetItemMediaResponses, GetItemMediaErrors, GetItemMediaSearchData, GetItemMediaSearchResponses, GetItemMediaSearchErrors, PostMediaData, PostMediaResponses, PostMediaErrors, DeleteMediaByIdData, DeleteMediaByIdResponses, DeleteMediaByIdErrors, GetMediaByIdData, GetMediaByIdResponses, GetMediaByIdErrors, PutMediaByIdData, PutMediaByIdResponses, PutMediaByIdErrors, GetMediaByIdAuditLogData, GetMediaByIdAuditLogResponses, GetMediaByIdAuditLogErrors, PutMediaByIdMoveData, PutMediaByIdMoveResponses, PutMediaByIdMoveErrors, PutMediaByIdMoveToRecycleBinData, PutMediaByIdMoveToRecycleBinResponses, PutMediaByIdMoveToRecycleBinErrors, GetMediaByIdReferencedByData, GetMediaByIdReferencedByResponses, GetMediaByIdReferencedByErrors, GetMediaByIdReferencedDescendantsData, GetMediaByIdReferencedDescendantsResponses, GetMediaByIdReferencedDescendantsErrors, PutMediaByIdValidateData, PutMediaByIdValidateResponses, PutMediaByIdValidateErrors, GetMediaAreReferencedData, GetMediaAreReferencedResponses, GetMediaAreReferencedErrors, GetMediaConfigurationData, GetMediaConfigurationResponses, GetMediaConfigurationErrors, PutMediaSortData, PutMediaSortResponses, PutMediaSortErrors, GetMediaUrlsData, GetMediaUrlsResponses, GetMediaUrlsErrors, PostMediaValidateData, PostMediaValidateResponses, PostMediaValidateErrors, DeleteRecycleBinMediaData, DeleteRecycleBinMediaResponses, DeleteRecycleBinMediaErrors, DeleteRecycleBinMediaByIdData, DeleteRecycleBinMediaByIdResponses, DeleteRecycleBinMediaByIdErrors, GetRecycleBinMediaByIdOriginalParentData, GetRecycleBinMediaByIdOriginalParentResponses, GetRecycleBinMediaByIdOriginalParentErrors, PutRecycleBinMediaByIdRestoreData, PutRecycleBinMediaByIdRestoreResponses, PutRecycleBinMediaByIdRestoreErrors, GetRecycleBinMediaChildrenData, GetRecycleBinMediaChildrenResponses, GetRecycleBinMediaChildrenErrors, GetRecycleBinMediaReferencedByData, GetRecycleBinMediaReferencedByResponses, GetRecycleBinMediaReferencedByErrors, GetRecycleBinMediaRootData, GetRecycleBinMediaRootResponses, GetRecycleBinMediaRootErrors, GetTreeMediaAncestorsData, GetTreeMediaAncestorsResponses, GetTreeMediaAncestorsErrors, GetTreeMediaChildrenData, GetTreeMediaChildrenResponses, GetTreeMediaChildrenErrors, GetTreeMediaRootData, GetTreeMediaRootResponses, GetTreeMediaRootErrors, GetTreeMediaSiblingsData, GetTreeMediaSiblingsResponses, GetTreeMediaSiblingsErrors, GetItemMemberGroupData, GetItemMemberGroupResponses, GetItemMemberGroupErrors, GetMemberGroupData, GetMemberGroupResponses, GetMemberGroupErrors, PostMemberGroupData, PostMemberGroupResponses, PostMemberGroupErrors, DeleteMemberGroupByIdData, DeleteMemberGroupByIdResponses, DeleteMemberGroupByIdErrors, GetMemberGroupByIdData, GetMemberGroupByIdResponses, GetMemberGroupByIdErrors, PutMemberGroupByIdData, PutMemberGroupByIdResponses, PutMemberGroupByIdErrors, GetTreeMemberGroupRootData, GetTreeMemberGroupRootResponses, GetTreeMemberGroupRootErrors, GetItemMemberTypeData, GetItemMemberTypeResponses, GetItemMemberTypeErrors, GetItemMemberTypeSearchData, GetItemMemberTypeSearchResponses, GetItemMemberTypeSearchErrors, PostMemberTypeData, PostMemberTypeResponses, PostMemberTypeErrors, DeleteMemberTypeByIdData, DeleteMemberTypeByIdResponses, DeleteMemberTypeByIdErrors, GetMemberTypeByIdData, GetMemberTypeByIdResponses, GetMemberTypeByIdErrors, PutMemberTypeByIdData, PutMemberTypeByIdResponses, PutMemberTypeByIdErrors, GetMemberTypeByIdCompositionReferencesData, GetMemberTypeByIdCompositionReferencesResponses, GetMemberTypeByIdCompositionReferencesErrors, PostMemberTypeByIdCopyData, PostMemberTypeByIdCopyResponses, PostMemberTypeByIdCopyErrors, PostMemberTypeAvailableCompositionsData, PostMemberTypeAvailableCompositionsResponses, PostMemberTypeAvailableCompositionsErrors, GetMemberTypeConfigurationData, GetMemberTypeConfigurationResponses, GetMemberTypeConfigurationErrors, GetTreeMemberTypeRootData, GetTreeMemberTypeRootResponses, GetTreeMemberTypeRootErrors, GetFilterMemberData, GetFilterMemberResponses, GetFilterMemberErrors, GetItemMemberData, GetItemMemberResponses, GetItemMemberErrors, GetItemMemberSearchData, GetItemMemberSearchResponses, GetItemMemberSearchErrors, PostMemberData, PostMemberResponses, PostMemberErrors, DeleteMemberByIdData, DeleteMemberByIdResponses, DeleteMemberByIdErrors, GetMemberByIdData, GetMemberByIdResponses, GetMemberByIdErrors, PutMemberByIdData, PutMemberByIdResponses, PutMemberByIdErrors, GetMemberByIdReferencedByData, GetMemberByIdReferencedByResponses, GetMemberByIdReferencedByErrors, GetMemberByIdReferencedDescendantsData, GetMemberByIdReferencedDescendantsResponses, GetMemberByIdReferencedDescendantsErrors, PutMemberByIdValidateData, PutMemberByIdValidateResponses, PutMemberByIdValidateErrors, GetMemberAreReferencedData, GetMemberAreReferencedResponses, GetMemberAreReferencedErrors, GetMemberConfigurationData, GetMemberConfigurationResponses, GetMemberConfigurationErrors, PostMemberValidateData, PostMemberValidateResponses, PostMemberValidateErrors, PostModelsBuilderBuildData, PostModelsBuilderBuildResponses, PostModelsBuilderBuildErrors, GetModelsBuilderDashboardData, GetModelsBuilderDashboardResponses, GetModelsBuilderDashboardErrors, GetModelsBuilderStatusData, GetModelsBuilderStatusResponses, GetModelsBuilderStatusErrors, GetObjectTypesData, GetObjectTypesResponses, GetObjectTypesErrors, GetOembedQueryData, GetOembedQueryResponses, GetOembedQueryErrors, PostPackageByNameRunMigrationData, PostPackageByNameRunMigrationResponses, PostPackageByNameRunMigrationErrors, GetPackageConfigurationData, GetPackageConfigurationResponses, GetPackageConfigurationErrors, GetPackageCreatedData, GetPackageCreatedResponses, GetPackageCreatedErrors, PostPackageCreatedData, PostPackageCreatedResponses, PostPackageCreatedErrors, DeletePackageCreatedByIdData, DeletePackageCreatedByIdResponses, DeletePackageCreatedByIdErrors, GetPackageCreatedByIdData, GetPackageCreatedByIdResponses, GetPackageCreatedByIdErrors, PutPackageCreatedByIdData, PutPackageCreatedByIdResponses, PutPackageCreatedByIdErrors, GetPackageCreatedByIdDownloadData, GetPackageCreatedByIdDownloadResponses, GetPackageCreatedByIdDownloadErrors, GetPackageMigrationStatusData, GetPackageMigrationStatusResponses, GetPackageMigrationStatusErrors, GetItemPartialViewData, GetItemPartialViewResponses, GetItemPartialViewErrors, PostPartialViewData, PostPartialViewResponses, PostPartialViewErrors, DeletePartialViewByPathData, DeletePartialViewByPathResponses, DeletePartialViewByPathErrors, GetPartialViewByPathData, GetPartialViewByPathResponses, GetPartialViewByPathErrors, PutPartialViewByPathData, PutPartialViewByPathResponses, PutPartialViewByPathErrors, PutPartialViewByPathRenameData, PutPartialViewByPathRenameResponses, PutPartialViewByPathRenameErrors, PostPartialViewFolderData, PostPartialViewFolderResponses, PostPartialViewFolderErrors, DeletePartialViewFolderByPathData, DeletePartialViewFolderByPathResponses, DeletePartialViewFolderByPathErrors, GetPartialViewFolderByPathData, GetPartialViewFolderByPathResponses, GetPartialViewFolderByPathErrors, GetPartialViewSnippetData, GetPartialViewSnippetResponses, GetPartialViewSnippetErrors, GetPartialViewSnippetByIdData, GetPartialViewSnippetByIdResponses, GetPartialViewSnippetByIdErrors, GetTreePartialViewAncestorsData, GetTreePartialViewAncestorsResponses, GetTreePartialViewAncestorsErrors, GetTreePartialViewChildrenData, GetTreePartialViewChildrenResponses, GetTreePartialViewChildrenErrors, GetTreePartialViewRootData, GetTreePartialViewRootResponses, GetTreePartialViewRootErrors, DeletePreviewData, DeletePreviewResponses, PostPreviewData, PostPreviewResponses, PostPreviewErrors, GetProfilingStatusData, GetProfilingStatusResponses, GetProfilingStatusErrors, PutProfilingStatusData, PutProfilingStatusResponses, PutProfilingStatusErrors, GetPropertyTypeIsUsedData, GetPropertyTypeIsUsedResponses, GetPropertyTypeIsUsedErrors, PostPublishedCacheRebuildData, PostPublishedCacheRebuildResponses, PostPublishedCacheRebuildErrors, GetPublishedCacheRebuildStatusData, GetPublishedCacheRebuildStatusResponses, GetPublishedCacheRebuildStatusErrors, PostPublishedCacheReloadData, PostPublishedCacheReloadResponses, PostPublishedCacheReloadErrors, GetRedirectManagementData, GetRedirectManagementResponses, GetRedirectManagementErrors, DeleteRedirectManagementByIdData, DeleteRedirectManagementByIdResponses, DeleteRedirectManagementByIdErrors, GetRedirectManagementByIdData, GetRedirectManagementByIdResponses, GetRedirectManagementByIdErrors, GetRedirectManagementStatusData, GetRedirectManagementStatusResponses, GetRedirectManagementStatusErrors, PostRedirectManagementStatusData, PostRedirectManagementStatusResponses, PostRedirectManagementStatusErrors, GetItemRelationTypeData, GetItemRelationTypeResponses, GetItemRelationTypeErrors, GetRelationTypeData, GetRelationTypeResponses, GetRelationTypeErrors, GetRelationTypeByIdData, GetRelationTypeByIdResponses, GetRelationTypeByIdErrors, GetRelationByRelationTypeIdData, GetRelationByRelationTypeIdResponses, GetRelationByRelationTypeIdErrors, GetItemScriptData, GetItemScriptResponses, GetItemScriptErrors, PostScriptData, PostScriptResponses, PostScriptErrors, DeleteScriptByPathData, DeleteScriptByPathResponses, DeleteScriptByPathErrors, GetScriptByPathData, GetScriptByPathResponses, GetScriptByPathErrors, PutScriptByPathData, PutScriptByPathResponses, PutScriptByPathErrors, PutScriptByPathRenameData, PutScriptByPathRenameResponses, PutScriptByPathRenameErrors, PostScriptFolderData, PostScriptFolderResponses, PostScriptFolderErrors, DeleteScriptFolderByPathData, DeleteScriptFolderByPathResponses, DeleteScriptFolderByPathErrors, GetScriptFolderByPathData, GetScriptFolderByPathResponses, GetScriptFolderByPathErrors, GetTreeScriptAncestorsData, GetTreeScriptAncestorsResponses, GetTreeScriptAncestorsErrors, GetTreeScriptChildrenData, GetTreeScriptChildrenResponses, GetTreeScriptChildrenErrors, GetTreeScriptRootData, GetTreeScriptRootResponses, GetTreeScriptRootErrors, GetSearcherData, GetSearcherResponses, GetSearcherErrors, GetSearcherBySearcherNameQueryData, GetSearcherBySearcherNameQueryResponses, GetSearcherBySearcherNameQueryErrors, GetSecurityConfigurationData, GetSecurityConfigurationResponses, GetSecurityConfigurationErrors, PostSecurityForgotPasswordData, PostSecurityForgotPasswordResponses, PostSecurityForgotPasswordErrors, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponses, PostSecurityForgotPasswordResetErrors, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponses, PostSecurityForgotPasswordVerifyErrors, GetSegmentData, GetSegmentResponses, GetSegmentErrors, GetServerConfigurationData, GetServerConfigurationResponses, GetServerInformationData, GetServerInformationResponses, GetServerInformationErrors, GetServerStatusData, GetServerStatusResponses, GetServerStatusErrors, GetServerTroubleshootingData, GetServerTroubleshootingResponses, GetServerTroubleshootingErrors, GetServerUpgradeCheckData, GetServerUpgradeCheckResponses, GetServerUpgradeCheckErrors, GetItemStaticFileData, GetItemStaticFileResponses, GetItemStaticFileErrors, GetTreeStaticFileAncestorsData, GetTreeStaticFileAncestorsResponses, GetTreeStaticFileAncestorsErrors, GetTreeStaticFileChildrenData, GetTreeStaticFileChildrenResponses, GetTreeStaticFileChildrenErrors, GetTreeStaticFileRootData, GetTreeStaticFileRootResponses, GetTreeStaticFileRootErrors, GetItemStylesheetData, GetItemStylesheetResponses, GetItemStylesheetErrors, PostStylesheetData, PostStylesheetResponses, PostStylesheetErrors, DeleteStylesheetByPathData, DeleteStylesheetByPathResponses, DeleteStylesheetByPathErrors, GetStylesheetByPathData, GetStylesheetByPathResponses, GetStylesheetByPathErrors, PutStylesheetByPathData, PutStylesheetByPathResponses, PutStylesheetByPathErrors, PutStylesheetByPathRenameData, PutStylesheetByPathRenameResponses, PutStylesheetByPathRenameErrors, PostStylesheetFolderData, PostStylesheetFolderResponses, PostStylesheetFolderErrors, DeleteStylesheetFolderByPathData, DeleteStylesheetFolderByPathResponses, DeleteStylesheetFolderByPathErrors, GetStylesheetFolderByPathData, GetStylesheetFolderByPathResponses, GetStylesheetFolderByPathErrors, GetTreeStylesheetAncestorsData, GetTreeStylesheetAncestorsResponses, GetTreeStylesheetAncestorsErrors, GetTreeStylesheetChildrenData, GetTreeStylesheetChildrenResponses, GetTreeStylesheetChildrenErrors, GetTreeStylesheetRootData, GetTreeStylesheetRootResponses, GetTreeStylesheetRootErrors, GetTagData, GetTagResponses, GetTagErrors, GetTelemetryData, GetTelemetryResponses, GetTelemetryErrors, GetTelemetryLevelData, GetTelemetryLevelResponses, GetTelemetryLevelErrors, PostTelemetryLevelData, PostTelemetryLevelResponses, PostTelemetryLevelErrors, GetItemTemplateData, GetItemTemplateResponses, GetItemTemplateErrors, GetItemTemplateSearchData, GetItemTemplateSearchResponses, GetItemTemplateSearchErrors, PostTemplateData, PostTemplateResponses, PostTemplateErrors, DeleteTemplateByIdData, DeleteTemplateByIdResponses, DeleteTemplateByIdErrors, GetTemplateByIdData, GetTemplateByIdResponses, GetTemplateByIdErrors, PutTemplateByIdData, PutTemplateByIdResponses, PutTemplateByIdErrors, GetTemplateConfigurationData, GetTemplateConfigurationResponses, GetTemplateConfigurationErrors, PostTemplateQueryExecuteData, PostTemplateQueryExecuteResponses, PostTemplateQueryExecuteErrors, GetTemplateQuerySettingsData, GetTemplateQuerySettingsResponses, GetTemplateQuerySettingsErrors, GetTreeTemplateAncestorsData, GetTreeTemplateAncestorsResponses, GetTreeTemplateAncestorsErrors, GetTreeTemplateChildrenData, GetTreeTemplateChildrenResponses, GetTreeTemplateChildrenErrors, GetTreeTemplateRootData, GetTreeTemplateRootResponses, GetTreeTemplateRootErrors, GetTreeTemplateSiblingsData, GetTreeTemplateSiblingsResponses, GetTreeTemplateSiblingsErrors, PostTemporaryFileData, PostTemporaryFileResponses, PostTemporaryFileErrors, DeleteTemporaryFileByIdData, DeleteTemporaryFileByIdResponses, DeleteTemporaryFileByIdErrors, GetTemporaryFileByIdData, GetTemporaryFileByIdResponses, GetTemporaryFileByIdErrors, GetTemporaryFileConfigurationData, GetTemporaryFileConfigurationResponses, GetTemporaryFileConfigurationErrors, PostUpgradeAuthorizeData, PostUpgradeAuthorizeResponses, PostUpgradeAuthorizeErrors, GetUpgradeSettingsData, GetUpgradeSettingsResponses, GetUpgradeSettingsErrors, GetUserDataData, GetUserDataResponses, GetUserDataErrors, PostUserDataData, PostUserDataResponses, PostUserDataErrors, PutUserDataData, PutUserDataResponses, PutUserDataErrors, GetUserDataByIdData, GetUserDataByIdResponses, GetUserDataByIdErrors, GetFilterUserGroupData, GetFilterUserGroupResponses, GetFilterUserGroupErrors, GetItemUserGroupData, GetItemUserGroupResponses, GetItemUserGroupErrors, DeleteUserGroupData, DeleteUserGroupResponses, DeleteUserGroupErrors, GetUserGroupData, GetUserGroupResponses, GetUserGroupErrors, PostUserGroupData, PostUserGroupResponses, PostUserGroupErrors, DeleteUserGroupByIdData, DeleteUserGroupByIdResponses, DeleteUserGroupByIdErrors, GetUserGroupByIdData, GetUserGroupByIdResponses, GetUserGroupByIdErrors, PutUserGroupByIdData, PutUserGroupByIdResponses, PutUserGroupByIdErrors, DeleteUserGroupByIdUsersData, DeleteUserGroupByIdUsersResponses, DeleteUserGroupByIdUsersErrors, PostUserGroupByIdUsersData, PostUserGroupByIdUsersResponses, PostUserGroupByIdUsersErrors, GetFilterUserData, GetFilterUserResponses, GetFilterUserErrors, GetItemUserData, GetItemUserResponses, GetItemUserErrors, DeleteUserData, DeleteUserResponses, DeleteUserErrors, GetUserData, GetUserResponses, GetUserErrors, PostUserData, PostUserResponses, PostUserErrors, DeleteUserByIdData, DeleteUserByIdResponses, DeleteUserByIdErrors, GetUserByIdData, GetUserByIdResponses, GetUserByIdErrors, PutUserByIdData, PutUserByIdResponses, PutUserByIdErrors, GetUserById2FaData, GetUserById2FaResponses, GetUserById2FaErrors, DeleteUserById2FaByProviderNameData, DeleteUserById2FaByProviderNameResponses, DeleteUserById2FaByProviderNameErrors, GetUserByIdCalculateStartNodesData, GetUserByIdCalculateStartNodesResponses, GetUserByIdCalculateStartNodesErrors, PostUserByIdChangePasswordData, PostUserByIdChangePasswordResponses, PostUserByIdChangePasswordErrors, GetUserByIdClientCredentialsData, GetUserByIdClientCredentialsResponses, GetUserByIdClientCredentialsErrors, PostUserByIdClientCredentialsData, PostUserByIdClientCredentialsResponses, PostUserByIdClientCredentialsErrors, DeleteUserByIdClientCredentialsByClientIdData, DeleteUserByIdClientCredentialsByClientIdResponses, DeleteUserByIdClientCredentialsByClientIdErrors, PostUserByIdResetPasswordData, PostUserByIdResetPasswordResponses, PostUserByIdResetPasswordErrors, DeleteUserAvatarByIdData, DeleteUserAvatarByIdResponses, DeleteUserAvatarByIdErrors, PostUserAvatarByIdData, PostUserAvatarByIdResponses, PostUserAvatarByIdErrors, GetUserConfigurationData, GetUserConfigurationResponses, GetUserConfigurationErrors, GetUserCurrentData, GetUserCurrentResponses, GetUserCurrentErrors, GetUserCurrent2FaData, GetUserCurrent2FaResponses, GetUserCurrent2FaErrors, DeleteUserCurrent2FaByProviderNameData, DeleteUserCurrent2FaByProviderNameResponses, DeleteUserCurrent2FaByProviderNameErrors, GetUserCurrent2FaByProviderNameData, GetUserCurrent2FaByProviderNameResponses, GetUserCurrent2FaByProviderNameErrors, PostUserCurrent2FaByProviderNameData, PostUserCurrent2FaByProviderNameResponses, PostUserCurrent2FaByProviderNameErrors, PostUserCurrentAvatarData, PostUserCurrentAvatarResponses, PostUserCurrentAvatarErrors, PostUserCurrentChangePasswordData, PostUserCurrentChangePasswordResponses, PostUserCurrentChangePasswordErrors, GetUserCurrentConfigurationData, GetUserCurrentConfigurationResponses, GetUserCurrentConfigurationErrors, GetUserCurrentLoginProvidersData, GetUserCurrentLoginProvidersResponses, GetUserCurrentLoginProvidersErrors, GetUserCurrentPermissionsData, GetUserCurrentPermissionsResponses, GetUserCurrentPermissionsErrors, GetUserCurrentPermissionsDocumentData, GetUserCurrentPermissionsDocumentResponses, GetUserCurrentPermissionsDocumentErrors, GetUserCurrentPermissionsMediaData, GetUserCurrentPermissionsMediaResponses, GetUserCurrentPermissionsMediaErrors, PostUserDisableData, PostUserDisableResponses, PostUserDisableErrors, PostUserEnableData, PostUserEnableResponses, PostUserEnableErrors, PostUserInviteData, PostUserInviteResponses, PostUserInviteErrors, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordResponses, PostUserInviteCreatePasswordErrors, PostUserInviteResendData, PostUserInviteResendResponses, PostUserInviteResendErrors, PostUserInviteVerifyData, PostUserInviteVerifyResponses, PostUserInviteVerifyErrors, PostUserSetUserGroupsData, PostUserSetUserGroupsResponses, PostUserSetUserGroupsErrors, PostUserUnlockData, PostUserUnlockResponses, PostUserUnlockErrors, GetItemWebhookData, GetItemWebhookResponses, GetItemWebhookErrors, GetWebhookData, GetWebhookResponses, GetWebhookErrors, PostWebhookData, PostWebhookResponses, PostWebhookErrors, DeleteWebhookByIdData, DeleteWebhookByIdResponses, DeleteWebhookByIdErrors, GetWebhookByIdData, GetWebhookByIdResponses, GetWebhookByIdErrors, PutWebhookByIdData, PutWebhookByIdResponses, PutWebhookByIdErrors, GetWebhookByIdLogsData, GetWebhookByIdLogsResponses, GetWebhookByIdLogsErrors, GetWebhookEventsData, GetWebhookEventsResponses, GetWebhookEventsErrors, GetWebhookLogsData, GetWebhookLogsResponses, GetWebhookLogsErrors } from './types.gen'; import { client as _heyApiClient } from './client.gen'; @@ -1160,6 +1160,29 @@ export class DocumentVersionService { } } +class DocumentByIdValidate1Service { + public static putUmbracoManagementApiV11DocumentByIdValidate11(options: Options) { + return (options.client ?? _heyApiClient).put({ + security: [ + { + scheme: 'bearer', + type: 'http' + } + ], + url: '/umbraco/management/api/v1.1/document/{id}/validate', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } + }); + } +} + +class PutUmbracoManagementApiV1Service { + static documentByIdValidate1Service = DocumentByIdValidate1Service; +} + export class DocumentService { public static getCollectionDocumentById(options: Options) { return (options.client ?? _heyApiClient).get({ @@ -1517,23 +1540,6 @@ export class DocumentService { }); } - public static putUmbracoManagementApiV11DocumentByIdValidate11(options: Options) { - return (options.client ?? _heyApiClient).put({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1.1/document/{id}/validate', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } - }); - } - public static getDocumentAreReferenced(options?: Options) { return (options?.client ?? _heyApiClient).get({ security: [ @@ -1779,6 +1785,7 @@ export class DocumentService { ...options }); } + static putUmbracoManagementApiV1Service = PutUmbracoManagementApiV1Service; } export class DynamicRootService { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts index 15d6395949a6..115dd08c874a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/backend-api/types.gen.ts @@ -1124,14 +1124,8 @@ export type IndexResponseModel = { } | null; }; -export type InstallRequestModelReadable = { - user: UserInstallRequestModelReadable; - database: DatabaseInstallRequestModel; - telemetryLevel: TelemetryLevelModel; -}; - -export type InstallRequestModelWritable = { - user: UserInstallRequestModelWritable; +export type InstallRequestModel = { + user: UserInstallRequestModel; database: DatabaseInstallRequestModel; telemetryLevel: TelemetryLevelModel; }; @@ -1707,7 +1701,7 @@ export type PackageConfigurationResponseModel = { marketplaceUrl: string; }; -export type PackageDefinitionResponseModelReadable = { +export type PackageDefinitionResponseModel = { name: string; contentNodeId?: string | null; contentLoadChildNodes: boolean; @@ -1726,24 +1720,6 @@ export type PackageDefinitionResponseModelReadable = { readonly packagePath: string; }; -export type PackageDefinitionResponseModelWritable = { - name: string; - contentNodeId?: string | null; - contentLoadChildNodes: boolean; - mediaIds: Array; - mediaLoadChildNodes: boolean; - documentTypes: Array; - mediaTypes: Array; - dataTypes: Array; - templates: Array; - partialViews: Array; - stylesheets: Array; - scripts: Array; - languages: Array; - dictionaryItems: Array; - id: string; -}; - export type PackageMigrationStatusResponseModel = { packageName: string; hasPendingMigrations: boolean; @@ -1949,14 +1925,9 @@ export type PagedObjectTypeResponseModel = { items: Array; }; -export type PagedPackageDefinitionResponseModelReadable = { +export type PagedPackageDefinitionResponseModel = { total: number; - items: Array; -}; - -export type PagedPackageDefinitionResponseModelWritable = { - total: number; - items: Array; + items: Array; }; export type PagedPackageMigrationStatusResponseModel = { @@ -1984,14 +1955,9 @@ export type PagedReferenceByIdModel = { items: Array; }; -export type PagedRelationResponseModelReadable = { +export type PagedRelationResponseModel = { total: number; - items: Array; -}; - -export type PagedRelationResponseModelWritable = { - total: number; - items: Array; + items: Array; }; export type PagedRelationTypeResponseModel = { @@ -2004,14 +1970,9 @@ export type PagedSavedLogSearchResponseModel = { items: Array; }; -export type PagedSearchResultResponseModelReadable = { - total: number; - items: Array; -}; - -export type PagedSearchResultResponseModelWritable = { +export type PagedSearchResultResponseModel = { total: number; - items: Array; + items: Array; }; export type PagedSearcherResponseModel = { @@ -2209,7 +2170,7 @@ export type RelationReferenceModel = { name?: string | null; }; -export type RelationResponseModelReadable = { +export type RelationResponseModel = { id: string; relationType: ReferenceByIdModel; parent: RelationReferenceModel; @@ -2218,13 +2179,6 @@ export type RelationResponseModelReadable = { readonly comment?: string | null; }; -export type RelationResponseModelWritable = { - id: string; - relationType: ReferenceByIdModel; - parent: RelationReferenceModel; - child: RelationReferenceModel; -}; - export type RelationTypeItemResponseModel = { id: string; signs: Array; @@ -2323,19 +2277,13 @@ export type ScriptResponseModel = { content: string; }; -export type SearchResultResponseModelReadable = { +export type SearchResultResponseModel = { id: string; score: number; readonly fieldCount: number; fields: Array; }; -export type SearchResultResponseModelWritable = { - id: string; - score: number; - fields: Array; -}; - export type SearcherResponseModel = { name: string; }; @@ -2788,7 +2736,7 @@ export type UpdateMemberTypeRequestModel = { compositions: Array; }; -export type UpdatePackageRequestModelReadable = { +export type UpdatePackageRequestModel = { name: string; contentNodeId?: string | null; contentLoadChildNodes: boolean; @@ -2806,23 +2754,6 @@ export type UpdatePackageRequestModelReadable = { readonly packagePath: string; }; -export type UpdatePackageRequestModelWritable = { - name: string; - contentNodeId?: string | null; - contentLoadChildNodes: boolean; - mediaIds: Array; - mediaLoadChildNodes: boolean; - documentTypes: Array; - mediaTypes: Array; - dataTypes: Array; - templates: Array; - partialViews: Array; - stylesheets: Array; - scripts: Array; - languages: Array; - dictionaryItems: Array; -}; - export type UpdatePartialViewRequestModel = { content: string; }; @@ -2898,7 +2829,7 @@ export type UpgradeCheckResponseModel = { url: string; }; -export type UpgradeSettingsResponseModelReadable = { +export type UpgradeSettingsResponseModel = { currentState: string; newState: string; newVersion: string; @@ -2906,13 +2837,6 @@ export type UpgradeSettingsResponseModelReadable = { readonly reportUrl: string; }; -export type UpgradeSettingsResponseModelWritable = { - currentState: string; - newState: string; - newVersion: string; - oldVersion: string; -}; - export type UserConfigurationResponseModel = { canInviteUsers: boolean; usernameIsEmail: boolean; @@ -2974,19 +2898,13 @@ export type UserGroupResponseModel = { aliasCanBeChanged: boolean; }; -export type UserInstallRequestModelReadable = { +export type UserInstallRequestModel = { name: string; email: string; password: string; readonly subscribeToNewsletter: boolean; }; -export type UserInstallRequestModelWritable = { - name: string; - email: string; - password: string; -}; - export type UserItemResponseModel = { id: string; signs: Array; @@ -7681,7 +7599,7 @@ export type GetInstallSettingsResponses = { export type GetInstallSettingsResponse = GetInstallSettingsResponses[keyof GetInstallSettingsResponses]; export type PostInstallSetupData = { - body?: InstallRequestModelWritable; + body?: InstallRequestModel; path?: never; query?: never; url: '/umbraco/management/api/v1/install/setup'; @@ -11375,7 +11293,7 @@ export type GetPackageCreatedResponses = { /** * OK */ - 200: PagedPackageDefinitionResponseModelReadable; + 200: PagedPackageDefinitionResponseModel; }; export type GetPackageCreatedResponse = GetPackageCreatedResponses[keyof GetPackageCreatedResponses]; @@ -11478,13 +11396,13 @@ export type GetPackageCreatedByIdResponses = { /** * OK */ - 200: PackageDefinitionResponseModelReadable; + 200: PackageDefinitionResponseModel; }; export type GetPackageCreatedByIdResponse = GetPackageCreatedByIdResponses[keyof GetPackageCreatedByIdResponses]; export type PutPackageCreatedByIdData = { - body?: UpdatePackageRequestModelWritable; + body?: UpdatePackageRequestModel; path: { id: string; }; @@ -12510,7 +12428,7 @@ export type GetRelationByRelationTypeIdResponses = { /** * OK */ - 200: PagedRelationResponseModelReadable; + 200: PagedRelationResponseModel; }; export type GetRelationByRelationTypeIdResponse = GetRelationByRelationTypeIdResponses[keyof GetRelationByRelationTypeIdResponses]; @@ -12974,7 +12892,7 @@ export type GetSearcherBySearcherNameQueryResponses = { /** * OK */ - 200: PagedSearchResultResponseModelReadable; + 200: PagedSearchResultResponseModel; }; export type GetSearcherBySearcherNameQueryResponse = GetSearcherBySearcherNameQueryResponses[keyof GetSearcherBySearcherNameQueryResponses]; @@ -14454,7 +14372,7 @@ export type GetUpgradeSettingsResponses = { /** * OK */ - 200: UpgradeSettingsResponseModelReadable; + 200: UpgradeSettingsResponseModel; }; export type GetUpgradeSettingsResponse = GetUpgradeSettingsResponses[keyof GetUpgradeSettingsResponses]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts index 8b396888955b..450649ecb292 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/http-client/index.ts @@ -1,2 +1 @@ export { client as umbHttpClient } from '@umbraco-cms/backoffice/external/backend-api'; -export type { RequestOptions } from '@hey-api/client-fetch'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js b/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js index 41ee9c430125..db0a583eb432 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js +++ b/src/Umbraco.Web.UI.Client/src/packages/core/openapi-ts.config.js @@ -1,7 +1,6 @@ import { defineConfig } from '@hey-api/openapi-ts'; export default defineConfig({ - debug: true, input: '../../../../Umbraco.Cms.Api.Management/OpenApi.json', output: { path: './backend-api', @@ -9,7 +8,6 @@ export default defineConfig({ plugins: [ { name: '@hey-api/client-fetch', - bundle: false, exportFromIndex: true, throwOnError: true, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/package.json b/src/Umbraco.Web.UI.Client/src/packages/core/package.json index d4907d423e88..ea1d94d79af4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/package.json +++ b/src/Umbraco.Web.UI.Client/src/packages/core/package.json @@ -10,9 +10,6 @@ "@types/diff": "^7.0.2", "diff": "^7.0.0", "uuid": "^11.1.0", - "@hey-api/client-fetch": "^0.12.0" - }, - "devDependencies": { - "@hey-api/openapi-ts": "^0.71.0" + "@hey-api/openapi-ts": "0.81.1" } } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts index b5a0dc6c3833..35436b03e056 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/api-interceptor.controller.ts @@ -5,7 +5,7 @@ import type { UmbProblemDetails } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { UMB_AUTH_CONTEXT } from '@umbraco-cms/backoffice/auth'; import type { UmbNotificationColor } from '@umbraco-cms/backoffice/notification'; -import type { RequestOptions, umbHttpClient } from '@umbraco-cms/backoffice/http-client'; +import type { umbHttpClient } from '@umbraco-cms/backoffice/http-client'; const MAX_RETRIES = 3; @@ -16,7 +16,7 @@ export class UmbApiInterceptorController extends UmbControllerBase { */ #pending401Requests: Array<{ request: Request; - requestConfig: RequestOptions; + requestConfig: unknown; retry: () => Promise; resolve: (value: Response) => void; reject: (reason?: unknown) => void; @@ -29,7 +29,7 @@ export class UmbApiInterceptorController extends UmbControllerBase { * These requests will not be retried, as they are not idempotent. * Instead, we will notify the user about these requests after re-authentication. */ - #nonGet401Requests: Array<{ request: Request; requestConfig: RequestOptions }> = []; + #nonGet401Requests: Array<{ request: Request; requestConfig: unknown }> = []; /** * Binds the default interceptors to the client. diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts index 661687bc54ae..68b04408a058 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts @@ -87,10 +87,12 @@ export class UmbDocumentValidationServerDataSource { // Maybe use: tryExecuteAndNotify const { data, error } = await tryExecute( this.#host, - DocumentService.putUmbracoManagementApiV11DocumentByIdValidate11({ - path: { id: model.unique }, - body, - }), + DocumentService.putUmbracoManagementApiV1Service.documentByIdValidate1Service.putUmbracoManagementApiV11DocumentByIdValidate11( + { + path: { id: model.unique }, + body, + }, + ), { disableNotifications: true, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts index 945c7fe59093..2277694786c0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/packages/package/repository/sources/package.server.data.ts @@ -2,13 +2,13 @@ import { tryExecute } from '@umbraco-cms/backoffice/resources'; import { ManifestService, PackageService } from '@umbraco-cms/backoffice/external/backend-api'; import type { CreatePackageRequestModel, - UpdatePackageRequestModelWritable, + UpdatePackageRequestModel, } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; /** * Data source for packages from the server - + */ export class UmbPackageServerDataSource { constructor(private readonly _host: UmbControllerHost) {} @@ -57,7 +57,7 @@ export class UmbPackageServerDataSource { return await tryExecute(this._host, PackageService.postPackageCreated({ body })); } - async updateCreatedPackage(id: string, body: UpdatePackageRequestModelWritable) { + async updateCreatedPackage(id: string, body: UpdatePackageRequestModel) { return await tryExecute(this._host, PackageService.putPackageCreatedById({ path: { id }, body })); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts index 3a59d87d6b42..664ca34f3ae2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/search/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/search/types.ts @@ -1,9 +1,6 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; -import type { - FieldPresentationModel, - SearchResultResponseModelReadable, -} from '@umbraco-cms/backoffice/external/backend-api'; +import type { FieldPresentationModel, SearchResultResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbPagedModel, UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository'; export type { UmbSearchDataSource } from './search-data-source.interface.js'; @@ -12,7 +9,7 @@ export type { UmbSearchRepository } from './search-repository.interface.js'; export type * from './extensions/types.js'; export type * from './global-search/types.js'; -export type UmbSearchResultModel = SearchResultResponseModelReadable; +export type UmbSearchResultModel = SearchResultResponseModel; // TODO: lower requirement for search provider item type export type UmbSearchResultItemModel = { diff --git a/src/Umbraco.Web.UI.Login/openapi-ts.config.ts b/src/Umbraco.Web.UI.Login/openapi-ts.config.ts index a91eeeb123db..623ee2a4cd52 100644 --- a/src/Umbraco.Web.UI.Login/openapi-ts.config.ts +++ b/src/Umbraco.Web.UI.Login/openapi-ts.config.ts @@ -2,10 +2,21 @@ import { defineConfig } from '@hey-api/openapi-ts'; export default defineConfig({ input: { - include: - '(ProblemDetails|ReferenceByIdModel|ResetPassword|PasswordConfiguration|SecurityConfiguration|InviteUser|CreateInitialPasswordUser|/security/|/user/invite/)', path: '../Umbraco.Cms.Api.Management/OpenApi.json', }, + parser: { + filters: { + operations: { + include: [ + 'POST /umbraco/management/api/v1/security/forgot-password', + 'POST /umbraco/management/api/v1/security/forgot-password/verify', + 'POST /umbraco/management/api/v1/security/forgot-password/reset', + 'POST /umbraco/management/api/v1/user/invite/verify', + 'POST /umbraco/management/api/v1/user/invite/create-password', + ], + }, + }, + }, output: { path: './src/api', }, diff --git a/src/Umbraco.Web.UI.Login/package-lock.json b/src/Umbraco.Web.UI.Login/package-lock.json index e13ddcd52ba0..249d9300ed35 100644 --- a/src/Umbraco.Web.UI.Login/package-lock.json +++ b/src/Umbraco.Web.UI.Login/package-lock.json @@ -6,9 +6,8 @@ "": { "name": "login", "devDependencies": { - "@hey-api/client-fetch": "^0.10.2", - "@hey-api/openapi-ts": "^0.67.6", - "@umbraco-cms/backoffice": "16.0.0-rc4", + "@hey-api/openapi-ts": "0.81.1", + "@umbraco-cms/backoffice": "16.2.0-rc", "msw": "^2.7.0", "typescript": "^5.8.3", "vite": "^6.3.5" @@ -474,12 +473,25 @@ "node": ">=18" } }, + "node_modules/@heximal/expressions": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@heximal/expressions/-/expressions-0.1.5.tgz", + "integrity": "sha512-QdWz9vNrdzi24so9KGEM9w4UYLg1yk+LVvYBEDbw9EY1BzKHITWdtYc55xJ3Zuio0/9Naz/D1YtYlCnfsycNDQ==", + "dev": true, + "license": "BSD 3-Clause", + "peer": true, + "dependencies": { + "tslib": "^2.7.0" + } + }, "node_modules/@hey-api/client-fetch": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.10.2.tgz", - "integrity": "sha512-AGiFYDx+y8VT1wlQ3EbzzZtfU8EfV+hLLRTtr8Y/tjYZaxIECwJagVZf24YzNbtEBXONFV50bwcU1wLVGXe1ow==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@hey-api/client-fetch/-/client-fetch-0.12.0.tgz", + "integrity": "sha512-/iZ6dhs39N0kjzCa9tlNeLNufVUd8zzv/wI1ewQt5AEHaVuDnAxvuQT+fRIPYkfIWKR3gVZKRp5mcCo29voYzQ==", + "deprecated": "Starting with v0.73.0, this package is bundled directly inside @hey-api/openapi-ts.", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/hey-api" }, @@ -507,16 +519,21 @@ } }, "node_modules/@hey-api/openapi-ts": { - "version": "0.67.6", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.67.6.tgz", - "integrity": "sha512-ywZggKKYieVjM6O6T60/Bl+QBRvhcKAov8dAIQor7reyKpFbEn3Ws+9WKoXR8QUuXN8AR8nMFjOuYPer5db/dg==", + "version": "0.81.1", + "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.81.1.tgz", + "integrity": "sha512-DdLEMbfQRMRDd+cOxG91G7Ro7vUUtt/zYlBGiYTahVO/4rn1HHnYl/WHL+to5I7CTX3sVVsVrxHWcJd0Fue7wg==", "dev": true, "license": "MIT", "dependencies": { "@hey-api/json-schema-ref-parser": "1.0.6", + "ansi-colors": "4.1.3", "c12": "2.0.1", + "color-support": "1.1.3", "commander": "13.0.0", - "handlebars": "4.7.8" + "handlebars": "4.7.8", + "js-yaml": "4.1.0", + "open": "10.1.2", + "semver": "7.7.2" }, "bin": { "openapi-ts": "bin/index.cjs" @@ -617,22 +634,22 @@ "license": "MIT" }, "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", - "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.4.0.tgz", + "integrity": "sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==", "dev": true, "license": "BSD-3-Clause", "peer": true }, "node_modules/@lit/reactive-element": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.0.tgz", - "integrity": "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.1.tgz", + "integrity": "sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==", "dev": true, "license": "BSD-3-Clause", "peer": true, "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0" + "@lit-labs/ssr-dom-shim": "^1.4.0" } }, "node_modules/@mswjs/interceptors": { @@ -967,9 +984,9 @@ ] }, "node_modules/@tiptap/core": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.11.7.tgz", - "integrity": "sha512-zN+NFFxLsxNEL8Qioc+DL6b8+Tt2bmRbXH22Gk6F6nD30x83eaUSFlSv3wqvgyCq3I1i1NO394So+Agmayx6rQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.26.1.tgz", + "integrity": "sha512-fymyd/XZvYiHjBoLt1gxs024xP/LY26d43R1vluYq7AHBL/7DE3ywzy+1GEsGyAv5Je2L0KBhNIR/izbq3Kaqg==", "dev": true, "license": "MIT", "peer": true, @@ -982,9 +999,9 @@ } }, "node_modules/@tiptap/extension-blockquote": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.12.0.tgz", - "integrity": "sha512-XUC2A77YAPMJS2SqZ2S62IGcUH8gZ7cdhoWlYQb1pR4ZzXFByeKDJPxfYeAePSiuI01YGrlzgY2c6Ncx/DtO0A==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.26.1.tgz", + "integrity": "sha512-viQ6AHRhjCYYipKK6ZepBzwZpkuMvO9yhRHeUZDvlSOAh8rvsUTSre0y74nu8QRYUt4a44lJJ6BpphJK7bEgYA==", "dev": true, "license": "MIT", "peer": true, @@ -997,9 +1014,9 @@ } }, "node_modules/@tiptap/extension-bold": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.12.0.tgz", - "integrity": "sha512-lAUtoLDLRc5ofD2I9MFY6MQ7d1qBLLqS1rvpwaPjOaoQb/GPVnaHj9qXYG0SY9K3erMtto48bMFpAcscjZHzZQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.26.1.tgz", + "integrity": "sha512-zCce9PRuTNhadFir71luLo99HERDpGJ0EEflGm7RN8I1SnNi9gD5ooK42BOIQtejGCJqg3hTPZiYDJC2hXvckQ==", "dev": true, "license": "MIT", "peer": true, @@ -1012,9 +1029,9 @@ } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.12.0.tgz", - "integrity": "sha512-YTCjztB8MaIpwyxFYr81H4+LdKCq1VlaSXQyrPdB44mVdhhRqc46BYQb8/B//XE3UIu3X2QWFjwrqRlUq6vUiw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.26.1.tgz", + "integrity": "sha512-HHakuV4ckYCDOnBbne088FvCEP4YICw+wgPBz/V2dfpiFYQ4WzT0LPK9s7OFMCN+ROraoug+1ryN1Z1KdIgujQ==", "dev": true, "license": "MIT", "peer": true, @@ -1027,9 +1044,9 @@ } }, "node_modules/@tiptap/extension-character-count": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-character-count/-/extension-character-count-2.11.7.tgz", - "integrity": "sha512-gcVbKou+uxzg8N0BBKceLwtpWvN8g2TIjTuCdyAcAPukX63DqVWOkofFHn1RqZbstJmtF4pTGZs9OH/GJrp27Q==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-character-count/-/extension-character-count-2.26.1.tgz", + "integrity": "sha512-F7LP1a9GF28thbApowWT2I41baqX74HMUTrV9LGrNXaOkW2gxZz+CDOzfHsbHyfuwfIxIjv07Qf/HKA6Cc1qbA==", "dev": true, "license": "MIT", "peer": true, @@ -1043,9 +1060,9 @@ } }, "node_modules/@tiptap/extension-code": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.12.0.tgz", - "integrity": "sha512-R7RaS+hJeHFim7alImQ9L9CSWSMjWXvz0Ote568x9ea5gdBGUYW8PcH+5a91lh8e1XGYWBM12a8oJZRyxg/tQA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.26.1.tgz", + "integrity": "sha512-GU9deB1A/Tr4FMPu71CvlcjGKwRhGYz60wQ8m4aM+ELZcVIcZRa1ebR8bExRIEWnvRztQuyRiCQzw2N0xQJ1QQ==", "dev": true, "license": "MIT", "peer": true, @@ -1058,9 +1075,9 @@ } }, "node_modules/@tiptap/extension-code-block": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.12.0.tgz", - "integrity": "sha512-1D7cYAjgxEFHdfC/35Ooi4GqWKB5sszbW8iI7N16XILNln26xb0d5KflXqYrwr9CN/ZnZoCl2o6YsP7xEObcZA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.26.1.tgz", + "integrity": "sha512-/TDDOwONl0qEUc4+B6V9NnWtSjz95eg7/8uCb8Y8iRbGvI9vT4/znRKofFxstvKmW4URu/H74/g0ywV57h0B+A==", "dev": true, "license": "MIT", "peer": true, @@ -1074,9 +1091,9 @@ } }, "node_modules/@tiptap/extension-document": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.12.0.tgz", - "integrity": "sha512-sA1Q+mxDIv0Y3qQTBkYGwknNbDcGFiJ/fyAFholXpqbrcRx3GavwR/o0chBdsJZlFht0x7AWGwUYWvIo7wYilA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.26.1.tgz", + "integrity": "sha512-2P2IZp1NRAE+21mRuFBiP3X2WKfZ6kUC23NJKpn8bcOamY3obYqCt0ltGPhE4eR8n8QAl2fI/3jIgjR07dC8ow==", "dev": true, "license": "MIT", "peer": true, @@ -1089,9 +1106,9 @@ } }, "node_modules/@tiptap/extension-dropcursor": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.12.0.tgz", - "integrity": "sha512-zcZSOXFj+7LVnmdPWTfKr5AoxYIzFPFlLJe35AdTQC5IhkljLn1Exct8I30ZREojX/00hKYsO7JJmePS6TEVlQ==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.26.1.tgz", + "integrity": "sha512-JkDQU2ZYFOuT5mNYb8OiWGwD1HcjbtmX8tLNugQbToECmz9WvVPqJmn7V/q8VGpP81iEECz/IsyRmuf2kSD4uA==", "dev": true, "license": "MIT", "peer": true, @@ -1105,9 +1122,9 @@ } }, "node_modules/@tiptap/extension-gapcursor": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.12.0.tgz", - "integrity": "sha512-k8ji5v9YKn7bNjo8UtI9hEfXfl4tKUp1hpJOEmUxGJQa3LIwrwSbReupUTnHszGQelzxikS/l1xO9P0TIGwRoA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.26.1.tgz", + "integrity": "sha512-KOiMZc3PwJS3hR0nSq5d0TJi2jkNZkLZElcT6pCEnhRHzPH6dRMu9GM5Jj798ZRUy0T9UFcKJalFZaDxnmRnpg==", "dev": true, "license": "MIT", "peer": true, @@ -1121,9 +1138,9 @@ } }, "node_modules/@tiptap/extension-hard-break": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.12.0.tgz", - "integrity": "sha512-08MNS2PK5DzdnAfqXn4krmJ/xebKmWpRpYqqN5EM8AvetYKlAJyTVSpo0ZUeGbZ3EZiPm9djgSnrLqpFUDjRCg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.26.1.tgz", + "integrity": "sha512-d6uStdNKi8kjPlHAyO59M6KGWATNwhLCD7dng0NXfwGndc22fthzIk/6j9F6ltQx30huy5qQram6j3JXwNACoA==", "dev": true, "license": "MIT", "peer": true, @@ -1136,9 +1153,9 @@ } }, "node_modules/@tiptap/extension-heading": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.12.0.tgz", - "integrity": "sha512-9DfES4Wd5TX1foI70N9sAL+35NN1UHrtzDYN2+dTHupnmKir9RaMXyZcbkUb4aDVzYrGxIqxJzHBVkquKIlTrw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.26.1.tgz", + "integrity": "sha512-KSzL8WZV3pjJG9ke4RaU70+B5UlYR2S6olNt5UCAawM+fi11mobVztiBoC19xtpSVqIXC1AmXOqUgnuSvmE4ZA==", "dev": true, "license": "MIT", "peer": true, @@ -1151,9 +1168,9 @@ } }, "node_modules/@tiptap/extension-history": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.12.0.tgz", - "integrity": "sha512-+B9CAf2BFURC6mQiM1OQtahVTzdEOEgT/UUNlRZkeeBc0K5of3dr6UdBqaoaMAefja3jx5PqiQ7mhUBAjSt6AA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.26.1.tgz", + "integrity": "sha512-m6YR1gkkauIDo3PRl0gP+7Oc4n5OqDzcjVh6LvWREmZP8nmi94hfseYbqOXUb6RPHIc0JKF02eiRifT4MSd2nw==", "dev": true, "license": "MIT", "peer": true, @@ -1167,9 +1184,9 @@ } }, "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.12.0.tgz", - "integrity": "sha512-Vi2+6RIehDSpoJn/7PDuOieUj7W7WrEb4wBxK9TG8PDscihR0mehhhzm/K2xhH4TN48iPJGRsjDFrFjTbXmcnw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.26.1.tgz", + "integrity": "sha512-mT6baqOhs/NakgrAeDeed194E/ZJFGL692H0C7f1N7WDRaWxUu2oR0LrnRqSH5OyPjELkzu6nQnNy0+0tFGHHg==", "dev": true, "license": "MIT", "peer": true, @@ -1183,9 +1200,9 @@ } }, "node_modules/@tiptap/extension-image": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.11.7.tgz", - "integrity": "sha512-YvCmTDB7Oo+A56tR4S/gcNaYpqU4DDlSQcRp5IQvmQV5EekSe0lnEazGDoqOCwsit9qQhj4MPQJhKrnaWrJUrg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.26.1.tgz", + "integrity": "sha512-96+MaYBJebQlR/ik5W72GLUfXdEoxFs+6jsoERxbM5qEdhb7TEnodBFtWZOwgDO27kFd6rSNZuW9r5KJNtljEg==", "dev": true, "license": "MIT", "peer": true, @@ -1198,9 +1215,9 @@ } }, "node_modules/@tiptap/extension-italic": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.12.0.tgz", - "integrity": "sha512-JKcXK3LmEsmxNzEq5e06rPUGMRLUxmJ2mYtBY4NlJ6yLM9XMDljtgeTnWT0ySLYmfINSFTkX4S7WIRbpl9l4pw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.26.1.tgz", + "integrity": "sha512-pOs6oU4LyGO89IrYE4jbE8ZYsPwMMIiKkYfXcfeD9NtpGNBnjeVXXF5I9ndY2ANrCAgC8k58C3/powDRf0T2yA==", "dev": true, "license": "MIT", "peer": true, @@ -1213,9 +1230,9 @@ } }, "node_modules/@tiptap/extension-link": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.11.7.tgz", - "integrity": "sha512-qKIowE73aAUrnQCIifYP34xXOHOsZw46cT/LBDlb0T60knVfQoKVE4ku08fJzAV+s6zqgsaaZ4HVOXkQYLoW7g==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.26.1.tgz", + "integrity": "sha512-7yfum5Jymkue/uOSTQPt2SmkZIdZx7t3QhZLqBU7R9ettkdSCBgEGok6N+scJM1R1Zes+maSckLm0JZw5BKYNA==", "dev": true, "license": "MIT", "peer": true, @@ -1232,9 +1249,9 @@ } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.12.0.tgz", - "integrity": "sha512-4YwZooC8HP+gPxs6YrkB1ayggyYbgVvJx/rWBT6lKSW2MVVg8QXi1zAcSI3MhIhHmqDysXXFPL8JURlbeGjaFA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.26.1.tgz", + "integrity": "sha512-quOXckC73Luc3x+Dcm88YAEBW+Crh3x5uvtQOQtn2GEG91AshrvbnhGRiYnfvEN7UhWIS+FYI5liHFcRKSUKrQ==", "dev": true, "license": "MIT", "peer": true, @@ -1247,9 +1264,9 @@ } }, "node_modules/@tiptap/extension-ordered-list": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.12.0.tgz", - "integrity": "sha512-1ys0e/oqk09oXxrB1WzAx5EntK/QreObG/V1yhgihGm429fxHMsxzIYN6dKAYxx0YOPQG7qEZRrrPuWU70Ms7g==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.26.1.tgz", + "integrity": "sha512-UHKNRxq6TBnXMGFSq91knD6QaHsyyOwLOsXMzupmKM5Su0s+CRXEjfav3qKlbb9e4m7D7S/a0aPm8nC9KIXNhQ==", "dev": true, "license": "MIT", "peer": true, @@ -1262,9 +1279,9 @@ } }, "node_modules/@tiptap/extension-paragraph": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.12.0.tgz", - "integrity": "sha512-QNK5cgewCunWFxpLlbvvoO1rrLgEtNKxiY79fctP9toV+e59R+1i1Q9lXC1O5mOfDgVxCb6uFDMsqmKhFjpPog==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.26.1.tgz", + "integrity": "sha512-UezvM9VDRAVJlX1tykgHWSD1g3MKfVMWWZ+Tg+PE4+kizOwoYkRWznVPgCAxjmyHajxpCKRXgqTZkOxjJ9Kjzg==", "dev": true, "license": "MIT", "peer": true, @@ -1277,9 +1294,9 @@ } }, "node_modules/@tiptap/extension-placeholder": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.11.7.tgz", - "integrity": "sha512-/06zXV4HIjYoiaUq1fVJo/RcU8pHbzx21evOpeG/foCfNpMI4xLU/vnxdUi6/SQqpZMY0eFutDqod1InkSOqsg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.26.1.tgz", + "integrity": "sha512-MBlqbkd+63btY7Qu+SqrXvWjPwooGZDsLTtl7jp52BczBl61cq9yygglt9XpM11TFMBdySgdLHBrLtQ0B7fBlw==", "dev": true, "license": "MIT", "peer": true, @@ -1293,9 +1310,9 @@ } }, "node_modules/@tiptap/extension-strike": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.12.0.tgz", - "integrity": "sha512-nBaa5YtBsLJPZFfSs36sBz4Zgi/c8b3MsmS/Az8uXaHb0R9yPewOVUMDIQbxMct8SXUlIo9VtKlOL+mVJ3Nkpw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.26.1.tgz", + "integrity": "sha512-CkoRH+pAi6MgdCh7K0cVZl4N2uR4pZdabXAnFSoLZRSg6imLvEUmWHfSi1dl3Z7JOvd3a4yZ4NxerQn5MWbJ7g==", "dev": true, "license": "MIT", "peer": true, @@ -1308,9 +1325,9 @@ } }, "node_modules/@tiptap/extension-subscript": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.11.7.tgz", - "integrity": "sha512-I25ZexCddFJ9701DCCtQbX3Vtxzj5d9ss2GAXVweIUCdATCScaebsznyUQoN5papmhTxXsw5OD+K2ZHxP82pew==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.26.1.tgz", + "integrity": "sha512-tnXu18nBbTE6PqmkcpoPun5VxElupYacNfl2WkLB/trN3rBJbyDkn0diS8pL0Ku1vPNi2kSfrHq78/PbX0O1iA==", "dev": true, "license": "MIT", "peer": true, @@ -1323,9 +1340,9 @@ } }, "node_modules/@tiptap/extension-superscript": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.11.7.tgz", - "integrity": "sha512-dNRpCcRJs0Qvv0sZRgbH7Y5hDVbWsGSZjtwFCs/mysPrvHqmXjzo7568kYWTggxEYxnXw6n0FfkCAEHlt0N90Q==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.26.1.tgz", + "integrity": "sha512-YTUmppwJchqXxE4nf+wTMuZuUU9/9ibg8p73rif6WxldjuH0RGZQRY8ad5Ha1c5clG+60e0nrXthqqLgvWfjtw==", "dev": true, "license": "MIT", "peer": true, @@ -1338,9 +1355,9 @@ } }, "node_modules/@tiptap/extension-table": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.11.7.tgz", - "integrity": "sha512-rfwWkNXz/EZuhc8lylsCWPbx0Xr5FlIhreWFyeoXYrDEO3x4ytYcVOpNmbabJYP2semfM0PvPR5o84zfFkLZyg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.26.1.tgz", + "integrity": "sha512-LQ63CK53qx2ZsbLTB4mUX0YCoGC0GbYQ82jS3kD+K7M/mb9MCkefvDk6rA8rXF8TjfGnv6o/Fseoot8uhH3qfg==", "dev": true, "license": "MIT", "peer": true, @@ -1354,9 +1371,9 @@ } }, "node_modules/@tiptap/extension-table-cell": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.11.7.tgz", - "integrity": "sha512-JMOkSYRckc5SJP86yGGiHzCxCR8ecrRENvTWAKib6qer2tutxs5u42W+Z8uTcHC2dRz7Fv54snOkDoqPwkf6cw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.26.1.tgz", + "integrity": "sha512-0P5zY+WGFnULggJkX6+CevmFoBmVv1aUiBBXfcFuLG2mnUsS3QALQTowFtz/0/VbtbjzcOSStaGDHRJxPbk9XQ==", "dev": true, "license": "MIT", "peer": true, @@ -1369,9 +1386,9 @@ } }, "node_modules/@tiptap/extension-table-header": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.11.7.tgz", - "integrity": "sha512-wPRKpliS5QQXgsp//ZjXrHMdLICMkjg2fUrQinOiBa7wDL5C7Y+SehtuK4s2tjeAkyAdj+nepfftyBRIlUSMXg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.26.1.tgz", + "integrity": "sha512-SAwTW9H+sjVYjoeU5z8pVDMHn3r3FCi+zp2KAxsEsmujcd7qrQdY0cAjQtWjckCq6H3sQkbICa+xlCCd7C8ZAQ==", "dev": true, "license": "MIT", "peer": true, @@ -1384,9 +1401,9 @@ } }, "node_modules/@tiptap/extension-table-row": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.11.7.tgz", - "integrity": "sha512-K254RiXWGXGjz5Cm835hqfQiwnYXm8aw6oOa3isDh4A1B+1Ev4DB2vEDKMrgaOor3nbTsSYmAx2iEMrZSbpaRg==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.26.1.tgz", + "integrity": "sha512-c4oLrUfj1EVVDpbfKX36v7nnaeI4NxML2KRTQXocvcY65VCe0bPQh8ujpPgPcnKEzdWYdIuAX9RbEAkiYWe8Ww==", "dev": true, "license": "MIT", "peer": true, @@ -1399,9 +1416,9 @@ } }, "node_modules/@tiptap/extension-text": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.12.0.tgz", - "integrity": "sha512-0ytN9V1tZYTXdiYDQg4FB2SQ56JAJC9r/65snefb9ztl+gZzDrIvih7CflHs1ic9PgyjexfMLeH+VzuMccNyZw==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.26.1.tgz", + "integrity": "sha512-p2n8WVMd/2vckdJlol24acaTDIZAhI7qle5cM75bn01sOEZoFlSw6SwINOULrUCzNJsYb43qrLEibZb4j2LeQw==", "dev": true, "license": "MIT", "peer": true, @@ -1414,9 +1431,9 @@ } }, "node_modules/@tiptap/extension-text-align": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.11.7.tgz", - "integrity": "sha512-3M8zd9ROADXazVNpgR6Ejs1evSvBveN36qN4GgV71GqrNlTcjqYgQcXFLQrsd2hnE+aXir8/8bLJ+aaJXDninA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.26.1.tgz", + "integrity": "sha512-x6mpNGELy2QtSPBoQqNgiXO9PjZoB+O2EAfXA9YRiBDSIRNOrw+7vOVpi+IgzswFmhMNgIYUVfQRud4FHUCNew==", "dev": true, "license": "MIT", "peer": true, @@ -1429,9 +1446,9 @@ } }, "node_modules/@tiptap/extension-text-style": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.12.0.tgz", - "integrity": "sha512-Pxwt23ZlvbQUahV0PvHy8Ej6IAuKR1FvHobUvwP3T8AiY7hob66fWRe7tQbESzSAzm5Vv2xkvyHeU8vekMTezA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.26.1.tgz", + "integrity": "sha512-t9Nc/UkrbCfnSHEUi1gvUQ2ZPzvfdYFT5TExoV2DTiUCkhG6+mecT5bTVFGW3QkPmbToL+nFhGn4ZRMDD0SP3Q==", "dev": true, "license": "MIT", "peer": true, @@ -1444,9 +1461,9 @@ } }, "node_modules/@tiptap/extension-underline": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.11.7.tgz", - "integrity": "sha512-NtoQw6PGijOAtXC6G+0Aq0/Z5wwEjPhNHs8nsjXogfWIgaj/aI4/zfBnA06eI3WT+emMYQTl0fTc4CUPnLVU8g==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.26.1.tgz", + "integrity": "sha512-/fufv41WDMdf0a4xmFAxONoAz08TonJXX6NEoSJmuGKO59M/Y0Pz8DTK1g32Wk44kn7dyScDiPlvvndl+UOv0A==", "dev": true, "license": "MIT", "peer": true, @@ -1459,14 +1476,14 @@ } }, "node_modules/@tiptap/pm": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.11.7.tgz", - "integrity": "sha512-7gEEfz2Q6bYKXM07vzLUD0vqXFhC5geWRA6LCozTiLdVFDdHWiBrvb2rtkL5T7mfLq03zc1QhH7rI3F6VntOEA==", + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.26.1.tgz", + "integrity": "sha512-8aF+mY/vSHbGFqyG663ds84b+vca5Lge3tHdTMTKazxCnhXR9dn2oQJMnZ78YZvdRbkPkMJJHti9h3K7u2UQvw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "prosemirror-changeset": "^2.2.1", + "prosemirror-changeset": "^2.3.0", "prosemirror-collab": "^1.3.1", "prosemirror-commands": "^1.6.2", "prosemirror-dropcursor": "^1.8.1", @@ -1491,34 +1508,34 @@ } }, "node_modules/@tiptap/starter-kit": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.11.7.tgz", - "integrity": "sha512-K+q51KwNU/l0kqRuV5e1824yOLVftj6kGplGQLvJG56P7Rb2dPbM/JeaDbxQhnHT/KDGamG0s0Po0M3pPY163A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@tiptap/core": "^2.11.7", - "@tiptap/extension-blockquote": "^2.11.7", - "@tiptap/extension-bold": "^2.11.7", - "@tiptap/extension-bullet-list": "^2.11.7", - "@tiptap/extension-code": "^2.11.7", - "@tiptap/extension-code-block": "^2.11.7", - "@tiptap/extension-document": "^2.11.7", - "@tiptap/extension-dropcursor": "^2.11.7", - "@tiptap/extension-gapcursor": "^2.11.7", - "@tiptap/extension-hard-break": "^2.11.7", - "@tiptap/extension-heading": "^2.11.7", - "@tiptap/extension-history": "^2.11.7", - "@tiptap/extension-horizontal-rule": "^2.11.7", - "@tiptap/extension-italic": "^2.11.7", - "@tiptap/extension-list-item": "^2.11.7", - "@tiptap/extension-ordered-list": "^2.11.7", - "@tiptap/extension-paragraph": "^2.11.7", - "@tiptap/extension-strike": "^2.11.7", - "@tiptap/extension-text": "^2.11.7", - "@tiptap/extension-text-style": "^2.11.7", - "@tiptap/pm": "^2.11.7" + "version": "2.26.1", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.26.1.tgz", + "integrity": "sha512-oziMGCds8SVQ3s5dRpBxVdEKZAmO/O//BjZ69mhA3q4vJdR0rnfLb5fTxSeQvHiqB878HBNn76kNaJrHrV35GA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@tiptap/core": "^2.26.1", + "@tiptap/extension-blockquote": "^2.26.1", + "@tiptap/extension-bold": "^2.26.1", + "@tiptap/extension-bullet-list": "^2.26.1", + "@tiptap/extension-code": "^2.26.1", + "@tiptap/extension-code-block": "^2.26.1", + "@tiptap/extension-document": "^2.26.1", + "@tiptap/extension-dropcursor": "^2.26.1", + "@tiptap/extension-gapcursor": "^2.26.1", + "@tiptap/extension-hard-break": "^2.26.1", + "@tiptap/extension-heading": "^2.26.1", + "@tiptap/extension-history": "^2.26.1", + "@tiptap/extension-horizontal-rule": "^2.26.1", + "@tiptap/extension-italic": "^2.26.1", + "@tiptap/extension-list-item": "^2.26.1", + "@tiptap/extension-ordered-list": "^2.26.1", + "@tiptap/extension-paragraph": "^2.26.1", + "@tiptap/extension-strike": "^2.26.1", + "@tiptap/extension-text": "^2.26.1", + "@tiptap/extension-text-style": "^2.26.1", + "@tiptap/pm": "^2.26.1" }, "funding": { "type": "github", @@ -1605,9 +1622,9 @@ "peer": true }, "node_modules/@umbraco-cms/backoffice": { - "version": "16.0.0-rc4", - "resolved": "https://registry.npmjs.org/@umbraco-cms/backoffice/-/backoffice-16.0.0-rc4.tgz", - "integrity": "sha512-qR9xkbgJjZzb8kI4p8W3xbfYVl4cHmoKde/83LBzdh3loaxjQ0VjbdU+FZfPbfAsp/KNdY7b6UP8ME+n+Be2TA==", + "version": "16.2.0-rc", + "resolved": "https://registry.npmjs.org/@umbraco-cms/backoffice/-/backoffice-16.2.0-rc.tgz", + "integrity": "sha512-DAimNYu3ZGy1my0BikVXW0iKxH6nmkUTCA2Lw1wjhHG93T8+KCyHCJSxpXBdLdxmgUdKjp6lWjlqKsZ3wQ6/gQ==", "dev": true, "license": "MIT", "engines": { @@ -1615,24 +1632,26 @@ "npm": ">=10.9" }, "peerDependencies": { - "@tiptap/core": "2.11.7", - "@tiptap/extension-character-count": "2.11.7", - "@tiptap/extension-image": "2.11.7", - "@tiptap/extension-link": "2.11.7", - "@tiptap/extension-placeholder": "2.11.7", - "@tiptap/extension-subscript": "2.11.7", - "@tiptap/extension-superscript": "2.11.7", - "@tiptap/extension-table": "2.11.7", - "@tiptap/extension-table-cell": "2.11.7", - "@tiptap/extension-table-header": "2.11.7", - "@tiptap/extension-table-row": "2.11.7", - "@tiptap/extension-text-align": "2.11.7", - "@tiptap/extension-underline": "2.11.7", - "@tiptap/pm": "2.11.7", - "@tiptap/starter-kit": "2.11.7", + "@heximal/expressions": "^0.1.5", + "@hey-api/client-fetch": "^0.12.0", + "@tiptap/core": "2.26.1", + "@tiptap/extension-character-count": "2.26.1", + "@tiptap/extension-image": "2.26.1", + "@tiptap/extension-link": "2.26.1", + "@tiptap/extension-placeholder": "2.26.1", + "@tiptap/extension-subscript": "2.26.1", + "@tiptap/extension-superscript": "2.26.1", + "@tiptap/extension-table": "2.26.1", + "@tiptap/extension-table-cell": "2.26.1", + "@tiptap/extension-table-header": "2.26.1", + "@tiptap/extension-table-row": "2.26.1", + "@tiptap/extension-text-align": "2.26.1", + "@tiptap/extension-underline": "2.26.1", + "@tiptap/pm": "2.26.1", + "@tiptap/starter-kit": "2.26.1", "@types/diff": "^7.0.2", - "@umbraco-ui/uui": "1.14.0-rc.3", - "@umbraco-ui/uui-css": "1.14.0-rc.2", + "@umbraco-ui/uui": "^1.15.0-rc.0", + "@umbraco-ui/uui-css": "^1.15.0-rc.0", "diff": "^7.0.0", "dompurify": "^3.2.5", "element-internals-polyfill": "^3.0.2", @@ -1644,148 +1663,148 @@ } }, "node_modules/@umbraco-ui/uui": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.14.0-rc.3.tgz", - "integrity": "sha512-4uSpbJ72qOUMv3wel1c5ALWwC2Tgr/tARU2YwkulBP8v8HBD2OsaFWHl55Pkqu+63kGBw5BlVk5WTbq4DuHhOw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@umbraco-ui/uui-action-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-avatar": "1.14.0-rc.1", - "@umbraco-ui/uui-avatar-group": "1.14.0-rc.1", - "@umbraco-ui/uui-badge": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-boolean-input": "1.14.0-rc.1", - "@umbraco-ui/uui-box": "1.14.0-rc.2", - "@umbraco-ui/uui-breadcrumbs": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-button-copy-text": "1.14.0-rc.1", - "@umbraco-ui/uui-button-group": "1.14.0-rc.1", - "@umbraco-ui/uui-button-inline-create": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1", - "@umbraco-ui/uui-card-block-type": "1.14.0-rc.1", - "@umbraco-ui/uui-card-content-node": "1.14.0-rc.1", - "@umbraco-ui/uui-card-media": "1.14.0-rc.1", - "@umbraco-ui/uui-card-user": "1.14.0-rc.1", - "@umbraco-ui/uui-caret": "1.14.0-rc.1", - "@umbraco-ui/uui-checkbox": "1.14.0-rc.1", - "@umbraco-ui/uui-color-area": "1.14.0-rc.1", - "@umbraco-ui/uui-color-picker": "1.14.0-rc.1", - "@umbraco-ui/uui-color-slider": "1.14.0-rc.1", - "@umbraco-ui/uui-color-swatch": "1.14.0-rc.1", - "@umbraco-ui/uui-color-swatches": "1.14.0-rc.1", - "@umbraco-ui/uui-combobox": "1.14.0-rc.1", - "@umbraco-ui/uui-combobox-list": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2", - "@umbraco-ui/uui-dialog": "1.14.0-rc.2", - "@umbraco-ui/uui-dialog-layout": "1.14.0-rc.1", - "@umbraco-ui/uui-file-dropzone": "1.14.0-rc.1", - "@umbraco-ui/uui-file-preview": "1.14.0-rc.1", - "@umbraco-ui/uui-form": "1.14.0-rc.1", - "@umbraco-ui/uui-form-layout-item": "1.14.0-rc.1", - "@umbraco-ui/uui-form-validation-message": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1", - "@umbraco-ui/uui-input": "1.14.0-rc.3", - "@umbraco-ui/uui-input-file": "1.14.0-rc.1", - "@umbraco-ui/uui-input-lock": "1.14.0-rc.3", - "@umbraco-ui/uui-input-password": "1.14.0-rc.3", - "@umbraco-ui/uui-keyboard-shortcut": "1.14.0-rc.1", - "@umbraco-ui/uui-label": "1.14.0-rc.1", - "@umbraco-ui/uui-loader": "1.14.0-rc.1", - "@umbraco-ui/uui-loader-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-loader-circle": "1.14.0-rc.1", - "@umbraco-ui/uui-menu-item": "1.14.0-rc.1", - "@umbraco-ui/uui-modal": "1.14.0-rc.1", - "@umbraco-ui/uui-pagination": "1.14.0-rc.1", - "@umbraco-ui/uui-popover": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", - "@umbraco-ui/uui-progress-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-radio": "1.14.0-rc.1", - "@umbraco-ui/uui-range-slider": "1.14.0-rc.1", - "@umbraco-ui/uui-ref": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-list": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-data-type": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-document-type": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-form": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-member": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-package": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node-user": "1.14.0-rc.1", - "@umbraco-ui/uui-scroll-container": "1.14.0-rc.1", - "@umbraco-ui/uui-select": "1.14.0-rc.1", - "@umbraco-ui/uui-slider": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-expand": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-dropzone": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-folder": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-lock": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-more": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-sort": "1.14.0-rc.1", - "@umbraco-ui/uui-table": "1.14.0-rc.1", - "@umbraco-ui/uui-tabs": "1.14.0-rc.1", - "@umbraco-ui/uui-tag": "1.14.0-rc.1", - "@umbraco-ui/uui-textarea": "1.14.0-rc.1", - "@umbraco-ui/uui-toast-notification": "1.14.0-rc.2", - "@umbraco-ui/uui-toast-notification-container": "1.14.0-rc.2", - "@umbraco-ui/uui-toast-notification-layout": "1.14.0-rc.2", - "@umbraco-ui/uui-toggle": "1.14.0-rc.1", - "@umbraco-ui/uui-visually-hidden": "1.14.0-rc.1" + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui/-/uui-1.15.0.tgz", + "integrity": "sha512-8yCzfKePv9zK+PMw1K3uwpnDDBZkbSCCOrt8dNDlZ1/6zf+yNLu+r/kVlMcauei6aNsCwXvcI4LhBGS1f5kJ/A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-avatar-group": "1.15.0", + "@umbraco-ui/uui-badge": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-box": "1.15.0", + "@umbraco-ui/uui-breadcrumbs": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-copy-text": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0", + "@umbraco-ui/uui-button-inline-create": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-card-block-type": "1.15.0", + "@umbraco-ui/uui-card-content-node": "1.15.0", + "@umbraco-ui/uui-card-media": "1.15.0", + "@umbraco-ui/uui-card-user": "1.15.0", + "@umbraco-ui/uui-caret": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0", + "@umbraco-ui/uui-color-area": "1.15.0", + "@umbraco-ui/uui-color-picker": "1.15.0", + "@umbraco-ui/uui-color-slider": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0", + "@umbraco-ui/uui-color-swatches": "1.15.0", + "@umbraco-ui/uui-combobox": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-dialog": "1.15.0", + "@umbraco-ui/uui-dialog-layout": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-file-preview": "1.15.0", + "@umbraco-ui/uui-form": "1.15.0", + "@umbraco-ui/uui-form-layout-item": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0", + "@umbraco-ui/uui-input-file": "1.15.0", + "@umbraco-ui/uui-input-lock": "1.15.0", + "@umbraco-ui/uui-input-password": "1.15.0", + "@umbraco-ui/uui-keyboard-shortcut": "1.15.0", + "@umbraco-ui/uui-label": "1.15.0", + "@umbraco-ui/uui-loader": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-loader-circle": "1.15.0", + "@umbraco-ui/uui-menu-item": "1.15.0", + "@umbraco-ui/uui-modal": "1.15.0", + "@umbraco-ui/uui-pagination": "1.15.0", + "@umbraco-ui/uui-popover": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-progress-bar": "1.15.0", + "@umbraco-ui/uui-radio": "1.15.0", + "@umbraco-ui/uui-range-slider": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0", + "@umbraco-ui/uui-ref-list": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0", + "@umbraco-ui/uui-ref-node-data-type": "1.15.0", + "@umbraco-ui/uui-ref-node-document-type": "1.15.0", + "@umbraco-ui/uui-ref-node-form": "1.15.0", + "@umbraco-ui/uui-ref-node-member": "1.15.0", + "@umbraco-ui/uui-ref-node-package": "1.15.0", + "@umbraco-ui/uui-ref-node-user": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-select": "1.15.0", + "@umbraco-ui/uui-slider": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0", + "@umbraco-ui/uui-symbol-lock": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0", + "@umbraco-ui/uui-symbol-sort": "1.15.0", + "@umbraco-ui/uui-table": "1.15.0", + "@umbraco-ui/uui-tabs": "1.15.0", + "@umbraco-ui/uui-tag": "1.15.0", + "@umbraco-ui/uui-textarea": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0", + "@umbraco-ui/uui-toast-notification-container": "1.15.0", + "@umbraco-ui/uui-toast-notification-layout": "1.15.0", + "@umbraco-ui/uui-toggle": "1.15.0", + "@umbraco-ui/uui-visually-hidden": "1.15.0" } }, "node_modules/@umbraco-ui/uui-action-bar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.14.0-rc.1.tgz", - "integrity": "sha512-kgA6W28xL4RVoMj9pZjB5PmVXtPxg60rvgpR1Nz3gqPKFSv6SqdyXGwOg/SrnFKg7TtIgQqZ6uU0+xisoaMMUg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-action-bar/-/uui-action-bar-1.15.0.tgz", + "integrity": "sha512-O0807+bWVWV/rsFihFVKSOkg9wBtLXKCszE5+eZk2KmONm93BFhIAE35rp7eD6X2SuJMHwYzInIxMIMjHzdpUQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button-group": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.14.0-rc.1.tgz", - "integrity": "sha512-JrkkkhEuaAA5BWZbPSTVSBXAGRZEp/2fAzmlZf7iVZexovM0ET3u7dxWbHN/ERU5hryPKW6Ibaa5u63Wr7kAtA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar/-/uui-avatar-1.15.0.tgz", + "integrity": "sha512-eEX83zwRN3tCiHScKcmkROWAfLu3TgFI9SntlbyxiuSSYfhJxWSZXOf6lVvQ/1CyvKq8XqSbBnN3VKXgcaKOpg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-avatar-group": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.14.0-rc.1.tgz", - "integrity": "sha512-fe9OWBkjJZQFztE1I+QYZUgJ+vCKBcLl02oNY6oTZxT/PG/alzVOVtfpjox4deTTFo9nGSLSGm9FgSkC5zLkTQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-avatar-group/-/uui-avatar-group-1.15.0.tgz", + "integrity": "sha512-CGYAFAHgNoQK2UTupP7pO0mwP6t9/Ms6WZ0gIC40a+kPjrGtaDWU52hiPsuXrUcR6WjJwZ5WRrJHOboRpdmM0g==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-avatar": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-badge": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.14.0-rc.1.tgz", - "integrity": "sha512-FwejfZ5ejTohVk4sNyDeArKBcVyPb3j+4IQGRinR5KFBTMZqCJvig16b60cxxqinyeRkAMfQ+dHhj1WqsnNf7Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-badge/-/uui-badge-1.15.0.tgz", + "integrity": "sha512-9aGmhRvey98kcR7wfsnno0BNftIRwJ0r2lCH6cNK2lhe69enYm0MWjp+4uutnlEWWskTLEI344BOqmqOHH1NPA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-base": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.14.0-rc.1.tgz", - "integrity": "sha512-pOI3Nu/QtYxJinJ+8DlmPD7F16+qaFV0UrxxaJZQdecxp2Yg1ri3rHh093ubV+0rIuZ9b5xXsAtbSJqL3tadvw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-base/-/uui-base-1.15.0.tgz", + "integrity": "sha512-0vtKmjzUOn/tIUHNrsx7aZpy3eq9aRKqV9kkJTrhH92S4WcMy+cOB1iw9t3Fe3xlBPuL3JpszwuxMTIuIqJTgQ==", "dev": true, "license": "MIT", "peer": true, @@ -1794,265 +1813,266 @@ } }, "node_modules/@umbraco-ui/uui-boolean-input": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.14.0-rc.1.tgz", - "integrity": "sha512-SNrxTsvUGEfm+5ZDKDUsYuaUoHj7MnNP3yp5t6FcCUFDpd4XRryScI7eQf8VVCFkduXmnUnzU9IvkZeHLNiKSg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-boolean-input/-/uui-boolean-input-1.15.0.tgz", + "integrity": "sha512-LkYX+p44mFVdvlZSliP5ClMcyHoOIVLWI3WVkaMLQdNi2LO9bbfaTneLzu4ruW6v0iF+kLsznr3bl73VHk7oEg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-box": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.14.0-rc.2.tgz", - "integrity": "sha512-I816yT+hbkpDNzRmRW8j9S3MDNtn3pVIb38mUgd72fw6VZX3mZRc+2RFCqUVlPl9dRg14gF2e27ni2MPYRQoYQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-box/-/uui-box-1.15.0.tgz", + "integrity": "sha512-MhSNcKsVNymD/yt3NFXujuaQmAqMqj5S+CBoDHEk88H7Id9NMw9RStZFJ37mI2CxHWkeHDotNVgOhSBiHJNJnw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-breadcrumbs": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.14.0-rc.1.tgz", - "integrity": "sha512-mFMVxVBmqN44exBwL6eZ3HutKzE3qoSBTH6HUnDD83/94q4oNSgF1czEviExATQHLPzKOqejet62FACRjryf9g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-breadcrumbs/-/uui-breadcrumbs-1.15.0.tgz", + "integrity": "sha512-TaUY+hNB0VIwv9SBi9fDjIFRtrmmkcT7hlhLCJLUVfQ7jJlGLPISAAdypSplNeCPthYvP1cJQ9m28OzscXHZxQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.14.0-rc.1.tgz", - "integrity": "sha512-4MKFpsXLw7TOTNGyqxKmCkoW8UUQZ78cDSaWkhELAsAmPGg7njLXsNvToNjc3qp0hxo9Ut5uGN6dAIZGRHfLKg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button/-/uui-button-1.15.0.tgz", + "integrity": "sha512-3Oaqj6Yta/Q/Ndme20YA1XbHdBBL71iNhpqREfTHli2YV4TEcgIiNy0s2op2oPhKjIEQPEfitU2BrruYEEWa7Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-copy-text": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.14.0-rc.1.tgz", - "integrity": "sha512-cHuOgMMgSMQSqeYBMZ0W1OIrsTpTieg9KiQCqkidMWISxVVf3XLqp4gP0w8MYF3ljl6/IWX5sZJs/Bg+0RSf4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-copy-text/-/uui-button-copy-text-1.15.0.tgz", + "integrity": "sha512-MAaJzpwVnlyGJNvLv6qIwrYsI5SaXXiVKgVi47I8+x//QmnArmetCN04766gGzmAb0m2uuC3ht0BXMDv05pxvw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-group": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.14.0-rc.1.tgz", - "integrity": "sha512-0Yirkr948H+zL44Vyc6y/Ts0v/02anxaaedKu6G41uCDVjl9CBx/y/cZ7+BLIa5i+uNetiGWMfQbDIqrK61PPw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-group/-/uui-button-group-1.15.0.tgz", + "integrity": "sha512-YPEnubKNbKmw04eWRH24/3Uxu+zhtLPeJoaT6ykPCyjr/EKc82rSTvn8fwQuP41UokQrXOac2pKn7SncyoST1Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-button-inline-create": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.14.0-rc.1.tgz", - "integrity": "sha512-36A/hzbipSR92bUpcLeEs78uralNt8OHDmpywiu0xTyRYjopUoo07R0mfJ9kUyRIWhcO3MidxgZ11X48xCh+Rg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-button-inline-create/-/uui-button-inline-create-1.15.0.tgz", + "integrity": "sha512-nLJZ6P5eK1rYgqjP5zCxbZp8g4WJ23RnUZQ49o7QpU/7zoPOK72/fuM3Ky00Iapixm/kAD6dYHO/P+GtNz8/CA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.14.0-rc.1.tgz", - "integrity": "sha512-U9egiHuD3djkZyqkzzGhBL2TwxWJCzBAu+zxdBljpAH/0OSeooUiW2JEQmZF0B4zUgYNZJBU+Bgb10FhOgNF6w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card/-/uui-card-1.15.0.tgz", + "integrity": "sha512-pNjpk2iIdSsmTtDdBsWaEr8JX0RcWbl8yKGaqLvo/S7d3bly5z+FjcsgGnX1i1GHo7dqmgVJfbdvN9V1jgn+FA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-checkbox": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-block-type": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.14.0-rc.1.tgz", - "integrity": "sha512-1ebp+44VXm2Ob+iewd3JFsNn0jSyiBhaNmxfumq/B9M+TPBiupbLLSddR0CGNn3rk81IatgZwwW0H1yWfyHQ8Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-block-type/-/uui-card-block-type-1.15.0.tgz", + "integrity": "sha512-cWag+D0XrogYZesAN8NMPQCCuU7L7uZ4Xz8dmirKQk1gjMrFDC4vYPZRQ/5O3ETTFupfDipVKimgRDsmarbLSQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-content-node": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.14.0-rc.1.tgz", - "integrity": "sha512-d/DSllcF+ZO/17SZyq8I7hk8lC+yad8tKEHpveJEgO4EG86wljCS2mdmDUgu6x1yvidViqe/AbgRA7MzvdpSeQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-content-node/-/uui-card-content-node-1.15.0.tgz", + "integrity": "sha512-DZ6JYNvGb5wVkhhLShENMm+Y6kTpz37YrApQTJVUUgPXhIABO2CDCnqgpH5tkQX73s9jjVB3Ca7SeivuYv8G9A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-media": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.14.0-rc.1.tgz", - "integrity": "sha512-XKDaXoLxEkeM50ExKmUejO0x3OWWiyQNtEZ23hvGC8iY8l9WUk9YZRlWqir8UlcZNQZpEnLuqSgxn/rBoXHZdQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-media/-/uui-card-media-1.15.0.tgz", + "integrity": "sha512-EzYebWCzR0wHY902NmAcTRSVSscYac3QntCz+xwSulrhzfy4copeOd1qE+Lz7FjHs+ho0IBPZol8sF4W6rK8FQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-folder": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-card-user": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.14.0-rc.1.tgz", - "integrity": "sha512-ONOpCMz3yZtZcyZYHUI0UpKJNDxISTzCV1lFzhjdBhmYdZ70Dmnl6/w6DZhpPg+s0z7SZvcck38XZ/UaBTCMnQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-card-user/-/uui-card-user-1.15.0.tgz", + "integrity": "sha512-oo7gCs3RGJ4ujFs+LpG9I1DS/XSNkz9gaqvp4BkaR0kBXzw5f2SLLGhA9S3M6M+OPlsXuuJNKlTV1tn2+LF6Ng==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-avatar": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-card": "1.14.0-rc.1" + "@umbraco-ui/uui-avatar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-card": "1.15.0" } }, "node_modules/@umbraco-ui/uui-caret": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.14.0-rc.1.tgz", - "integrity": "sha512-P8jAhm98B+bgIyMok/ZHFHtFVDuICgJ+Vn/yyKfX3g1yXBqdgmVS/LJyxbvldZLekgOczQDiY+KrjiQ8Y72pUQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-caret/-/uui-caret-1.15.0.tgz", + "integrity": "sha512-cnKP5GeaI028hGabVCki1kPqAVSekFeP7QEwu7lncA+dcX8uvg+ffV6kW9FV0emOhI5Tmxvh8o+UDKlLs28q3A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-checkbox": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.14.0-rc.1.tgz", - "integrity": "sha512-DBjiZtNGJwWPG9VP/7SkWyNiUts6cTR16DCQAeaRtoX+LAz/2jYDA41hQGFW3aHds27BkGtFL5XjkR/1cNRGcg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-checkbox/-/uui-checkbox-1.15.0.tgz", + "integrity": "sha512-vPkgrFAPDMvJdJTADIWNj48D8gJWD3dBotucUghg/wHhvJv8h/2MvnwMUNnnSB1REHbanl7hJBVvKcNkoil0gA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-boolean-input": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-area": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.14.0-rc.1.tgz", - "integrity": "sha512-HQ6IsRxQo2bNzEPbiHlOd9/cYP1uEug6wM6zGgz+80H7mkikl1gDboKEAZolksbsgMzkkBBNFNxKyUdtJjUVJw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-area/-/uui-color-area-1.15.0.tgz", + "integrity": "sha512-k6u//b+s6UYmzKYMizIf2MRGD4kFy1qWdSk1GnIeDdiQxABJuBZEtkACIe66j+lxnonFvZ/assbLbhRiu15ZCw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", + "@umbraco-ui/uui-base": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-picker": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.14.0-rc.1.tgz", - "integrity": "sha512-8GyAg0WAm4L7tiPB8Q9dEIeNwzPSf5SOgc8aAEoNnecJnlBdIj6iIFomV63Nosw3gVEXo8Hg/UuU8xw/BnsLjw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-picker/-/uui-color-picker-1.15.0.tgz", + "integrity": "sha512-I4KGyzZZazjeifcavHp7qnMbP0Jh0dM+gzZhV+YtdPR2JT0o7y6stkbY0f+dOln0K6Bu6BQLV0HLHl/1f/1NDg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-slider": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.14.0-rc.1.tgz", - "integrity": "sha512-sJm3Bw2XgC/rP+/I7a/WI+5/x6YBqMhLauCjV9WscaltsEQNQnSqQAkt1NJWGiv/H8mRH4IvmRvo+HFUQDtaPQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-slider/-/uui-color-slider-1.15.0.tgz", + "integrity": "sha512-lpT9kapypGkTelG9COSk169VKs0MSiKweX8menDDn0p6I4RfKQBy0N27HecCcf1RqPsCnTbP3lPr5DJy00KdzA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-color-swatch": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.14.0-rc.1.tgz", - "integrity": "sha512-IKgEJ/Qo0MmBJDG8/3Izkxf/WVGVq9enNkyI0W3QLrKZeoIA93fNfHKcZxM94ojoW/5JOtzfkeurS5MpzrlC1Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatch/-/uui-color-swatch-1.15.0.tgz", + "integrity": "sha512-1AI0QMr046fKc8xZ4aBO7FDwvggsS9plIpY0W4AGrqQxqGUR2u/mTU49+8xMtboaFOen5RQpJ65DN9hAgeNZ+w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", "colord": "^2.9.3" } }, "node_modules/@umbraco-ui/uui-color-swatches": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.14.0-rc.1.tgz", - "integrity": "sha512-NHRsgivUhyBnQKPjwDJkwZ2LCexNUH53a2/nbta58190qnYEvViiqiLx8AbyHUz6s294X2k3DgH6OG5GcaVxng==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-color-swatches/-/uui-color-swatches-1.15.0.tgz", + "integrity": "sha512-UzlgWdsVHyCM/znFThrfA4A/S/K/R9Nc2KyRYiyy2xgBoP7x2vJ5Rn4mnR02W4bhI3gNgCJ2fqhmyiW4dxyk0Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-color-swatch": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-color-swatch": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.14.0-rc.1.tgz", - "integrity": "sha512-foggvau6rHfhm8zO4DaDJWT/Htbrlfrz6cs9idYQAAt8KKnmRfg4GLiGkDvt62IZl9/LBT2zKOKCa/D/dwVPwg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox/-/uui-combobox-1.15.0.tgz", + "integrity": "sha512-CKslvVRCKCReMr/ZZh4wc3TKJNvFjKVm/hSIvFqCIoJuSKfC4XuLU9SK9FL1s42NUAUmccSD3hATZJZ9VXqY+Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-combobox-list": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", - "@umbraco-ui/uui-scroll-container": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-expand": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-combobox-list": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-scroll-container": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-combobox-list": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.14.0-rc.1.tgz", - "integrity": "sha512-WEJIPN9bm7vFdBbiqKUPaEQmJvcXj161T3AvQjW61cFsSq4Y+kTgTJx9IM2LYKWsXZCyy20yVJ2FW7ipv2K0Ag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-combobox-list/-/uui-combobox-list-1.15.0.tgz", + "integrity": "sha512-e8IhqU9AC5pOqXuzPzI+BDsW97Ac0u1GU/5MIJqRcBZ+ZttPcH4fsm4u8siCHbK1khCG0Vzo7HiKPZ0IuuOslg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-css": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.14.0-rc.2.tgz", - "integrity": "sha512-WnxD2XUGPykJ1uHKVIyZoVa6jlJBYciEmax6xy1sZlahDMIb0C8KgQ3GnocFPKIO5q+e/+zcMsaD5Iu3/4GB4g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-css/-/uui-css-1.15.0.tgz", + "integrity": "sha512-0FPJ/NHE8MSJ7vvdFp4cSWT5L73KS00bUHPyA6oiF/XnE0AfS9TzkSWObdSrU6kyPr/fybVwsycDZNBfPiyrCA==", "dev": true, "license": "MIT", "peer": true, @@ -2061,659 +2081,659 @@ } }, "node_modules/@umbraco-ui/uui-dialog": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.14.0-rc.2.tgz", - "integrity": "sha512-qN3OypIfUfBb9Kwj5ZU+QdOwOvv5vjoOrfey7v6adl8hv78NsDMcH1ez5E2l9HcqZ69S5a5e00RAKQxtI0ftzQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog/-/uui-dialog-1.15.0.tgz", + "integrity": "sha512-iVsrVVnvBrCCT9uJhyBE7b1kXwWUUKDmimhs/TyF1SFjxWP/U0Z99QqqI1pawdad+BuK3oVCmxYOdaReWDQXkQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-dialog-layout": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.14.0-rc.1.tgz", - "integrity": "sha512-a22uNk4cpPg+WEzoHfQo1+TCHGPukZUhFpyDVvL4D+0hBSHAkhAHsv/SIxSbibshgrvFtD+l4SdKZvxeYVxWUA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-dialog-layout/-/uui-dialog-layout-1.15.0.tgz", + "integrity": "sha512-JdDRIzSGGDnvVqXSIhc+5rDXMdYMO+Hd7s2hqLp+iRSn8IHISN/qT1nfFVO9LMbLdcApanl3JJ4Rru9LN4Q3HA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-dropzone": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.14.0-rc.1.tgz", - "integrity": "sha512-8YWpp/3Jbt7a+uDtIuAYQcJjlz6vxYQK4x5CtJ8Tod6Y9NR2bfTGM12BWz9Uhze5SnuYpR8iPsJrfkyTVQ3opQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-dropzone/-/uui-file-dropzone-1.15.0.tgz", + "integrity": "sha512-MhJRkVdDQWKEBvemNRD4bZCuIS0JUll1nNoPK7scA+e6vDmbv25vqPHNXGE/sIpVkChY/L+v+twokzlHn57XMw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-dropzone": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file-dropzone": "1.15.0" } }, "node_modules/@umbraco-ui/uui-file-preview": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.14.0-rc.1.tgz", - "integrity": "sha512-T3aRndX7bUxqxvcbJhSbR99S2VZMI0aqiSXeItkDtZ4dD3wGagvklelPG5ff+CB0UWU7NJGjO6CU1GIpXCaiaQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-file-preview/-/uui-file-preview-1.15.0.tgz", + "integrity": "sha512-AHKIdYLC0ga4Wgr68xtW/gG3NDqn+QhD2aus0l2n4lBoq6OAQ5aZiPwD9i1fCD7dgyjKQ6Ov9PJSaqRYQkOlNA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-file-thumbnail": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-folder": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-symbol-file": "1.15.0", + "@umbraco-ui/uui-symbol-file-thumbnail": "1.15.0", + "@umbraco-ui/uui-symbol-folder": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.14.0-rc.1.tgz", - "integrity": "sha512-vX1A0dWS5sA8H96DXnZ5NipkNRLKKvDn5mT2cWKdWV6ZuzrkTr6FOXIsuHDdXHdWCBWcGbnp5LHZQV0G7uwT2A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form/-/uui-form-1.15.0.tgz", + "integrity": "sha512-4u9ZryfVBunpb0IL0+TevytrISA6S1+AajiK/PUk0JMJfqMuQMjmpnNPdtYRNVgFFIcQFQKipjT/mrHbDVawxw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-layout-item": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.14.0-rc.1.tgz", - "integrity": "sha512-qdakkGDP6c4zg0PatTrAK2sAPpLXaUFyPf7YG7ZLgU9VaKKqbubfF2qjz4R7bwcsKtkqBIBEgZOZgnFmqhHErA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-layout-item/-/uui-form-layout-item-1.15.0.tgz", + "integrity": "sha512-fiWGeQpREnl6k+6VNHz9ixNdEmOoFNm7qsgdIYJ1jCDXBGME1mjxJOr2Eq7UWJuzQM8BeyQEcXq5SVIOv21PRw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-form-validation-message": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-form-validation-message": "1.15.0" } }, "node_modules/@umbraco-ui/uui-form-validation-message": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.14.0-rc.1.tgz", - "integrity": "sha512-qCcLn7F0n53HMFe47NDaGo99l84H2fQoJy5pTYKTT97WIWYfr8ZFwBhRh1NfJ2hSHYqnIb45/LJNH8IBXRCjtQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-form-validation-message/-/uui-form-validation-message-1.15.0.tgz", + "integrity": "sha512-RYfwmjPkY0KumjaalLW8gkasW25Mj87YFAzJn7mAYiZigURape9RqGpvrBfwcMmGj3W2/uVuHxpAHrvweQOt4A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.14.0-rc.1.tgz", - "integrity": "sha512-gDObIbvGfv4ROoHqwj9Tc+dVHgDjGXQ5TxDF94ecL/ZqRR5wYT3Ug1jGzGsRc6yMpo/+GyA4fEpuvFcjOOr67Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon/-/uui-icon-1.15.0.tgz", + "integrity": "sha512-e8/W6gu6kwrodH0f0U70LR5rHQhiZGq3NqLqikAQ1rvmwitXUqtkVXIhkGxSf7M6yPhpmoi2qEEZDQH9cvCE5A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.14.0-rc.1.tgz", - "integrity": "sha512-NudOm3N+ESxsyV/TxbvMlhoxDfm7gdnD/mVrS8w/aITGQuxtfxIUu2eTtLua9l0vDYZ9qtcBgR6Qp9yKFFu+Ag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry/-/uui-icon-registry-1.15.0.tgz", + "integrity": "sha512-nIdzCqoABeRVG6jW045ok649MiAhm5zPdfuMKc1a+TNw9xkKj+vnA1YcjaBN502+AekMhhwnqgj9mLL+mC2VPQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0" } }, "node_modules/@umbraco-ui/uui-icon-registry-essential": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.14.0-rc.1.tgz", - "integrity": "sha512-GGocutOSKx0F1eoAud9DIiR2tfVGyjAzBdczQwE4BPE1R44l7IzKz5by7bHp+d4FmyLkNusaYmXAjBM0BxIV7w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-icon-registry-essential/-/uui-icon-registry-essential-1.15.0.tgz", + "integrity": "sha512-llHFVMlV3Uyg2fHiNt1qfDgRhLthD37uQD2FzlQb0GEYjp+4dE8Jyc/eZW2mqABPweUJACVwbrwBUVrCeQJ1OQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.14.0-rc.3.tgz", - "integrity": "sha512-mnyzgObVWdlitx+8aS4N84ji95Uekd9WhvesOb+bj5Vf5Q7Z8NLgozf8oNcxDa1gg3gFBtV4rwbiWgr2aaKp6Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input/-/uui-input-1.15.0.tgz", + "integrity": "sha512-vPc4I/kkQM9RWfHI0F/OQhoTu+KefplbQp0JEQ4gfr6MwxIm6bBTEuw8T5K9t1DQs8EZ7yeLEsSh65FDPepRtg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-file": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.14.0-rc.1.tgz", - "integrity": "sha512-WIDKvzWSvSHT5VEGDjZuZC8G0DQUBN5a0l2XVGGc82hQPKfDPZKyaoW2KwJtwioYe/XWa6TT5o1W7MLZHkcIVQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-file/-/uui-input-file-1.15.0.tgz", + "integrity": "sha512-VVn2FMsflvEWd6fOX0HQ3JaUh7haznqSqCLTSTOduh/H3jE+dVYCW6YC5uTsxArmOwsSBYSfBQNetW23eJim3Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-action-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-file-dropzone": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-action-bar": "1.15.0", + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-file-dropzone": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-lock": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.14.0-rc.3.tgz", - "integrity": "sha512-oC7CUGhdxyg48/Ul26F6Dl4P0MtHtCHR+N1x+M+FR1EFnItjifeJYYdzpbdd6XM1vGk8amFREPiIQdHU0n2HOA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-lock/-/uui-input-lock-1.15.0.tgz", + "integrity": "sha512-AFyVYNeExHXe10b3/5/BLZOmMKyMxzftsO0HKbaQQuxrxL2SCHsQJRUpxSY+/0vAl2JbNdmrk0HTsP1O4Y9zig==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-input": "1.14.0-rc.3" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-input-password": { - "version": "1.14.0-rc.3", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.14.0-rc.3.tgz", - "integrity": "sha512-XBpvLyBuOJcy06ukvcy16iInxg7V8bwGstEECoqxydzOdCYn+vNe4QbvXp8tf2EgHzM0vFnXLxReRVSUdE+Zkg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-input-password/-/uui-input-password-1.15.0.tgz", + "integrity": "sha512-Pe8lNdHz/6IfbQyWEi0o+pKJ6/zunQ2b8HARCU0a9HFXRDk+XsAuBsn79zQXZl5MvseAUQrnouLwPHpdtMbeMg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1", - "@umbraco-ui/uui-input": "1.14.0-rc.3" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0", + "@umbraco-ui/uui-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-keyboard-shortcut": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.14.0-rc.1.tgz", - "integrity": "sha512-6AkBtciq2D0kQHyATDLXJmLtlAOX4eO0PDQG4SQXY6CHwdU/oZM3EqBw8bFyavxVLmos2glaCImecPnXthfbrQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-keyboard-shortcut/-/uui-keyboard-shortcut-1.15.0.tgz", + "integrity": "sha512-8Q/G5Lg6949BbMHQ1BhZ9UpoJjOQ19w1tl2y0d/rP3w/mKnTQaBSf+MQmA/6kQ/Unb2wHXJANr4pAGpUklOg6A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-label": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.14.0-rc.1.tgz", - "integrity": "sha512-6FW1D5Tfcf1Eq5/S3n8yM9+bWQwJQv3UiVdok4Uy7MVpyIJ2wHvzG4gi/lIG1EcScZtCI+7jM+sQEtlJ6FQjhg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-label/-/uui-label-1.15.0.tgz", + "integrity": "sha512-fnmRl+RGUROERvt+Jw0WiW3Btlddg0Xka6F+gR95gy5gr/v8s34uf1/bbPD3hWUXZPukLmxeMjbzyuqMrO8rpQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.14.0-rc.1.tgz", - "integrity": "sha512-QbnFYYWpn9lb2VCqp1UGPHt8Ox9wQ+Gx9sDsxjwfu4FwV5tRxXX1DSmwPXkeErLs7mZCJ/00vWGv4f3uArYNWw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader/-/uui-loader-1.15.0.tgz", + "integrity": "sha512-HQ2zCp2kz45GWQ3wV153ytuYD2KcdeAA5RRUVrN0Zn3GQB3wfG7xMkQQNRAOWMUdnfqmdQHeK+COO7NaET3VBA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-bar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.14.0-rc.1.tgz", - "integrity": "sha512-+5/hf3df9sHuckPMX1qLhG0ojhSo78FrOleRCU+73ekhamuHc63DhPvoWL+r4JBPcj8/bY6IOm6Wgxhfkdze9w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-bar/-/uui-loader-bar-1.15.0.tgz", + "integrity": "sha512-4eMeerunFc5yZsJIwpHADn8oGcu0Nn36oyKbSd0qC0mNmmN2i8UOF9w4O+lndd2L0Mhv23FGvBRo7mb5EAvWlg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-loader-circle": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.14.0-rc.1.tgz", - "integrity": "sha512-0JLJmz6Zp+0sLnh7dhUMWEhAh3JFz7Ek7AKxIxl7lEiZsPyFVhdj/3m/RuZVFizhNmS2EAdijXedWrx1C5oDvA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-loader-circle/-/uui-loader-circle-1.15.0.tgz", + "integrity": "sha512-4rG8UHvyS2qvsjQYEmYjKX01SRwfk60oH8SSSx8r3z2BM62dCOa+4SBhLxqiBciC/u8FtN8X20MIGE0+eMdtoA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-menu-item": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.14.0-rc.1.tgz", - "integrity": "sha512-tFUPa7xXu+Ol9eJ93gVOxhA0IIf14exO6iJKTIoglnRSz9s8SvPuTeCaLtRBJ3TBscVzvhn1MHktk9DSl74Eig==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-menu-item/-/uui-menu-item-1.15.0.tgz", + "integrity": "sha512-BOebCMB/p4TaK4kJYrYgimC6SSGBHN4y1MytK3tyvObbuj3gVqkbwHW5CZrhK4jMaywRgGq96OsuaGfc52HFog==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-loader-bar": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-expand": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-loader-bar": "1.15.0", + "@umbraco-ui/uui-symbol-expand": "1.15.0" } }, "node_modules/@umbraco-ui/uui-modal": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.14.0-rc.1.tgz", - "integrity": "sha512-SMdArBh1/8cPNoFSsVsK6ntXULRgqLOZDMtTHgAz75nzV+109b22F2Jaj8g72oRVzfRMJN+VrinfKAYSN6dU8A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-modal/-/uui-modal-1.15.0.tgz", + "integrity": "sha512-EDz1Qx+mTXNvOu565IculPCyuuFHwBon2wYnfWDBMoHJ5+P54jBHzg2U/8fUVse7xKPvU21hF4JneAvycNIiGQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-pagination": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.14.0-rc.1.tgz", - "integrity": "sha512-MhzGJ6ZDq2GpKgtSmb+RPri10fWOEAtaFyYaV0dGSSqydv7/aZgFurqlVhuYwyvtZwd8Mc0KBdFPU8DIvacP8g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-pagination/-/uui-pagination-1.15.0.tgz", + "integrity": "sha512-sPVs1bApKupNd2JcSMwFS1060Y++Fti1ybJrafcLh1+h4IjmLDIRTHTTL8C+kei5G2Oi3+Z7vGpLu7lrTAmRlw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-button-group": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-button-group": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.14.0-rc.1.tgz", - "integrity": "sha512-SAwvphLrI7dKJdpASGwewObweVMksKm42fx8ffBsTpDWvBqhbLj5pCnn89Nx39S1KIqVUDNOzzihiTluCgK0+g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover/-/uui-popover-1.15.0.tgz", + "integrity": "sha512-VCHVvO0fd5eL5UvB/RPL/K68UhOgsIpuyr+aXLblaYT/6at2LNosUxR4eRW2r0WOQzOiyE+Nu69pExBKyfT8bw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-popover-container": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.14.0-rc.1.tgz", - "integrity": "sha512-6pr47VkioxRToaXw+EfL+XxLXwXmRfaYFJeMJun6AXhXuMWTeWlfaRP2qOL0cpDoikCEXp7EfOs0RJF6dBE9zw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-popover-container/-/uui-popover-container-1.15.0.tgz", + "integrity": "sha512-54M4G0ru8j5ltPAdDGIxogdmos33hxeQeusI/uMFxo2yqHHyMHRi95vvCdcwFmGlEdFd2rsnxZKfNMUKM99GKQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-progress-bar": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.14.0-rc.1.tgz", - "integrity": "sha512-ECEVeldTgnfE2ke8DId0qRzKzhUxQgkTb5v0Qq6GyZ8PZ2o+8SPBEOCfLjWLWmh4mU089bQ52j+JXUdUwLanOA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-progress-bar/-/uui-progress-bar-1.15.0.tgz", + "integrity": "sha512-vtGUwHaG4EDLQERkwym51OasoWLj30LQLhcCCYXDJtTL1dG2nIKScEtlSUiVh5qRsI+V+kaBYPGD4TFD5o43tQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-radio": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.14.0-rc.1.tgz", - "integrity": "sha512-pdBlfY9P9BtVuMSwkQJ7D4d75a1hFcubhHw5UNdpKewfymgZQ+mKP7tud9OXHmHedgl33fhVhnoT3hIA5sAJJQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-radio/-/uui-radio-1.15.0.tgz", + "integrity": "sha512-5TUF/iWUzbVXvBs9Z273q6s9yLbns8itTiFHCITw5w5fZzDn8R6O5hrOW7tV79kCxAnBSOAVP8v1JhGTwXw19Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-range-slider": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.14.0-rc.1.tgz", - "integrity": "sha512-uOetRX6U+g5mNLRcDH787tEx068zrb8VNSLH8oYz5Gva7rCigz5U34VYjOjYjZRIph0W2CeUowI/FEil6N2/DQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-range-slider/-/uui-range-slider-1.15.0.tgz", + "integrity": "sha512-HMHVdBoB1O39rojofezee2aXGv6CMn7dUFvNefdF9HxmNrIcpFBYXSL8aBt5QJeziFQMwbCtqyY21aUag0nzfw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.14.0-rc.1.tgz", - "integrity": "sha512-5O1ixILx04ZIm9JaQuEz/O5I/LNNY5lOcd+2k52AQEEQFszBrQnEdvmh4iKmzGXRRkfW2c5UjJP5Vt2iy21lag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref/-/uui-ref-1.15.0.tgz", + "integrity": "sha512-w7FZIe5mtsgvsf6hOH5mHKDBzg9Rd/+viyk/xNVs1NeZBn1nWEIHZs0R7YMpv+QxulklhAOpBcbGoUTB8xE+vA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-list": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.14.0-rc.1.tgz", - "integrity": "sha512-dw+RYYK83R8c8DiClTNYp3fpiecExIJtFgbViBbzAu0Y9YX7VT2pTjAQJJtYM+oZ9B+J+mPpCLfErMVNPXHHlA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-list/-/uui-ref-list-1.15.0.tgz", + "integrity": "sha512-UT65bpUmRlEgVuvn2RlTZ5l2WDF82jH1t8g+6HV6OJctpqTKlOfPkQmd6AluESPhHFEwwTydS/M7x+X3Adkdtw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.14.0-rc.1.tgz", - "integrity": "sha512-7G13F0C/h2mqtnejuCoPJQwp3Vcb0iFBjVaTP/6zkcpKe9o16DRbjHOr83mhV5ocFqg4z+LSELh+2faEz0uBag==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node/-/uui-ref-node-1.15.0.tgz", + "integrity": "sha512-ybDqIt1cXd7AiZLZsDrSHCMp2zM8I+0lmN599b3NROjm59SZXIvpbY1TS1gJ45htgsc18x2y+S4laInYu2dGUg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-ref": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-ref": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-data-type": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.14.0-rc.1.tgz", - "integrity": "sha512-CVsyxHab7Ck+spHGp+1JCVJptWSpKmN5AHRaxYX+5JB+bSMcJPEQ8gEcEnPm+or74Fhe1j7tqaxCJfaK+8eTMA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-data-type/-/uui-ref-node-data-type-1.15.0.tgz", + "integrity": "sha512-59s16558ySCX7b9IT/Sorq0fdFeCRENSTa7DIkQUrvVPaFWqKFz9jCYFEqDnH11jZHGsNiYh5YCmWlF/VNbwJQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-document-type": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.14.0-rc.1.tgz", - "integrity": "sha512-3C3cmNc1WdlHaqCteTOAAhxkK58xx4LtsolOXw2UbskQx+nZqy8T9+GvpZvMNqfa7AwM4egi/TQEWCS/pdLDog==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-document-type/-/uui-ref-node-document-type-1.15.0.tgz", + "integrity": "sha512-AWPZPkFGcAkRx4j6JnOi2r3EJxnvZUXfhOWNyWB2/dFRckatPH56+lVkqV+fRC+81emKBSQWkx2NphFzLEMr0A==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-form": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.14.0-rc.1.tgz", - "integrity": "sha512-npyTxiVLD0Td5e1VmAxccEqkXXPnZZWFim8ua0Np9YnpakPndILy1ojMixY5LiwR24zRztF6GNXEYJY5eAb4gQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-form/-/uui-ref-node-form-1.15.0.tgz", + "integrity": "sha512-knIIbbfoWtepOvyC54dCo3xF0Vuap6i5uMQPd+wITCmg56a+yiJFuke+dyzatOIeXzgspLgFUngwQZEj5mJnWA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-member": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.14.0-rc.1.tgz", - "integrity": "sha512-k2hRnwot0gjLi8nYz5sebglVFF2r2ZPTNTQW6RtyHRHmKHEwIQKCNYqcw98Fg8uNsLB3zlbu65BYtxhh9FMgfA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-member/-/uui-ref-node-member-1.15.0.tgz", + "integrity": "sha512-pXvL523m2JR3P8OO+E1AE4YAaYhJLc519CtjNXSuctNIk1yWvwxBu8VozLIQV+xrOXGz+SiXwDkoaRPwjTQKtg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-package": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.14.0-rc.1.tgz", - "integrity": "sha512-Ix72i/STydhfkyK8mzh0Uqem/wLF2h561Wfo8+2szMdiE4Df82YAv+dXOA/DDwBDyDqZ0RSdng4zUVLo4TyVtQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-package/-/uui-ref-node-package-1.15.0.tgz", + "integrity": "sha512-bQWfZPKJyAf2O/YvOD6fVSSpKaYZMBsrEGT+ydLPv3BNJroYHS8+NEbulZxExWztNApTcs6Vo5T19AUz+vsnLQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-ref-node-user": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.14.0-rc.1.tgz", - "integrity": "sha512-axKvqQLksy2IlvW9jzGdKS6z+jZMpN+aoM1+oydiQT5oSTt7jKvV6hC+SFwY/C4ZwXT2wNK8Jcp4hxJdZVRUQg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-ref-node-user/-/uui-ref-node-user-1.15.0.tgz", + "integrity": "sha512-4GpRzhGedMwjqW1Wk7AvgakNCc6S1edYpHWeO6cfmryIm0hvnCfkU132lzLmB+Ag2QIOI8p4Ak0OQHYWd+XZHw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-ref-node": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-ref-node": "1.15.0" } }, "node_modules/@umbraco-ui/uui-scroll-container": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.14.0-rc.1.tgz", - "integrity": "sha512-j+Ieq1wxfHouBXeqncHVsqR7cLC2lFDkmdUC2POJgFGNQre+qoLsBuxCW+DUIlnPDOYK6xtveyx72cnxbM3KVw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-scroll-container/-/uui-scroll-container-1.15.0.tgz", + "integrity": "sha512-L4qM6GPDqu0/9B2OVb3EljZT3zYxbwp6uOz1nfVYpGAWBxd6INOtNbn8WYdZLq6qqa8NR6qK+su2554nInvQGA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-select": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.14.0-rc.1.tgz", - "integrity": "sha512-j0iC0pmMXj5pLAM/aiVtxQY3M9GJUrqB/ORB4lh/EdFzMCIYfuLBCuUsCVwBISLKahiwkbYgVDSSMqx6Wqm+KQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-select/-/uui-select-1.15.0.tgz", + "integrity": "sha512-yRx+TlXBB05jM8ShThRooFgCS5nSN7eAAnpttZgBWqY3sccIVy2Knbkz3kXLJE6ld+bO5nUXhsZBZ34MEHkiog==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-slider": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.14.0-rc.1.tgz", - "integrity": "sha512-f9/vO3G1OnKpQ+ondvT3kPd9QbUm51jrPXoBDia0KmB4sst3md+SYhsCiuDFZHWKZJSiO+DQnJcC2kPnRzfcsg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-slider/-/uui-slider-1.15.0.tgz", + "integrity": "sha512-+OAzOutyUB2WCI+e5aFRoUNsFFuc/hUXnpIjx4P1moOYiggc/NxjaTHz5mxbmkC11yyS+0vpl8lVSZglkLCH5w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-expand": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.14.0-rc.1.tgz", - "integrity": "sha512-v2jyDByfc4c6xqn4MTGbjXHtQzYc0exEfz9IGmGocxmNnQI7EZaXzfHeEQngg3eDp8tOBt4H0rN/2FzZB0nkrA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-expand/-/uui-symbol-expand-1.15.0.tgz", + "integrity": "sha512-6y9rpFfhtuWMnaAamlzrB5Q12dsZ8dprmQaGtKr+g97PTNRPC3/dc5sdROam8VMDAhL9MkfBAZBoS6yAoJsPcQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.14.0-rc.1.tgz", - "integrity": "sha512-fms6F/qRPA9nVGldJ03+/2WyvpQMXylWbo0OZm027egwtIsF5Pg/qLv/TNLd7tWjUPMTPglvdYvNDwSi1wiAIQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file/-/uui-symbol-file-1.15.0.tgz", + "integrity": "sha512-F0BueWxu6J5P7xyzkp1c/eFZJjStsw65hB3bNEmWBOqkm/jbBKg9+Xs99tov+VwCHYOt8T+DuEDkkKmdxVAxyQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-dropzone": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.14.0-rc.1.tgz", - "integrity": "sha512-Y3GB4UAOEQ1yDi7/YHORMZn9He4vXQwwK/KLJKfZZDUoARaOl7o9U742R/qxTtMSV9UNMbXW0fgduf1hHktzdg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-dropzone/-/uui-symbol-file-dropzone-1.15.0.tgz", + "integrity": "sha512-D5DottbukIFxL+YTVEMujHPdqB8Hhw02TKpegfDQb8UGSPC5pCQw4O212TSuyTalKb598niNmCzcjEG5TWNqww==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-file-thumbnail": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.14.0-rc.1.tgz", - "integrity": "sha512-DR/Lk0vBA/IQEq0kGzS8gp980/1H1x1eRFkkQNQzByaacAXYlbC9ia0Sp9ecVubQxRRDik38uWSqCYr/CO+QeQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-file-thumbnail/-/uui-symbol-file-thumbnail-1.15.0.tgz", + "integrity": "sha512-JLcEVnJqv2LL8VtscPCtPKda9ywWzV4vd0XODHLE3iI1cgHeNwMBhxqgkah0ULuw5w2Hrq8gwQ7/DuPHMSIFxw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-folder": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.14.0-rc.1.tgz", - "integrity": "sha512-j/p3f/TtwjMoGM/LMhlG6f/wF1ASOS22eyV0n3rPw934HeAEhNCEwGFlKpzm359BQY9gMA75ULW7K+f5jXrhEA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-folder/-/uui-symbol-folder-1.15.0.tgz", + "integrity": "sha512-CPsr1K5IkdxBgID+xoIcgbumm/z0q+Z/1NPxTO40EL7kx3KOLQ8vwLdOTSW1cTj90JFA9+XuRtOpmMEY0XjICg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-lock": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.14.0-rc.1.tgz", - "integrity": "sha512-mlNE6XkBGf4VggJjsS5HGdmAseLICVloTg96HEoRFsYpAGMtzQb57rif5P5YQMH+S+KyQ4YEULuYAujwla2R3g==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-lock/-/uui-symbol-lock-1.15.0.tgz", + "integrity": "sha512-5QyDNFjiBeuPgalT9zwPMP220zJUHPpbPvCohWCFLn/2JJsa6IjSMtsAcqxI154ZJ9vYX7vYiYUn8tJTY8CHpA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-more": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.14.0-rc.1.tgz", - "integrity": "sha512-bZ6bsKdiprHr4O4IzOp7R7HkRZukIEySfLqkU1Q5CKjX4O25BE1Wlq1+GcSjWjTNAHJg9H3m4kgGh5WgRDKtvQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-more/-/uui-symbol-more-1.15.0.tgz", + "integrity": "sha512-BQq7BwZ7nCcgKE5tMhG6OVYTrrMEIXpx8kQKec/ULgVfs0/Ws6qeH9u4rGVK/yHU8gecd6DSeUczjjq2iS4djA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-symbol-sort": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.14.0-rc.1.tgz", - "integrity": "sha512-K/RKOFSjt2YmnrTBaLg6kNHE9zzMaNRvETSWAbtxQz0TfttOkOszSQqo/HbgDAN+gNIWhRnhvgM1qcaqCLQleg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-symbol-sort/-/uui-symbol-sort-1.15.0.tgz", + "integrity": "sha512-5Akw8T0SV2OrwvPk1JSeFr1clvHE4N0DwceSU9bn9f6gLIGGRxvniJAclQDRI/Woe3hm8waMy6cC2fXfSdc6lg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-table": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.14.0-rc.1.tgz", - "integrity": "sha512-UcIY938Iy96qoU63BIGOi+onW10aRN27y69npB6qeRlVlqMcwS8ywV51qS/KdF/uO7P7uCBhqrAlhE/miVsIGQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-table/-/uui-table-1.15.0.tgz", + "integrity": "sha512-AnPp0QJeI70ucX8ludr3qaFmlxjKZUarX10DI8ieIB8VJiQZo0TjoPcPdSGmZupaPBLiszlpb3rKzGkZhXEIHg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tabs": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.14.0-rc.1.tgz", - "integrity": "sha512-HjdeqlnB+Q+4DAB/N8n/H1MIZcCusJnx4yh2JlrgZjiiQ70cYRSIOfd5MDTjjHHnT/GEehH9Fma9TMBpvjV38A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tabs/-/uui-tabs-1.15.0.tgz", + "integrity": "sha512-oS0eA5Z8+s+5o2ks3WCED5VGP8AunRLyuB2y7kVdRUfhCfck7B9v83zNfxPVoGoVsTDLtAQM1S4P8SHwNRmk7g==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-popover-container": "1.14.0-rc.1", - "@umbraco-ui/uui-symbol-more": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-popover-container": "1.15.0", + "@umbraco-ui/uui-symbol-more": "1.15.0" } }, "node_modules/@umbraco-ui/uui-tag": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.14.0-rc.1.tgz", - "integrity": "sha512-aap19BcZnmGMxjEW2YEHbrgFn9NqZ0zrQDEdYJsUwxCof10nE7cjAqbnPiwUGG1N6P6xkjHAJgvCbyoE0d6pEA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-tag/-/uui-tag-1.15.0.tgz", + "integrity": "sha512-PgyZvAiOZmXmiRW4UhfD6Tybx3ft755aKAVqT8ELpskLSvVr1oz4uTI6+QxoeQ1AkrHovenvIdBX+Iwi91SheQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-textarea": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.14.0-rc.1.tgz", - "integrity": "sha512-Cipf1trREF4MXeAV0YCuFBiEZ5LfmaL2v/gzFsSgSa55EEnmywBlw1J0HuFNBgPQR2o7CHmwiCBF/WKB1d6U1Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-textarea/-/uui-textarea-1.15.0.tgz", + "integrity": "sha512-tk/RVzCxs+KPSJ+qH2Xlr9RYxcdrSNulDKk5sBCQR0A9nwOffa15SGreSMKWgq+gYOVYChHBg/WxLWLq3d7Rlg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.14.0-rc.2.tgz", - "integrity": "sha512-2468kSLWvHpxgk2VrPJIdpA5u4Tk36OMvxmjcEOzJ+NT/Acw01l2DG5K5fL4aV61f9eCHrzjDatY9jNyNE9yfg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification/-/uui-toast-notification-1.15.0.tgz", + "integrity": "sha512-nz+snpjPFE+ftH5R/ekgZYy9ofGAf51yQYjWCtBwkrQ6D1dIBYA6kynZFdqIefrRwJJ5zHpe25BcS/AyRPc/9Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-button": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2", - "@umbraco-ui/uui-icon": "1.14.0-rc.1", - "@umbraco-ui/uui-icon-registry-essential": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-button": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0", + "@umbraco-ui/uui-icon": "1.15.0", + "@umbraco-ui/uui-icon-registry-essential": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-container": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.14.0-rc.2.tgz", - "integrity": "sha512-eGVZbkb/l9zGNu9JSxcbqJ6cC1Bqsytjw7aZN4g1n2KoCbjkqOCCQ+T6fY0CdwF5Au5RwZnTOuWdzvr43zU35w==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-container/-/uui-toast-notification-container-1.15.0.tgz", + "integrity": "sha512-fd5d0DU/x2+u15rP0wrjw29M0oqsDFmnAfbPEdgQoPV+hvq9/SLhxJtzx10ZSNXoyuO9sTK50Q7nYsqOvGCzqg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-toast-notification": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-toast-notification": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toast-notification-layout": { - "version": "1.14.0-rc.2", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.14.0-rc.2.tgz", - "integrity": "sha512-/oON/cmmLjOw6yhEp34EvHMZ/JKQWTtQJOmmC1hkyjG6fzoKOrcpncdJpp8sKgmxD5g8KMmLOElCFFOqyzBBSQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toast-notification-layout/-/uui-toast-notification-layout-1.15.0.tgz", + "integrity": "sha512-uf/e/dVN6kqX76vcawiQM3w1nMHa8A+ZTtNwxtmAZi8bNPwjXLNaqKfeSp2thTByCIzFz7imnft56QtYLbksOA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-css": "1.14.0-rc.2" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-css": "1.15.0" } }, "node_modules/@umbraco-ui/uui-toggle": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.14.0-rc.1.tgz", - "integrity": "sha512-DtgowNYwm7PglwZIbyXGO3JlLUedYBVu8JNvWGQeWpOjZq8B3OQlsDCMPnjCfvTklE/pwI+6CCuiFHbZF2zz1A==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-toggle/-/uui-toggle-1.15.0.tgz", + "integrity": "sha512-WLooENcxuAobbXxN1W2uKGh/cN9k0f3cRmDDtCZdgjeheGlBYWatkc5HQte7zchXHUi0xTrsvBCBa9CsLKN/3Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1", - "@umbraco-ui/uui-boolean-input": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0", + "@umbraco-ui/uui-boolean-input": "1.15.0" } }, "node_modules/@umbraco-ui/uui-visually-hidden": { - "version": "1.14.0-rc.1", - "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.14.0-rc.1.tgz", - "integrity": "sha512-PUCR/1mbeS4ziQ2uNp1egopUHvjwtJBgqyvMuXPSIk2KepkqiXCnU3P2+iDCuaLS79qTYzORiZXEDcNfZ6DSHA==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@umbraco-ui/uui-visually-hidden/-/uui-visually-hidden-1.15.0.tgz", + "integrity": "sha512-vn3dbpYGekAqG944Vkwd0ILQRtTaZtL1BVdsge2UsU8sOsEKwv5YzQal4b+o8yu8nb4vZbWHZ2zRmnpnPgPmjg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@umbraco-ui/uui-base": "1.14.0-rc.1" + "@umbraco-ui/uui-base": "1.15.0" } }, "node_modules/acorn": { @@ -2729,6 +2749,16 @@ "node": ">=0.4.0" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -2791,6 +2821,22 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/c12": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/c12/-/c12-2.0.1.tgz", @@ -2919,6 +2965,16 @@ "dev": true, "license": "MIT" }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -2972,6 +3028,49 @@ "license": "MIT", "peer": true }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/defu": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", @@ -3246,6 +3345,22 @@ "dev": true, "license": "MIT" }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -3256,6 +3371,25 @@ "node": ">=8" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-node-process": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", @@ -3263,6 +3397,22 @@ "dev": true, "license": "MIT" }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jiti": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", @@ -3306,9 +3456,9 @@ "peer": true }, "node_modules/lit": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.0.tgz", - "integrity": "sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.1.tgz", + "integrity": "sha512-Ksr/8L3PTapbdXJCk+EJVB78jDodUMaP54gD24W186zGRARvwrsPfS60wae/SSCTCNZVPd1chXqio1qHQmu4NA==", "dev": true, "license": "BSD-3-Clause", "peer": true, @@ -3319,22 +3469,22 @@ } }, "node_modules/lit-element": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.0.tgz", - "integrity": "sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.1.tgz", + "integrity": "sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==", "dev": true, "license": "BSD-3-Clause", "peer": true, "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit-labs/ssr-dom-shim": "^1.4.0", "@lit/reactive-element": "^2.1.0", "lit-html": "^3.3.0" } }, "node_modules/lit-html": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.0.tgz", - "integrity": "sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.1.tgz", + "integrity": "sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==", "dev": true, "license": "BSD-3-Clause", "peer": true, @@ -3601,6 +3751,25 @@ "dev": true, "license": "MIT" }, + "node_modules/open": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz", + "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/orderedmap": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", @@ -3706,9 +3875,9 @@ } }, "node_modules/prosemirror-changeset": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.0.tgz", - "integrity": "sha512-8wRKhlEwEJ4I13Ju54q2NZR1pVKGTgJ/8XsQ8L5A5uUsQ/YQScQJuEAuh8Bn8i6IwAMjjLRABd9lVli+DlIiVw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz", + "integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==", "dev": true, "license": "MIT", "peer": true, @@ -3833,9 +4002,9 @@ } }, "node_modules/prosemirror-model": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.1.tgz", - "integrity": "sha512-AUvbm7qqmpZa5d9fPKMvH1Q5bqYQvAZWOGRvxsB6iFLyycvC9MwNemNVjHVrWgjaoxAfY8XVg7DbvQ/qxvI9Eg==", + "version": "1.25.3", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.3.tgz", + "integrity": "sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==", "dev": true, "license": "MIT", "peer": true, @@ -3924,9 +4093,9 @@ } }, "node_modules/prosemirror-view": { - "version": "1.39.3", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.39.3.tgz", - "integrity": "sha512-bY/7kg0LzRE7ytR0zRdSMWX3sknEjw68l836ffLPMh0OG3OYnNuBDUSF3v0vjvnzgYjgY9ZH/RypbARURlcMFA==", + "version": "1.40.1", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.40.1.tgz", + "integrity": "sha512-pbwUjt3G7TlsQQHDiYSupWBhJswpLVB09xXm1YiJPdkjkh9Pe7Y51XdLh5VWIZmROLY8UpUpG03lkdhm9lzIBA==", "dev": true, "license": "MIT", "peer": true, @@ -4067,6 +4236,19 @@ "license": "MIT", "peer": true }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -4078,6 +4260,19 @@ "tslib": "^2.1.0" } }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", diff --git a/src/Umbraco.Web.UI.Login/package.json b/src/Umbraco.Web.UI.Login/package.json index f108d937d27a..e1ddaa5a9f4f 100644 --- a/src/Umbraco.Web.UI.Login/package.json +++ b/src/Umbraco.Web.UI.Login/package.json @@ -14,9 +14,8 @@ "npm": ">=10.9" }, "devDependencies": { - "@hey-api/client-fetch": "^0.10.2", - "@hey-api/openapi-ts": "^0.67.6", - "@umbraco-cms/backoffice": "16.0.0-rc4", + "@hey-api/openapi-ts": "0.81.1", + "@umbraco-cms/backoffice": "16.2.0-rc", "msw": "^2.7.0", "typescript": "^5.8.3", "vite": "^6.3.5" @@ -26,4 +25,4 @@ "public" ] } -} +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Login/src/api/client.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client.gen.ts index 6759c1f28e3b..163da4e54e92 100644 --- a/src/Umbraco.Web.UI.Login/src/api/client.gen.ts +++ b/src/Umbraco.Web.UI.Login/src/api/client.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts import type { ClientOptions } from './types.gen'; -import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from '@hey-api/client-fetch'; +import { type Config, type ClientOptions as DefaultClientOptions, createClient, createConfig } from './client'; /** * The `createClientConfig()` function will be called on client initialization diff --git a/src/Umbraco.Web.UI.Login/src/api/client/client.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client/client.gen.ts new file mode 100644 index 000000000000..0c60a9ab77ec --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/client.gen.ts @@ -0,0 +1,240 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import type { + Client, + Config, + RequestOptions, + ResolvedRequestOptions, +} from './types.gen'; +import { + buildUrl, + createConfig, + createInterceptors, + getParseAs, + mergeConfigs, + mergeHeaders, + setAuthParams, +} from './utils.gen'; + +type ReqInit = Omit & { + body?: any; + headers: ReturnType; +}; + +export const createClient = (config: Config = {}): Client => { + let _config = mergeConfigs(createConfig(), config); + + const getConfig = (): Config => ({ ..._config }); + + const setConfig = (config: Config): Config => { + _config = mergeConfigs(_config, config); + return getConfig(); + }; + + const interceptors = createInterceptors< + Request, + Response, + unknown, + ResolvedRequestOptions + >(); + + const beforeRequest = async (options: RequestOptions) => { + const opts = { + ..._config, + ...options, + fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, + headers: mergeHeaders(_config.headers, options.headers), + serializedBody: undefined, + }; + + if (opts.security) { + await setAuthParams({ + ...opts, + security: opts.security, + }); + } + + if (opts.requestValidator) { + await opts.requestValidator(opts); + } + + if (opts.body && opts.bodySerializer) { + opts.serializedBody = opts.bodySerializer(opts.body); + } + + // remove Content-Type header if body is empty to avoid sending invalid requests + if (opts.serializedBody === undefined || opts.serializedBody === '') { + opts.headers.delete('Content-Type'); + } + + const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); + const requestInit: ReqInit = { + redirect: 'follow', + ...opts, + body: opts.serializedBody, + }; + + let request = new Request(url, requestInit); + + for (const fn of interceptors.request._fns) { + if (fn) { + request = await fn(request, opts); + } + } + + // fetch must be assigned here, otherwise it would throw the error: + // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation + const _fetch = opts.fetch!; + let response = await _fetch(request); + + for (const fn of interceptors.response._fns) { + if (fn) { + response = await fn(response, request, opts); + } + } + + const result = { + request, + response, + }; + + if (response.ok) { + if ( + response.status === 204 || + response.headers.get('Content-Length') === '0' + ) { + return opts.responseStyle === 'data' + ? {} + : { + data: {}, + ...result, + }; + } + + const parseAs = + (opts.parseAs === 'auto' + ? getParseAs(response.headers.get('Content-Type')) + : opts.parseAs) ?? 'json'; + + let data: any; + switch (parseAs) { + case 'arrayBuffer': + case 'blob': + case 'formData': + case 'json': + case 'text': + data = await response[parseAs](); + break; + case 'stream': + return opts.responseStyle === 'data' + ? response.body + : { + data: response.body, + ...result, + }; + } + + if (parseAs === 'json') { + if (opts.responseValidator) { + await opts.responseValidator(data); + } + + if (opts.responseTransformer) { + data = await opts.responseTransformer(data); + } + } + + return opts.responseStyle === 'data' + ? data + : { + data, + ...result, + }; + } + + const textError = await response.text(); + let jsonError: unknown; + + try { + jsonError = JSON.parse(textError); + } catch { + // noop + } + + const error = jsonError ?? textError; + let finalError = error; + + for (const fn of interceptors.error._fns) { + if (fn) { + finalError = (await fn(error, response, request, opts)) as string; + } + } + + finalError = finalError || ({} as string); + + if (opts.throwOnError) { + throw finalError; + } + + // TODO: we probably want to return error and improve types + return opts.responseStyle === 'data' + ? undefined + : { + error: finalError, + ...result, + }; + }; + + const makeMethodFn = + (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = + (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + url, + }); + }; + + return { + buildUrl, + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), + getConfig, + head: makeMethodFn('HEAD'), + interceptors, + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), + request, + setConfig, + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/client/index.ts b/src/Umbraco.Web.UI.Login/src/api/client/index.ts new file mode 100644 index 000000000000..318a84b6a800 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/index.ts @@ -0,0 +1,25 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type { Auth } from '../core/auth.gen'; +export type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +export { + formDataBodySerializer, + jsonBodySerializer, + urlSearchParamsBodySerializer, +} from '../core/bodySerializer.gen'; +export { buildClientParams } from '../core/params.gen'; +export { createClient } from './client.gen'; +export type { + Client, + ClientOptions, + Config, + CreateClientConfig, + Options, + OptionsLegacyParser, + RequestOptions, + RequestResult, + ResolvedRequestOptions, + ResponseStyle, + TDataShape, +} from './types.gen'; +export { createConfig, mergeHeaders } from './utils.gen'; diff --git a/src/Umbraco.Web.UI.Login/src/api/client/types.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client/types.gen.ts new file mode 100644 index 000000000000..5bde93851e76 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/types.gen.ts @@ -0,0 +1,268 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; +import type { + Client as CoreClient, + Config as CoreConfig, +} from '../core/types.gen'; +import type { Middleware } from './utils.gen'; + +export type ResponseStyle = 'data' | 'fields'; + +export interface Config + extends Omit, + CoreConfig { + /** + * Base URL for all requests made by this client. + */ + baseUrl?: T['baseUrl']; + /** + * Fetch API implementation. You can use this option to provide a custom + * fetch instance. + * + * @default globalThis.fetch + */ + fetch?: (request: Request) => ReturnType; + /** + * Please don't use the Fetch client for Next.js applications. The `next` + * options won't have any effect. + * + * Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead. + */ + next?: never; + /** + * Return the response data parsed in a specified format. By default, `auto` + * will infer the appropriate method from the `Content-Type` response header. + * You can override this behavior with any of the {@link Body} methods. + * Select `stream` if you don't want to parse response data at all. + * + * @default 'auto' + */ + parseAs?: + | 'arrayBuffer' + | 'auto' + | 'blob' + | 'formData' + | 'json' + | 'stream' + | 'text'; + /** + * Should we return only data or multiple fields (data, error, response, etc.)? + * + * @default 'fields' + */ + responseStyle?: ResponseStyle; + /** + * Throw an error instead of returning it in the response? + * + * @default false + */ + throwOnError?: T['throwOnError']; +} + +export interface RequestOptions< + TData = unknown, + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends Config<{ + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { + /** + * Any body that you want to add to your request. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} + */ + body?: unknown; + path?: Record; + query?: Record; + /** + * Security mechanism(s) to use for the request. + */ + security?: ReadonlyArray; + url: Url; +} + +export interface ResolvedRequestOptions< + TResponseStyle extends ResponseStyle = 'fields', + ThrowOnError extends boolean = boolean, + Url extends string = string, +> extends RequestOptions { + serializedBody?: string; +} + +export type RequestResult< + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = ThrowOnError extends true + ? Promise< + TResponseStyle extends 'data' + ? TData extends Record + ? TData[keyof TData] + : TData + : { + data: TData extends Record + ? TData[keyof TData] + : TData; + request: Request; + response: Response; + } + > + : Promise< + TResponseStyle extends 'data' + ? + | (TData extends Record + ? TData[keyof TData] + : TData) + | undefined + : ( + | { + data: TData extends Record + ? TData[keyof TData] + : TData; + error: undefined; + } + | { + data: undefined; + error: TError extends Record + ? TError[keyof TError] + : TError; + } + ) & { + request: Request; + response: Response; + } + >; + +export interface ClientOptions { + baseUrl?: string; + responseStyle?: ResponseStyle; + throwOnError?: boolean; +} + +type MethodFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => RequestResult; + +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + +type RequestFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'> & + Pick< + Required>, + 'method' + >, +) => RequestResult; + +type BuildUrlFn = < + TData extends { + body?: unknown; + path?: Record; + query?: Record; + url: string; + }, +>( + options: Pick & Options, +) => string; + +export type Client = CoreClient< + RequestFn, + Config, + MethodFn, + BuildUrlFn, + SseFn +> & { + interceptors: Middleware; +}; + +/** + * The `createClientConfig()` function will be called on client initialization + * and the returned object will become the client's initial configuration. + * + * You may want to initialize your client this way instead of calling + * `setConfig()`. This is useful for example if you're using Next.js + * to ensure your client always has the correct values. + */ +export type CreateClientConfig = ( + override?: Config, +) => Config & T>; + +export interface TDataShape { + body?: unknown; + headers?: unknown; + path?: unknown; + query?: unknown; + url: string; +} + +type OmitKeys = Pick>; + +export type Options< + TData extends TDataShape = TDataShape, + ThrowOnError extends boolean = boolean, + TResponse = unknown, + TResponseStyle extends ResponseStyle = 'fields', +> = OmitKeys< + RequestOptions, + 'body' | 'path' | 'query' | 'url' +> & + Omit; + +export type OptionsLegacyParser< + TData = unknown, + ThrowOnError extends boolean = boolean, + TResponseStyle extends ResponseStyle = 'fields', +> = TData extends { body?: any } + ? TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'body' | 'headers' | 'url' + > & + TData + : OmitKeys< + RequestOptions, + 'body' | 'url' + > & + TData & + Pick, 'headers'> + : TData extends { headers?: any } + ? OmitKeys< + RequestOptions, + 'headers' | 'url' + > & + TData & + Pick, 'body'> + : OmitKeys, 'url'> & + TData; diff --git a/src/Umbraco.Web.UI.Login/src/api/client/utils.gen.ts b/src/Umbraco.Web.UI.Login/src/api/client/utils.gen.ts new file mode 100644 index 000000000000..a47509522bc5 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/client/utils.gen.ts @@ -0,0 +1,327 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { getAuthToken } from '../core/auth.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; +import { jsonBodySerializer } from '../core/bodySerializer.gen'; +import { + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; +import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; + +export const createQuerySerializer = ({ + allowReserved, + array, + object, +}: QuerySerializerOptions = {}) => { + const querySerializer = (queryParams: T) => { + const search: string[] = []; + if (queryParams && typeof queryParams === 'object') { + for (const name in queryParams) { + const value = queryParams[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + const serializedArray = serializeArrayParam({ + allowReserved, + explode: true, + name, + style: 'form', + value, + ...array, + }); + if (serializedArray) search.push(serializedArray); + } else if (typeof value === 'object') { + const serializedObject = serializeObjectParam({ + allowReserved, + explode: true, + name, + style: 'deepObject', + value: value as Record, + ...object, + }); + if (serializedObject) search.push(serializedObject); + } else { + const serializedPrimitive = serializePrimitiveParam({ + allowReserved, + name, + value: value as string, + }); + if (serializedPrimitive) search.push(serializedPrimitive); + } + } + } + return search.join('&'); + }; + return querySerializer; +}; + +/** + * Infers parseAs value from provided Content-Type header. + */ +export const getParseAs = ( + contentType: string | null, +): Exclude => { + if (!contentType) { + // If no Content-Type header is provided, the best we can do is return the raw response body, + // which is effectively the same as the 'stream' option. + return 'stream'; + } + + const cleanContent = contentType.split(';')[0]?.trim(); + + if (!cleanContent) { + return; + } + + if ( + cleanContent.startsWith('application/json') || + cleanContent.endsWith('+json') + ) { + return 'json'; + } + + if (cleanContent === 'multipart/form-data') { + return 'formData'; + } + + if ( + ['application/', 'audio/', 'image/', 'video/'].some((type) => + cleanContent.startsWith(type), + ) + ) { + return 'blob'; + } + + if (cleanContent.startsWith('text/')) { + return 'text'; + } + + return; +}; + +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + +export const setAuthParams = async ({ + security, + ...options +}: Pick, 'security'> & + Pick & { + headers: Headers; + }) => { + for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + + const token = await getAuthToken(auth, options.auth); + + if (!token) { + continue; + } + + const name = auth.name ?? 'Authorization'; + + switch (auth.in) { + case 'query': + if (!options.query) { + options.query = {}; + } + options.query[name] = token; + break; + case 'cookie': + options.headers.append('Cookie', `${name}=${token}`); + break; + case 'header': + default: + options.headers.set(name, token); + break; + } + } +}; + +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ + baseUrl: options.baseUrl as string, + path: options.path, + query: options.query, + querySerializer: + typeof options.querySerializer === 'function' + ? options.querySerializer + : createQuerySerializer(options.querySerializer), + url: options.url, + }); + +export const mergeConfigs = (a: Config, b: Config): Config => { + const config = { ...a, ...b }; + if (config.baseUrl?.endsWith('/')) { + config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1); + } + config.headers = mergeHeaders(a.headers, b.headers); + return config; +}; + +export const mergeHeaders = ( + ...headers: Array['headers'] | undefined> +): Headers => { + const mergedHeaders = new Headers(); + for (const header of headers) { + if (!header || typeof header !== 'object') { + continue; + } + + const iterator = + header instanceof Headers ? header.entries() : Object.entries(header); + + for (const [key, value] of iterator) { + if (value === null) { + mergedHeaders.delete(key); + } else if (Array.isArray(value)) { + for (const v of value) { + mergedHeaders.append(key, v as string); + } + } else if (value !== undefined) { + // assume object headers are meant to be JSON stringified, i.e. their + // content value in OpenAPI specification is 'application/json' + mergedHeaders.set( + key, + typeof value === 'object' ? JSON.stringify(value) : (value as string), + ); + } + } + } + return mergedHeaders; +}; + +type ErrInterceptor = ( + error: Err, + response: Res, + request: Req, + options: Options, +) => Err | Promise; + +type ReqInterceptor = ( + request: Req, + options: Options, +) => Req | Promise; + +type ResInterceptor = ( + response: Res, + request: Req, + options: Options, +) => Res | Promise; + +class Interceptors { + _fns: (Interceptor | null)[]; + + constructor() { + this._fns = []; + } + + clear() { + this._fns = []; + } + + getInterceptorIndex(id: number | Interceptor): number { + if (typeof id === 'number') { + return this._fns[id] ? id : -1; + } else { + return this._fns.indexOf(id); + } + } + exists(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + return !!this._fns[index]; + } + + eject(id: number | Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = null; + } + } + + update(id: number | Interceptor, fn: Interceptor) { + const index = this.getInterceptorIndex(id); + if (this._fns[index]) { + this._fns[index] = fn; + return id; + } else { + return false; + } + } + + use(fn: Interceptor) { + this._fns = [...this._fns, fn]; + return this._fns.length - 1; + } +} + +// `createInterceptors()` response, meant for external use as it does not +// expose internals +export interface Middleware { + error: Pick< + Interceptors>, + 'eject' | 'use' + >; + request: Pick>, 'eject' | 'use'>; + response: Pick< + Interceptors>, + 'eject' | 'use' + >; +} + +// do not add `Middleware` as return type so we can use _fns internally +export const createInterceptors = () => ({ + error: new Interceptors>(), + request: new Interceptors>(), + response: new Interceptors>(), +}); + +const defaultQuerySerializer = createQuerySerializer({ + allowReserved: false, + array: { + explode: true, + style: 'form', + }, + object: { + explode: true, + style: 'deepObject', + }, +}); + +const defaultHeaders = { + 'Content-Type': 'application/json', +}; + +export const createConfig = ( + override: Config & T> = {}, +): Config & T> => ({ + ...jsonBodySerializer, + headers: defaultHeaders, + parseAs: 'auto', + querySerializer: defaultQuerySerializer, + ...override, +}); diff --git a/src/Umbraco.Web.UI.Login/src/api/core/auth.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/auth.gen.ts new file mode 100644 index 000000000000..f8a73266f934 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/auth.gen.ts @@ -0,0 +1,42 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type AuthToken = string | undefined; + +export interface Auth { + /** + * Which part of the request do we use to send the auth? + * + * @default 'header' + */ + in?: 'header' | 'query' | 'cookie'; + /** + * Header or query parameter name. + * + * @default 'Authorization' + */ + name?: string; + scheme?: 'basic' | 'bearer'; + type: 'apiKey' | 'http'; +} + +export const getAuthToken = async ( + auth: Auth, + callback: ((auth: Auth) => Promise | AuthToken) | AuthToken, +): Promise => { + const token = + typeof callback === 'function' ? await callback(auth) : callback; + + if (!token) { + return; + } + + if (auth.scheme === 'bearer') { + return `Bearer ${token}`; + } + + if (auth.scheme === 'basic') { + return `Basic ${btoa(token)}`; + } + + return token; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/bodySerializer.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/bodySerializer.gen.ts new file mode 100644 index 000000000000..49cd8925e3bd --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/bodySerializer.gen.ts @@ -0,0 +1,92 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { + ArrayStyle, + ObjectStyle, + SerializerOptions, +} from './pathSerializer.gen'; + +export type QuerySerializer = (query: Record) => string; + +export type BodySerializer = (body: any) => any; + +export interface QuerySerializerOptions { + allowReserved?: boolean; + array?: SerializerOptions; + object?: SerializerOptions; +} + +const serializeFormDataPair = ( + data: FormData, + key: string, + value: unknown, +): void => { + if (typeof value === 'string' || value instanceof Blob) { + data.append(key, value); + } else if (value instanceof Date) { + data.append(key, value.toISOString()); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +const serializeUrlSearchParamsPair = ( + data: URLSearchParams, + key: string, + value: unknown, +): void => { + if (typeof value === 'string') { + data.append(key, value); + } else { + data.append(key, JSON.stringify(value)); + } +}; + +export const formDataBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): FormData => { + const data = new FormData(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeFormDataPair(data, key, v)); + } else { + serializeFormDataPair(data, key, value); + } + }); + + return data; + }, +}; + +export const jsonBodySerializer = { + bodySerializer: (body: T): string => + JSON.stringify(body, (_key, value) => + typeof value === 'bigint' ? value.toString() : value, + ), +}; + +export const urlSearchParamsBodySerializer = { + bodySerializer: | Array>>( + body: T, + ): string => { + const data = new URLSearchParams(); + + Object.entries(body).forEach(([key, value]) => { + if (value === undefined || value === null) { + return; + } + if (Array.isArray(value)) { + value.forEach((v) => serializeUrlSearchParamsPair(data, key, v)); + } else { + serializeUrlSearchParamsPair(data, key, value); + } + }); + + return data.toString(); + }, +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/params.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/params.gen.ts new file mode 100644 index 000000000000..71c88e852b72 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/params.gen.ts @@ -0,0 +1,153 @@ +// This file is auto-generated by @hey-api/openapi-ts + +type Slot = 'body' | 'headers' | 'path' | 'query'; + +export type Field = + | { + in: Exclude; + /** + * Field name. This is the name we want the user to see and use. + */ + key: string; + /** + * Field mapped name. This is the name we want to use in the request. + * If omitted, we use the same value as `key`. + */ + map?: string; + } + | { + in: Extract; + /** + * Key isn't required for bodies. + */ + key?: string; + map?: string; + }; + +export interface Fields { + allowExtra?: Partial>; + args?: ReadonlyArray; +} + +export type FieldsConfig = ReadonlyArray; + +const extraPrefixesMap: Record = { + $body_: 'body', + $headers_: 'headers', + $path_: 'path', + $query_: 'query', +}; +const extraPrefixes = Object.entries(extraPrefixesMap); + +type KeyMap = Map< + string, + { + in: Slot; + map?: string; + } +>; + +const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => { + if (!map) { + map = new Map(); + } + + for (const config of fields) { + if ('in' in config) { + if (config.key) { + map.set(config.key, { + in: config.in, + map: config.map, + }); + } + } else if (config.args) { + buildKeyMap(config.args, map); + } + } + + return map; +}; + +interface Params { + body: unknown; + headers: Record; + path: Record; + query: Record; +} + +const stripEmptySlots = (params: Params) => { + for (const [slot, value] of Object.entries(params)) { + if (value && typeof value === 'object' && !Object.keys(value).length) { + delete params[slot as Slot]; + } + } +}; + +export const buildClientParams = ( + args: ReadonlyArray, + fields: FieldsConfig, +) => { + const params: Params = { + body: {}, + headers: {}, + path: {}, + query: {}, + }; + + const map = buildKeyMap(fields); + + let config: FieldsConfig[number] | undefined; + + for (const [index, arg] of args.entries()) { + if (fields[index]) { + config = fields[index]; + } + + if (!config) { + continue; + } + + if ('in' in config) { + if (config.key) { + const field = map.get(config.key)!; + const name = field.map || config.key; + (params[field.in] as Record)[name] = arg; + } else { + params.body = arg; + } + } else { + for (const [key, value] of Object.entries(arg ?? {})) { + const field = map.get(key); + + if (field) { + const name = field.map || key; + (params[field.in] as Record)[name] = value; + } else { + const extra = extraPrefixes.find(([prefix]) => + key.startsWith(prefix), + ); + + if (extra) { + const [prefix, slot] = extra; + (params[slot] as Record)[ + key.slice(prefix.length) + ] = value; + } else { + for (const [slot, allowed] of Object.entries( + config.allowExtra ?? {}, + )) { + if (allowed) { + (params[slot as Slot] as Record)[key] = value; + break; + } + } + } + } + } + } + } + + stripEmptySlots(params); + + return params; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/pathSerializer.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/pathSerializer.gen.ts new file mode 100644 index 000000000000..8d9993104743 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/pathSerializer.gen.ts @@ -0,0 +1,181 @@ +// This file is auto-generated by @hey-api/openapi-ts + +interface SerializeOptions + extends SerializePrimitiveOptions, + SerializerOptions {} + +interface SerializePrimitiveOptions { + allowReserved?: boolean; + name: string; +} + +export interface SerializerOptions { + /** + * @default true + */ + explode: boolean; + style: T; +} + +export type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; +export type ArraySeparatorStyle = ArrayStyle | MatrixStyle; +type MatrixStyle = 'label' | 'matrix' | 'simple'; +export type ObjectStyle = 'form' | 'deepObject'; +type ObjectSeparatorStyle = ObjectStyle | MatrixStyle; + +interface SerializePrimitiveParam extends SerializePrimitiveOptions { + value: string; +} + +export const separatorArrayExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const separatorArrayNoExplode = (style: ArraySeparatorStyle) => { + switch (style) { + case 'form': + return ','; + case 'pipeDelimited': + return '|'; + case 'spaceDelimited': + return '%20'; + default: + return ','; + } +}; + +export const separatorObjectExplode = (style: ObjectSeparatorStyle) => { + switch (style) { + case 'label': + return '.'; + case 'matrix': + return ';'; + case 'simple': + return ','; + default: + return '&'; + } +}; + +export const serializeArrayParam = ({ + allowReserved, + explode, + name, + style, + value, +}: SerializeOptions & { + value: unknown[]; +}) => { + if (!explode) { + const joinedValues = ( + allowReserved ? value : value.map((v) => encodeURIComponent(v as string)) + ).join(separatorArrayNoExplode(style)); + switch (style) { + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + case 'simple': + return joinedValues; + default: + return `${name}=${joinedValues}`; + } + } + + const separator = separatorArrayExplode(style); + const joinedValues = value + .map((v) => { + if (style === 'label' || style === 'simple') { + return allowReserved ? v : encodeURIComponent(v as string); + } + + return serializePrimitiveParam({ + allowReserved, + name, + value: v as string, + }); + }) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; + +export const serializePrimitiveParam = ({ + allowReserved, + name, + value, +}: SerializePrimitiveParam) => { + if (value === undefined || value === null) { + return ''; + } + + if (typeof value === 'object') { + throw new Error( + 'Deeply-nested arrays/objects aren’t supported. Provide your own `querySerializer()` to handle these.', + ); + } + + return `${name}=${allowReserved ? value : encodeURIComponent(value)}`; +}; + +export const serializeObjectParam = ({ + allowReserved, + explode, + name, + style, + value, + valueOnly, +}: SerializeOptions & { + value: Record | Date; + valueOnly?: boolean; +}) => { + if (value instanceof Date) { + return valueOnly ? value.toISOString() : `${name}=${value.toISOString()}`; + } + + if (style !== 'deepObject' && !explode) { + let values: string[] = []; + Object.entries(value).forEach(([key, v]) => { + values = [ + ...values, + key, + allowReserved ? (v as string) : encodeURIComponent(v as string), + ]; + }); + const joinedValues = values.join(','); + switch (style) { + case 'form': + return `${name}=${joinedValues}`; + case 'label': + return `.${joinedValues}`; + case 'matrix': + return `;${name}=${joinedValues}`; + default: + return joinedValues; + } + } + + const separator = separatorObjectExplode(style); + const joinedValues = Object.entries(value) + .map(([key, v]) => + serializePrimitiveParam({ + allowReserved, + name: style === 'deepObject' ? `${name}[${key}]` : key, + value: v as string, + }), + ) + .join(separator); + return style === 'label' || style === 'matrix' + ? separator + joinedValues + : joinedValues; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/serverSentEvents.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/serverSentEvents.gen.ts new file mode 100644 index 000000000000..01b5818fdf12 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/serverSentEvents.gen.ts @@ -0,0 +1,237 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit< + RequestInit, + 'method' +> & + Pick & { + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult< + TData = unknown, + TReturn = void, + TNext = unknown, +> = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = + sseSleepFn ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const response = await fetch(url, { ...options, headers, signal }); + + if (!response.ok) + throw new Error( + `SSE failed: ${response.status} ${response.statusText}`, + ); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body + .pipeThrough(new TextDecoderStream()) + .getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt( + line.replace(/^retry:\s*/, ''), + 10, + ); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if ( + sseMaxRetryAttempts !== undefined && + attempt >= sseMaxRetryAttempts + ) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min( + retryDelay * 2 ** (attempt - 1), + sseMaxRetryDelay ?? 30000, + ); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/types.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/types.gen.ts new file mode 100644 index 000000000000..643c070c9d29 --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/types.gen.ts @@ -0,0 +1,118 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Auth, AuthToken } from './auth.gen'; +import type { + BodySerializer, + QuerySerializer, + QuerySerializerOptions, +} from './bodySerializer.gen'; + +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< + RequestFn = never, + Config = unknown, + MethodFn = never, + BuildUrlFn = never, + SseFn = never, +> = { + /** + * Returns the final request URL. + */ + buildUrl: BuildUrlFn; + getConfig: () => Config; + request: RequestFn; + setConfig: (config: Config) => Config; +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] + ? { sse?: never } + : { sse: { [K in HttpMethod]: SseFn } }); + +export interface Config { + /** + * Auth token or a function returning auth token. The resolved value will be + * added to the request payload as defined by its `security` array. + */ + auth?: ((auth: Auth) => Promise | AuthToken) | AuthToken; + /** + * A function for serializing request body parameter. By default, + * {@link JSON.stringify()} will be used. + */ + bodySerializer?: BodySerializer | null; + /** + * An object containing any HTTP headers that you want to pre-populate your + * `Headers` object with. + * + * {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more} + */ + headers?: + | RequestInit['headers'] + | Record< + string, + | string + | number + | boolean + | (string | number | boolean)[] + | null + | undefined + | unknown + >; + /** + * The request method. + * + * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} + */ + method?: Uppercase; + /** + * A function for serializing request query parameters. By default, arrays + * will be exploded in form style, objects will be exploded in deepObject + * style, and reserved characters are percent-encoded. + * + * This method will have no effect if the native `paramsSerializer()` Axios + * API function is used. + * + * {@link https://swagger.io/docs/specification/serialization/#query View examples} + */ + querySerializer?: QuerySerializer | QuerySerializerOptions; + /** + * A function validating request data. This is useful if you want to ensure + * the request conforms to the desired shape, so it can be safely sent to + * the server. + */ + requestValidator?: (data: unknown) => Promise; + /** + * A function transforming response data before it's returned. This is useful + * for post-processing data, e.g. converting ISO strings into Date objects. + */ + responseTransformer?: (data: unknown) => Promise; + /** + * A function validating response data. This is useful if you want to ensure + * the response conforms to the desired shape, so it can be safely passed to + * the transformers and returned to the user. + */ + responseValidator?: (data: unknown) => Promise; +} + +type IsExactlyNeverOrNeverUndefined = [T] extends [never] + ? true + : [T] extends [never | undefined] + ? [undefined] extends [T] + ? false + : true + : false; + +export type OmitNever> = { + [K in keyof T as IsExactlyNeverOrNeverUndefined extends true + ? never + : K]: T[K]; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/core/utils.gen.ts b/src/Umbraco.Web.UI.Login/src/api/core/utils.gen.ts new file mode 100644 index 000000000000..ac31396feaad --- /dev/null +++ b/src/Umbraco.Web.UI.Login/src/api/core/utils.gen.ts @@ -0,0 +1,114 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }), + ); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +}; diff --git a/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts b/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts index c780cbdccbe2..a1f8a830f3f1 100644 --- a/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts +++ b/src/Umbraco.Web.UI.Login/src/api/sdk.gen.ts @@ -1,7 +1,7 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { Options as ClientOptions, TDataShape, Client } from '@hey-api/client-fetch'; -import type { GetSecurityConfigurationData, GetSecurityConfigurationResponse, PostSecurityForgotPasswordData, PostSecurityForgotPasswordError, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponse, PostSecurityForgotPasswordResetError, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponse, PostSecurityForgotPasswordVerifyError, PostUserInviteData, PostUserInviteError, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordError, PostUserInviteResendData, PostUserInviteResendError, PostUserInviteVerifyData, PostUserInviteVerifyResponse, PostUserInviteVerifyError } from './types.gen'; +import type { Options as ClientOptions, TDataShape, Client } from './client'; +import type { PostSecurityForgotPasswordData, PostSecurityForgotPasswordResponses, PostSecurityForgotPasswordErrors, PostSecurityForgotPasswordResetData, PostSecurityForgotPasswordResetResponses, PostSecurityForgotPasswordResetErrors, PostSecurityForgotPasswordVerifyData, PostSecurityForgotPasswordVerifyResponses, PostSecurityForgotPasswordVerifyErrors, PostUserInviteCreatePasswordData, PostUserInviteCreatePasswordResponses, PostUserInviteCreatePasswordErrors, PostUserInviteVerifyData, PostUserInviteVerifyResponses, PostUserInviteVerifyErrors } from './types.gen'; import { client as _heyApiClient } from './client.gen'; export type Options = ClientOptions & { @@ -18,21 +18,8 @@ export type Options; }; -export const getSecurityConfiguration = (options?: Options) => { - return (options?.client ?? _heyApiClient).get({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1/security/configuration', - ...options - }); -}; - export const postSecurityForgotPassword = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ security: [ { scheme: 'bearer', @@ -49,7 +36,7 @@ export const postSecurityForgotPassword = }; export const postSecurityForgotPasswordReset = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ security: [ { scheme: 'bearer', @@ -66,7 +53,7 @@ export const postSecurityForgotPasswordReset = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ url: '/umbraco/management/api/v1/security/forgot-password/verify', ...options, headers: { @@ -76,25 +63,8 @@ export const postSecurityForgotPasswordVerify = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1/user/invite', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } - }); -}; - export const postUserInviteCreatePassword = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ url: '/umbraco/management/api/v1/user/invite/create-password', ...options, headers: { @@ -104,25 +74,8 @@ export const postUserInviteCreatePassword = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ - security: [ - { - scheme: 'bearer', - type: 'http' - } - ], - url: '/umbraco/management/api/v1/user/invite/resend', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options?.headers - } - }); -}; - export const postUserInviteVerify = (options?: Options) => { - return (options?.client ?? _heyApiClient).post({ + return (options?.client ?? _heyApiClient).post({ url: '/umbraco/management/api/v1/user/invite/verify', ...options, headers: { diff --git a/src/Umbraco.Web.UI.Login/src/api/types.gen.ts b/src/Umbraco.Web.UI.Login/src/api/types.gen.ts index aad460ad8c0c..0171a9aa0715 100644 --- a/src/Umbraco.Web.UI.Login/src/api/types.gen.ts +++ b/src/Umbraco.Web.UI.Login/src/api/types.gen.ts @@ -1,28 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts -export type CreateInitialPasswordUserRequestModel = { +export type VerifyResetPasswordTokenRequestModel = { user: ReferenceByIdModel; - token: string; - password: string; -}; - -export type InviteUserRequestModel = { - email: string; - userName: string; - name: string; - userGroupIds: Array; - id?: string | null; - message?: string | null; + resetCode: string; }; -export type PagedProblemDetailsModel = { - total: number; - items: Array; +export type ReferenceByIdModel = { + id: string; }; -export type PagedReferenceByIdModel = { - total: number; - items: Array; +export type VerifyResetPasswordResponseModel = { + passwordConfiguration: PasswordConfigurationResponseModel; }; export type PasswordConfigurationResponseModel = { @@ -33,30 +21,13 @@ export type PasswordConfigurationResponseModel = { requireUppercase: boolean; }; -export type ProblemDetails = { - type?: string | null; - title?: string | null; - status?: number | null; - detail?: string | null; - instance?: string | null; - [key: string]: unknown | (string | null) | (string | null) | (number | null) | (string | null) | (string | null) | undefined; -}; - -export type ProblemDetailsBuilderModel = { - [key: string]: never; -}; - -export type ReferenceByIdModel = { - id: string; +export type VerifyInviteUserResponseModel = { + passwordConfiguration: PasswordConfigurationResponseModel; }; -export type ResendInviteUserRequestModel = { +export type VerifyInviteUserRequestModel = { user: ReferenceByIdModel; - message?: string | null; -}; - -export type ResetPasswordRequestModel = { - email: string; + token: string; }; export type ResetPasswordTokenRequestModel = { @@ -65,59 +36,43 @@ export type ResetPasswordTokenRequestModel = { password: string; }; -export type ResetPasswordUserResponseModel = { - resetPassword?: string | null; +export type ResetPasswordRequestModel = { + email: string; }; -export type SecurityConfigurationResponseModel = { - passwordConfiguration: PasswordConfigurationResponseModel; +export type ProblemDetailsBuilderModel = { + [key: string]: never; }; -export type VerifyInviteUserRequestModel = { - user: ReferenceByIdModel; - token: string; +export type ProblemDetails = { + type?: string | null; + title?: string | null; + status?: number | null; + detail?: string | null; + instance?: string | null; + [key: string]: unknown | (string | null) | (string | null) | (number | null) | (string | null) | (string | null) | undefined; }; -export type VerifyInviteUserResponseModel = { - passwordConfiguration: PasswordConfigurationResponseModel; +export type NotificationHeaderModel = { + message: string; + category: string; + type: EventMessageTypeModel; }; -export type VerifyResetPasswordResponseModel = { - passwordConfiguration: PasswordConfigurationResponseModel; -}; +export enum EventMessageTypeModel { + DEFAULT = 'Default', + INFO = 'Info', + ERROR = 'Error', + SUCCESS = 'Success', + WARNING = 'Warning' +} -export type VerifyResetPasswordTokenRequestModel = { +export type CreateInitialPasswordUserRequestModel = { user: ReferenceByIdModel; - resetCode: string; -}; - -export type GetSecurityConfigurationData = { - body?: never; - path?: never; - query?: never; - url: '/umbraco/management/api/v1/security/configuration'; -}; - -export type GetSecurityConfigurationErrors = { - /** - * The resource is protected and requires an authentication token - */ - 401: unknown; - /** - * The authenticated user does not have access to this resource - */ - 403: unknown; -}; - -export type GetSecurityConfigurationResponses = { - /** - * OK - */ - 200: SecurityConfigurationResponseModel; + token: string; + password: string; }; -export type GetSecurityConfigurationResponse = GetSecurityConfigurationResponses[keyof GetSecurityConfigurationResponses]; - export type PostSecurityForgotPasswordData = { body?: ResetPasswordRequestModel; path?: never; @@ -215,41 +170,6 @@ export type PostSecurityForgotPasswordVerifyResponses = { export type PostSecurityForgotPasswordVerifyResponse = PostSecurityForgotPasswordVerifyResponses[keyof PostSecurityForgotPasswordVerifyResponses]; -export type PostUserInviteData = { - body?: InviteUserRequestModel; - path?: never; - query?: never; - url: '/umbraco/management/api/v1/user/invite'; -}; - -export type PostUserInviteErrors = { - /** - * Bad Request - */ - 400: ProblemDetails; - /** - * The resource is protected and requires an authentication token - */ - 401: unknown; - /** - * The authenticated user does not have access to this resource - */ - 403: unknown; - /** - * Not Found - */ - 404: ProblemDetails; -}; - -export type PostUserInviteError = PostUserInviteErrors[keyof PostUserInviteErrors]; - -export type PostUserInviteResponses = { - /** - * Created - */ - 201: unknown; -}; - export type PostUserInviteCreatePasswordData = { body?: CreateInitialPasswordUserRequestModel; path?: never; @@ -281,41 +201,6 @@ export type PostUserInviteCreatePasswordResponses = { 200: unknown; }; -export type PostUserInviteResendData = { - body?: ResendInviteUserRequestModel; - path?: never; - query?: never; - url: '/umbraco/management/api/v1/user/invite/resend'; -}; - -export type PostUserInviteResendErrors = { - /** - * Bad Request - */ - 400: ProblemDetails; - /** - * The resource is protected and requires an authentication token - */ - 401: unknown; - /** - * The authenticated user does not have access to this resource - */ - 403: unknown; - /** - * Not Found - */ - 404: ProblemDetails; -}; - -export type PostUserInviteResendError = PostUserInviteResendErrors[keyof PostUserInviteResendErrors]; - -export type PostUserInviteResendResponses = { - /** - * OK - */ - 200: unknown; -}; - export type PostUserInviteVerifyData = { body?: VerifyInviteUserRequestModel; path?: never; diff --git a/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts b/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts index 202ab042fe99..bce27e852fe0 100644 --- a/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts +++ b/src/Umbraco.Web.UI.Login/src/contexts/auth.repository.ts @@ -14,9 +14,9 @@ import { postUserInviteCreatePassword, postUserInviteVerify, } from '../api/index.js'; -import { isProblemDetails } from '../utils/is-problem-details.function.js'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; +import { isProblemDetailsLike } from '@umbraco-cms/backoffice/resources'; export class UmbAuthRepository extends UmbRepositoryBase { #localize = new UmbLocalizationController(this); @@ -195,7 +195,7 @@ export class UmbAuthRepository extends UmbRepositoryBase { } #getApiErrorDetailText(error: unknown, fallbackText?: string): string | undefined { - if (isProblemDetails(error)) { + if (isProblemDetailsLike(error)) { return error.detail ?? error.title ?? undefined; } diff --git a/templates/UmbracoExtension/Client/package.json b/templates/UmbracoExtension/Client/package.json index 72f8ab4120da..c5a5d53e2e66 100644 --- a/templates/UmbracoExtension/Client/package.json +++ b/templates/UmbracoExtension/Client/package.json @@ -9,7 +9,7 @@ "generate-client": "node scripts/generate-openapi.js https://localhost:44339/umbraco/swagger/umbracoextension/swagger.json" }, "devDependencies": { - "@hey-api/openapi-ts": "^0.80.14", + "@hey-api/openapi-ts": "0.81.1", "@umbraco-cms/backoffice": "^UMBRACO_VERSION_FROM_TEMPLATE", "chalk": "^5.6.0", "cross-env": "^10.0.0", @@ -17,4 +17,4 @@ "typescript": "^5.9.2", "vite": "^7.1.3" } -} +} \ No newline at end of file diff --git a/templates/UmbracoExtension/Client/scripts/generate-openapi.js b/templates/UmbracoExtension/Client/scripts/generate-openapi.js index c54afa56f982..4df6ca1483f5 100644 --- a/templates/UmbracoExtension/Client/scripts/generate-openapi.js +++ b/templates/UmbracoExtension/Client/scripts/generate-openapi.js @@ -32,11 +32,11 @@ fetch(swaggerUrl).then(async (response) => { console.log(`Calling ${chalk.yellow('hey-api')} to generate TypeScript client`); await createClient({ - client: '@hey-api/client-fetch', input: swaggerUrl, output: 'src/api', plugins: [ ...defaultPlugins, + '@hey-api/client-fetch', { name: '@hey-api/sdk', asClass: true, diff --git a/templates/UmbracoExtension/Client/src/api/client/client.gen.ts b/templates/UmbracoExtension/Client/src/api/client/client.gen.ts index 0c606b81c603..0c60a9ab77ec 100644 --- a/templates/UmbracoExtension/Client/src/api/client/client.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/client/client.gen.ts @@ -1,6 +1,13 @@ // This file is auto-generated by @hey-api/openapi-ts -import type { Client, Config, ResolvedRequestOptions } from './types.gen'; +import { createSseClient } from '../core/serverSentEvents.gen'; +import type { HttpMethod } from '../core/types.gen'; +import type { + Client, + Config, + RequestOptions, + ResolvedRequestOptions, +} from './types.gen'; import { buildUrl, createConfig, @@ -33,7 +40,7 @@ export const createClient = (config: Config = {}): Client => { ResolvedRequestOptions >(); - const request: Client['request'] = async (options) => { + const beforeRequest = async (options: RequestOptions) => { const opts = { ..._config, ...options, @@ -63,6 +70,13 @@ export const createClient = (config: Config = {}): Client => { } const url = buildUrl(opts); + + return { opts, url }; + }; + + const request: Client['request'] = async (options) => { + // @ts-expect-error + const { opts, url } = await beforeRequest(options); const requestInit: ReqInit = { redirect: 'follow', ...opts, @@ -180,20 +194,47 @@ export const createClient = (config: Config = {}): Client => { }; }; + const makeMethodFn = + (method: Uppercase) => (options: RequestOptions) => + request({ ...options, method }); + + const makeSseFn = + (method: Uppercase) => async (options: RequestOptions) => { + const { opts, url } = await beforeRequest(options); + return createSseClient({ + ...opts, + body: opts.body as BodyInit | null | undefined, + headers: opts.headers as unknown as Record, + method, + url, + }); + }; + return { buildUrl, - connect: (options) => request({ ...options, method: 'CONNECT' }), - delete: (options) => request({ ...options, method: 'DELETE' }), - get: (options) => request({ ...options, method: 'GET' }), + connect: makeMethodFn('CONNECT'), + delete: makeMethodFn('DELETE'), + get: makeMethodFn('GET'), getConfig, - head: (options) => request({ ...options, method: 'HEAD' }), + head: makeMethodFn('HEAD'), interceptors, - options: (options) => request({ ...options, method: 'OPTIONS' }), - patch: (options) => request({ ...options, method: 'PATCH' }), - post: (options) => request({ ...options, method: 'POST' }), - put: (options) => request({ ...options, method: 'PUT' }), + options: makeMethodFn('OPTIONS'), + patch: makeMethodFn('PATCH'), + post: makeMethodFn('POST'), + put: makeMethodFn('PUT'), request, setConfig, - trace: (options) => request({ ...options, method: 'TRACE' }), - }; + sse: { + connect: makeSseFn('CONNECT'), + delete: makeSseFn('DELETE'), + get: makeSseFn('GET'), + head: makeSseFn('HEAD'), + options: makeSseFn('OPTIONS'), + patch: makeSseFn('PATCH'), + post: makeSseFn('POST'), + put: makeSseFn('PUT'), + trace: makeSseFn('TRACE'), + }, + trace: makeMethodFn('TRACE'), + } as Client; }; diff --git a/templates/UmbracoExtension/Client/src/api/client/types.gen.ts b/templates/UmbracoExtension/Client/src/api/client/types.gen.ts index 2a123be9a16b..5bde93851e76 100644 --- a/templates/UmbracoExtension/Client/src/api/client/types.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/client/types.gen.ts @@ -1,6 +1,10 @@ // This file is auto-generated by @hey-api/openapi-ts import type { Auth } from '../core/auth.gen'; +import type { + ServerSentEventsOptions, + ServerSentEventsResult, +} from '../core/serverSentEvents.gen'; import type { Client as CoreClient, Config as CoreConfig, @@ -61,13 +65,22 @@ export interface Config } export interface RequestOptions< + TData = unknown, TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string, > extends Config<{ - responseStyle: TResponseStyle; - throwOnError: ThrowOnError; - }> { + responseStyle: TResponseStyle; + throwOnError: ThrowOnError; + }>, + Pick< + ServerSentEventsOptions, + | 'onSseError' + | 'onSseEvent' + | 'sseDefaultRetryDelay' + | 'sseMaxRetryAttempts' + | 'sseMaxRetryDelay' + > { /** * Any body that you want to add to your request. * @@ -87,7 +100,7 @@ export interface ResolvedRequestOptions< TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string, -> extends RequestOptions { +> extends RequestOptions { serializedBody?: string; } @@ -148,17 +161,29 @@ type MethodFn = < ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields', >( - options: Omit, 'method'>, + options: Omit, 'method'>, ) => RequestResult; +type SseFn = < + TData = unknown, + TError = unknown, + ThrowOnError extends boolean = false, + TResponseStyle extends ResponseStyle = 'fields', +>( + options: Omit, 'method'>, +) => Promise>; + type RequestFn = < TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields', >( - options: Omit, 'method'> & - Pick>, 'method'>, + options: Omit, 'method'> & + Pick< + Required>, + 'method' + >, ) => RequestResult; type BuildUrlFn = < @@ -172,7 +197,13 @@ type BuildUrlFn = < options: Pick & Options, ) => string; -export type Client = CoreClient & { +export type Client = CoreClient< + RequestFn, + Config, + MethodFn, + BuildUrlFn, + SseFn +> & { interceptors: Middleware; }; @@ -201,9 +232,10 @@ type OmitKeys = Pick>; export type Options< TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, + TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields', > = OmitKeys< - RequestOptions, + RequestOptions, 'body' | 'path' | 'query' | 'url' > & Omit; @@ -215,18 +247,22 @@ export type OptionsLegacyParser< > = TData extends { body?: any } ? TData extends { headers?: any } ? OmitKeys< - RequestOptions, + RequestOptions, 'body' | 'headers' | 'url' > & TData - : OmitKeys, 'body' | 'url'> & + : OmitKeys< + RequestOptions, + 'body' | 'url' + > & TData & - Pick, 'headers'> + Pick, 'headers'> : TData extends { headers?: any } ? OmitKeys< - RequestOptions, + RequestOptions, 'headers' | 'url' > & TData & - Pick, 'body'> - : OmitKeys, 'url'> & TData; + Pick, 'body'> + : OmitKeys, 'url'> & + TData; diff --git a/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts b/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts index 6d82364ef878..a47509522bc5 100644 --- a/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/client/utils.gen.ts @@ -1,99 +1,16 @@ // This file is auto-generated by @hey-api/openapi-ts import { getAuthToken } from '../core/auth.gen'; -import type { - QuerySerializer, - QuerySerializerOptions, -} from '../core/bodySerializer.gen'; +import type { QuerySerializerOptions } from '../core/bodySerializer.gen'; import { jsonBodySerializer } from '../core/bodySerializer.gen'; import { serializeArrayParam, serializeObjectParam, serializePrimitiveParam, } from '../core/pathSerializer.gen'; +import { getUrl } from '../core/utils.gen'; import type { Client, ClientOptions, Config, RequestOptions } from './types.gen'; -interface PathSerializer { - path: Record; - url: string; -} - -const PATH_PARAM_RE = /\{[^{}]+\}/g; - -type ArrayStyle = 'form' | 'spaceDelimited' | 'pipeDelimited'; -type MatrixStyle = 'label' | 'matrix' | 'simple'; -type ArraySeparatorStyle = ArrayStyle | MatrixStyle; - -const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { - let url = _url; - const matches = _url.match(PATH_PARAM_RE); - if (matches) { - for (const match of matches) { - let explode = false; - let name = match.substring(1, match.length - 1); - let style: ArraySeparatorStyle = 'simple'; - - if (name.endsWith('*')) { - explode = true; - name = name.substring(0, name.length - 1); - } - - if (name.startsWith('.')) { - name = name.substring(1); - style = 'label'; - } else if (name.startsWith(';')) { - name = name.substring(1); - style = 'matrix'; - } - - const value = path[name]; - - if (value === undefined || value === null) { - continue; - } - - if (Array.isArray(value)) { - url = url.replace( - match, - serializeArrayParam({ explode, name, style, value }), - ); - continue; - } - - if (typeof value === 'object') { - url = url.replace( - match, - serializeObjectParam({ - explode, - name, - style, - value: value as Record, - valueOnly: true, - }), - ); - continue; - } - - if (style === 'matrix') { - url = url.replace( - match, - `;${serializePrimitiveParam({ - name, - value: value as string, - })}`, - ); - continue; - } - - const replaceValue = encodeURIComponent( - style === 'label' ? `.${value as string}` : (value as string), - ); - url = url.replace(match, replaceValue); - } - } - return url; -}; - export const createQuerySerializer = ({ allowReserved, array, @@ -188,6 +105,25 @@ export const getParseAs = ( return; }; +const checkForExistence = ( + options: Pick & { + headers: Headers; + }, + name?: string, +): boolean => { + if (!name) { + return false; + } + if ( + options.headers.has(name) || + options.query?.[name] || + options.headers.get('Cookie')?.includes(`${name}=`) + ) { + return true; + } + return false; +}; + export const setAuthParams = async ({ security, ...options @@ -196,6 +132,10 @@ export const setAuthParams = async ({ headers: Headers; }) => { for (const auth of security) { + if (checkForExistence(options, auth.name)) { + continue; + } + const token = await getAuthToken(auth, options.auth); if (!token) { @@ -219,13 +159,11 @@ export const setAuthParams = async ({ options.headers.set(name, token); break; } - - return; } }; -export const buildUrl: Client['buildUrl'] = (options) => { - const url = getUrl({ +export const buildUrl: Client['buildUrl'] = (options) => + getUrl({ baseUrl: options.baseUrl as string, path: options.path, query: options.query, @@ -235,36 +173,6 @@ export const buildUrl: Client['buildUrl'] = (options) => { : createQuerySerializer(options.querySerializer), url: options.url, }); - return url; -}; - -export const getUrl = ({ - baseUrl, - path, - query, - querySerializer, - url: _url, -}: { - baseUrl?: string; - path?: Record; - query?: Record; - querySerializer: QuerySerializer; - url: string; -}) => { - const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; - let url = (baseUrl ?? '') + pathUrl; - if (path) { - url = defaultPathSerializer({ path, url }); - } - let search = query ? querySerializer(query) : ''; - if (search.startsWith('?')) { - search = search.substring(1); - } - if (search) { - url += `?${search}`; - } - return url; -}; export const mergeConfigs = (a: Config, b: Config): Config => { const config = { ...a, ...b }; diff --git a/templates/UmbracoExtension/Client/src/api/core/serverSentEvents.gen.ts b/templates/UmbracoExtension/Client/src/api/core/serverSentEvents.gen.ts new file mode 100644 index 000000000000..01b5818fdf12 --- /dev/null +++ b/templates/UmbracoExtension/Client/src/api/core/serverSentEvents.gen.ts @@ -0,0 +1,237 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { Config } from './types.gen'; + +export type ServerSentEventsOptions = Omit< + RequestInit, + 'method' +> & + Pick & { + /** + * Callback invoked when a network or parsing error occurs during streaming. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param error The error that occurred. + */ + onSseError?: (error: unknown) => void; + /** + * Callback invoked when an event is streamed from the server. + * + * This option applies only if the endpoint returns a stream of events. + * + * @param event Event streamed from the server. + * @returns Nothing (void). + */ + onSseEvent?: (event: StreamEvent) => void; + /** + * Default retry delay in milliseconds. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 3000 + */ + sseDefaultRetryDelay?: number; + /** + * Maximum number of retry attempts before giving up. + */ + sseMaxRetryAttempts?: number; + /** + * Maximum retry delay in milliseconds. + * + * Applies only when exponential backoff is used. + * + * This option applies only if the endpoint returns a stream of events. + * + * @default 30000 + */ + sseMaxRetryDelay?: number; + /** + * Optional sleep function for retry backoff. + * + * Defaults to using `setTimeout`. + */ + sseSleepFn?: (ms: number) => Promise; + url: string; + }; + +export interface StreamEvent { + data: TData; + event?: string; + id?: string; + retry?: number; +} + +export type ServerSentEventsResult< + TData = unknown, + TReturn = void, + TNext = unknown, +> = { + stream: AsyncGenerator< + TData extends Record ? TData[keyof TData] : TData, + TReturn, + TNext + >; +}; + +export const createSseClient = ({ + onSseError, + onSseEvent, + responseTransformer, + responseValidator, + sseDefaultRetryDelay, + sseMaxRetryAttempts, + sseMaxRetryDelay, + sseSleepFn, + url, + ...options +}: ServerSentEventsOptions): ServerSentEventsResult => { + let lastEventId: string | undefined; + + const sleep = + sseSleepFn ?? + ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms))); + + const createStream = async function* () { + let retryDelay: number = sseDefaultRetryDelay ?? 3000; + let attempt = 0; + const signal = options.signal ?? new AbortController().signal; + + while (true) { + if (signal.aborted) break; + + attempt++; + + const headers = + options.headers instanceof Headers + ? options.headers + : new Headers(options.headers as Record | undefined); + + if (lastEventId !== undefined) { + headers.set('Last-Event-ID', lastEventId); + } + + try { + const response = await fetch(url, { ...options, headers, signal }); + + if (!response.ok) + throw new Error( + `SSE failed: ${response.status} ${response.statusText}`, + ); + + if (!response.body) throw new Error('No body in SSE response'); + + const reader = response.body + .pipeThrough(new TextDecoderStream()) + .getReader(); + + let buffer = ''; + + const abortHandler = () => { + try { + reader.cancel(); + } catch { + // noop + } + }; + + signal.addEventListener('abort', abortHandler); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += value; + + const chunks = buffer.split('\n\n'); + buffer = chunks.pop() ?? ''; + + for (const chunk of chunks) { + const lines = chunk.split('\n'); + const dataLines: Array = []; + let eventName: string | undefined; + + for (const line of lines) { + if (line.startsWith('data:')) { + dataLines.push(line.replace(/^data:\s*/, '')); + } else if (line.startsWith('event:')) { + eventName = line.replace(/^event:\s*/, ''); + } else if (line.startsWith('id:')) { + lastEventId = line.replace(/^id:\s*/, ''); + } else if (line.startsWith('retry:')) { + const parsed = Number.parseInt( + line.replace(/^retry:\s*/, ''), + 10, + ); + if (!Number.isNaN(parsed)) { + retryDelay = parsed; + } + } + } + + let data: unknown; + let parsedJson = false; + + if (dataLines.length) { + const rawData = dataLines.join('\n'); + try { + data = JSON.parse(rawData); + parsedJson = true; + } catch { + data = rawData; + } + } + + if (parsedJson) { + if (responseValidator) { + await responseValidator(data); + } + + if (responseTransformer) { + data = await responseTransformer(data); + } + } + + onSseEvent?.({ + data, + event: eventName, + id: lastEventId, + retry: retryDelay, + }); + + if (dataLines.length) { + yield data as any; + } + } + } + } finally { + signal.removeEventListener('abort', abortHandler); + reader.releaseLock(); + } + + break; // exit loop on normal completion + } catch (error) { + // connection failed or aborted; retry after delay + onSseError?.(error); + + if ( + sseMaxRetryAttempts !== undefined && + attempt >= sseMaxRetryAttempts + ) { + break; // stop after firing error + } + + // exponential backoff: double retry each attempt, cap at 30s + const backoff = Math.min( + retryDelay * 2 ** (attempt - 1), + sseMaxRetryDelay ?? 30000, + ); + await sleep(backoff); + } + } + }; + + const stream = createStream(); + + return { stream }; +}; diff --git a/templates/UmbracoExtension/Client/src/api/core/types.gen.ts b/templates/UmbracoExtension/Client/src/api/core/types.gen.ts index 5bfae35c0af1..643c070c9d29 100644 --- a/templates/UmbracoExtension/Client/src/api/core/types.gen.ts +++ b/templates/UmbracoExtension/Client/src/api/core/types.gen.ts @@ -7,29 +7,36 @@ import type { QuerySerializerOptions, } from './bodySerializer.gen'; -export interface Client< +export type HttpMethod = + | 'connect' + | 'delete' + | 'get' + | 'head' + | 'options' + | 'patch' + | 'post' + | 'put' + | 'trace'; + +export type Client< RequestFn = never, Config = unknown, MethodFn = never, BuildUrlFn = never, -> { + SseFn = never, +> = { /** * Returns the final request URL. */ buildUrl: BuildUrlFn; - connect: MethodFn; - delete: MethodFn; - get: MethodFn; getConfig: () => Config; - head: MethodFn; - options: MethodFn; - patch: MethodFn; - post: MethodFn; - put: MethodFn; request: RequestFn; setConfig: (config: Config) => Config; - trace: MethodFn; -} +} & { + [K in HttpMethod]: MethodFn; +} & ([SseFn] extends [never] + ? { sse?: never } + : { sse: { [K in HttpMethod]: SseFn } }); export interface Config { /** @@ -65,16 +72,7 @@ export interface Config { * * {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more} */ - method?: - | 'CONNECT' - | 'DELETE' - | 'GET' - | 'HEAD' - | 'OPTIONS' - | 'PATCH' - | 'POST' - | 'PUT' - | 'TRACE'; + method?: Uppercase; /** * A function for serializing request query parameters. By default, arrays * will be exploded in form style, objects will be exploded in deepObject diff --git a/templates/UmbracoExtension/Client/src/api/core/utils.gen.ts b/templates/UmbracoExtension/Client/src/api/core/utils.gen.ts new file mode 100644 index 000000000000..ac31396feaad --- /dev/null +++ b/templates/UmbracoExtension/Client/src/api/core/utils.gen.ts @@ -0,0 +1,114 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import type { QuerySerializer } from './bodySerializer.gen'; +import { + type ArraySeparatorStyle, + serializeArrayParam, + serializeObjectParam, + serializePrimitiveParam, +} from './pathSerializer.gen'; + +export interface PathSerializer { + path: Record; + url: string; +} + +export const PATH_PARAM_RE = /\{[^{}]+\}/g; + +export const defaultPathSerializer = ({ path, url: _url }: PathSerializer) => { + let url = _url; + const matches = _url.match(PATH_PARAM_RE); + if (matches) { + for (const match of matches) { + let explode = false; + let name = match.substring(1, match.length - 1); + let style: ArraySeparatorStyle = 'simple'; + + if (name.endsWith('*')) { + explode = true; + name = name.substring(0, name.length - 1); + } + + if (name.startsWith('.')) { + name = name.substring(1); + style = 'label'; + } else if (name.startsWith(';')) { + name = name.substring(1); + style = 'matrix'; + } + + const value = path[name]; + + if (value === undefined || value === null) { + continue; + } + + if (Array.isArray(value)) { + url = url.replace( + match, + serializeArrayParam({ explode, name, style, value }), + ); + continue; + } + + if (typeof value === 'object') { + url = url.replace( + match, + serializeObjectParam({ + explode, + name, + style, + value: value as Record, + valueOnly: true, + }), + ); + continue; + } + + if (style === 'matrix') { + url = url.replace( + match, + `;${serializePrimitiveParam({ + name, + value: value as string, + })}`, + ); + continue; + } + + const replaceValue = encodeURIComponent( + style === 'label' ? `.${value as string}` : (value as string), + ); + url = url.replace(match, replaceValue); + } + } + return url; +}; + +export const getUrl = ({ + baseUrl, + path, + query, + querySerializer, + url: _url, +}: { + baseUrl?: string; + path?: Record; + query?: Record; + querySerializer: QuerySerializer; + url: string; +}) => { + const pathUrl = _url.startsWith('/') ? _url : `/${_url}`; + let url = (baseUrl ?? '') + pathUrl; + if (path) { + url = defaultPathSerializer({ path, url }); + } + let search = query ? querySerializer(query) : ''; + if (search.startsWith('?')) { + search = search.substring(1); + } + if (search) { + url += `?${search}`; + } + return url; +};