diff --git a/examples/fdc3-appdirectory/apps-with-intents.json b/examples/fdc3-appdirectory/apps-with-intents.json new file mode 100644 index 000000000..a788de7dd --- /dev/null +++ b/examples/fdc3-appdirectory/apps-with-intents.json @@ -0,0 +1,70 @@ +{ + "applications": [ + { + "appId": "Morgan Stanley", + "name": "Morgan Stanley", + "type": "web", + "details": { + "url": "http://www.morganstanley.com" + }, + "interop": { + "intents": {} + } + }, + { + "appId": "Microsoft", + "name": "Microsoft", + "type": "web", + "details": { + "url": "http://www.microsoft.com" + }, + "interop": { + "intents": { + "listensFor": { + "startMicrosoft": { + "name": "startMicrosoft", + "displayName": "StartMicrosoft", + "contexts": [ + "fdc3.nothing" + ] + } + }, + "raises": {} + } + } + }, + { + "appId": "Google", + "name": "Google", + "type": "web", + "details": { + "url": "http://www.google.com" + }, + "interop": { + "intents": { + "listensFor": { + "viewGoogle": { + "name": "viewGoogle", + "displayName": "ViewGoogle", + "contexts": [ + "fdc3.testContext" + ] + } + }, + "raises": {} + } + } + }, + { + "appId": "FINOS FDC3 Workbench", + "name": "FINOS FDC3 Workbench", + "type": "web", + "details": { + "url": "https://fdc3.finos.org/toolbox/fdc3-workbench/" + }, + "interop": { + "intents": {} + } + } + ] +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9c884b7eb..125a5d9cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -127,9 +127,8 @@ }, "examples/js-datagrid/node_modules/@angular-devkit/architect": { "version": "0.1502.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1502.9.tgz", - "integrity": "sha512-CFn+LbtYeLG7WqO+BBSjogl764StHpwgfJnNAXQ/3UouUktZ92z4lxhUm0PwIPb5k0lILsf81ubcS1vzwoXEEg==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "15.2.9", "rxjs": "6.6.7" @@ -142,9 +141,8 @@ }, "examples/js-datagrid/node_modules/@angular-devkit/architect/node_modules/rxjs": { "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -154,15 +152,13 @@ }, "examples/js-datagrid/node_modules/@angular-devkit/architect/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "examples/js-datagrid/node_modules/@angular-devkit/core": { "version": "15.2.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-15.2.9.tgz", - "integrity": "sha512-6u44YJ9tEG2hiWITL1rwA9yP6ot4a3cyN/UOMRkYSa/XO2Gz5/dM3U74E2kwg+P1NcxLXffBWl0rz8/Y/lSZyQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", @@ -186,9 +182,8 @@ }, "examples/js-datagrid/node_modules/@angular-devkit/core/node_modules/rxjs": { "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -198,15 +193,13 @@ }, "examples/js-datagrid/node_modules/@angular-devkit/core/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "examples/js-datagrid/node_modules/@angular-devkit/schematics": { "version": "15.2.9", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-15.2.9.tgz", - "integrity": "sha512-o08nE8sTpfq/Fknrr1rzBsM8vY36BDox+8dOo9Zc/KqcVPwDy94YKRzHb+xxVaU9jy1VYeCjy63mkyELy7Z3zQ==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "15.2.9", "jsonc-parser": "3.2.0", @@ -222,9 +215,8 @@ }, "examples/js-datagrid/node_modules/@angular-devkit/schematics/node_modules/rxjs": { "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "tslib": "^1.9.0" }, @@ -234,15 +226,13 @@ }, "examples/js-datagrid/node_modules/@angular-devkit/schematics/node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, "examples/js-datagrid/node_modules/@angular/cli": { "version": "15.2.9", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-15.2.9.tgz", - "integrity": "sha512-mI6hkGyIJDKd8MRiBl3p5chsUhgnluwmpsq3g1FFPw+wv+eXsPYgCiHqXS/OsK+shFxii9XMxoZQO28bJ4NAOQ==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1502.9", "@angular-devkit/core": "15.2.9", @@ -274,9 +264,8 @@ }, "examples/js-datagrid/node_modules/@schematics/angular": { "version": "15.2.9", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-15.2.9.tgz", - "integrity": "sha512-0Lit6TLNUwcAYiEkXgZp3vY9xAO1cnZCBXuUcp+6v+Ddnrt2w/YOiGe74p21cYe0StkTpTljsqsKBTiX7TMjQg==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "15.2.9", "@angular-devkit/schematics": "15.2.9", @@ -352,9 +341,8 @@ }, "examples/js-datagrid/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -450,9 +438,8 @@ }, "examples/js-datagrid/node_modules/semver": { "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -476,9 +463,8 @@ }, "examples/js-datagrid/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "examples/js-datagrid/node_modules/yargs": { "version": "17.6.2", @@ -665,9 +651,8 @@ }, "node_modules/@angular-devkit/build-angular/node_modules/@babel/runtime": { "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -724,18 +709,16 @@ }, "node_modules/@angular-devkit/build-angular/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@angular-devkit/build-angular/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -790,9 +773,8 @@ }, "node_modules/@angular-devkit/build-angular/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1090,9 +1072,8 @@ }, "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1312,9 +1293,7 @@ }, "node_modules/@babel/code-frame": { "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, + "license": "MIT", "dependencies": { "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" @@ -1325,9 +1304,7 @@ }, "node_modules/@babel/code-frame/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -1337,9 +1314,7 @@ }, "node_modules/@babel/code-frame/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1351,42 +1326,32 @@ }, "node_modules/@babel/code-frame/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "license": "MIT" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/code-frame/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/code-frame/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -1396,9 +1361,8 @@ }, "node_modules/@babel/compat-data": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -1434,9 +1398,8 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1480,9 +1443,8 @@ }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", - "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1492,9 +1454,8 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz", - "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.9", "@babel/helper-validator-option": "^7.22.5", @@ -1511,8 +1472,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/browserslist": { "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -1528,6 +1487,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001517", "electron-to-chromium": "^1.4.477", @@ -1543,18 +1503,16 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz", - "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5", @@ -1575,9 +1533,8 @@ }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1587,9 +1544,8 @@ }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1599,18 +1555,16 @@ }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz", - "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "regexpu-core": "^5.3.1", @@ -1625,9 +1579,8 @@ }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1637,9 +1590,8 @@ }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -1662,27 +1614,24 @@ }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -1693,9 +1642,8 @@ }, "node_modules/@babel/helper-function-name/node_modules/@babel/template": { "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/parser": "^7.22.15", @@ -1707,9 +1655,8 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1719,9 +1666,8 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1731,9 +1677,8 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1743,9 +1688,8 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-module-imports": "^7.22.5", @@ -1762,9 +1706,8 @@ }, "node_modules/@babel/helper-module-transforms/node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1774,9 +1717,8 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1786,18 +1728,16 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz", - "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.5", @@ -1812,9 +1752,8 @@ }, "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1824,9 +1763,8 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", - "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-member-expression-to-functions": "^7.22.5", @@ -1841,9 +1779,8 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1853,9 +1790,8 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -1876,36 +1812,31 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz", - "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.5", @@ -1917,9 +1848,8 @@ }, "node_modules/@babel/helper-wrap-function/node_modules/@babel/template": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.5", "@babel/parser": "^7.22.5", @@ -1931,9 +1861,8 @@ }, "node_modules/@babel/helpers": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", - "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.22.5", "@babel/traverse": "^7.22.6", @@ -1945,9 +1874,8 @@ }, "node_modules/@babel/helpers/node_modules/@babel/template": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.5", "@babel/parser": "^7.22.5", @@ -1959,9 +1887,7 @@ }, "node_modules/@babel/highlight": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -1973,7 +1899,6 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -1984,7 +1909,6 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -1997,7 +1921,6 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "dev": true, "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -2005,12 +1928,10 @@ }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "dev": true, "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.0" @@ -2018,7 +1939,6 @@ }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -2026,7 +1946,6 @@ }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^3.0.0" @@ -2037,9 +1956,8 @@ }, "node_modules/@babel/parser": { "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -2049,9 +1967,8 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", - "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2064,9 +1981,8 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", - "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -2384,9 +2300,8 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", - "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2399,9 +2314,8 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", - "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2558,9 +2472,8 @@ }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -2574,9 +2487,8 @@ }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", - "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2589,9 +2501,8 @@ }, "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz", - "integrity": "sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", @@ -2623,9 +2534,8 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", - "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2638,9 +2548,8 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", - "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2653,9 +2562,8 @@ }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", - "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -2669,9 +2577,8 @@ }, "node_modules/@babel/plugin-transform-class-static-block": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", @@ -2686,9 +2593,8 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", - "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.22.6", @@ -2709,9 +2615,8 @@ }, "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -2721,9 +2626,8 @@ }, "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -2733,9 +2637,8 @@ }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", - "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/template": "^7.22.5" @@ -2749,9 +2652,8 @@ }, "node_modules/@babel/plugin-transform-computed-properties/node_modules/@babel/template": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.5", "@babel/parser": "^7.22.5", @@ -2763,9 +2665,8 @@ }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", - "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2778,9 +2679,8 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", - "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -2794,9 +2694,8 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", - "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2809,9 +2708,8 @@ }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -2825,9 +2723,8 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", - "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -2841,9 +2738,8 @@ }, "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -2857,9 +2753,8 @@ }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2872,9 +2767,8 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", - "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.5", "@babel/helper-function-name": "^7.22.5", @@ -2889,9 +2783,8 @@ }, "node_modules/@babel/plugin-transform-json-strings": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -2905,9 +2798,8 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", - "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2920,9 +2812,8 @@ }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -2936,9 +2827,8 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", - "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -2951,9 +2841,8 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", - "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -2967,9 +2856,8 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", @@ -2984,9 +2872,8 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.22.5", @@ -3002,9 +2889,8 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", - "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -3018,9 +2904,8 @@ }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -3034,9 +2919,8 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", - "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3049,9 +2933,8 @@ }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -3065,9 +2948,8 @@ }, "node_modules/@babel/plugin-transform-numeric-separator": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -3081,9 +2963,8 @@ }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.5", "@babel/helper-compilation-targets": "^7.22.5", @@ -3100,9 +2981,8 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", - "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.5" @@ -3116,9 +2996,8 @@ }, "node_modules/@babel/plugin-transform-optional-catch-binding": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -3132,9 +3011,8 @@ }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz", - "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -3149,9 +3027,8 @@ }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3164,9 +3041,8 @@ }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", - "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -3180,9 +3056,8 @@ }, "node_modules/@babel/plugin-transform-private-property-in-object": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.22.5", @@ -3198,9 +3073,8 @@ }, "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -3210,9 +3084,8 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", - "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3225,9 +3098,8 @@ }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", - "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "regenerator-transform": "^0.15.1" @@ -3241,9 +3113,8 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", - "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3275,18 +3146,16 @@ }, "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", - "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3299,9 +3168,8 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", - "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -3315,9 +3183,8 @@ }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", - "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3330,9 +3197,8 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", - "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3345,9 +3211,8 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", - "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3360,9 +3225,8 @@ }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", - "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -3375,9 +3239,8 @@ }, "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", - "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -3391,9 +3254,8 @@ }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", - "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -3407,9 +3269,8 @@ }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", - "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -3511,9 +3372,8 @@ }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -3540,9 +3400,8 @@ }, "node_modules/@babel/runtime": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", - "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -3565,9 +3424,8 @@ }, "node_modules/@babel/traverse": { "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.23.0", @@ -3586,9 +3444,8 @@ }, "node_modules/@babel/traverse/node_modules/@babel/generator": { "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", @@ -3601,9 +3458,8 @@ }, "node_modules/@babel/traverse/node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -3613,9 +3469,8 @@ }, "node_modules/@babel/traverse/node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -3627,9 +3482,8 @@ }, "node_modules/@babel/types": { "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.22.5", "@babel/helper-validator-identifier": "^7.22.20", @@ -3680,460 +3534,115 @@ "node": ">=10.0.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", - "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", + "node_modules/@esbuild/win32-x64": { + "version": "0.17.8", "cpu": [ - "arm" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "android" + "win32" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", - "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", - "cpu": [ - "arm64" - ], + "node_modules/@finos/fdc3": { + "version": "2.0.3", + "license": "Apache-2.0" + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", "dev": true, - "optional": true, - "os": [ - "android" - ], + "license": "MIT" + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=12" + "node": ">=6.9.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", - "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", - "cpu": [ - "x64" - ], + "node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, - "optional": true, - "os": [ - "android" - ], + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, "engines": { "node": ">=12" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", - "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", - "cpu": [ - "arm64" - ], + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", - "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", - "cpu": [ - "x64" - ], + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "license": "MIT", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", - "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", - "cpu": [ - "arm64" - ], + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", - "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", - "cpu": [ - "x64" - ], + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", - "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", - "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", - "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", - "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", - "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", - "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", - "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", - "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", - "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", - "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", - "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", - "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", - "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", - "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.17.8", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@finos/fdc3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@finos/fdc3/-/fdc3-2.0.3.tgz", - "integrity": "sha512-sq+iGbjU6yRl7xHhp62nB1tV4biFaHZgUAInzPTJvzXWl9xjZMmXvvbeZW6WGZaCSvjQhJPSrmWs+4z2c73T+g==" - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -4252,14 +3761,13 @@ } }, "node_modules/@jest/environment": { - "version": "29.5.0", - "dev": true, + "version": "29.7.0", "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0" + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4289,16 +3797,15 @@ } }, "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "dev": true, + "version": "29.7.0", "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4380,11 +3887,10 @@ } }, "node_modules/@jest/schemas": { - "version": "29.4.3", - "dev": true, + "version": "29.6.3", "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4462,11 +3968,10 @@ "license": "MIT" }, "node_modules/@jest/types": { - "version": "29.5.0", - "dev": true, + "version": "29.6.3", "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -4507,9 +4012,8 @@ }, "node_modules/@jridgewell/source-map": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -4549,9 +4053,8 @@ }, "node_modules/@lerna/child-process": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-7.1.1.tgz", - "integrity": "sha512-mR8PaTkckYPLmEBG2VsVsJq2UuzEvjXevOB1rKLKUZ/dPCGcottVhbiEzTxickc+s7Y/1dTTLn/1BKj3B1a5BA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "execa": "^5.0.0", @@ -4563,9 +4066,8 @@ }, "node_modules/@lerna/create": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-7.1.1.tgz", - "integrity": "sha512-1PY2OgwGxp7b91JzLKEhONVl69mCt1IyYEc6pzKy3Sv+UOdeK2QFq1SX/85hNOR3iitiyZ75bNWUTcBly1ZlZg==", "dev": true, + "license": "MIT", "dependencies": { "@lerna/child-process": "7.1.1", "dedent": "0.7.0", @@ -5374,9 +4876,8 @@ }, "node_modules/@npmcli/git": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-4.1.0.tgz", - "integrity": "sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==", "dev": true, + "license": "ISC", "dependencies": { "@npmcli/promise-spawn": "^6.0.0", "lru-cache": "^7.4.4", @@ -5393,18 +4894,16 @@ }, "node_modules/@npmcli/git/node_modules/lru-cache": { "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/@npmcli/git/node_modules/which": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5452,9 +4951,8 @@ }, "node_modules/@npmcli/promise-spawn": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", - "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", "dev": true, + "license": "ISC", "dependencies": { "which": "^3.0.0" }, @@ -5464,9 +4962,8 @@ }, "node_modules/@npmcli/promise-spawn/node_modules/which": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5479,9 +4976,8 @@ }, "node_modules/@npmcli/run-script": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-6.0.2.tgz", - "integrity": "sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==", "dev": true, + "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^3.0.0", "@npmcli/promise-spawn": "^6.0.0", @@ -5495,238 +4991,85 @@ }, "node_modules/@npmcli/run-script/node_modules/which": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/which.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@nrwl/devkit": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-16.5.0.tgz", - "integrity": "sha512-O/CH43gM2sumfO1BX7f20B4rniE9P48XwMEQoi1HssdzL+IstHWw5Q9BO2uoSCNpu5x04V/VzX/8yFmoFmOJ7g==", - "dev": true, - "dependencies": { - "@nx/devkit": "16.5.0" - } - }, - "node_modules/@nrwl/tao": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-16.5.0.tgz", - "integrity": "sha512-lY/XV2n7iulHY77Uakt3Epa9m/NG7oTSN196baLjFykxUvLJI47PMX5qytugHkS8JLdcAB5p0qGsrQSHoi6jvg==", - "dev": true, - "dependencies": { - "nx": "16.5.0" - }, - "bin": { - "tao": "index.js" - } - }, - "node_modules/@nx/devkit": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-16.5.0.tgz", - "integrity": "sha512-IfGGKwgOBZshgRtL0V0IOuTaW8mnuSFft708fQfRyw8ArpNeyJbdbIvd9lCsHAFaKE5VTIKug4C48tyQikM7eA==", - "dev": true, - "dependencies": { - "@nrwl/devkit": "16.5.0", - "ejs": "^3.1.7", - "ignore": "^5.0.4", - "semver": "7.5.3", - "tmp": "~0.2.1", - "tslib": "^2.3.0" - }, - "peerDependencies": { - "nx": ">= 15 <= 17" - } - }, - "node_modules/@nx/devkit/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@nx/devkit/node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@nx/devkit/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/@nx/nx-darwin-arm64": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.5.0.tgz", - "integrity": "sha512-0+5FH3ot5o0lpL0OKD4fO2n0a6LqLxr0LwU2VYxaAR1GLzOeVE5W3jBWY9ztOE+ktm8mGaZsdIIOQ77Iz/xwsQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-darwin-x64": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.5.0.tgz", - "integrity": "sha512-yziX2oXUSyOPOcRLmFMRsNs0eBVla5IGjAKqpY4OXAPBuyrOfgsW5ztj0PQM34gvqipXtTlN04Xt/U0jzQLudA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-freebsd-x64": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.5.0.tgz", - "integrity": "sha512-hwIRRMyWrT2R4ozp6yXRNR1fwcclBlkkIQ51/1IzINPQxynMguuOvNZaJFD4OuZIDmI526++GmogPZc0aMzwkg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + }, "engines": { - "node": ">= 10" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@nx/nx-linux-arm-gnueabihf": { + "node_modules/@nrwl/devkit": { "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.5.0.tgz", - "integrity": "sha512-BEWLpBhJ2AcZNDsiExLDcM9kmQ4+E+0YUcOsrAeX1s5D4HXXVtHMdTmOucKs4NNFqMuJ2Cf3ZzqmAIkRug0beA==", - "cpu": [ - "arm" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" + "license": "MIT", + "dependencies": { + "@nx/devkit": "16.5.0" } }, - "node_modules/@nx/nx-linux-arm64-gnu": { + "node_modules/@nrwl/tao": { "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.5.0.tgz", - "integrity": "sha512-EWmTbDLbBIjM/OJ594hoFKsEka/b8jM6NehL37mlIXL6fixUEA8LlO0MfUQ+kIPg79nWIujzulkIEhYFDWM1WA==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" + "license": "MIT", + "dependencies": { + "nx": "16.5.0" + }, + "bin": { + "tao": "index.js" } }, - "node_modules/@nx/nx-linux-arm64-musl": { + "node_modules/@nx/devkit": { "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.5.0.tgz", - "integrity": "sha512-np/7+HEtEEvtu4zo3GBBPtTG8IP++vvH3o8VXpAB9eD4Jctz3rYzbfMc7GtLZkz8LCmCsjzqnrNtmcmoaRbomQ==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" + "license": "MIT", + "dependencies": { + "@nrwl/devkit": "16.5.0", + "ejs": "^3.1.7", + "ignore": "^5.0.4", + "semver": "7.5.3", + "tmp": "~0.2.1", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "nx": ">= 15 <= 17" } }, - "node_modules/@nx/nx-linux-x64-gnu": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.5.0.tgz", - "integrity": "sha512-iLOwgAaa1BHPLFhkBVi7GLAf6LfdYuv/R2rxlqq4d6fhv4Eq91Wo08LsqbFds+LpMN0CA+W/QMc3w9IIS/MPrA==", - "cpu": [ - "x64" - ], + "node_modules/@nx/devkit/node_modules/lru-cache": { + "version": "6.0.0", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">= 10" + "node": ">=10" } }, - "node_modules/@nx/nx-linux-x64-musl": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.5.0.tgz", - "integrity": "sha512-UE3tpgli7a08AsRaw/o1BUXnFOxICGzcYj1aglHBh6urVeUHK0aNt11djZcQ6ETgPgcjoGdwr7RqpANGnJQH9g==", - "cpu": [ - "x64" - ], + "node_modules/@nx/devkit/node_modules/semver": { + "version": "7.5.3", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">= 10" + "node": ">=10" } }, - "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.5.0.tgz", - "integrity": "sha512-u9cNKP8zrNIdeyaK5LHX+Zh+rkadE8tSE+vNulphCLhGuXJRpjaVY1juq9UQEo41NJQE6DuWWk2fnj4gALWugQ==", - "cpu": [ - "arm64" - ], + "node_modules/@nx/devkit/node_modules/yallist": { + "version": "4.0.0", "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } + "license": "ISC" }, "node_modules/@nx/nx-win32-x64-msvc": { "version": "16.5.0", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.5.0.tgz", - "integrity": "sha512-E9109SAYNZXqCeWikZXyxNd7SZnCbdKGvqtQktS7dedHGwOmgIWfJ6bsvA7s2zHr09THQKJ4+7U1tDkWVNR9cg==", "cpu": [ "x64" ], @@ -5741,18 +5084,16 @@ }, "node_modules/@octokit/auth-token": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14" } }, "node_modules/@octokit/core": { "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", - "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", @@ -5768,9 +5109,8 @@ }, "node_modules/@octokit/endpoint": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", - "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/types": "^9.0.0", "is-plain-object": "^5.0.0", @@ -5782,9 +5122,8 @@ }, "node_modules/@octokit/graphql": { "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/request": "^6.0.0", "@octokit/types": "^9.0.0", @@ -5796,9 +5135,8 @@ }, "node_modules/@octokit/openapi-types": { "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", - "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@octokit/plugin-enterprise-rest": { "version": "6.0.1", @@ -5807,9 +5145,8 @@ }, "node_modules/@octokit/plugin-paginate-rest": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", - "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/tsconfig": "^1.0.2", "@octokit/types": "^9.2.3" @@ -5823,18 +5160,16 @@ }, "node_modules/@octokit/plugin-request-log": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", "dev": true, + "license": "MIT", "peerDependencies": { "@octokit/core": ">=3" } }, "node_modules/@octokit/plugin-rest-endpoint-methods": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz", - "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/types": "^10.0.0" }, @@ -5847,18 +5182,16 @@ }, "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", - "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/openapi-types": "^18.0.0" } }, "node_modules/@octokit/request": { "version": "6.2.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", - "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/endpoint": "^7.0.0", "@octokit/request-error": "^3.0.0", @@ -5873,9 +5206,8 @@ }, "node_modules/@octokit/request-error": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", - "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/types": "^9.0.0", "deprecation": "^2.0.0", @@ -5887,9 +5219,8 @@ }, "node_modules/@octokit/rest": { "version": "19.0.11", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz", - "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/core": "^4.2.1", "@octokit/plugin-paginate-rest": "^6.1.2", @@ -5902,25 +5233,22 @@ }, "node_modules/@octokit/tsconfig": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", - "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@octokit/types": { "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", - "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/openapi-types": "^18.0.0" } }, "node_modules/@parcel/watcher": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", - "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "node-addon-api": "^3.2.1", "node-gyp-build": "^4.3.0" @@ -5935,9 +5263,8 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=14" @@ -5978,18 +5305,16 @@ }, "node_modules/@rollup/plugin-commonjs/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/@rollup/plugin-commonjs/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6017,9 +5342,8 @@ }, "node_modules/@rollup/plugin-commonjs/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -6029,9 +5353,8 @@ }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", - "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", @@ -6107,13 +5430,11 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "dev": true, + "version": "0.27.8", "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "2.0.0", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" @@ -6121,7 +5442,6 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "10.0.2", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^2.0.0" @@ -6134,7 +5454,6 @@ }, "node_modules/@tootallnate/once": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 10" @@ -6348,12 +5667,10 @@ }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", - "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.0", - "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" @@ -6361,7 +5678,6 @@ }, "node_modules/@types/istanbul-reports": { "version": "3.0.1", - "dev": true, "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" @@ -6374,14 +5690,22 @@ }, "node_modules/@types/jest": { "version": "29.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.2.tgz", - "integrity": "sha512-mSoZVJF5YzGVCk+FsDxzDuH7s+SCkzrgKZzf0Z0T2WudhBUPoF6ktoTPC4R0ZoCPCV5xUvuU6ias5NvxcBcMMg==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.11", "dev": true, @@ -6394,15 +5718,13 @@ }, "node_modules/@types/minimatch": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/minimist": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "18.14.6", @@ -6410,9 +5732,8 @@ }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -6471,7 +5792,10 @@ }, "node_modules/@types/stack-utils": { "version": "2.0.1", - "dev": true, + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.3", "license": "MIT" }, "node_modules/@types/ws": { @@ -6484,7 +5808,6 @@ }, "node_modules/@types/yargs": { "version": "17.0.22", - "dev": true, "license": "MIT", "dependencies": { "@types/yargs-parser": "*" @@ -6492,7 +5815,6 @@ }, "node_modules/@types/yargs-parser": { "version": "21.0.0", - "dev": true, "license": "MIT" }, "node_modules/@types/yauzl": { @@ -6505,9 +5827,8 @@ }, "node_modules/@vitejs/plugin-basic-ssl": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", - "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.6.0" }, @@ -6663,9 +5984,8 @@ }, "node_modules/@yarnpkg/parsers": { "version": "3.0.0-rc.46", - "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz", - "integrity": "sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "js-yaml": "^3.10.0", "tslib": "^2.4.0" @@ -6676,18 +5996,16 @@ }, "node_modules/@yarnpkg/parsers/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -6698,9 +6016,8 @@ }, "node_modules/@zkochan/js-yaml": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", - "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -6710,7 +6027,6 @@ }, "node_modules/abab": { "version": "2.0.6", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/abbrev": { @@ -6730,9 +6046,26 @@ "node": ">= 0.6" } }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "8.10.0", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/acorn-walk": { "version": "8.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -6740,9 +6073,8 @@ }, "node_modules/add-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", - "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", @@ -6771,7 +6103,6 @@ }, "node_modules/agent-base": { "version": "6.0.2", - "dev": true, "license": "MIT", "dependencies": { "debug": "4" @@ -6898,7 +6229,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -6946,15 +6276,13 @@ }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/array-differ": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6966,9 +6294,8 @@ }, "node_modules/array-ify": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/array-union": { "version": "2.1.0", @@ -6980,18 +6307,16 @@ }, "node_modules/arrify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/async": { "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/asynckit": { "version": "0.4.0", @@ -7118,9 +6443,8 @@ }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -7240,9 +6564,8 @@ }, "node_modules/before-after-hook": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/big.js": { "version": "5.2.2", @@ -7355,7 +6678,6 @@ }, "node_modules/braces": { "version": "3.0.2", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.0.1" @@ -7466,9 +6788,8 @@ }, "node_modules/byte-size": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", - "integrity": "sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.17" } @@ -7506,18 +6827,16 @@ }, "node_modules/cacache/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/cacache/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7542,9 +6861,8 @@ }, "node_modules/cacache/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7593,9 +6911,8 @@ }, "node_modules/camelcase-keys": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, + "license": "MIT", "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", @@ -7610,8 +6927,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001519", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz", - "integrity": "sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==", "dev": true, "funding": [ { @@ -7626,11 +6941,11 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -7700,15 +7015,13 @@ }, "node_modules/ci-info": { "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } @@ -7800,9 +7113,8 @@ }, "node_modules/cmd-shim": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz", - "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", "dev": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -7823,7 +7135,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -7834,7 +7145,6 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/color-support": { @@ -7852,9 +7162,8 @@ }, "node_modules/columnify": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", - "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", "dev": true, + "license": "MIT", "dependencies": { "strip-ansi": "^6.0.1", "wcwidth": "^1.0.0" @@ -7885,9 +7194,8 @@ }, "node_modules/compare-func": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, + "license": "MIT", "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" @@ -7954,12 +7262,11 @@ }, "node_modules/concat-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "engines": [ "node >= 6.0" ], + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -8064,9 +7371,8 @@ }, "node_modules/conventional-changelog-angular": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", "dev": true, + "license": "ISC", "dependencies": { "compare-func": "^2.0.0" }, @@ -8076,9 +7382,8 @@ }, "node_modules/conventional-changelog-core": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz", - "integrity": "sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==", "dev": true, + "license": "MIT", "dependencies": { "add-stream": "^1.0.0", "conventional-changelog-writer": "^6.0.0", @@ -8098,18 +7403,16 @@ }, "node_modules/conventional-changelog-preset-loader": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", - "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" } }, "node_modules/conventional-changelog-writer": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.0.tgz", - "integrity": "sha512-8PyWTnn7zBIt9l4hj4UusFs1TyG+9Ulu1zlOAc72L7Sdv9Hsc8E86ot7htY3HXCVhXHB/NO0pVGvZpwsyJvFfw==", "dev": true, + "license": "MIT", "dependencies": { "conventional-commits-filter": "^3.0.0", "dateformat": "^3.0.3", @@ -8128,18 +7431,16 @@ }, "node_modules/conventional-changelog-writer/node_modules/semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/conventional-commits-filter": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", "dev": true, + "license": "MIT", "dependencies": { "lodash.ismatch": "^4.4.0", "modify-values": "^1.0.1" @@ -8150,9 +7451,8 @@ }, "node_modules/conventional-commits-parser": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", "dev": true, + "license": "MIT", "dependencies": { "is-text-path": "^1.0.1", "JSONStream": "^1.3.5", @@ -8168,9 +7468,8 @@ }, "node_modules/conventional-recommended-bump": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", - "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", "dev": true, + "license": "MIT", "dependencies": { "concat-stream": "^2.0.0", "conventional-changelog-preset-loader": "^3.0.0", @@ -8281,9 +7580,8 @@ }, "node_modules/core-js-compat": { "version": "3.32.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.0.tgz", - "integrity": "sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw==", "dev": true, + "license": "MIT", "dependencies": { "browserslist": "^4.21.9" }, @@ -8294,8 +7592,6 @@ }, "node_modules/core-js-compat/node_modules/browserslist": { "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", "dev": true, "funding": [ { @@ -8311,6 +7607,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001517", "electron-to-chromium": "^1.4.477", @@ -8462,6 +7759,21 @@ "node": ">=4" } }, + "node_modules/cssom": { + "version": "0.5.0", + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/custom-event": { "version": "1.0.1", "dev": true, @@ -8469,13 +7781,56 @@ }, "node_modules/dargs": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/data-urls": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/data-urls/node_modules/tr46": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/data-urls/node_modules/whatwg-url": { + "version": "12.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/date-format": { "version": "4.0.14", "dev": true, @@ -8486,9 +7841,8 @@ }, "node_modules/dateformat": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true, + "license": "MIT", "engines": { "node": "*" } @@ -8510,18 +7864,16 @@ }, "node_modules/decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/decamelize-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, + "license": "MIT", "dependencies": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" @@ -8535,13 +7887,16 @@ }, "node_modules/decamelize-keys/node_modules/map-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "license": "MIT" + }, "node_modules/dedent": { "version": "0.7.0", "dev": true, @@ -8615,9 +7970,8 @@ }, "node_modules/deprecation": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/destroy": { "version": "1.2.0", @@ -8630,9 +7984,8 @@ }, "node_modules/detect-indent": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -8733,6 +8086,23 @@ ], "license": "BSD-2-Clause" }, + "node_modules/domexception": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "7.0.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, "node_modules/domhandler": { "version": "4.3.1", "dev": true, @@ -8762,9 +8132,8 @@ }, "node_modules/dot-prop": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, + "license": "MIT", "dependencies": { "is-obj": "^2.0.0" }, @@ -8774,24 +8143,21 @@ }, "node_modules/dotenv": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=10" } }, "node_modules/duplexer": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", @@ -8800,9 +8166,8 @@ }, "node_modules/ejs": { "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -8815,9 +8180,8 @@ }, "node_modules/electron-to-chromium": { "version": "1.4.485", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.485.tgz", - "integrity": "sha512-1ndQ5IBNEnFirPwvyud69GHL+31FkE09gH/CJ6m3KCbkx3i0EVOrjwz4UNxRmN9H8OVHbC6vMRZGN1yCvjSs9w==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", @@ -8881,9 +8245,8 @@ }, "node_modules/engine.io": { "version": "6.4.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", - "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, + "license": "MIT", "dependencies": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -8893,494 +8256,157 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.11.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.0.6", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/cookie": { - "version": "0.4.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/ent": { - "version": "2.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/envinfo": { - "version": "7.8.1", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/errno": { - "version": "0.1.8", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-module-lexer": { - "version": "0.9.3", - "dev": true, - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.17.8", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.8", - "@esbuild/android-arm64": "0.17.8", - "@esbuild/android-x64": "0.17.8", - "@esbuild/darwin-arm64": "0.17.8", - "@esbuild/darwin-x64": "0.17.8", - "@esbuild/freebsd-arm64": "0.17.8", - "@esbuild/freebsd-x64": "0.17.8", - "@esbuild/linux-arm": "0.17.8", - "@esbuild/linux-arm64": "0.17.8", - "@esbuild/linux-ia32": "0.17.8", - "@esbuild/linux-loong64": "0.17.8", - "@esbuild/linux-mips64el": "0.17.8", - "@esbuild/linux-ppc64": "0.17.8", - "@esbuild/linux-riscv64": "0.17.8", - "@esbuild/linux-s390x": "0.17.8", - "@esbuild/linux-x64": "0.17.8", - "@esbuild/netbsd-x64": "0.17.8", - "@esbuild/openbsd-x64": "0.17.8", - "@esbuild/sunos-x64": "0.17.8", - "@esbuild/win32-arm64": "0.17.8", - "@esbuild/win32-ia32": "0.17.8", - "@esbuild/win32-x64": "0.17.8" - } - }, - "node_modules/esbuild-wasm": { - "version": "0.17.8", - "dev": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild/node_modules/@esbuild/android-arm": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.8.tgz", - "integrity": "sha512-0/rb91GYKhrtbeglJXOhAv9RuYimgI8h623TplY2X+vA4EXnk3Zj1fXZreJ0J3OJJu1bwmb0W7g+2cT/d8/l/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild/node_modules/@esbuild/android-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.8.tgz", - "integrity": "sha512-oa/N5j6v1svZQs7EIRPqR8f+Bf8g6HBDjD/xHC02radE/NjKHK7oQmtmLxPs1iVwYyvE+Kolo6lbpfEQ9xnhxQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild/node_modules/@esbuild/android-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.8.tgz", - "integrity": "sha512-bTliMLqD7pTOoPg4zZkXqCDuzIUguEWLpeqkNfC41ODBHwoUgZ2w5JBeYimv4oP6TDVocoYmEhZrCLQTrH89bg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.8.tgz", - "integrity": "sha512-ghAbV3ia2zybEefXRRm7+lx8J/rnupZT0gp9CaGy/3iolEXkJ6LYRq4IpQVI9zR97ID80KJVoUlo3LSeA/sMAg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.8.tgz", - "integrity": "sha512-n5WOpyvZ9TIdv2V1K3/iIkkJeKmUpKaCTdun9buhGRWfH//osmUjlv4Z5mmWdPWind/VGcVxTHtLfLCOohsOXw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.8.tgz", - "integrity": "sha512-a/SATTaOhPIPFWvHZDoZYgxaZRVHn0/LX1fHLGfZ6C13JqFUZ3K6SMD6/HCtwOQ8HnsNaEeokdiDSFLuizqv5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.8.tgz", - "integrity": "sha512-xpFJb08dfXr5+rZc4E+ooZmayBW6R3q59daCpKZ/cDU96/kvDM+vkYzNeTJCGd8rtO6fHWMq5Rcv/1cY6p6/0Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "engine.io-parser": "~5.0.3", + "ws": "~8.11.0" + }, "engines": { - "node": ">=12" + "node": ">=10.0.0" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-arm": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.8.tgz", - "integrity": "sha512-6Ij8gfuGszcEwZpi5jQIJCVIACLS8Tz2chnEBfYjlmMzVsfqBP1iGmHQPp7JSnZg5xxK9tjCc+pJ2WtAmPRFVA==", - "cpu": [ - "arm" - ], + "node_modules/engine.io-parser": { + "version": "5.0.6", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10.0.0" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.8.tgz", - "integrity": "sha512-v3iwDQuDljLTxpsqQDl3fl/yihjPAyOguxuloON9kFHYwopeJEf1BkDXODzYyXEI19gisEsQlG1bM65YqKSIww==", - "cpu": [ - "arm64" - ], + "node_modules/engine.io/node_modules/cookie": { + "version": "0.4.2", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 0.6" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.8.tgz", - "integrity": "sha512-8svILYKhE5XetuFk/B6raFYIyIqydQi+GngEXJgdPdI7OMKUbSd7uzR02wSY4kb53xBrClLkhH4Xs8P61Q2BaA==", - "cpu": [ - "ia32" - ], + "node_modules/enhanced-resolve": { + "version": "5.15.0", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, "engines": { - "node": ">=12" + "node": ">=10.13.0" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.8.tgz", - "integrity": "sha512-B6FyMeRJeV0NpyEOYlm5qtQfxbdlgmiGdD+QsipzKfFky0K5HW5Td6dyK3L3ypu1eY4kOmo7wW0o94SBqlqBSA==", - "cpu": [ - "loong64" - ], + "node_modules/enquirer": { + "version": "2.3.6", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, "engines": { - "node": ">=12" + "node": ">=8.6" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.8.tgz", - "integrity": "sha512-CCb67RKahNobjm/eeEqeD/oJfJlrWyw29fgiyB6vcgyq97YAf3gCOuP6qMShYSPXgnlZe/i4a8WFHBw6N8bYAA==", - "cpu": [ - "mips64el" - ], + "node_modules/ent": { + "version": "2.2.0", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.8.tgz", - "integrity": "sha512-bytLJOi55y55+mGSdgwZ5qBm0K9WOCh0rx+vavVPx+gqLLhxtSFU0XbeYy/dsAAD6xECGEv4IQeFILaSS2auXw==", - "cpu": [ - "ppc64" - ], + "node_modules/entities": { + "version": "2.2.0", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.8.tgz", - "integrity": "sha512-2YpRyQJmKVBEHSBLa8kBAtbhucaclb6ex4wchfY0Tj3Kg39kpjeJ9vhRU7x4mUpq8ISLXRXH1L0dBYjAeqzZAw==", - "cpu": [ - "riscv64" - ], + "node_modules/env-paths": { + "version": "2.2.1", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.8.tgz", - "integrity": "sha512-QgbNY/V3IFXvNf11SS6exkpVcX0LJcob+0RWCgV9OiDAmVElnxciHIisoSix9uzYzScPmS6dJFbZULdSAEkQVw==", - "cpu": [ - "s390x" - ], + "node_modules/envinfo": { + "version": "7.8.1", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, "engines": { - "node": ">=12" + "node": ">=4" } }, - "node_modules/esbuild/node_modules/@esbuild/linux-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.8.tgz", - "integrity": "sha512-mM/9S0SbAFDBc4OPoyP6SEOo5324LpUxdpeIUUSrSTOfhHU9hEfqRngmKgqILqwx/0DVJBzeNW7HmLEWp9vcOA==", - "cpu": [ - "x64" - ], + "node_modules/err-code": { + "version": "2.0.3", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.8.tgz", - "integrity": "sha512-eKUYcWaWTaYr9zbj8GertdVtlt1DTS1gNBWov+iQfWuWyuu59YN6gSEJvFzC5ESJ4kMcKR0uqWThKUn5o8We6Q==", - "cpu": [ - "x64" - ], + "node_modules/errno": { + "version": "0.1.8", "dev": true, + "license": "MIT", "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" } }, - "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.8.tgz", - "integrity": "sha512-Vc9J4dXOboDyMXKD0eCeW0SIeEzr8K9oTHJU+Ci1mZc5njPfhKAqkRt3B/fUNU7dP+mRyralPu8QUkiaQn7iIg==", - "cpu": [ - "x64" - ], + "node_modules/error-ex": { + "version": "1.3.2", "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" } }, - "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { - "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.8.tgz", - "integrity": "sha512-0xvOTNuPXI7ft1LYUgiaXtpCEjp90RuBBYovdd2lqAFxje4sEucurg30M1WIm03+3jxByd3mfo+VUmPtRSVuOw==", - "cpu": [ - "x64" - ], + "node_modules/es-module-lexer": { + "version": "0.9.3", "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "node_modules/esbuild": { "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.8.tgz", - "integrity": "sha512-G0JQwUI5WdEFEnYNKzklxtBheCPkuDdu1YrtRrjuQv30WsYbkkoixKxLLv8qhJmNI+ATEWquZe/N0d0rpr55Mg==", - "cpu": [ - "arm64" - ], "dev": true, - "optional": true, - "os": [ - "win32" - ], + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.8", + "@esbuild/android-arm64": "0.17.8", + "@esbuild/android-x64": "0.17.8", + "@esbuild/darwin-arm64": "0.17.8", + "@esbuild/darwin-x64": "0.17.8", + "@esbuild/freebsd-arm64": "0.17.8", + "@esbuild/freebsd-x64": "0.17.8", + "@esbuild/linux-arm": "0.17.8", + "@esbuild/linux-arm64": "0.17.8", + "@esbuild/linux-ia32": "0.17.8", + "@esbuild/linux-loong64": "0.17.8", + "@esbuild/linux-mips64el": "0.17.8", + "@esbuild/linux-ppc64": "0.17.8", + "@esbuild/linux-riscv64": "0.17.8", + "@esbuild/linux-s390x": "0.17.8", + "@esbuild/linux-x64": "0.17.8", + "@esbuild/netbsd-x64": "0.17.8", + "@esbuild/openbsd-x64": "0.17.8", + "@esbuild/sunos-x64": "0.17.8", + "@esbuild/win32-arm64": "0.17.8", + "@esbuild/win32-ia32": "0.17.8", + "@esbuild/win32-x64": "0.17.8" } }, - "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "node_modules/esbuild-wasm": { "version": "0.17.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.8.tgz", - "integrity": "sha512-Fqy63515xl20OHGFykjJsMnoIWS+38fqfg88ClvPXyDbLtgXal2DTlhb1TfTX34qWi3u4I7Cq563QcHpqgLx8w==", - "cpu": [ - "ia32" - ], "dev": true, - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { "node": ">=12" } @@ -9398,6 +8424,33 @@ "dev": true, "license": "MIT" }, + "node_modules/escodegen": { + "version": "2.1.0", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "dev": true, @@ -9420,7 +8473,6 @@ }, "node_modules/esprima": { "version": "4.0.1", - "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -9443,7 +8495,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -9456,7 +8507,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -9729,27 +8779,24 @@ }, "node_modules/filelist": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, + "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" } }, "node_modules/filelist/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/filelist/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9759,7 +8806,6 @@ }, "node_modules/fill-range": { "version": "7.0.1", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -9828,9 +8874,8 @@ }, "node_modules/flat": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, + "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } @@ -9860,9 +8905,8 @@ }, "node_modules/foreground-child": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -9876,9 +8920,8 @@ }, "node_modules/foreground-child/node_modules/signal-exit": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -9928,15 +8971,13 @@ }, "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fs-extra": { "version": "11.1.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", - "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -9967,20 +9008,6 @@ "dev": true, "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "dev": true, @@ -10043,9 +9070,8 @@ }, "node_modules/get-pkg-repo": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", "dev": true, + "license": "MIT", "dependencies": { "@hutson/parse-repository-url": "^3.0.0", "hosted-git-info": "^4.0.0", @@ -10061,9 +9087,8 @@ }, "node_modules/get-pkg-repo/node_modules/hosted-git-info": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -10073,9 +9098,8 @@ }, "node_modules/get-pkg-repo/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -10085,15 +9109,13 @@ }, "node_modules/get-pkg-repo/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/get-port": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", - "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -10114,9 +9136,8 @@ }, "node_modules/git-raw-commits": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", - "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", "dev": true, + "license": "MIT", "dependencies": { "dargs": "^7.0.0", "meow": "^8.1.2", @@ -10131,9 +9152,8 @@ }, "node_modules/git-remote-origin-url": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", "dev": true, + "license": "MIT", "dependencies": { "gitconfiglocal": "^1.0.0", "pify": "^2.3.0" @@ -10144,18 +9164,16 @@ }, "node_modules/git-remote-origin-url/node_modules/pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/git-semver-tags": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.0.tgz", - "integrity": "sha512-fZ+tmZ1O5aXW/T5nLzZLbxWAHdQTLLXalOECMNAmhoEQSfqZjtaeMjpsXH4C5qVhrICTkVQeQFujB1lKzIHljA==", "dev": true, + "license": "MIT", "dependencies": { "meow": "^8.1.2", "semver": "^6.3.0" @@ -10169,18 +9187,16 @@ }, "node_modules/git-semver-tags/node_modules/semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/git-up": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", - "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", "dev": true, + "license": "MIT", "dependencies": { "is-ssh": "^1.4.0", "parse-url": "^8.1.0" @@ -10188,33 +9204,29 @@ }, "node_modules/git-url-parse": { "version": "13.1.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-13.1.0.tgz", - "integrity": "sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==", "dev": true, + "license": "MIT", "dependencies": { "git-up": "^7.0.0" } }, "node_modules/gitconfiglocal": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", "dev": true, + "license": "BSD", "dependencies": { "ini": "^1.3.2" } }, "node_modules/gitconfiglocal/node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/glob": { "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", @@ -10250,18 +9262,16 @@ }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/glob/node_modules/minimatch": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10274,9 +9284,8 @@ }, "node_modules/glob/node_modules/minipass": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -10310,9 +9319,7 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "license": "ISC" }, "node_modules/handle-thing": { "version": "2.0.1", @@ -10321,9 +9328,8 @@ }, "node_modules/handlebars": { "version": "4.7.7", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", - "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.0", @@ -10342,18 +9348,16 @@ }, "node_modules/handlebars/node_modules/source-map": { "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" } }, "node_modules/hard-rejection": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -10371,7 +9375,6 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10418,8 +9421,7 @@ }, "node_modules/highcharts": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-11.1.0.tgz", - "integrity": "sha512-vhmqq6/frteWMx0GKYWwEFL25g4OYc7+m+9KQJb/notXbNtIb8KVy+ijOF7XAFqF165cq0pdLIePAmyFY5ph3g==" + "license": "https://www.highcharts.com/license" }, "node_modules/hosted-git-info": { "version": "6.1.1", @@ -10480,7 +9482,6 @@ }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", - "dev": true, "license": "MIT", "dependencies": { "whatwg-encoding": "^2.0.0" @@ -10501,8 +9502,6 @@ }, "node_modules/htmlparser2": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -10511,6 +9510,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -10520,9 +9520,8 @@ }, "node_modules/htmlparser2/node_modules/dom-serializer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -10534,9 +9533,8 @@ }, "node_modules/htmlparser2/node_modules/domhandler": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -10549,9 +9547,8 @@ }, "node_modules/htmlparser2/node_modules/domutils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -10563,9 +9560,8 @@ }, "node_modules/htmlparser2/node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -10618,7 +9614,6 @@ }, "node_modules/http-proxy-agent": { "version": "5.0.0", - "dev": true, "license": "MIT", "dependencies": { "@tootallnate/once": "2", @@ -10691,7 +9686,6 @@ }, "node_modules/https-proxy-agent": { "version": "5.0.1", - "dev": true, "license": "MIT", "dependencies": { "agent-base": "6", @@ -10768,9 +9762,8 @@ }, "node_modules/ignore-walk": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-5.0.1.tgz", - "integrity": "sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==", "dev": true, + "license": "ISC", "dependencies": { "minimatch": "^5.0.1" }, @@ -10780,18 +9773,16 @@ }, "node_modules/ignore-walk/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/ignore-walk/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10902,9 +9893,8 @@ }, "node_modules/init-package-json": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-5.0.0.tgz", - "integrity": "sha512-kBhlSheBfYmq3e0L1ii+VKe3zBTLL5lDCDWR+f9dLmEGSB3MqLlMlsolubSsyI88Bg6EA+BIMlomAnQ1SwgQBw==", "dev": true, + "license": "ISC", "dependencies": { "npm-package-arg": "^10.0.0", "promzard": "^1.0.0", @@ -10920,9 +9910,8 @@ }, "node_modules/init-package-json/node_modules/npm-package-arg": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", "dev": true, + "license": "ISC", "dependencies": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", @@ -11003,9 +9992,8 @@ }, "node_modules/is-ci": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dev": true, + "license": "MIT", "dependencies": { "ci-info": "^3.2.0" }, @@ -11093,7 +10081,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -11101,31 +10088,32 @@ }, "node_modules/is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-plain-object": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "license": "MIT" + }, "node_modules/is-reference": { "version": "1.2.1", "dev": true, @@ -11136,9 +10124,8 @@ }, "node_modules/is-ssh": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", "dev": true, + "license": "MIT", "dependencies": { "protocols": "^2.0.1" } @@ -11156,9 +10143,8 @@ }, "node_modules/is-text-path": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", "dev": true, + "license": "MIT", "dependencies": { "text-extensions": "^1.0.0" }, @@ -11247,9 +10233,8 @@ }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -11302,9 +10287,8 @@ }, "node_modules/jackspeak": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -11320,9 +10304,8 @@ }, "node_modules/jake": { "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -11343,9 +10326,8 @@ }, "node_modules/jest": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, + "license": "MIT", "dependencies": { "@jest/core": "^29.5.0", "@jest/types": "^29.5.0", @@ -11583,6 +10565,138 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-environment-jsdom": { + "version": "29.7.0", + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/acorn": { + "version": "8.10.0", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle": { + "version": "2.3.0", + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "license": "MIT" + }, + "node_modules/jest-environment-jsdom/node_modules/data-urls": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jsdom": { + "version": "20.0.3", + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-jsdom/node_modules/tr46": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-environment-jsdom/node_modules/whatwg-url": { + "version": "11.0.0", + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/jest-environment-node": { "version": "29.5.0", "dev": true, @@ -11601,9 +10715,8 @@ }, "node_modules/jest-extended": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-4.0.2.tgz", - "integrity": "sha512-FH7aaPgtGYHc9mRjriS0ZEHYM5/W69tLrFTIdzm+yJgeoCmmrSB/luSfMSqWP9O29QWHPEmJ4qmU6EwsZideog==", "dev": true, + "license": "MIT", "dependencies": { "jest-diff": "^29.0.0", "jest-get-type": "^29.0.0" @@ -11679,17 +10792,16 @@ } }, "node_modules/jest-message-util": { - "version": "29.5.0", - "dev": true, + "version": "29.7.0", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -11698,13 +10810,12 @@ } }, "node_modules/jest-mock": { - "version": "29.5.0", - "dev": true, + "version": "29.7.0", "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.5.0" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -11898,11 +11009,10 @@ } }, "node_modules/jest-util": { - "version": "29.5.0", - "dev": true, + "version": "29.7.0", "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -11988,9 +11098,8 @@ }, "node_modules/jiti": { "version": "1.19.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", - "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", "dev": true, + "license": "MIT", "bin": { "jiti": "bin/jiti.js" } @@ -12001,14 +11110,12 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "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" }, @@ -12016,6 +11123,98 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "22.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "cssstyle": "^3.0.0", + "data-urls": "^4.0.0", + "decimal.js": "^10.4.3", + "domexception": "^4.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.4", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^12.0.1", + "ws": "^8.13.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/tr46": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jsdom/node_modules/webidl-conversions": { + "version": "7.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/jsdom/node_modules/whatwg-url": { + "version": "12.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^4.1.1", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jsdom/node_modules/ws": { + "version": "8.14.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/jsesc": { "version": "2.5.2", "dev": true, @@ -12029,9 +11228,8 @@ }, "node_modules/json-parse-better-errors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -12045,9 +11243,8 @@ }, "node_modules/json-stringify-safe": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/json5": { "version": "2.2.3", @@ -12067,9 +11264,8 @@ }, "node_modules/jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -12087,9 +11283,8 @@ }, "node_modules/JSONStream": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, + "license": "(MIT OR Apache-2.0)", "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" @@ -12140,9 +11335,8 @@ }, "node_modules/karma-chrome-launcher": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, + "license": "MIT", "dependencies": { "which": "^1.2.1" } @@ -12281,9 +11475,8 @@ }, "node_modules/launch-editor": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", - "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", "dev": true, + "license": "MIT", "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.7.3" @@ -12291,9 +11484,8 @@ }, "node_modules/lerna": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-7.1.1.tgz", - "integrity": "sha512-rjivAl3bYu2+lWOi90vy0tYFgwBYPMiNkR/DuEWZC08wle5dsbOZ/SlXeLk9+kzbF89Bt5P6p+qF78A2tJsWPA==", "dev": true, + "license": "MIT", "dependencies": { "@lerna/child-process": "7.1.1", "@lerna/create": "7.1.1", @@ -12394,9 +11586,8 @@ }, "node_modules/lerna/node_modules/cosmiconfig": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", "dev": true, + "license": "MIT", "dependencies": { "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -12506,9 +11697,8 @@ }, "node_modules/lerna/node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/lerna/node_modules/is-stream": { "version": "2.0.0", @@ -12575,18 +11765,16 @@ }, "node_modules/lerna/node_modules/uuid": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "dev": true, + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/lerna/node_modules/write-file-atomic": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" @@ -12597,9 +11785,8 @@ }, "node_modules/lerna/node_modules/write-file-atomic/node_modules/signal-exit": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -12680,9 +11867,8 @@ }, "node_modules/less/node_modules/semver": { "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, + "license": "ISC", "optional": true, "bin": { "semver": "bin/semver" @@ -12707,9 +11893,8 @@ }, "node_modules/libnpmaccess": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-7.0.2.tgz", - "integrity": "sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw==", "dev": true, + "license": "ISC", "dependencies": { "npm-package-arg": "^10.1.0", "npm-registry-fetch": "^14.0.3" @@ -12720,9 +11905,8 @@ }, "node_modules/libnpmaccess/node_modules/npm-package-arg": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", "dev": true, + "license": "ISC", "dependencies": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", @@ -12735,9 +11919,8 @@ }, "node_modules/libnpmpublish": { "version": "7.3.0", - "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-7.3.0.tgz", - "integrity": "sha512-fHUxw5VJhZCNSls0KLNEG0mCD2PN1i14gH5elGOgiVnU3VgTcRahagYP2LKI1m0tFCJ+XrAm0zVYyF5RCbXzcg==", "dev": true, + "license": "ISC", "dependencies": { "ci-info": "^3.6.1", "normalize-package-data": "^5.0.0", @@ -12754,18 +11937,16 @@ }, "node_modules/libnpmpublish/node_modules/minipass": { "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" } }, "node_modules/libnpmpublish/node_modules/normalize-package-data": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", - "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^6.0.0", "is-core-module": "^2.8.1", @@ -12778,9 +11959,8 @@ }, "node_modules/libnpmpublish/node_modules/npm-package-arg": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", "dev": true, + "license": "ISC", "dependencies": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", @@ -12793,9 +11973,8 @@ }, "node_modules/libnpmpublish/node_modules/ssri": { "version": "10.0.4", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", - "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^5.0.0" }, @@ -12821,18 +12000,16 @@ }, "node_modules/lines-and-columns": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", - "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/load-json-file": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", - "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.15", "parse-json": "^5.0.0", @@ -12845,9 +12022,8 @@ }, "node_modules/load-json-file/node_modules/type-fest": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } @@ -12891,9 +12067,8 @@ }, "node_modules/lodash.ismatch": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -12965,9 +12140,8 @@ }, "node_modules/make-dir/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -13017,9 +12191,8 @@ }, "node_modules/make-fetch-happen/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -13065,9 +12238,8 @@ }, "node_modules/make-fetch-happen/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -13092,9 +12264,8 @@ }, "node_modules/make-fetch-happen/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -13150,9 +12321,8 @@ }, "node_modules/map-obj": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -13185,9 +12355,8 @@ }, "node_modules/meow": { "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", @@ -13210,15 +12379,13 @@ }, "node_modules/meow/node_modules/hosted-git-info": { "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/meow/node_modules/read-pkg": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, + "license": "MIT", "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", @@ -13231,9 +12398,8 @@ }, "node_modules/meow/node_modules/read-pkg-up": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", @@ -13248,18 +12414,16 @@ }, "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -13269,27 +12433,24 @@ }, "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, "node_modules/meow/node_modules/semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/meow/node_modules/type-fest": { "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -13325,7 +12486,6 @@ }, "node_modules/micromatch": { "version": "4.0.5", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.2", @@ -13373,9 +12533,8 @@ }, "node_modules/min-indent": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -13424,9 +12583,8 @@ }, "node_modules/minimist-options": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, + "license": "MIT", "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", @@ -13650,18 +12808,16 @@ }, "node_modules/modify-values": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/mrmime": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -13684,9 +12840,8 @@ }, "node_modules/multimatch": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", - "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimatch": "^3.0.3", "array-differ": "^3.0.0", @@ -13703,9 +12858,8 @@ }, "node_modules/multimatch/node_modules/arrify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -13717,8 +12871,6 @@ }, "node_modules/nanoid": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", "dev": true, "funding": [ { @@ -13726,6 +12878,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -13791,15 +12944,13 @@ }, "node_modules/node-addon-api": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-fetch": { "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dev": true, + "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -13848,9 +12999,8 @@ }, "node_modules/node-gyp-build": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", - "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", "dev": true, + "license": "MIT", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -13897,15 +13047,13 @@ }, "node_modules/node-releases": { "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", @@ -13918,9 +13066,8 @@ }, "node_modules/normalize-package-data/node_modules/hosted-git-info": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -13930,9 +13077,8 @@ }, "node_modules/normalize-package-data/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -13942,9 +13088,8 @@ }, "node_modules/normalize-package-data/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -13994,9 +13139,8 @@ }, "node_modules/npm-package-arg": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.1.tgz", - "integrity": "sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg==", "dev": true, + "license": "ISC", "dependencies": { "hosted-git-info": "^3.0.6", "semver": "^7.0.0", @@ -14008,15 +13152,13 @@ }, "node_modules/npm-package-arg/node_modules/builtins": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/npm-package-arg/node_modules/hosted-git-info": { "version": "3.0.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.8.tgz", - "integrity": "sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -14026,9 +13168,8 @@ }, "node_modules/npm-package-arg/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14038,24 +13179,21 @@ }, "node_modules/npm-package-arg/node_modules/validate-npm-package-name": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", "dev": true, + "license": "ISC", "dependencies": { "builtins": "^1.0.3" } }, "node_modules/npm-package-arg/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/npm-packlist": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-5.1.1.tgz", - "integrity": "sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^8.0.1", "ignore-walk": "^5.0.1", @@ -14071,18 +13209,16 @@ }, "node_modules/npm-packlist/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/npm-packlist/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14099,9 +13235,8 @@ }, "node_modules/npm-packlist/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -14111,18 +13246,16 @@ }, "node_modules/npm-packlist/node_modules/npm-bundled": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", - "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", "dev": true, + "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^1.0.1" } }, "node_modules/npm-packlist/node_modules/npm-normalize-package-bin": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/npm-pick-manifest": { "version": "8.0.1", @@ -14287,12 +13420,15 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/nwsapi": { + "version": "2.2.7", + "license": "MIT" + }, "node_modules/nx": { "version": "16.5.0", - "resolved": "https://registry.npmjs.org/nx/-/nx-16.5.0.tgz", - "integrity": "sha512-X95atskaF1ejrF+C80mC4SwFPq0G/yFvxhfeWpPjKj7vUJEy1nZ4SjqlNVMORdN8dKQTE6ss76cIJux3fE7EXw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@nrwl/tao": "16.5.0", "@parcel/watcher": "2.0.4", @@ -14359,9 +13495,8 @@ }, "node_modules/nx/node_modules/fast-glob": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -14375,9 +13510,8 @@ }, "node_modules/nx/node_modules/glob": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -14392,9 +13526,8 @@ }, "node_modules/nx/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14404,9 +13537,8 @@ }, "node_modules/nx/node_modules/minimatch": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -14416,9 +13548,8 @@ }, "node_modules/nx/node_modules/semver": { "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -14431,15 +13562,13 @@ }, "node_modules/nx/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/nx/node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -14455,18 +13584,16 @@ }, "node_modules/nx/node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "node_modules/nx/node_modules/yargs/node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -14593,9 +13720,8 @@ }, "node_modules/p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -14655,9 +13781,8 @@ }, "node_modules/p-map-series": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz", - "integrity": "sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -14675,9 +13800,8 @@ }, "node_modules/p-queue": { "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", "dev": true, + "license": "MIT", "dependencies": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" @@ -14691,9 +13815,8 @@ }, "node_modules/p-reduce": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", - "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -14720,9 +13843,8 @@ }, "node_modules/p-timeout": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", "dev": true, + "license": "MIT", "dependencies": { "p-finally": "^1.0.0" }, @@ -14740,9 +13862,8 @@ }, "node_modules/p-waterfall": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz", - "integrity": "sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==", "dev": true, + "license": "MIT", "dependencies": { "p-reduce": "^2.0.0" }, @@ -14755,9 +13876,8 @@ }, "node_modules/pacote": { "version": "15.2.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", - "integrity": "sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==", "dev": true, + "license": "ISC", "dependencies": { "@npmcli/git": "^4.0.0", "@npmcli/installed-package-contents": "^2.0.1", @@ -14787,18 +13907,16 @@ }, "node_modules/pacote/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/pacote/node_modules/ignore-walk": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.3.tgz", - "integrity": "sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==", "dev": true, + "license": "ISC", "dependencies": { "minimatch": "^9.0.0" }, @@ -14808,9 +13926,8 @@ }, "node_modules/pacote/node_modules/minimatch": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.2.tgz", - "integrity": "sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -14823,18 +13940,16 @@ }, "node_modules/pacote/node_modules/minipass": { "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" } }, "node_modules/pacote/node_modules/npm-package-arg": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", "dev": true, + "license": "ISC", "dependencies": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", @@ -14847,9 +13962,8 @@ }, "node_modules/pacote/node_modules/npm-packlist": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", - "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", "dev": true, + "license": "ISC", "dependencies": { "ignore-walk": "^6.0.0" }, @@ -14859,9 +13973,8 @@ }, "node_modules/pacote/node_modules/ssri": { "version": "10.0.4", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", - "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^5.0.0" }, @@ -14917,25 +14030,22 @@ }, "node_modules/parse-path": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", - "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", "dev": true, + "license": "MIT", "dependencies": { "protocols": "^2.0.0" } }, "node_modules/parse-url": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", - "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", "dev": true, + "license": "MIT", "dependencies": { "parse-path": "^7.0.0" } }, "node_modules/parse5": { "version": "7.1.2", - "devOptional": true, "license": "MIT", "dependencies": { "entities": "^4.4.0" @@ -14994,7 +14104,6 @@ }, "node_modules/parse5/node_modules/entities": { "version": "4.4.0", - "devOptional": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -15042,9 +14151,8 @@ }, "node_modules/path-scurry": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -15096,7 +14204,6 @@ }, "node_modules/picomatch": { "version": "2.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -15107,9 +14214,8 @@ }, "node_modules/pify": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -15246,9 +14352,8 @@ }, "node_modules/postcss-modules-local-by-default": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -15318,11 +14423,10 @@ } }, "node_modules/pretty-format": { - "version": "29.5.0", - "dev": true, + "version": "29.7.0", "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -15332,7 +14436,6 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -15385,9 +14488,8 @@ }, "node_modules/promzard": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/promzard/-/promzard-1.0.0.tgz", - "integrity": "sha512-KQVDEubSUHGSt5xLakaToDFrSoZhStB8dXLzk2xvwR67gJktrHFvpR63oZgHyK19WKbHFLXJqCPXdVR3aBP8Ig==", "dev": true, + "license": "ISC", "dependencies": { "read": "^2.0.0" }, @@ -15397,9 +14499,8 @@ }, "node_modules/protocols": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -15423,6 +14524,10 @@ "license": "MIT", "optional": true }, + "node_modules/psl": { + "version": "1.9.0", + "license": "MIT" + }, "node_modules/pump": { "version": "3.0.0", "license": "MIT", @@ -15433,7 +14538,6 @@ }, "node_modules/punycode": { "version": "2.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -15476,6 +14580,10 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "dev": true, @@ -15497,9 +14605,8 @@ }, "node_modules/quick-lru": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -15536,14 +14643,12 @@ }, "node_modules/react-is": { "version": "18.2.0", - "dev": true, "license": "MIT" }, "node_modules/read": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/read/-/read-2.1.0.tgz", - "integrity": "sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ==", "dev": true, + "license": "ISC", "dependencies": { "mute-stream": "~1.0.0" }, @@ -15553,18 +14658,16 @@ }, "node_modules/read-cmd-shim": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", - "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", "dev": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/read-package-json": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz", - "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^10.2.2", "json-parse-even-better-errors": "^3.0.0", @@ -15597,18 +14700,16 @@ }, "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", - "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", "dev": true, + "license": "MIT", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/read-package-json/node_modules/normalize-package-data": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz", - "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^6.0.0", "is-core-module": "^2.8.1", @@ -15621,9 +14722,8 @@ }, "node_modules/read-pkg": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "dev": true, + "license": "MIT", "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -15635,9 +14735,8 @@ }, "node_modules/read-pkg-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" @@ -15648,9 +14747,8 @@ }, "node_modules/read-pkg-up/node_modules/find-up": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^2.0.0" }, @@ -15660,9 +14758,8 @@ }, "node_modules/read-pkg-up/node_modules/locate-path": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -15673,9 +14770,8 @@ }, "node_modules/read-pkg-up/node_modules/p-limit": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^1.0.0" }, @@ -15685,9 +14781,8 @@ }, "node_modules/read-pkg-up/node_modules/p-locate": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^1.1.0" }, @@ -15697,33 +14792,29 @@ }, "node_modules/read-pkg-up/node_modules/p-try": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/read-pkg-up/node_modules/path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/read-pkg/node_modules/hosted-git-info": { "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/read-pkg/node_modules/load-json-file": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -15736,9 +14827,8 @@ }, "node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -15748,9 +14838,8 @@ }, "node_modules/read-pkg/node_modules/parse-json": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, + "license": "MIT", "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -15761,9 +14850,8 @@ }, "node_modules/read-pkg/node_modules/path-type": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^3.0.0" }, @@ -15773,36 +14861,32 @@ }, "node_modules/read-pkg/node_modules/pify": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/read-pkg/node_modules/semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/read-pkg/node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/read/node_modules/mute-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", "dev": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -15833,9 +14917,8 @@ }, "node_modules/redent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, + "license": "MIT", "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" @@ -15935,7 +15018,6 @@ }, "node_modules/requires-port": { "version": "1.0.0", - "dev": true, "license": "MIT" }, "node_modules/resolve": { @@ -16086,9 +15168,8 @@ }, "node_modules/rollup": { "version": "3.27.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.27.2.tgz", - "integrity": "sha512-YGwmHf7h2oUHkVBT248x0yt6vZkYQ3/rvE5iQuVBh3WO8GcJ6BNeOkpoX1yMHIiBm18EMLjBPIoUDkhgnyxGOQ==", "dev": true, + "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -16132,6 +15213,11 @@ "node": ">=12" } }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "dev": true, + "license": "MIT" + }, "node_modules/run-async": { "version": "2.4.1", "dev": true, @@ -16190,7 +15276,6 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "dev": true, "license": "MIT" }, "node_modules/safevalues": { @@ -16256,6 +15341,16 @@ "license": "ISC", "optional": true }, + "node_modules/saxes": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/schema-utils": { "version": "4.0.0", "dev": true, @@ -16500,9 +15595,8 @@ }, "node_modules/shell-quote": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -16608,7 +15702,6 @@ }, "node_modules/slash": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -16697,9 +15790,8 @@ }, "node_modules/sort-keys": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", "dev": true, + "license": "MIT", "dependencies": { "is-plain-obj": "^1.0.0" }, @@ -16829,9 +15921,8 @@ }, "node_modules/split": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, + "license": "MIT", "dependencies": { "through": "2" }, @@ -16841,9 +15932,8 @@ }, "node_modules/split2": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, + "license": "ISC", "dependencies": { "readable-stream": "^3.0.0" } @@ -16882,7 +15972,6 @@ }, "node_modules/stack-utils": { "version": "2.0.6", - "dev": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" @@ -16893,7 +15982,6 @@ }, "node_modules/stack-utils/node_modules/escape-string-regexp": { "version": "2.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -16985,9 +16073,8 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -17011,9 +16098,8 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -17039,9 +16125,8 @@ }, "node_modules/strip-indent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, + "license": "MIT", "dependencies": { "min-indent": "^1.0.0" }, @@ -17062,9 +16147,8 @@ }, "node_modules/strong-log-transformer": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", - "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "duplexer": "^0.1.1", "minimist": "^1.2.0", @@ -17079,7 +16163,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -17107,6 +16190,10 @@ "node": ">=0.10" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "license": "MIT" + }, "node_modules/tapable": { "version": "2.2.1", "dev": true, @@ -17133,9 +16220,8 @@ }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, + "license": "MIT", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -17176,9 +16262,8 @@ }, "node_modules/temp-dir": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -17202,9 +16287,8 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", @@ -17236,9 +16320,8 @@ }, "node_modules/terser-webpack-plugin/node_modules/acorn": { "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -17320,9 +16403,8 @@ }, "node_modules/terser-webpack-plugin/node_modules/terser": { "version": "5.19.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", - "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -17381,9 +16463,8 @@ }, "node_modules/text-extensions": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10" } @@ -17465,7 +16546,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -17482,11 +16562,30 @@ "node": ">=0.6" } }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tree-kill": { "version": "1.2.2", @@ -17498,9 +16597,8 @@ }, "node_modules/trim-newlines": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -17610,9 +16708,8 @@ }, "node_modules/tsconfig-paths": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, + "license": "MIT", "dependencies": { "json5": "^2.2.2", "minimist": "^1.2.6", @@ -17624,9 +16721,8 @@ }, "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -17717,7 +16813,6 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -17753,9 +16848,8 @@ }, "node_modules/typedarray": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/typescript": { "version": "4.9.5", @@ -17789,9 +16883,8 @@ }, "node_modules/uglify-js": { "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, + "license": "BSD-2-Clause", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -17870,15 +16963,13 @@ }, "node_modules/universal-user-agent": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/universalify": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -17893,9 +16984,8 @@ }, "node_modules/upath": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", - "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4", "yarn": "*" @@ -17903,8 +16993,6 @@ }, "node_modules/update-browserslist-db": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, "funding": [ { @@ -17920,6 +17008,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -17944,6 +17033,14 @@ "dev": true, "license": "MIT" }, + "node_modules/url-parse": { + "version": "1.5.10", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "dev": true, @@ -17999,9 +17096,8 @@ }, "node_modules/validate-npm-package-name": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", - "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", "dev": true, + "license": "ISC", "dependencies": { "builtins": "^5.0.0" }, @@ -18019,9 +17115,8 @@ }, "node_modules/vite": { "version": "4.3.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", - "integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.17.5", "postcss": "^8.4.23", @@ -18067,8 +17162,6 @@ }, "node_modules/vite/node_modules/postcss": { "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", "dev": true, "funding": [ { @@ -18084,6 +17177,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -18101,6 +17195,16 @@ "node": ">=0.10.0" } }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/walker": { "version": "1.0.8", "dev": true, @@ -18139,15 +17243,13 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "dev": true, + "license": "BSD-2-Clause" }, "node_modules/webpack": { "version": "5.86.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.86.0.tgz", - "integrity": "sha512-3BOvworZ8SO/D4GVP+GoRC3fVeg5MO4vzmq8TJJEkdmopxyazGDxN8ClqN12uzrZW9Tv8EED8v5VSb6Sqyi0pg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -18338,9 +17440,8 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/ast": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -18348,27 +17449,23 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -18377,15 +17474,13 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -18395,33 +17490,29 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/ieee754": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/webpack/node_modules/@webassemblyjs/leb128": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/webpack/node_modules/@webassemblyjs/utf8": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -18435,9 +17526,8 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -18448,9 +17538,8 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -18460,9 +17549,8 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -18474,9 +17562,8 @@ }, "node_modules/webpack/node_modules/@webassemblyjs/wast-printer": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" @@ -18484,9 +17571,8 @@ }, "node_modules/webpack/node_modules/acorn": { "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -18496,18 +17582,16 @@ }, "node_modules/webpack/node_modules/acorn-import-assertions": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^8" } }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -18521,30 +17605,26 @@ }, "node_modules/webpack/node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/webpack/node_modules/es-module-lexer": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", - "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -18581,7 +17661,6 @@ }, "node_modules/whatwg-encoding": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "iconv-lite": "0.6.3" @@ -18592,7 +17671,6 @@ }, "node_modules/whatwg-encoding/node_modules/iconv-lite": { "version": "0.6.3", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -18601,11 +17679,17 @@ "node": ">=0.10.0" } }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, + "license": "MIT", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -18640,9 +17724,8 @@ }, "node_modules/wordwrap": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -18663,9 +17746,8 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -18696,9 +17778,8 @@ }, "node_modules/write-json-file": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", - "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", "dev": true, + "license": "MIT", "dependencies": { "detect-indent": "^5.0.0", "graceful-fs": "^4.1.15", @@ -18713,9 +17794,8 @@ }, "node_modules/write-json-file/node_modules/make-dir": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -18726,27 +17806,24 @@ }, "node_modules/write-json-file/node_modules/pify": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/write-json-file/node_modules/semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver" } }, "node_modules/write-json-file/node_modules/write-file-atomic": { "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, + "license": "ISC", "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -18755,9 +17832,8 @@ }, "node_modules/write-pkg": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz", - "integrity": "sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==", "dev": true, + "license": "MIT", "dependencies": { "sort-keys": "^2.0.0", "type-fest": "^0.4.1", @@ -18769,16 +17845,14 @@ }, "node_modules/write-pkg/node_modules/type-fest": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", - "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=6" } }, "node_modules/ws": { "version": "8.11.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -18796,6 +17870,17 @@ } } }, + "node_modules/xml-name-validator": { + "version": "4.0.0", + "license": "Apache-2.0", + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "license": "MIT" + }, "node_modules/xtend": { "version": "4.0.2", "dev": true, @@ -18886,59 +17971,7 @@ } }, "prototypes/process-explorer/js": { - "name": "@morgan-stanley/composeui-process-explorer-frontend", - "version": "0.1.0-alpha.1", - "extraneous": true, - "dependencies": { - "@angular/animations": "^15.1.0", - "@angular/common": "^15.1.0", - "@angular/compiler": "^15.1.0", - "@angular/core": "^15.1.0", - "@angular/forms": "^15.1.0", - "@angular/platform-browser": "^15.1.0", - "@angular/platform-browser-dynamic": "^15.1.0", - "@angular/router": "^15.1.0", - "core-js": "^3.6.5", - "hammerjs": "^2.0.8", - "igniteui-angular": "^15.0.9", - "igniteui-angular-charts": "^15.0.0", - "igniteui-angular-core": "^15.0.0", - "jszip": "^3.5.0", - "material-icons": "1.13.1", - "minireset.css": "~0.0.4", - "rxjs": "~7.8.0", - "super-rpc": "^1.0.1", - "throttle-typescript": "^1.1.0", - "tslib": "^2.3.0", - "web-animations-js": "^2.3.2", - "zone.js": "~0.13.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^15.2.4", - "@angular-eslint/builder": "^15.2.0", - "@angular-eslint/eslint-plugin": "^16.0.3", - "@angular-eslint/eslint-plugin-template": "^15.2.0", - "@angular-eslint/schematics": "^15.2.0", - "@angular-eslint/template-parser": "^15.2.0", - "@angular/cli": "15.2.4", - "@angular/compiler-cli": "^15.1.0", - "@babel/runtime": "7.22.6", - "@igniteui/angular-schematics": "^15.0.1101", - "@types/hammerjs": "^2.0.41", - "@types/jasmine": "~4.3.0", - "@types/node": "^12.11.1", - "@typescript-eslint/eslint-plugin": "^5.51.0", - "@typescript-eslint/parser": "^5.51.0", - "eslint": "^7.26.0", - "jasmine-core": "~4.6.0", - "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.4.0", - "karma-chrome-launcher": "^3.1.1", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.0.0", - "typescript": "~4.9.4" - } + "extraneous": true }, "prototypes/process-explorer/oss-frontend": { "name": "@morgan-stanley/composeui-process-explorer-frontend-oss", @@ -18975,9 +18008,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@ampproject/remapping": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -18988,9 +18020,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular-devkit/architect": { "version": "0.1601.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1601.8.tgz", - "integrity": "sha512-kOXVGwsQnZvtz2UZNefcEy64Jiwq0eSoQUeozvDXOaYRJABLjPKI2YaarvKC9/Z1SGLuje0o/eRJO4T8aRk9rQ==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.1.8", "rxjs": "7.8.1" @@ -19003,9 +18034,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular-devkit/build-angular": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-16.1.8.tgz", - "integrity": "sha512-iyElPBQdcJq2plw5YqSz4mzNUfSRXI3ISFTEwPtimzPOorsj/OxB3Z6kJ8fDUsBAJ5OKR7xL7VnQJJ3S+05RhQ==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "2.2.1", "@angular-devkit/architect": "0.1601.8", @@ -19125,9 +18155,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular-devkit/build-webpack": { "version": "0.1601.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1601.8.tgz", - "integrity": "sha512-LUMA3xNnN4IY/FPaqyF6rzba+QVxl3vA+v0l71CBIKNU+Qee6D9xe8KG0Bn7relqDhWZOSHY0nhhO2mBoz4iQg==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1601.8", "rxjs": "7.8.1" @@ -19144,9 +18173,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular-devkit/core": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.1.8.tgz", - "integrity": "sha512-dSRD/+bGanArIXkj+kaU1kDFleZeQMzmBiOXX+pK0Ah9/0Yn1VmY3RZh1zcX9vgIQXV+t7UPrTpOjaERMUtVGw==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "8.12.0", "ajv-formats": "2.1.1", @@ -19170,9 +18198,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular-devkit/schematics": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.1.8.tgz", - "integrity": "sha512-6LyzMdFJs337RTxxkI2U1Ndw0CW5mMX/aXWl8d7cW2odiSrAg8IdlMqpc+AM8+CPfsB0FtS1aWkEZqJLT0jHOg==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.1.8", "jsonc-parser": "3.2.0", @@ -19188,8 +18215,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/animations": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.1.8.tgz", - "integrity": "sha512-aIAf8EAZomgXMF6AP0wTPAc04Cvw+nL9nkEVwQNVxMByZpcbnnqHWHokLD8es8DzlwDT+EIZS4wZMBA4XUmPyA==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19202,8 +18228,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/cdk": { "version": "16.1.7", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-16.1.7.tgz", - "integrity": "sha512-KLiqzbilkGBtQcaNdqjN16XyNdQxEkN4Oqbg6coahWqwvEVEdhNwLrwOJcCHMH2vvMzCd4XHaOnAxQjVy5pkjQ==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19218,9 +18243,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/cli": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-16.1.8.tgz", - "integrity": "sha512-amOIHMq8EvixhnI+do5Bcy6IZSFAJx0njhhLM4ltDuNUczH8VH0hNegZKxhb8K87AMO8jITFM+NLrzccyghsDQ==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/architect": "0.1601.8", "@angular-devkit/core": "16.1.8", @@ -19252,8 +18276,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/common": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-16.1.8.tgz", - "integrity": "sha512-Zm+Ysxdf74VwG3mbAqs2v1QFUR+h9RyJBXF5VFABEpgFw7NUOBKrayjJmKjgZ0TBAmL2+nXehJgcPph3zNp3sg==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19267,8 +18290,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/compiler": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-16.1.8.tgz", - "integrity": "sha512-jF2zk3LjrcI/xpjJG6yoLiL2t2l5227i8SjhRUawAL1sy0xtb/PiSLjCNhuSgyixbB/8az/YezZe11MSg48FDg==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19286,9 +18308,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/compiler-cli": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-16.1.8.tgz", - "integrity": "sha512-Whk3RBnEYwN0c6Mo7hU6JDpHSyKONmIQEN8ViHJXwmyHK8w+/Z27iBw10QiyWUMtYb4tIM1xSLhRFAwH/3WnPQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "7.22.5", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -19314,8 +18335,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/core": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-16.1.8.tgz", - "integrity": "sha512-XtOpY9HA85hPGrPwe1rgE8NJ3bFWbuJFx4SUlzB66k9B5jo8bD2Dxl/0id55RFS5gmvCe/Qhh0zoGyMpkWjMHA==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19329,8 +18349,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/forms": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-16.1.8.tgz", - "integrity": "sha512-V36q42ExvL93T7oYvRf4Z2z2V/kOm0wgaFgkNSiBHgIpuwvrAZ9nRZBui5Fqdnep3xKYd980vAaTtACA1blv3Q==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19346,8 +18365,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/material": { "version": "16.1.7", - "resolved": "https://registry.npmjs.org/@angular/material/-/material-16.1.7.tgz", - "integrity": "sha512-n4h843O8wjV8xpLk4XmxV3ICDQo+a4Ofk2LZ9ja1KzohgweXOJ3PBpBrVeesToa5EMvuFgejcPwE6sJysxoyUg==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/auto-init": "15.0.0-canary.b994146f6.0", @@ -19410,8 +18428,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/platform-browser": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-16.1.8.tgz", - "integrity": "sha512-wfUCVU7DLMHy5Rw7LY8KSTuLk0ff2bWElT6WSAKXXFEPjQiWuXbbIe+gglJX5HFQQHoyVwNbsSDIIgEp535Kvw==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19431,8 +18448,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/platform-browser-dynamic": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-16.1.8.tgz", - "integrity": "sha512-mhQH78Zn/oFe+U8DmVvPJ0/7neDlnKcgktQ7f1vFNibRLqkmHW/o1vZ0B7CAmO+yzGbB8mt+RBCFAfA7g3oRDg==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19448,8 +18464,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@angular/router": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-16.1.8.tgz", - "integrity": "sha512-p11Mz0qQbl26fcEEQ9LEUZhKrca9kqSwMWgxBRMWZl0AgtbWQadiVdjiQY0rvpohI7qSO8m3s7CFIQLKIOEvYQ==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, @@ -19465,9 +18480,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/core": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz", - "integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.5", @@ -19495,18 +18509,16 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/generator": { "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz", - "integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5", "@jridgewell/gen-mapping": "^0.3.2", @@ -19519,9 +18531,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -19531,9 +18542,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/helper-define-polyfill-provider": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", - "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -19547,9 +18557,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/helper-split-export-declaration": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -19559,9 +18568,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -19571,9 +18579,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", - "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", @@ -19588,9 +18595,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/plugin-transform-runtime": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.5.tgz", - "integrity": "sha512-bg4Wxd1FWeFx3daHFTWk1pkSWK/AyQuiyAoeZAOkAOUBjnZPH6KT7eMxouV47tQ6hl6ax2zyAWBdWZXbrvXlaw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5", @@ -19608,18 +18614,16 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/plugin-transform-runtime/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/preset-env": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.5.tgz", - "integrity": "sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.5", "@babel/helper-compilation-targets": "^7.22.5", @@ -19711,18 +18715,16 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/runtime": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", - "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -19732,9 +18734,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@babel/template": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.22.5", "@babel/parser": "^7.22.5", @@ -19746,12 +18747,11 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@esbuild/win32-x64": { "version": "0.17.19", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", - "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -19762,9 +18762,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -19776,16 +18775,14 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/animation": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/animation/-/animation-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-kqqzG54tabYJ5VsBur5k1bqCFQCEpaW3hmLRMiSVVxRY7XgTt7qkuOOz48gs+MPqR6P8VIi6gFpuscV1+DWDhw==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/@material/auto-init": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/auto-init/-/auto-init-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-8nLe/XeueJg5yyYx5e4UxWQXpTDyUhibKfyroGwnRKc8pdpOCOulHSOj/fIVGJAIbxkEJoebwMadWUNCjUhc9A==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "tslib": "^2.1.0" @@ -19793,8 +18790,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/banner": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/banner/-/banner-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-gJ4/VdP4dJgHP72Kdjy2f/UjHB45J4CuxoGvI0NIQYUjOSsr4kQiQHsjVgyEPZR/5wa7kBhM7/0mJ+zF7Ghv2A==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/button": "15.0.0-canary.b994146f6.0", @@ -19812,16 +18808,14 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/base": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/base/-/base-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-rW2upYD5YjRFBL6DzYn3SCRhtvpEDkwplDS810e3vt71uLMRyqXyw4OQJH+Nab/t+32TFDtKNUphXIzwICXGDQ==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/@material/button": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/button/-/button-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-SMyqtsvJuCqpXBz2JgciuR6wddNJSGpTXUFxmLbGluBy5/hHm06JWlOFcUOxGDv46OdRGGrRfkg6A9JtvtsJsw==", + "license": "MIT", "dependencies": { "@material/density": "15.0.0-canary.b994146f6.0", "@material/dom": "15.0.0-canary.b994146f6.0", @@ -19840,8 +18834,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/card": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/card/-/card-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-WSggGon91HcDhJyatnYLFkoM9glkkeJjyjFDWrcJkwN1rdrPJU+GH+PNjvmArz5hGv9WkmjDjhOdAuPnL4Mb7g==", + "license": "MIT", "dependencies": { "@material/dom": "15.0.0-canary.b994146f6.0", "@material/elevation": "15.0.0-canary.b994146f6.0", @@ -19856,8 +18849,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/checkbox": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/checkbox/-/checkbox-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-pulRiwG9S/dS6WBG+GteODBltddFiL0Sb7HAqdzF2BTKNKv25q1ZIR3ftoEa09TNeWM88AOzTJ4aBHiADfJn2w==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -19874,8 +18866,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/chips": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/chips/-/chips-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-3yJPj7x+eKLA4LMKG7aTWI+itAnKRVGOcniuR6aiXVy0OKr5asNuWNeZc9J0/VErjjxF3tdybDzDSPo01qPy9w==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -19898,8 +18889,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/circular-progress": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/circular-progress/-/circular-progress-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-6YUvGXdtZKJoE7AuovR4xk1aiWp/EDZ6j2U3TOeynd1assQQCg5XT4abqAoHtpJrRPaCFgUAp836HyiDVVuYug==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -19913,8 +18903,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/data-table": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/data-table/-/data-table-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-v4hIduIe/wzyibuL/RPM/ErYrt8XpB7fxyQqtV+0JsMpFa8E81QYyvMCS9EJj9m4YdkrQnZgA+vXQlOkhWvmdQ==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -19939,16 +18928,14 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/density": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/density/-/density-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-m8l0vuoWSoAPItBpWp5eZDvitUcB2JWoO8V486hLgdveVcKgXG09xWM43ScH+PLXAWjzr5olDEuJ2tvfkN3SpQ==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/@material/dialog": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/dialog/-/dialog-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-JucU92yh8cfZQpyRBunHr6uohacePLYmhcPaGpkAGQ1b+zCznEsNs55tjhaVQNoj91XA9rrBqtL6Otg+fxFJtQ==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -19969,8 +18956,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/dom": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/dom/-/dom-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-DiUsTezrCi4iytjIn7xXoXZSNFvuTrVVZgc7cR9cW8yu2Hpz8bPf87PacVn4IP9OsNwy/dCDMk1Kcq/DMh7gXQ==", + "license": "MIT", "dependencies": { "@material/feature-targeting": "15.0.0-canary.b994146f6.0", "@material/rtl": "15.0.0-canary.b994146f6.0", @@ -19979,8 +18965,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/drawer": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/drawer/-/drawer-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-Kbuf32V0eX69amvCVbAjNSabNDerZWyG8ip466EfQHRh0OUZwvsbhLp9FZOB7AyR+/bQiHf3mVLcombOdmdkcQ==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -19998,8 +18983,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/elevation": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-l2YDNgBajSI6oA2l6gaeYCTGHRao657syqQ/tv95/Hkcee9900A4RrsxCwSxOqqAs5pZZDEJ33kFJjj27nqZDw==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20011,8 +18995,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/fab": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/fab/-/fab-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-ExyDVkNWINpns41Ahj4u8I/OhiVkqI0nmcqjFRtgTJMmKEd4NhlvqIxE7gakAlyS68riJu5UleqTSTVmt8mv2Q==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/dom": "15.0.0-canary.b994146f6.0", @@ -20031,16 +19014,14 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/feature-targeting": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-HR/FjSQmza98B1DF80MRjODyfOI9r7wXkPSts/cLQsYkpwZ5uJmxhvQKjDCeYVpMV0lQuvuvVOQo7uD44TdWEg==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/@material/floating-label": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/floating-label/-/floating-label-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-g64talBNWCS0FUfLWal0uB637gUciSIqYxFzSW//LglTtbZLGK2J4+9gAEswQGnKeO4ux08EN2n1ZcMDYQ58ow==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20054,8 +19035,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/focus-ring": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-87qEMuXsCvlQfTiimnzJUZoebnIXWcMtRZevNLymN9Y0t9jGckQxZPmrI0llRkpyiR/Ewhec5SI/JGrFlYHnsA==", + "license": "MIT", "dependencies": { "@material/dom": "15.0.0-canary.b994146f6.0", "@material/feature-targeting": "15.0.0-canary.b994146f6.0", @@ -20064,8 +19044,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/form-field": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/form-field/-/form-field-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-Tg1SQQaopvXMyDEYxGTWnhCWQmNcWVIoKMLmle9P/gi2p8ulcj0iOCPYf+3ECqUBVozOmTPKlYOOiRwtKStAeA==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/feature-targeting": "15.0.0-canary.b994146f6.0", @@ -20078,8 +19057,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/icon-button": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-X6DvOv4jpymHUjI7ZAbO946nDgGYKDwPZfkRzBE84gv2XEr2qfMuABhojxkYubRbt03oauBdcJVVMFCXkVhArQ==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/density": "15.0.0-canary.b994146f6.0", @@ -20096,8 +19074,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/image-list": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/image-list/-/image-list-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-kf903XFF1P+V5ZPXCt+7R6c55g4UyQE1ZHkTViCIJfd52gU40bHODMhTQy/ywBkwDeJfNk8uf1V1IM24WQYpxA==", + "license": "MIT", "dependencies": { "@material/feature-targeting": "15.0.0-canary.b994146f6.0", "@material/shape": "15.0.0-canary.b994146f6.0", @@ -20108,16 +19085,14 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/layout-grid": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/layout-grid/-/layout-grid-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-OALBSGue8g1/mEwLYYi2d950dJFpNYKW87jPS9/KM65JKMyxoU7tU2d4An1BuyqK0r9sopGq6Pn/zhill0iLaw==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/@material/line-ripple": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/line-ripple/-/line-ripple-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-evjZxCu4iodiKtW8N0xjY8ACRXm3sY+4rAmq3vV5BmHWAJ3BobjbFYslDMZQ+4mu3HmwMatbJehKxHegahitNg==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20128,8 +19103,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/linear-progress": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/linear-progress/-/linear-progress-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-jlXh+tIj+/o0Ks7fHdC/24fH6IXCAl2vF52U6NwT39ESrlwmlLhp3gtag5GSBHN5E7Z09nK871Yo1G/b1F+COg==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20143,8 +19117,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/list": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/list/-/list-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-kY/i6VvFBb/W3VvCPvWRMzWvu7mvNFJ+R8ijfawDoAXiv4fj42GO4iFyTcFXaUevEPKp791pN/09BMJQ6jYEvA==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/density": "15.0.0-canary.b994146f6.0", @@ -20161,8 +19134,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/menu": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/menu/-/menu-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-y6smNmLJ+U0DoXWbyqzW+VW/uWDuklhdGHc5MbZrTOhsKkhvoTVNMSOa+NFPU4gTwrplvUjaUvnIsQ0wygwD3g==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/dom": "15.0.0-canary.b994146f6.0", @@ -20180,8 +19152,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/menu-surface": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/menu-surface/-/menu-surface-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-StmM3lrRn1iMEZfq532jpMNppqyBBy68FbPurKEsHuP/3q+CscfnwjrS9ym+JcHqXKMHnQXbL/49ymffRGX2AQ==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20195,8 +19166,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/notched-outline": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/notched-outline/-/notched-outline-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-UZxU8jXM2t/bk/CiO0K+TSPspuJRZIyrYlIS0gd+qq/u8Gi2DpALBlLAh9Jeu46IUg4YGlPsNWYfe8p3QAVyoA==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/feature-targeting": "15.0.0-canary.b994146f6.0", @@ -20209,16 +19179,14 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/progress-indicator": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/progress-indicator/-/progress-indicator-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-VT+mOQhohaM+pBX1rknbVOI6JCGKg9NiOHBoYljIvnexNeILE+mW9g6mtQ0ZCJPz0oMmiSAMLcuxMIcBXx84Xw==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/@material/radio": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/radio/-/radio-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-U/RR2lVNWwEO2+kJtGz9XzvnOF0gAZn1krMY0z/eU9Wnl0OgPZbqQrxXMoVNv1pzKYSEwZQEGado/rv8qp7piA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20234,8 +19202,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/ripple": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-WzIbc8wYTzMOczqGXVCBPdNcv/73Ef8FwcQYsscGMaqCzgVsdpoqilTfsx7Ryyz6dQbyfmJqp7s+YpPujcezOA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20248,8 +19215,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/rtl": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-H/W6BVn4Ygfkrf/FgSrNhbu1uY7PST2wlsjEYQt06EfAM0CDHEwSL1MwV4FmpQA/r40Q0PqoLN6moDrtCe5S8g==", + "license": "MIT", "dependencies": { "@material/theme": "15.0.0-canary.b994146f6.0", "tslib": "^2.1.0" @@ -20257,8 +19223,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/segmented-button": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/segmented-button/-/segmented-button-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-jd+f4BTnU0tghxBpAM/XdVmruDXSoQ88TYSFWbrhulS+/c/ooCZURWvVC4mHNej+QR/fODkx4adbqkBiwwCtMw==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/elevation": "15.0.0-canary.b994146f6.0", @@ -20272,8 +19237,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/select": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/select/-/select-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-5thEQS+B17JSm3I8D+mqQe2G3ArVnXJALTEEE9FmMUKwKYkrsLplm3FYuEXERZGJnYeTRdkdmhYY/YeocfZoyA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20298,8 +19262,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/shape": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/shape/-/shape-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-sINM3gr3aLgdvqZVfqfXV5EB77owLLJjy+2NqchJ8ZPqucCJ+F/BsCBfLA2Wu3O4Sc9IpAEn/o1hzYm/CWAFAw==", + "license": "MIT", "dependencies": { "@material/feature-targeting": "15.0.0-canary.b994146f6.0", "@material/rtl": "15.0.0-canary.b994146f6.0", @@ -20309,8 +19272,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/slider": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/slider/-/slider-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-dyT72+Kp//AEajJxDUVoMoizUjf2uggVMGXOaQ7FhpGHuf7LC3EyEjrrJ15efFzYgTjdJUU1YQkCwGmdt6CQsA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20327,8 +19289,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/snackbar": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/snackbar/-/snackbar-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-fEhPASJossScNpcrNYrrH8uU+rUf6+kw7/ZMrpUzzz1lVXliL28jTNEmU1nFpcDI4M2GXH+Z64f7vl2hiMDG8g==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20348,8 +19309,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/switch": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/switch/-/switch-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-czCXTUa30ILIf1J3exiuSVIRcodGATHexd3eWDq4sfHo4iMh4rBMaIxcqkmnb2iwE/mMTNyVfoauijx2QiNKrA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20369,8 +19329,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/tab": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/tab/-/tab-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-ygswooiNdBNNDnQdbPX0nzDQu7oQlHo8vWZ0/xL4IPVEXabY5zCzsEbGNZw2u/syo56c/NHPyMsUmXDGRSXOvQ==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/elevation": "15.0.0-canary.b994146f6.0", @@ -20387,8 +19346,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/tab-bar": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/tab-bar/-/tab-bar-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-F9NegACnFEWMu1pAAypV4Jd7qROeffkvEgVO28Xxk/CvzZxFz8kAjYJZ+rI6RUhPX3BhXzwsz/AlLwsJMT2tnA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20406,8 +19364,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/tab-indicator": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/tab-indicator/-/tab-indicator-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-8IH/DmwlZhQlw/2Y3aKrEvjEhZB+qbKUiyaij3BkTAexvyFeDBh5cLNjRpYkUJSGeSPhS6yu4SYzMHPmQEwQmA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20418,8 +19375,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/tab-scroller": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/tab-scroller/-/tab-scroller-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-1MeWkr62OICfTv8oqhIZe6jFo0dKeMlUfB+/WcgnpoeMBszCOSlx5tQ4pedxUkuR3I+Z7rsTfSN0LavgF8bATA==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20431,8 +19387,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/textfield": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/textfield/-/textfield-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-Kxb3DoJ5o8u3Y1gRMHKmWrDl1TirVxuf/UFrxPFiCE3J1SqiE2VQpakiD1emZwp+LSKtbRsQ/iILYLB/h7Wuvw==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20453,8 +19408,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/theme": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/theme/-/theme-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-5tsZ92dAeUcZ9g9CrIkqX/GYc0M5DIfsydtI1PAidaBzr1Uokuh4rTZVQZBv7gyglF0yDua59lkb0I6wI9vxXg==", + "license": "MIT", "dependencies": { "@material/feature-targeting": "15.0.0-canary.b994146f6.0", "tslib": "^2.1.0" @@ -20462,16 +19416,14 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/tokens": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/tokens/-/tokens-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-jFqU7PtvGkrP8b8i2soCrYQInTrnZ1/rIPDi+Xm3sa/qSghCNwFrdJEqwcwtv1fPlJIOtzkIuVRYRmAP9rXQIQ==", + "license": "MIT", "dependencies": { "@material/elevation": "15.0.0-canary.b994146f6.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/@material/tooltip": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/tooltip/-/tooltip-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-bVzydXGn3fauHJ8pkh32DsdyRJXleeFQ4t7jZ/rcRik+n4G1BvYiblfuu3Z/OCC0m3TJDyMdJhd+sLqRDqLUUg==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20490,8 +19442,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/top-app-bar": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/top-app-bar/-/top-app-bar-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-VHq0wX3OJE1TKvjO8Qtlu+rv5EGoqAhNLBcEjpUUGoqHH/gpd356FEuIqJId4pUh5jaWf8T4ZU9xVbQGMtntzw==", + "license": "MIT", "dependencies": { "@material/animation": "15.0.0-canary.b994146f6.0", "@material/base": "15.0.0-canary.b994146f6.0", @@ -20506,8 +19457,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/touch-target": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-X26Y9OWvIqYOHo+sC2VMvOoeQWlUR3/yb7uPdfq92Y44zlQ4Vexgq7nEUblEiXQ8Fj+d0T9rIhRh1y9PP3Z2dw==", + "license": "MIT", "dependencies": { "@material/base": "15.0.0-canary.b994146f6.0", "@material/feature-targeting": "15.0.0-canary.b994146f6.0", @@ -20518,8 +19468,7 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@material/typography": { "version": "15.0.0-canary.b994146f6.0", - "resolved": "https://registry.npmjs.org/@material/typography/-/typography-15.0.0-canary.b994146f6.0.tgz", - "integrity": "sha512-sWU5W30WWqdw5P6bsRx9AbvMNcz/QvQg56Syr06V6nfgSztpeuo7TfPk2J+N0ArRALo1mUrkAPk66iWYQ2p/QA==", + "license": "MIT", "dependencies": { "@material/feature-targeting": "15.0.0-canary.b994146f6.0", "@material/theme": "15.0.0-canary.b994146f6.0", @@ -20528,9 +19477,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@ngtools/webpack": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.1.8.tgz", - "integrity": "sha512-co2SC1a822655Ek2f6fkMFsswHeCm2obNceb0kftLSpqomCgPAC3T447pB3TE1Iw+BEMFdjrAgIrp3nyYWwHsQ==", "dev": true, + "license": "MIT", "engines": { "node": "^16.14.0 || >=18.10.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", @@ -20544,9 +19492,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/@schematics/angular": { "version": "16.1.8", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.1.8.tgz", - "integrity": "sha512-gTHy1A/E9BCr0sj3VCr6eBYkgVkO96QWiZcFumedGnvstvp5wiCoIoJPLLfYaxVt1vt08xmnmS3OZ3r0qCLdpA==", "dev": true, + "license": "MIT", "dependencies": { "@angular-devkit/core": "16.1.8", "@angular-devkit/schematics": "16.1.8", @@ -20560,9 +19507,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/acorn": { "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -20572,8 +19518,6 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/autoprefixer": { "version": "10.4.14", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", - "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", "dev": true, "funding": [ { @@ -20585,6 +19529,7 @@ "url": "https://tidelift.com/funding/github/npm/autoprefixer" } ], + "license": "MIT", "dependencies": { "browserslist": "^4.21.5", "caniuse-lite": "^1.0.30001464", @@ -20605,9 +19550,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", - "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.4.2", @@ -20619,18 +19563,16 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "prototypes/process-explorer/oss-frontend/node_modules/babel-plugin-polyfill-corejs3": { "version": "0.8.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz", - "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.4.2", "core-js-compat": "^3.31.0" @@ -20641,9 +19583,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/babel-plugin-polyfill-regenerator": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", - "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.4.2" }, @@ -20653,9 +19594,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/cacache": { "version": "17.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-17.1.3.tgz", - "integrity": "sha512-jAdjGxmPxZh0IipMdR7fK/4sDSrHMLUV0+GvVUsjwyGNKHsh79kW/otg+GkbXwl6Uzvy9wsvHOX4nUoWldeZMg==", "dev": true, + "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -20676,9 +19616,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -20690,9 +19629,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/cosmiconfig": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", - "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", "dev": true, + "license": "MIT", "dependencies": { "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -20708,9 +19646,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/critters": { "version": "0.0.20", - "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.20.tgz", - "integrity": "sha512-CImNRorKOl5d8TWcnAz5n5izQ6HFsvz29k327/ELy6UFcmbiZNOsinaKvzv16WZR0P6etfSWYzE47C4/56B3Uw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "chalk": "^4.1.0", "css-select": "^5.1.0", @@ -20723,9 +19660,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/css-loader": { "version": "6.8.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", - "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.21", @@ -20749,9 +19685,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/css-select": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -20765,9 +19700,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/dom-serializer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -20779,9 +19713,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/domhandler": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -20794,9 +19727,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/domutils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -20808,9 +19740,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -20820,10 +19751,9 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/esbuild": { "version": "0.17.19", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", - "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "bin": { "esbuild": "bin/esbuild" @@ -20858,9 +19788,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/esbuild-wasm": { "version": "0.17.19", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.17.19.tgz", - "integrity": "sha512-X9UQEMJMZXwlGCfqcBmJ1jEa+KrLfd+gCBypO/TSzo5hZvbVwFqpxj1YCuX54ptTF75wxmrgorR4RL40AKtLVg==", "dev": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -20870,18 +19799,16 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/ini": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", "dev": true, + "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "prototypes/process-explorer/oss-frontend/node_modules/inquirer": { "version": "8.2.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-escapes": "^4.2.1", "chalk": "^4.1.1", @@ -20905,24 +19832,21 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/ipaddr.js": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 10" } }, "prototypes/process-explorer/oss-frontend/node_modules/jasmine-core": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.0.tgz", - "integrity": "sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ==", - "dev": true + "dev": true, + "license": "MIT" }, "prototypes/process-explorer/oss-frontend/node_modules/karma-jasmine-html-reporter": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", - "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", "dev": true, + "license": "MIT", "peerDependencies": { "jasmine-core": "^4.0.0 || ^5.0.0", "karma": "^6.0.0", @@ -20931,18 +19855,16 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/lru-cache": { "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "prototypes/process-explorer/oss-frontend/node_modules/magic-string": { "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" }, @@ -20952,14 +19874,12 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/material-icons": { "version": "1.13.10", - "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.10.tgz", - "integrity": "sha512-XSESl/zo7XzD9nz8ihUq5HO0DzsvnVex9t8hpH8pqY1SFlESAdHlMQQbcCyyP58mPp6Wm1tyt0OaDNZhBT9lXQ==" + "license": "Apache-2.0" }, "prototypes/process-explorer/oss-frontend/node_modules/mini-css-extract-plugin": { "version": "2.7.6", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", - "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", "dev": true, + "license": "MIT", "dependencies": { "schema-utils": "^4.0.0" }, @@ -20976,18 +19896,16 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/minipass": { "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" } }, "prototypes/process-explorer/oss-frontend/node_modules/npm-package-arg": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", "dev": true, + "license": "ISC", "dependencies": { "hosted-git-info": "^6.0.0", "proc-log": "^3.0.0", @@ -21000,9 +19918,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/open": { "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -21017,8 +19934,6 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/postcss": { "version": "8.4.24", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz", - "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==", "dev": true, "funding": [ { @@ -21034,6 +19949,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -21045,9 +19961,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/postcss-loader": { "version": "7.3.2", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.2.tgz", - "integrity": "sha512-c7qDlXErX6n0VT+LUsW+nwefVtTu3ORtVvK8EXuUIDcxo+b/euYqpuHlJAvePb0Af5e8uMjR/13e0lTuYifaig==", "dev": true, + "license": "MIT", "dependencies": { "cosmiconfig": "^8.1.3", "jiti": "^1.18.2", @@ -21068,9 +19983,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/resolve": { "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.11.0", "path-parse": "^1.0.7", @@ -21085,9 +19999,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/sass": { "version": "1.63.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.63.2.tgz", - "integrity": "sha512-u56TU0AIFqMtauKl/OJ1AeFsXqRHkgO7nCWmHaDwfxDo9GUMSqBA4NEh6GMuh1CYVM7zuROYtZrHzPc2ixK+ww==", "dev": true, + "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -21102,9 +20015,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/sass-loader": { "version": "13.3.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.1.tgz", - "integrity": "sha512-cBTxmgyVA1nXPvIK4brjJMXOMJ2v2YrQEuHqLw3LylGb3gsR6jAvdjHMcy/+JGTmmIF9SauTrLLR7bsWDMWqgg==", "dev": true, + "license": "MIT", "dependencies": { "klona": "^2.0.6", "neo-async": "^2.6.2" @@ -21140,9 +20052,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/semver": { "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -21155,9 +20066,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/semver/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -21167,9 +20077,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/ssri": { "version": "10.0.4", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.4.tgz", - "integrity": "sha512-12+IR2CB2C28MMAw0Ncqwj5QbTcs0nGIhgJzYWzDkb21vWmfNI83KS4f3Ci6GI98WreIfG7o9UXp3C0qbpA8nQ==", "dev": true, + "license": "ISC", "dependencies": { "minipass": "^5.0.0" }, @@ -21179,9 +20088,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/terser": { "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -21197,14 +20105,12 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/tslib": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "license": "0BSD" }, "prototypes/process-explorer/oss-frontend/node_modules/typescript": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -21215,9 +20121,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/webpack-dev-middleware": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz", - "integrity": "sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ==", "dev": true, + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.12", @@ -21243,9 +20148,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/webpack-dev-server": { "version": "4.15.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz", - "integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -21302,9 +20206,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", "dev": true, + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -21325,9 +20228,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/webpack-merge": { "version": "5.9.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", - "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "wildcard": "^2.0.0" @@ -21338,9 +20240,8 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/ws": { "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -21359,15 +20260,13 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "dev": true, + "license": "ISC" }, "prototypes/process-explorer/oss-frontend/node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -21383,17 +20282,15 @@ }, "prototypes/process-explorer/oss-frontend/node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } }, "prototypes/process-explorer/oss-frontend/node_modules/zone.js": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.1.tgz", - "integrity": "sha512-+bIeDAFEBYuXRuU3qGQvzdPap+N1zjM4KkBAiiQuVVCrHrhjDuY6VkUhNa5+U27+9w0q3fbKiMCbpJ0XzMmSWA==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" } @@ -21406,6 +20303,7 @@ "@finos/fdc3": "^2.0.0", "@morgan-stanley/composeui-messaging-client": "*", "@types/node": "^18.11.18", + "jest-environment-jsdom": "^29.7.0", "rxjs": "^7.8.1" }, "devDependencies": { @@ -21414,6 +20312,7 @@ "@types/jest": "^29.4.0", "@types/node": "^18.11.18", "jest": "^29.4.3", + "jsdom": "^22.1.0", "rimraf": "4.1.2", "rollup": "^3.14.0", "ts-jest": "29.1.0", @@ -21424,9 +20323,8 @@ }, "src/fdc3/js/composeui-fdc3/node_modules/@rollup/plugin-node-resolve": { "version": "15.0.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz", - "integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==", "dev": true, + "license": "MIT", "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", @@ -21449,10 +20347,8 @@ }, "src/fdc3/js/composeui-fdc3/node_modules/rimraf": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz", - "integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==", - "deprecated": "Please upgrade to 4.3.1 or higher to fix a potentially damaging issue regarding symbolic link following. See https://github.com/isaacs/rimraf/issues/259 for details.", "dev": true, + "license": "ISC", "bin": { "rimraf": "dist/cjs/src/bin.js" }, @@ -21629,175 +20525,6 @@ "funding": { "url": "https://github.com/sponsors/isaacs" } - }, - "Tryouts/Messaging-JS": { - "name": "@morgan-stanley/composeui-messaging-client", - "version": "0.1.0", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@types/node": "^18.11.18", - "rxjs": "^7.8.0" - }, - "devDependencies": { - "@jest/expect-utils": "^29.4.1", - "@rollup/plugin-node-resolve": "^15.0.1", - "@rollup/plugin-typescript": "^11.0.0", - "@types/jest": "^29.4.0", - "expect": "^29.4.1", - "glob": "^8.1.0", - "jest": "^29.4.2", - "jest-extended": "^3.2.3", - "rimraf": "^4.1.1", - "rollup": "^3.17.2", - "rollup-plugin-dts": "^5.2.0", - "ts-jest": "^29.0.5", - "tslib": "^2.5.0", - "typescript": "^4.9.4" - } - }, - "Tryouts/Plugins/ApplicationPlugins/chart": { - "name": "@morgan-stanley/composeui-example-chart", - "version": "0.1.0", - "extraneous": true, - "dependencies": { - "@morgan-stanley/composeui-messaging-client": "*", - "bootstrap": "5.2.3", - "highcharts": "10.3.3", - "jquery": "3.6.3", - "tslib": "2.5.0" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "24.0.1", - "@rollup/plugin-node-resolve": "15.0.1", - "http-server": "14.1.1", - "rimraf": "4.1.2", - "rollup": "^3.14.0" - } - }, - "Tryouts/Plugins/ApplicationPlugins/datagrid": { - "name": "@morgan-stanley/composeui-example-grid", - "version": "0.1.0", - "extraneous": true, - "dependencies": { - "@angular/animations": "^15.1.0", - "@angular/cdk": "~15.1.4", - "@angular/common": "^15.1.0", - "@angular/compiler": "^15.1.0", - "@angular/core": "^15.1.0", - "@angular/flex-layout": "^15.0.0-beta.42", - "@angular/forms": "^15.1.0", - "@angular/material": "~15.1.4", - "@angular/platform-browser": "^15.1.0", - "@angular/platform-browser-dynamic": "^15.1.0", - "@angular/router": "^15.1.0", - "@morgan-stanley/composeui-messaging-client": "*", - "material-icons": "1.13.1", - "rxjs": "~7.8.0", - "tslib": "^2.3.0", - "zone.js": "~0.12.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^15.1.4", - "@angular/cli": "~15.1.4", - "@angular/compiler-cli": "^15.1.0", - "@types/jasmine": "~4.3.0", - "jasmine-core": "~4.5.0", - "karma": "~6.4.0", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.0.0", - "typescript": "~4.9.4" - } - }, - "Tryouts/Plugins/ApplicationPlugins/defaultApp": { - "name": "@morgan-stanley/composeui-example-default", - "version": "0.1.0-alpha.1", - "extraneous": true, - "devDependencies": { - "http-server": "14.1.1" - } - }, - "Tryouts/Plugins/ApplicationPlugins/process explorer": { - "name": "@morgan-stanley/composeui-process-explorer-frontend", - "version": "0.1.0-alpha.1", - "extraneous": true, - "dependencies": { - "@angular/animations": "^15.1.0", - "@angular/common": "^15.1.0", - "@angular/compiler": "^15.1.0", - "@angular/core": "^15.1.0", - "@angular/forms": "^15.1.0", - "@angular/platform-browser": "^15.1.0", - "@angular/platform-browser-dynamic": "^15.1.0", - "@angular/router": "^15.1.0", - "core-js": "^3.6.5", - "hammerjs": "^2.0.8", - "igniteui-angular": "^15.0.9", - "igniteui-angular-charts": "^15.0.0", - "igniteui-angular-core": "^15.0.0", - "jszip": "^3.5.0", - "material-icons": "1.13.1", - "minireset.css": "~0.0.4", - "rxjs": "~7.8.0", - "super-rpc": "^1.0.1", - "throttle-typescript": "^1.1.0", - "tslib": "^2.3.0", - "web-animations-js": "^2.3.2", - "zone.js": "~0.13.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^15.2.4", - "@angular-eslint/builder": "^15.2.0", - "@angular-eslint/eslint-plugin": "^15.2.0", - "@angular-eslint/eslint-plugin-template": "^15.2.0", - "@angular-eslint/schematics": "^15.2.0", - "@angular-eslint/template-parser": "^15.2.0", - "@angular/cli": "15.2.4", - "@angular/compiler-cli": "^15.1.0", - "@babel/runtime": "7.21.0", - "@igniteui/angular-schematics": "^15.0.1101", - "@types/jasmine": "~4.3.0", - "@types/node": "^12.11.1", - "@typescript-eslint/eslint-plugin": "^5.51.0", - "@typescript-eslint/parser": "^5.51.0", - "eslint": "^7.26.0", - "jasmine-core": "~4.6.0", - "jasmine-spec-reporter": "~7.0.0", - "karma": "~6.4.0", - "karma-chrome-launcher": "^3.1.1", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.0.0", - "typescript": "~4.9.4" - } - }, - "Tryouts/Prototypes/Shell/Node-launcher/Demo": { - "name": "@morgan-stanley/composeui-node-launcher-example", - "version": "0.1.0", - "extraneous": true, - "dependencies": { - "@morgan-stanley/composeui-node-launcher": "*" - } - }, - "Tryouts/Prototypes/Shell/Node-launcher/Lib": { - "name": "@morgan-stanley/composeui-node-launcher", - "version": "0.1.0", - "extraneous": true, - "bin": { - "composeui": "output/cli/cli.js" - }, - "devDependencies": { - "@types/jest": "29.4.0", - "@types/node": "^18.11.18", - "jest": "29.4.3", - "rimraf": "4.1.2", - "ts-jest": "29.0.5", - "ts-node": "10.9.1", - "tslib": "^2.4.0", - "typescript": "^4.7.4" - } } } } diff --git a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/BackgroundModuleHost.cs b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/BackgroundModuleHost.cs index 169493199..40a26da5d 100644 --- a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/BackgroundModuleHost.cs +++ b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/BackgroundModuleHost.cs @@ -20,7 +20,7 @@ internal class BackgroundModuleHost : ModuleHostBase public BackgroundModuleHost(string name, Guid instanceId, IModuleRunner runner) : base(name, instanceId) { _runner = runner; - _processInfo = new ProcessInfo(base.Name, base.InstanceId, UIType.None, null, 0); + _processInfo = new ProcessInfo(base.Name, base.InstanceId, UIType.None, null, 0); } public override ProcessInfo ProcessInfo => _processInfo; diff --git a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/ModuleHostBase.cs b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/ModuleHostBase.cs index 091873961..784dac85c 100644 --- a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/ModuleHostBase.cs +++ b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/ModuleHostBase.cs @@ -25,7 +25,6 @@ public ModuleHostBase(string name, Guid instanceId) public string Name { get; } public Guid InstanceId { get; } - public abstract ProcessInfo ProcessInfo { get; } protected readonly Subject _lifecycleEvents = new Subject(); diff --git a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WebpageModuleHost.cs b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WebpageModuleHost.cs index 10b104487..a1518bafc 100644 --- a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WebpageModuleHost.cs +++ b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WebpageModuleHost.cs @@ -24,8 +24,6 @@ public WebpageModuleHost(string name, Guid instanceId, string url, IModuleRunner _runner = runner; } - - public override ProcessInfo ProcessInfo => new ProcessInfo( name: Name, instanceId: InstanceId, @@ -41,7 +39,6 @@ public async override Task Launch() { pid = await _runner.Launch(); } - _lifecycleEvents.OnNext(LifecycleEvent.Started(new ProcessInfo(Name, InstanceId, UIType.Web, _url, pid))); } diff --git a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WindowedModuleHost.cs b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WindowedModuleHost.cs index 52667b4fb..2921f17f3 100644 --- a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WindowedModuleHost.cs +++ b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Hosts/WindowedModuleHost.cs @@ -22,7 +22,7 @@ public WindowedModuleHost(string name, Guid instanceId, IWindowedModuleRunner mo { _moduleRunner = moduleRunner; _moduleRunner.StoppedUnexpectedly += HandleUnexpectedStop; - _processInfo = new ProcessInfo(name: Name, instanceId: InstanceId,uiType: UIType.Window,uiHint: _moduleRunner.MainWindowHandle.ToString(),pid: 0); + _processInfo = new ProcessInfo(name: Name, instanceId: InstanceId,uiType: UIType.Window,uiHint: _moduleRunner.MainWindowHandle.ToString(), pid: 0); } public override ProcessInfo ProcessInfo => _processInfo; diff --git a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/ModuleLoader.cs b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/ModuleLoader.cs index 15e60646f..ef036c861 100644 --- a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/ModuleLoader.cs +++ b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/ModuleLoader.cs @@ -23,7 +23,6 @@ internal class ModuleLoader : IModuleLoader private readonly IModuleHostFactory _moduleHostFactory; private readonly IModuleCatalogue _moduleCatalogue; - public ModuleLoader(IModuleCatalogue moduleCatalogue, IModuleHostFactory moduleHostFactory) { _moduleCatalogue = moduleCatalogue; diff --git a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Modules/ProcessInfo.cs b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Modules/ProcessInfo.cs index d7dd7d5b1..70b47e689 100644 --- a/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Modules/ProcessInfo.cs +++ b/prototypes/multi-module-prototype/src/module-loader/dotnet/ModuleLoader/Modules/ProcessInfo.cs @@ -42,6 +42,6 @@ public ProcessInfo(string name, Guid instanceId, string uiType, string? uiHint, /// - Window: ProcessID of the process owning the main window /// public string? uiHint; - + public int? pid; } diff --git a/prototypes/process-explorer/.gitignore b/prototypes/process-explorer/.gitignore new file mode 100644 index 000000000..0711527ef --- /dev/null +++ b/prototypes/process-explorer/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/prototypes/process-explorer/js/.gitignore b/prototypes/process-explorer/js/.gitignore new file mode 100644 index 000000000..0711527ef --- /dev/null +++ b/prototypes/process-explorer/js/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings + +# System files +.DS_Store +Thumbs.db diff --git a/src/fdc3/dotnet/DesktopAgent/DesktopAgent.sln b/src/fdc3/dotnet/DesktopAgent/DesktopAgent.sln index ceba9358a..d7ddf2e3f 100644 --- a/src/fdc3/dotnet/DesktopAgent/DesktopAgent.sln +++ b/src/fdc3/dotnet/DesktopAgent/DesktopAgent.sln @@ -11,7 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{44C08E9B EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopAgent.Tests", "tests\DesktopAgent.Tests\DesktopAgent.Tests.csproj", "{96398594-52D7-4A21-A8DA-CCD1D1038741}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{2CE54671-6C98-455E-B2A0-52F8564DDA5D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libs", "libs", "{2CE54671-6C98-455E-B2A0-52F8564DDA5D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Messaging.Client", "..\..\..\messaging\dotnet\src\Client\MorganStanley.ComposeUI.Messaging.Client.csproj", "{855B4208-30B4-4978-8ED9-D212AE0A63DA}" EndProject @@ -19,6 +19,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Mes EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Messaging.Host", "..\..\..\messaging\dotnet\src\Host\MorganStanley.ComposeUI.Messaging.Host.csproj", "{ECC53672-0EBA-4BB9-8578-4180D1A4358D}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Messaging.Server", "..\..\..\messaging\dotnet\src\Server\MorganStanley.ComposeUI.Messaging.Server.csproj", "{4CF751F6-0A49-4315-A473-1DBE365AE254}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.ModuleLoader.Abstractions", "..\..\..\module-loader\dotnet\src\MorganStanley.ComposeUI.ModuleLoader.Abstractions\MorganStanley.ComposeUI.ModuleLoader.Abstractions.csproj", "{94E84562-211E-4BA7-A45F-9ADC3D402B74}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Utilities", "..\..\..\shared\dotnet\src\MorganStanley.ComposeUI.Utilities\MorganStanley.ComposeUI.Utilities.csproj", "{2C25BA40-0103-4EB5-B181-98362F563B0F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppDirectory", "..\AppDirectory\src\AppDirectory\AppDirectory.csproj", "{50BD1318-FC44-4582-B333-3033076164E7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.ModuleLoader", "..\..\..\module-loader\dotnet\src\MorganStanley.ComposeUI.ModuleLoader\MorganStanley.ComposeUI.ModuleLoader.csproj", "{4207C810-55CC-433E-BD5B-B9B4D639C7A2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,6 +55,26 @@ Global {ECC53672-0EBA-4BB9-8578-4180D1A4358D}.Debug|Any CPU.Build.0 = Debug|Any CPU {ECC53672-0EBA-4BB9-8578-4180D1A4358D}.Release|Any CPU.ActiveCfg = Release|Any CPU {ECC53672-0EBA-4BB9-8578-4180D1A4358D}.Release|Any CPU.Build.0 = Release|Any CPU + {4CF751F6-0A49-4315-A473-1DBE365AE254}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4CF751F6-0A49-4315-A473-1DBE365AE254}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4CF751F6-0A49-4315-A473-1DBE365AE254}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4CF751F6-0A49-4315-A473-1DBE365AE254}.Release|Any CPU.Build.0 = Release|Any CPU + {94E84562-211E-4BA7-A45F-9ADC3D402B74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {94E84562-211E-4BA7-A45F-9ADC3D402B74}.Debug|Any CPU.Build.0 = Debug|Any CPU + {94E84562-211E-4BA7-A45F-9ADC3D402B74}.Release|Any CPU.ActiveCfg = Release|Any CPU + {94E84562-211E-4BA7-A45F-9ADC3D402B74}.Release|Any CPU.Build.0 = Release|Any CPU + {2C25BA40-0103-4EB5-B181-98362F563B0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C25BA40-0103-4EB5-B181-98362F563B0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C25BA40-0103-4EB5-B181-98362F563B0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C25BA40-0103-4EB5-B181-98362F563B0F}.Release|Any CPU.Build.0 = Release|Any CPU + {50BD1318-FC44-4582-B333-3033076164E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50BD1318-FC44-4582-B333-3033076164E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50BD1318-FC44-4582-B333-3033076164E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50BD1318-FC44-4582-B333-3033076164E7}.Release|Any CPU.Build.0 = Release|Any CPU + {4207C810-55CC-433E-BD5B-B9B4D639C7A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4207C810-55CC-433E-BD5B-B9B4D639C7A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4207C810-55CC-433E-BD5B-B9B4D639C7A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4207C810-55CC-433E-BD5B-B9B4D639C7A2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -55,6 +85,11 @@ Global {855B4208-30B4-4978-8ED9-D212AE0A63DA} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} {C404E0C4-A97A-4062-A4A8-88F8C109515D} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} {ECC53672-0EBA-4BB9-8578-4180D1A4358D} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} + {4CF751F6-0A49-4315-A473-1DBE365AE254} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} + {94E84562-211E-4BA7-A45F-9ADC3D402B74} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} + {2C25BA40-0103-4EB5-B181-98362F563B0F} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} + {50BD1318-FC44-4582-B333-3033076164E7} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} + {4207C810-55CC-433E-BD5B-B9B4D639C7A2} = {2CE54671-6C98-455E-B2A0-52F8564DDA5D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {70FE103D-26D8-42D8-88BA-1BECB1F73A18} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelRequest.cs index 1609e60e2..7fd9da37b 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelRequest.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelRequest.cs @@ -16,7 +16,7 @@ namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; -internal class FindChannelRequest +internal sealed class FindChannelRequest { public string ChannelId { get; set; } public ChannelType ChannelType { get; set; } diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelResponse.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelResponse.cs index 6f9092f7e..cb419ff56 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelResponse.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindChannelResponse.cs @@ -14,7 +14,7 @@ namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; -internal class FindChannelResponse +internal sealed class FindChannelResponse { public bool Found { get; set; } public string? Error { get; set; } diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentRequest.cs new file mode 100644 index 000000000..111a4bc12 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentRequest.cs @@ -0,0 +1,44 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3.Context; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Request for the fdc3.findIntent call. +/// +internal sealed class FindIntentRequest +{ + /// + /// Unique identifier from the application which sent the RaiseIntentRequest type of message. + /// eg.: the instanceId of the application which can be queried from the window.object.composeui.fdc3.config, if it's a webapplication. + /// + public string Fdc3InstanceId { get; set; } + + /// + /// Intent that has been raised via fdc3.findIntent. + /// + public string Intent { get; set; } + + /// + /// + /// + public Context? Context { get; set; } + + /// + /// ResultType indicating what resultType the requesting app is expecting. + /// + public string? ResultType { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentResponse.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentResponse.cs new file mode 100644 index 000000000..db5d35235 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentResponse.cs @@ -0,0 +1,36 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using AppIntent = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIntent; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Response from the backend to the fdc3.findIntent . +/// +internal sealed class FindIntentResponse +{ + /// + /// , as result of executing the fdc3.findIntent. + /// + public AppIntent? AppIntent { get; init; } + + /// + /// Contains error text if an error happened during the execution of fdc3.findIntent. + /// + public string? Error { get; init; } + + public static FindIntentResponse Success(AppIntent appIntent) => new() { AppIntent = appIntent }; + public static FindIntentResponse Failure(string error) => new() { Error = error }; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextRequest.cs new file mode 100644 index 000000000..5e54d466d --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextRequest.cs @@ -0,0 +1,39 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3.Context; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Request by calling the fdc3.findIntentsByContext. +/// +internal sealed class FindIntentsByContextRequest +{ + /// + /// Unique identifier from the application which sent the FindIntentsByContextRequest type of message. + /// eg.: the instanceId of the application which can be queried from the window.object.composeui.fdc3.config, if it's a webapplication. + /// + public string Fdc3InstanceId { get; set; } + + /// + /// + /// + public Context Context { get; set; } + + /// + /// ResultType indicating what resultType the requesting app is expecting. + /// + public string? ResultType { get; set; } +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextResponse.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextResponse.cs new file mode 100644 index 000000000..709b5f8ef --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextResponse.cs @@ -0,0 +1,38 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + + +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Response for the raised fdc3.findIntentsByContext call by the clients with . +/// +internal sealed class FindIntentsByContextResponse +{ + /// + /// AppIntents that might be returned as result of executing the fdc3.findIntentsByContext. + /// + public IEnumerable? AppIntents { get; set; } + + /// + /// Contains error text if an error happened during execution of the fdc3.findIntentsByContext. + /// + public string? Error { get; set; } + + public static FindIntentsByContextResponse Success(IEnumerable appIntents) => new() { AppIntents = appIntents }; + + public static FindIntentsByContextResponse Failure(string error) => new() { Error = error }; +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetCurrentContextRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetCurrentContextRequest.cs index 264282f23..ce5ce7879 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetCurrentContextRequest.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetCurrentContextRequest.cs @@ -12,10 +12,9 @@ * and limitations under the License. */ -namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +internal sealed class GetCurrentContextRequest { - internal class GetCurrentContextRequest - { - public string? ContextType { get; set; } - } + public string? ContextType { get; set; } } diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultRequest.cs new file mode 100644 index 000000000..2c4b2a2f4 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultRequest.cs @@ -0,0 +1,44 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + + +using AppIdentifier = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIdentifier; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Request raised by the client via calling the IntentResolution.getResult(). +/// +internal sealed class GetIntentResultRequest +{ + /// + /// IntentResolution's stored MessageId received via . + /// + public string MessageId { get; set; } + + /// + /// The intent that was raised. + /// + public string Intent { get; set; } + + /// + /// for the app instance that was selected (or started) to resolve the intent. + /// + public AppIdentifier TargetAppIdentifier { get; set; } + + /// + /// The version number of the Intents schema, that is being used. + /// + public string? Version { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultResponse.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultResponse.cs new file mode 100644 index 000000000..c2d983591 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultResponse.cs @@ -0,0 +1,80 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; +using MorganStanley.Fdc3; +using MorganStanley.Fdc3.Context; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Response for the , raised by the clients by calling the IntentResolution.getResult(). +/// +internal sealed class GetIntentResultResponse +{ + /// + /// Indicates that the IntentResult is a typeof Context. + /// + public Context? Context { get; set; } + + /// + /// Indicates that the IntentResult is a typeof Channel. + /// + public string? ChannelId { get; set; } + + /// + /// Indicates that the IntentResult is a typeof Channel. Identifies the type of the Channel. + /// + public ChannelType? ChannelType { get; set; } + + /// + /// Contains error text if an error happened during retrieving the IntentResult. + /// + public string? Error { get; set; } + + /// + /// Indicates that the IntentHandler returned without result during its execution. + /// + public bool? VoidResult { get; set; } + + public static GetIntentResultResponse Success( + string? channelId = null, + ChannelType? channelType = null, + Context? context = null, + bool? voidResult = null) + { + var response = new GetIntentResultResponse(); + if (channelId != null && channelType != null) + { + response.ChannelId = channelId; + response.ChannelType = channelType; + } + else if (context != null) + { + response.Context = context; + } + else if (voidResult != null) + { + response.VoidResult = voidResult; + } + else + { + return Failure(Fdc3DesktopAgentErrors.ResponseHasNoAttribute); + } + + return response; + } + + public static GetIntentResultResponse Failure(string error) => new() { Error = error }; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerRequest.cs new file mode 100644 index 000000000..ab6c7a397 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerRequest.cs @@ -0,0 +1,40 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Text.Json.Serialization; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Request originated by the client which indicates that it would like to add or remove its IntentListener. +/// +internal sealed class IntentListenerRequest +{ + /// + /// State that indicates the action that the client's listener would like to take, like subscribe or unsubscribe from an intent. + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public SubscribeState State { get; set; } + + /// + /// Intent for the listener which would like to (un)subscribe. + /// + public string Intent { get; set; } + + /// + /// Fdc3 specific instance id from the client which would like to add/remove its intent listener. + /// + public string Fdc3InstanceId { get; set; } + +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerResponse.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerResponse.cs new file mode 100644 index 000000000..bfc457f37 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerResponse.cs @@ -0,0 +1,35 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Response from the server that it successfully registered the IntentListener of the client raised by the client via . +/// +internal sealed class IntentListenerResponse +{ + /// + /// Indicates if the server successfully stored the IntentListener. + /// + public bool Stored { get; set; } + + /// + /// Contains error text if an error happened during the registration. + /// + public string? Error { get; set; } + + public static IntentListenerResponse Failure(string error) => new() { Error = error }; + public static IntentListenerResponse SubscribeSuccess() => new() { Stored = true }; + public static IntentListenerResponse UnsubscribeSuccess() => new() { Stored = false }; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentRequest.cs new file mode 100644 index 000000000..37b407fd6 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentRequest.cs @@ -0,0 +1,60 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3.Context; +using AppIdentifier = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIdentifier; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Request raised by the client via fdc.raiseIntent. +/// +internal sealed class RaiseIntentRequest +{ + /// + /// An identifier for the message. + /// + public int MessageId { get; set; } + + /// + /// Unique identifier from the application which sent the RaiseIntentRequest type of message. + /// eg.: the instanceId of the application which can be queried from the window.object.composeui.fdc3.config, if it's a webapplication. + /// + public string Fdc3InstanceId { get; set; } + + /// + /// Intent that has been raised. + /// + public string Intent { get; set; } + + /// + /// Indicates that the client selected an instance or an app to start and resolve the raised intent. + /// + public bool Selected { get; set; } + + /// + /// Context for identifying more the specific app that should handle the raised intent. + /// + public Context Context { get; set; } + + /// + /// Information about the app that should resolve the raised intent. + /// + public AppIdentifier? TargetAppIdentifier { get; set; } + + /// + /// Contains error text if an error happened during executing the raiseIntent method. + /// + public string? Error { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResolutionRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResolutionRequest.cs new file mode 100644 index 000000000..19e0f10af --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResolutionRequest.cs @@ -0,0 +1,40 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + + +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; +using MorganStanley.Fdc3.Context; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Request raised via fdc3.raiseIntent to publish the raiseIntent request to the selected app. +/// +internal sealed class RaiseIntentResolutionRequest +{ + /// + /// Unique identifier for the raised intent message which was generated from the received MessageId as int from the client and a . + /// + public string MessageId { get; set; } + + /// + /// Context which should be sent to the selected app via raiseIntent by the FDC3 client. + /// + public Context Context { get; set; } + + /// + /// ContextMetadata which contains information about the source app, that raised the request. + /// + public ContextMetadata ContextMetadata { get; set; } +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResponse.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResponse.cs new file mode 100644 index 000000000..55aa54260 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResponse.cs @@ -0,0 +1,50 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3; +using AppMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppMetadata; +using AppIntent = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIntent; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Response for handling raised via fdc.raiseIntent by client. +/// +internal sealed class RaiseIntentResponse +{ + /// + /// Unique identifier for the raised intent message which was generated from the received MessageId as type int from the client and a . + /// + public string? MessageId { get; set; } + + /// + /// Intent that have been raised. + /// + public string? Intent { get; set; } + + /// + /// Apps that could handle the raiseIntent. + /// + public IEnumerable? AppMetadata { get; set; } + + /// + /// Contains error text if an error happened during the raiseIntent's execution. + /// + public string? Error { get; set; } + + public static RaiseIntentResponse Success(string messageId, AppIntent appIntent) => new() { MessageId = messageId, Intent = appIntent.Intent.Name, AppMetadata = appIntent.Apps.Select(appMetadata => (AppMetadata)appMetadata) }; + public static RaiseIntentResponse Success(string messageId, string intent, IAppMetadata appMetadata) => new() { MessageId = messageId, Intent = intent, AppMetadata = new[] { (AppMetadata)appMetadata } }; + public static RaiseIntentResponse Success(string messageId, string intent, AppMetadata appMetadata) => new() {MessageId = messageId, Intent = intent, AppMetadata = new[] { appMetadata } }; + public static RaiseIntentResponse Failure(string error) => new() { Error = error }; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultRequest.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultRequest.cs new file mode 100644 index 000000000..09f04c4a1 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultRequest.cs @@ -0,0 +1,70 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3; +using MorganStanley.Fdc3.Context; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Request for the backend, indicating that the IntentHandler of the FDC3 client has executed the raised intent and handled it appropriately, +/// and the backend should store and send back to the client which originated the request if the client calls the IntentResolution.getResult(). +/// +internal sealed class StoreIntentResultRequest +{ + /// + /// Unique identifier for the raised intent message which was a received MessageId as int type from the client and concatenated with a . + /// + public string MessageId { get; set; } + + /// + /// Intent from IntentResolution by IntentHandler of FDC3 clients. + /// + public string Intent { get; set; } + + /// + /// Source app instance id which had handled the raised intent. + /// + public string OriginFdc3InstanceId { get; set; } + + /// + /// Target app instance id which should receive the IntentResult that have raised the intent. + /// + public string TargetFdc3InstanceId { get; set; } + + /// + /// ChannelId indicating the result of the IntentListener was a channel. + /// + public string? ChannelId { get; set; } + + /// + /// ChannelType indicating the result of the IntentListener was a channel. Clarifies the type of the Channel. + /// + public ChannelType? ChannelType { get; set; } + + /// + /// Context indicating the result of the IntentListener was a context. + /// + public Context? Context { get; set; } + + /// + /// Indicates that the result of the IntentHandler is void type. + /// + public bool? VoidResult { get; set; } + + /// + /// Indicates that error occurred while resolving the raised intent via the registered IntentHandler. + /// + public string? Error { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultResponse.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultResponse.cs new file mode 100644 index 000000000..9972eb443 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultResponse.cs @@ -0,0 +1,35 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Response for the client which handled the intent, if the request was successfully stored. +/// +internal sealed class StoreIntentResultResponse +{ + /// + /// Indicates that the IntentResult is successfully stored or not. + /// + public bool Stored { get; init; } = false; + + /// + /// Contains error text if an error happened while handling the request. + /// + public string? Error { get; init; } + + public static StoreIntentResultResponse Success() => new() { Stored = true }; + + public static StoreIntentResultResponse Failure(string error) => new() { Error = error }; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/SubscribeState.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/SubscribeState.cs new file mode 100644 index 000000000..1b7dbbb23 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/SubscribeState.cs @@ -0,0 +1,30 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + + +using System.Runtime.Serialization; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +/// +/// Indicates the state of the IntentListener which was sent to the DesktopAgent backend. +/// +internal enum SubscribeState +{ + [EnumMember(Value = "Subscribe")] + Subscribe, + + [EnumMember(Value = "Unsubscribe")] + Unsubscribe +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppIntentJsonConverter.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppIntentJsonConverter.cs new file mode 100644 index 000000000..a4c2fbfae --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppIntentJsonConverter.cs @@ -0,0 +1,33 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Text.Json; +using System.Text.Json.Serialization; +using MorganStanley.Fdc3; +using AppIntent = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIntent; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; + +public class AppIntentJsonConverter : JsonConverter +{ + public override IAppIntent? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader, options); + } + + public override void Write(Utf8JsonWriter writer, IAppIntent value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, (AppIntent)value, options); + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppMetadataJsonConverter.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppMetadataJsonConverter.cs new file mode 100644 index 000000000..eb907fea9 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppMetadataJsonConverter.cs @@ -0,0 +1,33 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Text.Json; +using System.Text.Json.Serialization; +using MorganStanley.Fdc3; +using AppMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppMetadata; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; + +public class AppMetadataJsonConverter : JsonConverter +{ + public override IAppMetadata? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader, options); + } + + public override void Write(Utf8JsonWriter writer, IAppMetadata value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, (AppMetadata)value, options); + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IconJsonConverter.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IconJsonConverter.cs new file mode 100644 index 000000000..4004b5cc5 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IconJsonConverter.cs @@ -0,0 +1,33 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Text.Json; +using System.Text.Json.Serialization; +using MorganStanley.Fdc3; +using Icon = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.Icon; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; + +public class IconJsonConverter : JsonConverter +{ + public override IIcon? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader, options); + } + + public override void Write(Utf8JsonWriter writer, IIcon value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, (Icon)value, options); + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/ImageJsonConverter.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/ImageJsonConverter.cs new file mode 100644 index 000000000..1f79be5f8 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/ImageJsonConverter.cs @@ -0,0 +1,33 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Text.Json; +using System.Text.Json.Serialization; +using MorganStanley.Fdc3; +using Screenshot = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.Screenshot; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; + +public class ImageJsonConverter : JsonConverter +{ + public override IImage? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader, options); + } + + public override void Write(Utf8JsonWriter writer, IImage value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, (Screenshot) value, options); + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IntentMetadataJsonConverter.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IntentMetadataJsonConverter.cs new file mode 100644 index 000000000..b3a144616 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IntentMetadataJsonConverter.cs @@ -0,0 +1,33 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Text.Json; +using System.Text.Json.Serialization; +using MorganStanley.Fdc3; +using IntentMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.IntentMetadata; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; + +public class IntentMetadataJsonConverter : JsonConverter +{ + public override IIntentMetadata? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader, options); + } + + public override void Write(Utf8JsonWriter writer, IIntentMetadata value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, (IntentMetadata)value, options); + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/Fdc3DesktopAgentOptions.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/Fdc3DesktopAgentOptions.cs index 8d4bbc53b..f9f71cbb3 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/Fdc3DesktopAgentOptions.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/Fdc3DesktopAgentOptions.cs @@ -23,5 +23,12 @@ public sealed class Fdc3DesktopAgentOptions : IOptions /// public string? ChannelId { get; set; } + /// + /// Indicates a timeout value for getting the IntentResult from the backend in milliseconds. + /// When set to any value, it sets the timeout for the getResult() client calls, which should wait either for this timeout or the task which gets the appropriate resolved IntentResolution. + /// Timeout by default is 1000 milliseconds. + /// + public TimeSpan IntentResultTimeout { get; set; } = TimeSpan.FromMilliseconds(1000); + Fdc3DesktopAgentOptions IOptions.Value => this; } diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/ServiceCollectionExtensions.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/ServiceCollectionExtensions.cs index 7396890f6..d253a7dd8 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DependencyInjection/ServiceCollectionExtensions.cs @@ -15,6 +15,9 @@ using Microsoft.Extensions.Hosting; using MorganStanley.ComposeUI.Fdc3.DesktopAgent; using MorganStanley.ComposeUI.Fdc3.DesktopAgent.DependencyInjection; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; +using MorganStanley.ComposeUI.ModuleLoader; +using MorganStanley.ComposeUI.Shell.Fdc3; // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection; @@ -31,7 +34,10 @@ public static IServiceCollection AddFdc3DesktopAgent( builderAction(builder); } - serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); + serviceCollection.AddHostedService(); + serviceCollection.AddTransient(); + return serviceCollection; } } diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DesktopAgent.csproj b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DesktopAgent.csproj index 41e8f5552..8ca86583d 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DesktopAgent.csproj +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/DesktopAgent.csproj @@ -3,6 +3,7 @@ net6.0 enable enable + preview MorganStanley.ComposeUI.Fdc3.$(MSBuildProjectName) MorganStanley.ComposeUI.Fdc3.$(MSBuildProjectName.Replace(" ", "_")) @@ -12,10 +13,38 @@ + + + + + + + + + + $(ComposeUIRepositoryRoot)\src\fdc3\js\composeui-fdc3\dist\fdc3-iife-bundle.js + + + + + + + + + + + + + + + + + + diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentErrors.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentErrors.cs new file mode 100644 index 000000000..501d6365f --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentErrors.cs @@ -0,0 +1,48 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; + +public static class Fdc3DesktopAgentErrors +{ + /// + /// Indicates that the instanceId of the app that was raising the request is missing. + /// + public const string MissingId = $"{nameof(MissingId)}"; + + /// + /// Given payload from is null. + /// + public const string PayloadNull = $"{nameof(PayloadNull)}"; + + /// + /// Indicates that multiple matching were registered to an IntentResolver. + /// + public const string MultipleIntent = $"{nameof(MultipleIntent)}"; + + /// + /// Indicates that getting the IntentResult from the backend, has no appropriate attribute. + /// + public const string ResponseHasNoAttribute = $"{nameof(ResponseHasNoAttribute)}"; + + /// + /// Indicates that could not start a module via raiseIntent, etc. + /// + public const string StartModuleFailure = $"{nameof(StartModuleFailure)}"; + + /// + /// Indicates that querying raised intent invocations does not contain an element for the intent. + /// + public const string MissingIntent = $"{nameof(MissingIntent)}"; +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentException.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentException.cs new file mode 100644 index 000000000..b164dc938 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentException.cs @@ -0,0 +1,33 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; + +/// +/// Exceptions for FDC3 DesktopAgent backend related exceptions. +/// +public class Fdc3DesktopAgentException : Exception +{ + public string ErrorType { get; } + + public Fdc3DesktopAgentException(string errorType, string message) : base(message) + { + ErrorType = errorType; + } + + public Fdc3DesktopAgentException(string errorType, string message, Exception innerException) : base(message, innerException) + { + ErrorType = errorType; + } +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/ThrowHelper.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/ThrowHelper.cs new file mode 100644 index 000000000..69c28e1b2 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/ThrowHelper.cs @@ -0,0 +1,38 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; + +public static class ThrowHelper +{ + public static Fdc3DesktopAgentException MissingFdc3InstanceId(string moduleId) => + new(Fdc3DesktopAgentErrors.MissingId, $"Missing Fdc3InstanceId for module: {moduleId}, when module is started and FDC3 is enabled by the application."); + + public static Fdc3DesktopAgentException MissingAppFromRaisedIntentInvocations(string instanceId) => + new(Fdc3DesktopAgentErrors.MissingId, $"Missing Fdc3InstanceId: {instanceId}, when module has added its intent listener and FDC3 is enabled by the application."); + + public static Fdc3DesktopAgentException MultipleIntentRegisteredToAnAppInstance(string intent) => + new(Fdc3DesktopAgentErrors.MultipleIntent, $"Multiplpe intent were registered to the running instance. Intent: {intent}."); + + public static Fdc3DesktopAgentException TargetInstanceUnavailable() => + new(ResolveError.TargetAppUnavailable, $"Target app is unavailable when intent was raised."); + + public static Fdc3DesktopAgentException StartModuleFailure(Exception exception) => + new(Fdc3DesktopAgentErrors.StartModuleFailure, $"Could not start module when intent was raised.", exception); + + public static Fdc3DesktopAgentException MissingIntentForMessage(string messageId, string intent) => + new(Fdc3DesktopAgentErrors.MissingIntent, $"Could not found raised intent invocations for message: {messageId} with intent: {intent}"); +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3DesktopAgent.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3DesktopAgent.cs index b06b0fdd5..0189a5806 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3DesktopAgent.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3DesktopAgent.cs @@ -12,80 +12,707 @@ * and limitations under the License. */ -using Microsoft.Extensions.Hosting; +using System.Collections.Concurrent; +using System.Reactive.Linq; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; using MorganStanley.ComposeUI.Fdc3.DesktopAgent.DependencyInjection; -using MorganStanley.ComposeUI.Messaging; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; +using MorganStanley.ComposeUI.ModuleLoader; using MorganStanley.Fdc3; +using MorganStanley.Fdc3.AppDirectory; +using MorganStanley.Fdc3.Context; +using IntentMetadata = MorganStanley.Fdc3.AppDirectory.IntentMetadata; +using AppMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppMetadata; +using AppIntent = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIntent; +using AppIdentifier = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIdentifier; +using ContextMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.ContextMetadata; +using Icon = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.Icon; +using Screenshot = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.Screenshot; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent; -public class Fdc3DesktopAgent : IHostedService +internal class Fdc3DesktopAgent : IFdc3DesktopAgentBridge { + private readonly ILogger _logger; private readonly List _userChannels = new(); - private readonly ILoggerFactory _loggerFactory; private readonly Fdc3DesktopAgentOptions _options; - private readonly IMessageRouter _messageRouter; + private readonly IAppDirectory _appDirectory; + private readonly IModuleLoader _moduleLoader; + private readonly ConcurrentDictionary _runningModules = new(); + private readonly ConcurrentDictionary _raisedIntentResolutions = new(); + private IAsyncDisposable? _subscription; public Fdc3DesktopAgent( - IOptions options, - IMessageRouter messageRouter, + IAppDirectory appDirectory, + IModuleLoader moduleLoader, + IOptions options, ILoggerFactory? loggerFactory = null) { + _appDirectory = appDirectory; + _moduleLoader = moduleLoader; _options = options.Value; - _messageRouter = messageRouter; _loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; + _logger = _loggerFactory.CreateLogger() ?? NullLogger.Instance; } - public async ValueTask AddUserChannel(string id) + public async ValueTask AddUserChannel(UserChannel userChannel) { - var uc = new UserChannel(id, _messageRouter, _loggerFactory.CreateLogger()); - await uc.Connect(); - _userChannels.Add(uc); + await userChannel.Connect(); + _userChannels.Add(userChannel); } - internal async ValueTask FindChannel(string _, MessageBuffer? requestBuffer, MessageContext _2) + public async Task StartAsync(CancellationToken cancellationToken) { - var request = requestBuffer?.ReadJson(); - if (request?.ChannelType == ChannelType.User) + var observable = _moduleLoader.LifetimeEvents.ToAsyncObservable(); + var subscription = await observable.SubscribeAsync(async (lifetimeEvent) => { - if (_userChannels.Any(x => x.Id == request.ChannelId)) + switch (lifetimeEvent) { - return MessageBuffer.Factory.CreateJson(FindChannelResponse.Success); + case LifetimeEvent.Stopped: + await RemoveModuleAsync(lifetimeEvent.Instance); + break; + + case LifetimeEvent.Started: + await AddOrUpdateModuleAsync(lifetimeEvent.Instance); + break; } + }); + + _subscription = subscription; + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + var tasks = _userChannels.Select(x => x.DisposeAsync()).ToArray(); + + await SafeWaitAsync(tasks); + + if (_subscription != null) + { + _runningModules.Clear(); + await _subscription.DisposeAsync(); } - return MessageBuffer.Factory.CreateJson(FindChannelResponse.Failure(ChannelError.NoChannelFound)); } - public async Task StartAsync(CancellationToken cancellationToken) + public bool FindChannel(string channelId, ChannelType channelType) { - await _messageRouter.RegisterServiceAsync(Fdc3Topic.FindChannel, FindChannel); + return channelType switch + { + ChannelType.User => _userChannels.Any(x => x.Id == channelId), + ChannelType.App or ChannelType.Private => throw new NotSupportedException(), + _ => false, + }; + } - if (_options.ChannelId == null) return; + public async ValueTask FindIntent(FindIntentRequest? request) + { + if (request == null) + { + return FindIntentResponse.Failure(ResolveError.IntentDeliveryFailed); + } + + //This function returns null, if the app could not be accepted based on the intent (required), context (optional in request), resultType (optional in request) + //else for consistency it will return a single element array containing the intentMetadata which is allowed by the request. + Func?> selector = (fdc3App) => + { + if (fdc3App.Interop?.Intents?.ListensFor == null || !fdc3App.Interop.Intents.ListensFor.TryGetValue(request.Intent!, out var intentMetadata)) return null; + if (request.Context != null && (intentMetadata.Contexts == null || !intentMetadata.Contexts.Contains(request.Context.Type)) && request.Context?.Type != ContextTypes.Nothing) return null; + if (request.ResultType != null && (intentMetadata.ResultType == null || !intentMetadata.ResultType.Contains(request.ResultType))) return null; + return new[] { intentMetadata }; + }; + + var appIntents = await GetAppIntentsByRequest(selector, null, false); + + if (!appIntents.Any()) + { + return FindIntentResponse.Failure(ResolveError.NoAppsFound); + } - await AddUserChannel(_options.ChannelId); + return appIntents.Count > 1 + ? FindIntentResponse.Failure(ResolveError.IntentDeliveryFailed) + : FindIntentResponse.Success(appIntents.Values.First()); } - public async Task StopAsync(CancellationToken cancellationToken) + public async ValueTask FindIntentsByContext(FindIntentsByContextRequest? request) { - var tasks = _userChannels.Select(x => x.DisposeAsync()).ToArray(); - var unregister = _messageRouter.UnregisterServiceAsync(Fdc3Topic.FindChannel); + if (request == null) + { + return FindIntentsByContextResponse.Failure(ResolveError.IntentDeliveryFailed); + } + + //This function returns null, if the app could not be accepted based on the context(optional in request), resultType (optional in request) + //else for consistency it will return a collection containing the intentMetadata which is allowed by the request. + Func?> selector = (fdc3App) => + { + var intentMetadataCollection = new List(); + if (fdc3App.Interop?.Intents?.ListensFor?.Values != null) + { + foreach (var intentMetadata in fdc3App.Interop.Intents.ListensFor.Values) + { + if (intentMetadata.Contexts == null || !intentMetadata.Contexts.Contains(request.Context?.Type) && request.Context?.Type != ContextTypes.Nothing) continue; + if (request.ResultType != null && (intentMetadata.ResultType == null || !intentMetadata.ResultType.Contains(request.ResultType))) continue; + intentMetadataCollection.Add(intentMetadata); + } + } + + if (intentMetadataCollection.Any()) + { + return intentMetadataCollection; + } + + return null; + }; + + var appIntents = await GetAppIntentsByRequest(selector, null, false); + + if (!appIntents.Any()) + { + return FindIntentsByContextResponse.Failure(ResolveError.NoAppsFound); + } + + return FindIntentsByContextResponse.Success(appIntents.Values); + } + + public async ValueTask GetIntentResult(GetIntentResultRequest? request) + { + if (request == null) + { + return GetIntentResultResponse.Failure(ResolveError.IntentDeliveryFailed); + } + + if (request.TargetAppIdentifier?.InstanceId == null || request.Intent == null || request.MessageId == null) + { + return GetIntentResultResponse.Failure(ResolveError.IntentDeliveryFailed); + } + + using var cancellationTokenSource = new CancellationTokenSource(); + try + { + var intentResolution = await GetIntentResolutionResult(request).WaitAsync(_options.IntentResultTimeout); + + return GetIntentResultResponse.Success( + intentResolution!.ResultChannelId, + intentResolution!.ResultChannelType, + intentResolution!.ResultContext, + intentResolution!.ResultVoid); + } + catch (TimeoutException) + { + + return GetIntentResultResponse.Failure(ResolveError.IntentDeliveryFailed); + } + } + + public ValueTask StoreIntentResult(StoreIntentResultRequest? request) + { + if (request == null) + { + return ValueTask.FromResult(StoreIntentResultResponse.Failure(ResolveError.IntentDeliveryFailed)); + } + + if (request.TargetFdc3InstanceId == null || request.Intent == null) + { + return ValueTask.FromResult(StoreIntentResultResponse.Failure(ResolveError.IntentDeliveryFailed)); + } + + _raisedIntentResolutions.AddOrUpdate( + new Guid(request.OriginFdc3InstanceId), + _ => throw ThrowHelper.MissingAppFromRaisedIntentInvocations(request.OriginFdc3InstanceId), + (key, oldValue) => oldValue.AddIntentResult( + messageId: request.MessageId, + intent: request.Intent, + channelId: request.ChannelId, + channelType: request.ChannelType, + context: request.Context, + voidResult: request.VoidResult, + error: request.Error)); + + return ValueTask.FromResult(StoreIntentResultResponse.Success()); + } + + public async ValueTask> AddIntentListener(IntentListenerRequest? request) + { + if (request == null) + { + return new() + { + Response = IntentListenerResponse.Failure(Fdc3DesktopAgentErrors.PayloadNull) + }; + } + + switch (request.State) + { + case SubscribeState.Subscribe: + if (_raisedIntentResolutions.TryGetValue(new(request.Fdc3InstanceId), out var resolver)) + { + resolver.AddIntentListener(request.Intent); + + var resolutions = new List(); + foreach (var raisedIntent in resolver.RaiseIntentResolutions.Where(invocation => invocation.Intent == request.Intent)) + { + var resolution = await RaiseIntentResolution( + raisedIntent.RaiseIntentMessageId, + raisedIntent.Intent, + raisedIntent.Context, + request.Fdc3InstanceId, + raisedIntent.OriginFdc3InstanceId); + + if (resolution != null) + { + resolutions.Add(resolution); + } + } + + return new() + { + Response = IntentListenerResponse.SubscribeSuccess(), + RaiseIntentResolutionMessages = resolutions + }; + } + else + { + var createdResolver = _raisedIntentResolutions.GetOrAdd( + new(request.Fdc3InstanceId), + new RaisedIntentRequestHandler()); + + createdResolver.AddIntentListener(request.Intent); + + return new() + { + Response = IntentListenerResponse.SubscribeSuccess(), + }; + } + + case SubscribeState.Unsubscribe: + + if (_raisedIntentResolutions.TryGetValue(new(request.Fdc3InstanceId), out var resolverToRemove)) + { + resolverToRemove.RemoveIntentListener(request.Intent); + return new() + { + Response = IntentListenerResponse.UnsubscribeSuccess() + }; + } + + break; + } + + return new() + { + Response = IntentListenerResponse.Failure(Fdc3DesktopAgentErrors.MissingId) + }; + } + + public async ValueTask> RaiseIntent(RaiseIntentRequest? request) + { + if (request == null) + { + return new() + { + Response = RaiseIntentResponse.Failure(ResolveError.IntentDeliveryFailed) + }; + } + + if (!string.IsNullOrEmpty(request.Error)) + { + return new() + { + Response = RaiseIntentResponse.Failure(request.Error) + }; + } + //This function returns null, if the app could not be accepted based on the intent (required), context (optional in request), appIdentifier (optional in request) + //else for consistency it will return a single element array containing the intentMetadata which is allowed by the request. + Func?> selector = (fdc3App) => + { + if (fdc3App.Interop?.Intents?.ListensFor == null || !fdc3App.Interop.Intents.ListensFor.TryGetValue(request.Intent!, out var intentMetadata)) return null; + if (request.Context != null && (intentMetadata.Contexts == null || !intentMetadata.Contexts.Contains(request.Context.Type)) && request.Context?.Type != ContextTypes.Nothing) return null; + if (request.TargetAppIdentifier != null && (fdc3App.AppId != request.TargetAppIdentifier.AppId)) return null; + return new[] { intentMetadata }; + }; + + var appIntents = await GetAppIntentsByRequest(selector, request.TargetAppIdentifier, request.Selected); + + //No intents were found which would have the right information to handle the raised intent + if (!appIntents.Any()) + { + return new() + { + Response = RaiseIntentResponse.Failure(ResolveError.NoAppsFound) + }; + } + + //Here we have used a method, which could return multiple IAppIntents to multiple intents, this is for abstracting method to findIntent, findIntentsByContext, etc. + //Here we should get just one IAppIntent, as the intent field is required (at least fdc3.nothing) + if (appIntents.Count > 1) + { + return new() + { + Response = RaiseIntentResponse.Failure(ResolveError.IntentDeliveryFailed) + }; + } + + var appIntent = appIntents.Values.First(); + + if (appIntent.Apps.Count() == 1) + { + return await RaiseIntentToApplication( + request.MessageId, + appIntent.Apps.ElementAt(0), + request.Intent, + request.Context, + request.Fdc3InstanceId); + } + + //Multiple app inside one AppIntent, we pass back the messageId as string. + return new() + { + Response = RaiseIntentResponse.Success(request.MessageId.ToString(), appIntent) + }; + } + + //Here we have a specific application which should either start or we should send a intent resolution request + private async ValueTask> RaiseIntentToApplication( + int messageId, + IAppMetadata targetAppMetadata, + string intent, + Context context, + string sourceFdc3InstanceId) + { + RaiseIntentResolutionMessage? resolution = null; + if (!string.IsNullOrEmpty(targetAppMetadata.InstanceId)) + { + var raisedIntentMessageId = StoreRaisedIntentForTarget(messageId, targetAppMetadata.InstanceId, intent, context, sourceFdc3InstanceId); + + if (!_raisedIntentResolutions.TryGetValue(new(targetAppMetadata.InstanceId), out var registeredFdc3App)) + { + return new() + { + Response = RaiseIntentResponse.Failure(ResolveError.TargetInstanceUnavailable) + }; + } + + if (registeredFdc3App.IsIntentListenerRegistered(intent)) + { + resolution = await RaiseIntentResolution(raisedIntentMessageId, intent, context, targetAppMetadata.InstanceId, sourceFdc3InstanceId); + } + + return new() + { + Response = RaiseIntentResponse.Success(raisedIntentMessageId, intent, targetAppMetadata), + RaiseIntentResolutionMessages = resolution != null + ? new[] { resolution } + : Enumerable.Empty() + }; + } + else + { + try + { + var fdc3InstanceId = Guid.NewGuid(); + var moduleInstance = await _moduleLoader.StartModule( + new StartRequest( + targetAppMetadata.AppId, //TODO: possible remove some identifier like @"fdc3." + new List>() + { + { new(Fdc3StartupParameters.Fdc3InstanceId, fdc3InstanceId.ToString()) } + })) ?? throw ThrowHelper.TargetInstanceUnavailable(); + + var raisedIntentMessageId = StoreRaisedIntentForTarget(messageId, fdc3InstanceId.ToString(), intent, context, sourceFdc3InstanceId); + + var target = new AppMetadata() + { + AppId = targetAppMetadata.AppId, + InstanceId = fdc3InstanceId.ToString(), + Name = targetAppMetadata.Name, + Version = targetAppMetadata.Version, + Title = targetAppMetadata.Title, + Tooltip = targetAppMetadata.Tooltip, + Description = targetAppMetadata.Description, + Icons = targetAppMetadata.Icons.Select(icon => Icon.GetIcon(icon)), + Screenshots = targetAppMetadata.Screenshots.Select(screenshot => Screenshot.GetScreenshot(screenshot)), + ResultType = targetAppMetadata.ResultType + }; + + return new() + { + Response = RaiseIntentResponse.Success(raisedIntentMessageId, intent, target) + }; + } + catch (Fdc3DesktopAgentException exception) + { + _logger.LogError(exception, "Error while starting module."); + + return new() + { + Response = RaiseIntentResponse.Failure(exception.Message), + }; + } + } + } + + private async Task GetIntentResolutionResult(GetIntentResultRequest request) + { + RaiseIntentResolutionInvocation? resolution; + while ( + !_raisedIntentResolutions.TryGetValue(new Guid(request.TargetAppIdentifier.InstanceId!), out var resolver) + || !resolver.TryGetRaisedIntentResult(request.MessageId, request.Intent, out resolution) + || (resolution.ResultChannelId == null && resolution.ResultChannelType == null && resolution.ResultContext == null && resolution.ResultVoid == null)) + { + await Task.Delay(100); + } + + return resolution; + } + + private string StoreRaisedIntentForTarget( + int messageId, + string targetFdc3InstanceId, + string intent, + Context context, + string sourceFdc3InstanceId) + { + var invocation = new RaiseIntentResolutionInvocation( + raiseIntentMessageId: messageId, + intent: intent, + originFdc3InstanceId: sourceFdc3InstanceId, + contextToHandle: context); + + _raisedIntentResolutions.AddOrUpdate( + new(targetFdc3InstanceId), + _ => + { + var resolver = new RaisedIntentRequestHandler(); + resolver.AddRaiseIntentToHandle(invocation); + return resolver; + }, + (key, oldValue) => oldValue.AddRaiseIntentToHandle(invocation)); + + return invocation.RaiseIntentMessageId; + } + + //Publishing intent resolution request to the fdc3 clients, they will receive the message and start their intenthandler appropriately, and send a store request back to the backend. + private Task RaiseIntentResolution(string raisedIntentMessageId, string intent, Context context, string targetId, string sourceFdc3InstanceId) + { + if (_runningModules.TryGetValue(new(sourceFdc3InstanceId), out var sourceApp)) + { + var sourceAppIdentifier = new AppIdentifier() + { + AppId = sourceApp.AppId, + InstanceId = sourceFdc3InstanceId + }; + + return Task.FromResult( + new() + { + Intent = intent, + TargetModuleInstanceId = targetId, + Request = new RaiseIntentResolutionRequest() + { + MessageId = raisedIntentMessageId, + Context = context, + ContextMetadata = new ContextMetadata() + { + Source = sourceAppIdentifier + } + } + }); + } + + return Task.FromResult(null); + } + + private async Task> GetAppIntentsByRequest( + Func?> selector, + IAppIdentifier? targetAppIdentifier, + bool selected) + { + var appIntents = new Dictionary(); + + if (targetAppIdentifier?.InstanceId == null) + { + appIntents = await GetAppIntentsFromAppDirectory(selector, targetAppIdentifier, appIntents); + + if (selected && appIntents.Count > 0) + { + return appIntents; + } + } + + appIntents = GetAppIntentsFromRunningModules(selector, targetAppIdentifier, appIntents); + + return appIntents; + } + + private Dictionary GetAppIntentsFromRunningModules( + Func?> selector, + IAppIdentifier? targetAppIdentifier, + Dictionary appIntents) + { + foreach (var app in _runningModules) + { + if (targetAppIdentifier?.InstanceId != null && new Guid(targetAppIdentifier.InstanceId) != app.Key) + { + continue; + } + + var intentMetadataCollection = selector(app.Value); + + if (intentMetadataCollection == null) + { + continue; + } + + appIntents = GetAppIntentsFromIntentMetadaCollection(app.Value, app.Key.ToString(), intentMetadataCollection, appIntents); + } + + return appIntents; + } + + private async Task> GetAppIntentsFromAppDirectory( + Func?> selector, + IAppIdentifier? targetAppIdentifier, + Dictionary appIntents) + { + foreach (var app in await _appDirectory.GetApps()) + { + if (targetAppIdentifier != null && targetAppIdentifier.AppId != app.AppId) + { + continue; + } + + var intentMetadataCollection = selector(app); + + if (intentMetadataCollection == null) + { + continue; + } + + appIntents = GetAppIntentsFromIntentMetadaCollection(app, null, intentMetadataCollection, appIntents); + } + + return appIntents; + } + + private Dictionary GetAppIntentsFromIntentMetadaCollection( + Fdc3App app, + string? instanceId, + IEnumerable intentMetadataCollection, + Dictionary appIntents) + { + foreach (var intentMetadata in intentMetadataCollection) + { + var appMetadata = + new AppMetadata() + { + AppId = app.AppId, + InstanceId = instanceId, + Name = app.Name, + Version = app.Version, + Title = app.Title, + Tooltip = app.ToolTip, + Description = app.Description, + Icons = app.Icons == null ? Enumerable.Empty() : app.Icons.Select(icon => Icon.GetIcon(icon)), + Screenshots = app.Screenshots == null ? Enumerable.Empty() : app.Screenshots.Select(screenshot => Screenshot.GetScreenshot(screenshot)), + ResultType = intentMetadata?.ResultType + }; + + if (appIntents.ContainsKey(intentMetadata!.Name)) + { + appIntents[intentMetadata.Name] = new AppIntent() + { + Intent = new Protocol.IntentMetadata { Name = intentMetadata.Name, DisplayName = intentMetadata.DisplayName }, + Apps = appIntents[intentMetadata.Name].Apps.Append(appMetadata) + }; + } + else + { + appIntents.Add( + intentMetadata.Name, + new AppIntent() + { + Intent = new Protocol.IntentMetadata { Name = intentMetadata.Name, DisplayName = intentMetadata.DisplayName }, + Apps = new List() { appMetadata } + }); + } + } + + return appIntents; + } + + private Task RemoveModuleAsync(IModuleInstance instance) + { + var fdc3InstanceId = GetFdc3InstanceId(instance); + if (!_runningModules.TryRemove(new(fdc3InstanceId), out _)) + { + _logger.LogError($"Could not remove the closed window with instanceId: {fdc3InstanceId}."); + } + + return Task.CompletedTask; + } + + private async Task AddOrUpdateModuleAsync(IModuleInstance instance) + { + var fdc3App = await _appDirectory.GetApp(instance.Manifest.Id); + if (fdc3App == null) + { + _logger.LogError($"Could not retrieve app: {instance.Manifest.Id} from AppDirectory."); + return; + } + + var fdc3InstanceId = GetFdc3InstanceId(instance); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + _runningModules.GetOrAdd( + new(fdc3InstanceId), + _ => fdc3App); + } + + private bool IsFdc3StartedModule(IModuleInstance instance, out string instanceId) + { + instanceId = string.Empty; + var fdc3InstanceId = instance.StartRequest.Parameters.FirstOrDefault(parameter => parameter.Key == Fdc3StartupParameters.Fdc3InstanceId); + + if (string.IsNullOrEmpty(fdc3InstanceId.Value)) + { + return false; + } + + instanceId = fdc3InstanceId.Value; + return true; + } + + private string GetFdc3InstanceId(IModuleInstance instance) + { + if (!IsFdc3StartedModule(instance, out var fdc3InstanceId)) + { + var startupProperties = instance.GetProperties().FirstOrDefault(p => p is Fdc3StartupProperties); + + return startupProperties == null + ? throw ThrowHelper.MissingFdc3InstanceId(instance.Manifest.Id) + : ((Fdc3StartupProperties)startupProperties).InstanceId; + } + + return fdc3InstanceId; + } + + private async ValueTask SafeWaitAsync(IEnumerable tasks) + { foreach (var task in tasks) { try { await task; } - catch + catch (Exception exception) { - // If disposing one of the channels fails for some reason, we should still try to wait for the rest + _logger.LogError(exception, "An exception was thrown while waiting for a task to finish."); } } - await unregister; } -} +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupAction.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupAction.cs new file mode 100644 index 000000000..6605fde32 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupAction.cs @@ -0,0 +1,73 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent; +using MorganStanley.ComposeUI.ModuleLoader; +using MorganStanley.Fdc3.AppDirectory; +using ResourceReader = MorganStanley.ComposeUI.Utilities.ResourceReader; + +namespace MorganStanley.ComposeUI.Shell.Fdc3; + +internal sealed class Fdc3StartupAction : IStartupAction +{ + private readonly IAppDirectory _appDirectory; + private readonly ILogger _logger; + + public Fdc3StartupAction( + IAppDirectory appDirectory, + ILogger? logger = null) + { + _appDirectory = appDirectory; + _logger = logger ?? NullLogger.Instance; + } + + public async Task InvokeAsync(StartupContext startupContext, Func next) + { + if (startupContext.ModuleInstance.Manifest.ModuleType == ModuleType.Web) + { + //TODO: should add some identifier to the query => "fdc3:" + startupContext.StartRequest.ModuleId + try + { + var appId = (await _appDirectory.GetApp(startupContext.StartRequest.ModuleId)).AppId; + var fdc3InstanceId = startupContext.StartRequest.Parameters.FirstOrDefault(parameter => parameter.Key == Fdc3StartupParameters.Fdc3InstanceId).Value ?? Guid.NewGuid().ToString(); + var fdc3StartupProperties = new Fdc3StartupProperties() { InstanceId = fdc3InstanceId }; + fdc3InstanceId = startupContext.GetOrAddProperty(_ => fdc3StartupProperties).InstanceId; + + var webProperties = startupContext.GetOrAddProperty(); + + webProperties + .ScriptProviders.Add(_ => + new ValueTask( + $$""" + window.composeui.fdc3 = { + ...window.composeui.fdc3, + config: { + appId: "{{appId}}", + instanceId: "{{fdc3InstanceId}}" + } + }; + """)); + + webProperties + .ScriptProviders.Add(_ => new ValueTask(ResourceReader.ReadResource(ResourceNames.Fdc3Bundle))); + } + catch (AppNotFoundException exception) + { + _logger.LogError(exception, $"Fdc3 bundle js could be not added to the {startupContext.StartRequest.ModuleId}."); + } + } + + await (next.Invoke()); + } +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupParameters.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupParameters.cs new file mode 100644 index 000000000..b29860e2e --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupParameters.cs @@ -0,0 +1,23 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent; + +/// +/// This class is for setting internally the Fdc3InstanceId via the Fdc3DesktopAgent client's raiseIntent call. +/// +internal class Fdc3StartupParameters +{ + public static string Fdc3InstanceId = nameof(Fdc3InstanceId); +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupProperties.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupProperties.cs new file mode 100644 index 000000000..09ff7571c --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupProperties.cs @@ -0,0 +1,23 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent; + +internal class Fdc3StartupProperties +{ + /// + /// Fdc3 DesktopAgent's specific identifier for the created application instance. + /// + public string InstanceId { get; init; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3Topic.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3Topic.cs index d6af82a2f..44e5e8f59 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3Topic.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3Topic.cs @@ -18,6 +18,19 @@ internal static class Fdc3Topic { internal static string TopicRoot => "ComposeUI/fdc3/v2.0/"; internal static string FindChannel => TopicRoot + "findChannel"; + internal static string FindIntent => TopicRoot + "findIntent"; + internal static string FindIntentsByContext => TopicRoot + "findIntentsByContext"; + internal static string RaiseIntent => TopicRoot + "raiseIntent"; + internal static string GetIntentResult => TopicRoot + "getIntentResult"; + internal static string SendIntentResult => TopicRoot + "sendIntentResult"; + internal static string AddIntentListener => TopicRoot + "addIntentListener"; + + //IntentListeners will be listening at this endpoint + internal static string RaiseIntentResolution(string intent, string instanceId) + { + return $"{RaiseIntent}/{intent}/{instanceId}"; + } + internal static UserChannelTopics UserChannel(string id) => new UserChannelTopics(id); } @@ -33,4 +46,4 @@ public UserChannelTopics(string id) public string Broadcast { get; } public string GetCurrentContext { get; } -} +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.cs new file mode 100644 index 000000000..776974b34 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.cs @@ -0,0 +1,201 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using System.Reactive.Linq; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.DependencyInjection; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; +using MorganStanley.ComposeUI.Messaging; +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; + +internal class Fdc3DesktopAgentMessageRouterService : IHostedService +{ + private readonly IMessageRouter _messageRouter; + private readonly IFdc3DesktopAgentBridge _desktopAgent; + private readonly Fdc3DesktopAgentOptions _options; + private readonly ILoggerFactory _loggerFactory; + private readonly ILogger _logger; + private readonly JsonSerializerOptions _jsonSerializerOptions = new(JsonSerializerDefaults.Web) + { + WriteIndented = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + Converters = + { + new AppMetadataJsonConverter(), + new IntentMetadataJsonConverter(), + new AppIntentJsonConverter(), + new IconJsonConverter(), + new ImageJsonConverter(), + new IntentMetadataJsonConverter(), + } + }; + + public JsonSerializerOptions JsonMessageSerializerOptions => new(_jsonSerializerOptions); + + public Fdc3DesktopAgentMessageRouterService( + IMessageRouter messageRouter, + IFdc3DesktopAgentBridge desktopAgent, + IOptions options, + ILoggerFactory? loggerFactory = null) + { + _messageRouter = messageRouter; + _desktopAgent = desktopAgent; + _options = options.Value; + _loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; + _logger = _loggerFactory.CreateLogger() ?? NullLogger.Instance; + } + + public async ValueTask HandleAddUserChannel(string id) + { + var userChannel = new UserChannel(id, _messageRouter, _loggerFactory.CreateLogger()); + await _desktopAgent.AddUserChannel(userChannel); + return userChannel; + } + + internal ValueTask HandleFindChannel(FindChannelRequest? request, MessageContext context) + { + return ValueTask.FromResult( + _desktopAgent.FindChannel(request!.ChannelId, request!.ChannelType) + ? FindChannelResponse.Success + : FindChannelResponse.Failure(ChannelError.NoChannelFound)); + } + + internal async ValueTask HandleFindIntent(FindIntentRequest? request, MessageContext context) + { + return await _desktopAgent.FindIntent(request); + } + + internal async ValueTask HandleFindIntentsByContext(FindIntentsByContextRequest? request, MessageContext context) + { + return await _desktopAgent.FindIntentsByContext(request); + } + + internal async ValueTask HandleRaiseIntent(RaiseIntentRequest? request, MessageContext context) + { + try + { + var result = await _desktopAgent.RaiseIntent(request); + if (result.RaiseIntentResolutionMessages.Any()) + { + foreach (var message in result.RaiseIntentResolutionMessages) + { + await _messageRouter.PublishAsync( + Fdc3Topic.RaiseIntentResolution(message.Intent, message.TargetModuleInstanceId), + MessageBuffer.Factory.CreateJson(message.Request, _jsonSerializerOptions)); + } + } + + return result.Response; + } + catch (Fdc3DesktopAgentException) + { + throw; + } + } + + internal async ValueTask HandleAddIntentListener(IntentListenerRequest? request, MessageContext context) + { + var result = await _desktopAgent.AddIntentListener(request); + + if (result.RaiseIntentResolutionMessages.Any()) + { + foreach (var message in result.RaiseIntentResolutionMessages) + { + await _messageRouter.PublishAsync( + Fdc3Topic.RaiseIntentResolution(message.Intent, message.TargetModuleInstanceId), + MessageBuffer.Factory.CreateJson(message.Request, _jsonSerializerOptions)); + } + } + + return result.Response; + } + + internal async ValueTask HandleStoreIntentResult(StoreIntentResultRequest? request, MessageContext context) + { + return await _desktopAgent.StoreIntentResult(request); + } + + internal async ValueTask HandleGetIntentResult(GetIntentResultRequest? request, MessageContext context) + { + return await _desktopAgent.GetIntentResult(request); + } + + private async ValueTask SafeWaitAsync(IEnumerable tasks) + { + foreach (var task in tasks) + { + try + { + await task; + } + catch (Exception exception) + { + _logger.LogError($"An exception was thrown while waiting for a teask to finish. Exception: {exception}"); + } + } + } + + public async Task StartAsync(CancellationToken cancellationToken) + { + async Task RegisterHandler(string topic, Func> handler) where TRequest : class + { + await _messageRouter.RegisterServiceAsync(topic, + async (endpoint, payload, context) => + { + var request = payload?.ReadJson(_jsonSerializerOptions); + var response = await handler(request, context); + return response is null ? null : MessageBuffer.Factory.CreateJson(response, _jsonSerializerOptions); + }, cancellationToken: cancellationToken); + } + + await RegisterHandler(Fdc3Topic.FindChannel, HandleFindChannel); + await RegisterHandler(Fdc3Topic.FindIntent, HandleFindIntent); + await RegisterHandler(Fdc3Topic.FindIntentsByContext, HandleFindIntentsByContext); + await RegisterHandler(Fdc3Topic.RaiseIntent, HandleRaiseIntent); + await RegisterHandler(Fdc3Topic.GetIntentResult, HandleGetIntentResult); + await RegisterHandler(Fdc3Topic.SendIntentResult, HandleStoreIntentResult); + await RegisterHandler(Fdc3Topic.AddIntentListener, HandleAddIntentListener); + + await _desktopAgent.StartAsync(cancellationToken); + + if (_options.ChannelId != null) + { + await HandleAddUserChannel(_options.ChannelId); + } + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + var unregisteringTasks = new ValueTask[] + { + _messageRouter.UnregisterServiceAsync(Fdc3Topic.FindChannel, cancellationToken), + _messageRouter.UnregisterServiceAsync(Fdc3Topic.FindIntent, cancellationToken), + _messageRouter.UnregisterServiceAsync(Fdc3Topic.RaiseIntent, cancellationToken), + _messageRouter.UnregisterServiceAsync(Fdc3Topic.FindIntentsByContext, cancellationToken), + _messageRouter.UnregisterServiceAsync(Fdc3Topic.GetIntentResult, cancellationToken), + _messageRouter.UnregisterServiceAsync(Fdc3Topic.SendIntentResult, cancellationToken), + _messageRouter.UnregisterServiceAsync(Fdc3Topic.AddIntentListener, cancellationToken) + }; + + await SafeWaitAsync(unregisteringTasks); + await _desktopAgent.StopAsync(cancellationToken); + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/IFdc3DesktopAgentBridge.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/IFdc3DesktopAgentBridge.cs new file mode 100644 index 000000000..a2df9d36b --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/IFdc3DesktopAgentBridge.cs @@ -0,0 +1,92 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; + +internal interface IFdc3DesktopAgentBridge +{ + /// + /// Triggers the necessary events like ModuleLoader's Subscribe when Startup. + /// + /// + /// + public Task StartAsync(CancellationToken cancellationToken); + + /// + /// Disposes the disposable resources. + /// + /// + /// + public Task StopAsync(CancellationToken cancellationToken); + + /// + /// Handles the AddUserChannel call in the bridge. + /// + /// + /// + public ValueTask AddUserChannel(UserChannel userChannel); + + /// + /// Handles the FindChannel call in the bridge. + /// + /// + /// + /// + public bool FindChannel(string channelId, ChannelType channelType); + + /// + /// Handles the FindIntent call in the bridge. + /// + /// + /// + public ValueTask FindIntent(FindIntentRequest? request); + + /// + /// Handles the FindIntentsByContext call in the bridge. + /// + /// + /// + public ValueTask FindIntentsByContext(FindIntentsByContextRequest? request); + + /// + /// Handles the GetIntentResult call in the bridge. + /// + /// + /// + public ValueTask GetIntentResult(GetIntentResultRequest? request); + + /// + /// Handles the RaiseIntent call in the bridge. + /// + /// + /// + public ValueTask> RaiseIntent(RaiseIntentRequest? request); + + /// + /// Handles the AddIntentListener call in the bridge. + /// + /// + /// + public ValueTask> AddIntentListener(IntentListenerRequest? request); + + /// + /// Handles the StoreIntentResult call in the bridge. + /// + /// + /// + public ValueTask StoreIntentResult(StoreIntentResultRequest? request); +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionInvocation.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionInvocation.cs new file mode 100644 index 000000000..2a6606eb1 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionInvocation.cs @@ -0,0 +1,53 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3.Context; +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; + +internal class RaiseIntentResolutionInvocation +{ + public RaiseIntentResolutionInvocation( + int raiseIntentMessageId, + string intent, + string originFdc3InstanceId, + Context contextToHandle, + Context? resultContext = null, + string? resultChannelId = null, + ChannelType? resultChannelType = null, + bool? resultVoid = null, + string? resultError = null) + { + RaiseIntentMessageId = $"{raiseIntentMessageId}-{Guid.NewGuid()}"; + Intent = intent; + OriginFdc3InstanceId = originFdc3InstanceId; + Context = contextToHandle; + ResultContext = resultContext; + ResultChannelId = resultChannelId; + ResultChannelType = resultChannelType; + ResultVoid = resultVoid; + ResultError = resultError; + } + + public string RaiseIntentMessageId { get; } + public string Intent { get; } + public string OriginFdc3InstanceId { get; } + public Context Context { get; } + public Context? ResultContext { get; set; } + public string? ResultChannelId { get; set; } + public ChannelType? ResultChannelType { get; set; } + public bool? ResultVoid { get; set; } + public string? ResultError { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionMessage.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionMessage.cs new file mode 100644 index 000000000..4c08ccd24 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionMessage.cs @@ -0,0 +1,33 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; + +internal partial class RaiseIntentResolutionMessage +{ + /// + /// Intent for identifying the endpoint. + /// + public string Intent { get; init; } + + /// + /// InstanceId to identify the target application. + /// + public string TargetModuleInstanceId { get; init; } + + /// + /// Request that should be sent to the target module. + /// + public RaiseIntentResolutionRequest Request { get; init; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResult.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResult.cs new file mode 100644 index 000000000..d6f0c3a35 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResult.cs @@ -0,0 +1,30 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; + +/// +/// This message type is used to check if an IntentResult could be sent to the client(s). +/// +/// This is either IntentListenerResponse or RaiseIntentResponse +internal partial class RaiseIntentResult +{ + /// + /// Response for the call. + /// + public TResponse Response { get; set; } + + /// + /// RaiseIntentResolution messages to forward to the registered IntentListeners to resolve with their registered IntentListener. + /// + public IEnumerable RaiseIntentResolutionMessages { get; set; } = Enumerable.Empty(); +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaisedIntentRequestHandler.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaisedIntentRequestHandler.cs new file mode 100644 index 000000000..bc520b8b8 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaisedIntentRequestHandler.cs @@ -0,0 +1,116 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.Fdc3.Context; +using MorganStanley.Fdc3; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; + +internal class RaisedIntentRequestHandler +{ + private readonly object _intentListenersLock = new(); + private readonly object _raiseIntentInvocationsLock = new(); + private readonly List _registeredIntentListeners = new(); + private readonly List _raiseIntentResolutions = new(); + public IEnumerable IntentListeners => _registeredIntentListeners; + public IEnumerable RaiseIntentResolutions => _raiseIntentResolutions; + + public RaisedIntentRequestHandler AddIntentListener(string intent) + { + lock (_intentListenersLock) + { + _registeredIntentListeners.Add(intent); + return this; + } + } + + public RaisedIntentRequestHandler RemoveIntentListener(string intent) + { + lock (_intentListenersLock) + { + _registeredIntentListeners.Remove(intent); + return this; + } + } + + public bool IsIntentListenerRegistered(string intent) + { + lock (_intentListenersLock) + { + return _registeredIntentListeners.Contains(intent); + } + } + + public RaisedIntentRequestHandler AddRaiseIntentToHandle(RaiseIntentResolutionInvocation raiseIntentInvocation) + { + lock (_raiseIntentInvocationsLock) + { + _raiseIntentResolutions.Add(raiseIntentInvocation); + return this; + } + } + + public RaisedIntentRequestHandler AddIntentResult( + string messageId, + string intent, + string? channelId = null, + ChannelType? channelType = null, + Context? context = null, + bool? voidResult = false, + string? error = null) + { + lock (_raiseIntentInvocationsLock) + { + var raisedIntentInvocations = _raiseIntentResolutions.Where( + raisedIntentToHandle => raisedIntentToHandle.RaiseIntentMessageId == messageId && raisedIntentToHandle.Intent == intent); + + if (raisedIntentInvocations.Count() == 1) + { + var raisedIntentInvocation = raisedIntentInvocations.First(); + raisedIntentInvocation.ResultChannelId = channelId; + raisedIntentInvocation.ResultChannelType = channelType; + raisedIntentInvocation.ResultContext = context; + raisedIntentInvocation.ResultVoid = voidResult; + raisedIntentInvocation.ResultError = error; + } + else if (raisedIntentInvocations.Count() > 1) + { + throw ThrowHelper.MultipleIntentRegisteredToAnAppInstance(intent); + } + + return this; + } + } + + public bool TryGetRaisedIntentResult(string messageId, string intent, out RaiseIntentResolutionInvocation raiseIntentInvocation) + { + lock (_raiseIntentInvocationsLock) + { + var raiseIntentInvocations = _raiseIntentResolutions.Where(raiseIntentInvocation => raiseIntentInvocation.RaiseIntentMessageId == messageId && raiseIntentInvocation.Intent == intent); + if (raiseIntentInvocations.Any()) + { + if (raiseIntentInvocations.Count() > 1) + { + throw ThrowHelper.MultipleIntentRegisteredToAnAppInstance(intent); + } + raiseIntentInvocation = raiseIntentInvocations.First(); + return true; + } + + raiseIntentInvocation = null; + return false; + } + } +} \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIdentifier.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIdentifier.cs new file mode 100644 index 000000000..8020225d1 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIdentifier.cs @@ -0,0 +1,22 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class AppIdentifier : IAppIdentifier +{ + public string AppId { get; set; } + + public string? InstanceId { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIntent.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIntent.cs new file mode 100644 index 000000000..6d135e549 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIntent.cs @@ -0,0 +1,24 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class AppIntent : IAppIntent +{ + public IntentMetadata Intent { get; set; } + IIntentMetadata IAppIntent.Intent => Intent; + + public IEnumerable Apps { get; set; } + IEnumerable IAppIntent.Apps => Apps; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppMetadata.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppMetadata.cs new file mode 100644 index 000000000..4daf686b4 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppMetadata.cs @@ -0,0 +1,43 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + + +using MorganStanley.Fdc3; +using Icon = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.Icon; +using Screenshot = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.Screenshot; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class AppMetadata : IAppMetadata +{ + public string? Name { get; set; } + + public string? Version { get; set; } + + public string? Title { get; set; } + + public string? Tooltip { get; set; } + + public string? Description { get; set; } + + public IEnumerable Icons { get; set; } = Enumerable.Empty(); + IEnumerable IAppMetadata.Icons => Icons; + + public IEnumerable Screenshots { get; set; } = Enumerable.Empty(); + IEnumerable IAppMetadata.Screenshots => Screenshots; + + public string? ResultType { get; set; } + + public string AppId { get; set; } + + public string? InstanceId { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ContextMetadata.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ContextMetadata.cs new file mode 100644 index 000000000..d948a22bf --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ContextMetadata.cs @@ -0,0 +1,22 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.Fdc3; +using AppIdentifier = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIdentifier; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class ContextMetadata : IContextMetadata +{ + public AppIdentifier? Source { get; set; } + IAppIdentifier? IContextMetadata.Source => Source; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/DisplayMetadata.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/DisplayMetadata.cs new file mode 100644 index 000000000..4467df37f --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/DisplayMetadata.cs @@ -0,0 +1,24 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class DisplayMetadata : IDisplayMetadata +{ + public string? Name { get; set; } + + public string? Color { get; set; } + + public string? Glyph { get; set; } +} diff --git a/src/shell/dotnet/Shell/Fdc3/Fdc3StartupAction.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Icon.cs similarity index 51% rename from src/shell/dotnet/Shell/Fdc3/Fdc3StartupAction.cs rename to src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Icon.cs index ffcc4eb47..a49470558 100644 --- a/src/shell/dotnet/Shell/Fdc3/Fdc3StartupAction.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Icon.cs @@ -10,23 +10,25 @@ // or implied. See the License for the specific language governing permissions // and limitations under the License. -using System; -using System.Threading.Tasks; -using MorganStanley.ComposeUI.ModuleLoader; -using MorganStanley.ComposeUI.Shell.Utilities; +using MorganStanley.Fdc3; -namespace MorganStanley.ComposeUI.Shell.Fdc3; +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; -internal sealed class Fdc3StartupAction : IStartupAction +public class Icon : IIcon { - public Task InvokeAsync(StartupContext startupContext, Func next) + public string Src { get; set; } + + public string? Size { get; set; } + + public string? Type { get; set; } + + public static Icon GetIcon(IIcon icon) { - if (startupContext.ModuleInstance.Manifest.ModuleType == ModuleType.Web) + return new() { - startupContext.GetOrAddProperty() - .ScriptProviders.Add(_ => new ValueTask(ResourceReader.ReadResource(ResourceNames.Fdc3Bundle))); - } - - return next(); + Src = icon.Src, + Size = icon.Size, + Type = icon.Type, + }; } -} \ No newline at end of file +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ImplementationMetadata.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ImplementationMetadata.cs new file mode 100644 index 000000000..57a75e0f8 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ImplementationMetadata.cs @@ -0,0 +1,30 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.Fdc3; +using AppMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppMetadata; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class ImplementationMetadata : IImplementationMetadata +{ + public string Fdc3Version { get; set; } + + public string Provider { get; set; } + + public string ProviderVersion { get; set; } + + public OptionalDesktopAgentFeatures OptionalFeatures { get; set; } + + public AppMetadata AppMetadata { get; set; } + IAppMetadata IImplementationMetadata.AppMetadata => AppMetadata; +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/IntentMetadata.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/IntentMetadata.cs new file mode 100644 index 000000000..5c0427348 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/IntentMetadata.cs @@ -0,0 +1,22 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class IntentMetadata : IIntentMetadata +{ + public string Name { get; set; } + + public string DisplayName { get; set; } +} diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Screenshot.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Screenshot.cs new file mode 100644 index 000000000..fe123c051 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Screenshot.cs @@ -0,0 +1,37 @@ +// Morgan Stanley makes this available to you under the Apache License, +// Version 2.0 (the "License"). You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0. +// +// See the NOTICE file distributed with this work for additional information +// regarding copyright ownership. Unless required by applicable law or agreed +// to in writing, software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// or implied. See the License for the specific language governing permissions +// and limitations under the License. + +using MorganStanley.Fdc3; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol; + +public class Screenshot : IImage +{ + public string Src { get; set; } + + public string? Size { get; set; } + + public string? Type { get; set; } + + public string? Label { get; set; } + + public static Screenshot GetScreenshot(IImage screenshot) + { + return new() + { + Src = screenshot.Src, + Size = screenshot.Size, + Type = screenshot.Type, + Label = screenshot.Label, + }; + } +} diff --git a/src/shell/dotnet/Shell/Utilities/ResourceNames.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/ResourceNames.cs similarity index 73% rename from src/shell/dotnet/Shell/Utilities/ResourceNames.cs rename to src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/ResourceNames.cs index 7dc114dac..243229041 100644 --- a/src/shell/dotnet/Shell/Utilities/ResourceNames.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/ResourceNames.cs @@ -14,10 +14,9 @@ using System.Reflection; -namespace MorganStanley.ComposeUI.Shell.Utilities; +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent; public static class ResourceNames { - public static readonly string Fdc3Bundle = @$"{Assembly.GetExecutingAssembly().ManifestModule.Assembly.GetName()?.Name}.fdc3-iife-bundle.js"; - public static readonly string MessageRouter = $"{nameof(MessageRouter)}"; + public static readonly string Fdc3Bundle = @$"{Assembly.GetCallingAssembly().ManifestModule.Assembly.GetName()?.Name}.fdc3-iife-bundle.js"; } diff --git a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/UserChannel.cs b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/UserChannel.cs index e9f602379..1f886fcf8 100644 --- a/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/UserChannel.cs +++ b/src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/UserChannel.cs @@ -56,7 +56,6 @@ public async ValueTask Connect() var broadcastSubscribing = _messageRouter.SubscribeAsync(_topics.Broadcast, broadcastObserver); - //await _messageRouter.RegisterEndpointAsync(_topics.GetCurrentContext, GetCurrentContext); await _messageRouter.RegisterServiceAsync(_topics.GetCurrentContext, GetCurrentContext); _broadcastSubscription = await broadcastSubscribing; @@ -102,24 +101,24 @@ internal ValueTask HandleBroadcast(MessageBuffer? payloadBuffer) return ValueTask.CompletedTask; } - internal async ValueTask GetCurrentContext(string endpoint, MessageBuffer? payloadBuffer, MessageContext? _) + internal ValueTask GetCurrentContext(string endpoint, MessageBuffer? payloadBuffer, MessageContext? context) { if (payloadBuffer == null) - { - return _lastContext; + { + return ValueTask.FromResult(_lastContext); } var payload = payloadBuffer.ReadJson(); if (payload?.ContextType == null) { - return _lastContext; + return ValueTask.FromResult(_lastContext); } - if (_contexts.TryGetValue(payload.ContextType, out MessageBuffer? context)) + if (_contexts.TryGetValue(payload.ContextType, out MessageBuffer? messageBuffer)) { - return context; + return ValueTask.FromResult(messageBuffer); } - return null; + return ValueTask.FromResult(null); } public async ValueTask DisposeAsync() @@ -128,7 +127,7 @@ public async ValueTask DisposeAsync() { await _broadcastSubscription.DisposeAsync(); } - + _broadcastSubscription = null; await _messageRouter.UnregisterServiceAsync(_topics.GetCurrentContext); diff --git a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/DesktopAgent.Tests.csproj b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/DesktopAgent.Tests.csproj index 544a5afa3..65047687e 100644 --- a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/DesktopAgent.Tests.csproj +++ b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/DesktopAgent.Tests.csproj @@ -32,7 +32,15 @@ + + + + + PreserveNewest + + + diff --git a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/EndToEndTests.cs b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/EndToEndTests.cs index d8a7ce5ce..d189ceb76 100644 --- a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/EndToEndTests.cs +++ b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/EndToEndTests.cs @@ -13,12 +13,21 @@ */ +using System.Text.Json; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.Helpers; using MorganStanley.ComposeUI.Messaging.Client.WebSocket; +using MorganStanley.ComposeUI.ModuleLoader; using MorganStanley.Fdc3; using MorganStanley.Fdc3.Context; +using AppMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppMetadata; +using AppIntent = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIntent; +using AppIdentifier = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIdentifier; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests { @@ -31,6 +40,11 @@ public class EndToEndTests : IAsyncLifetime private const string TestChannel = "testChannel"; private readonly UserChannelTopics _topics = new UserChannelTopics(TestChannel); private const string AccessToken = "token"; + private JsonSerializerOptions _options; + private IModuleLoader _moduleLoader; + private readonly object _runningAppsLock = new(); + private IDisposable _runningAppsObserver; + private readonly List _runningApps = new(); public async Task InitializeAsync() { @@ -47,14 +61,20 @@ public async Task InitializeAsync() opt.Port = _webSocketUri.Port; })); services.AddMessageRouter(mr => mr.UseServer()); + + services.AddFdc3AppDirectory( + _ => _.Source = new Uri($"file:\\\\{Directory.GetCurrentDirectory()}\\TestUtils\\appDirectorySample.json")); + + services.AddModuleLoader(); + services.AddFdc3DesktopAgent( fdc3 => fdc3.Configure( builder => { - builder.ChannelId = - TestChannel; //DesktopAgent will call the `AddUserChannel` method, as this property is set for the `_options` field; + builder.ChannelId = TestChannel; })); }); + _host = builder.Build(); await _host.StartAsync(); @@ -69,10 +89,42 @@ public async Task InitializeAsync() .BuildServiceProvider(); _messageRouter = _clientServices.GetRequiredService(); + + _moduleLoader = _host.Services.GetRequiredService(); + + _runningAppsObserver = _moduleLoader.LifetimeEvents.Subscribe((lifetimeEvent) => + { + lock (_runningAppsLock) + { + switch (lifetimeEvent.EventType) + { + case LifetimeEventType.Started: + _runningApps.Add(lifetimeEvent.Instance); + break; + + case LifetimeEventType.Stopped: + _runningApps.Remove(lifetimeEvent.Instance); + break; + } + } + }); + + var fdc3DesktopAgentMessageRouterService = _host.Services.GetRequiredService() as Fdc3DesktopAgentMessageRouterService; + _options = fdc3DesktopAgentMessageRouterService!.JsonMessageSerializerOptions; } public async Task DisposeAsync() { + List runningApps; + _runningAppsObserver?.Dispose(); + lock (_runningAppsLock) + { + runningApps = _runningApps.Reverse().ToList(); + } + foreach (var instance in runningApps) + { + await _moduleLoader.StopModule(new StopRequest(instance.InstanceId)); + } await _clientServices.DisposeAsync(); await _host.StopAsync(); _host.Dispose(); @@ -134,7 +186,7 @@ public async void FindUserChannelReturnsFoundTrueForExistingChannel() { var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindChannel, FindRequest); resultBuffer.Should().NotBeNull(); - var result = resultBuffer!.ReadJson(); + var result = resultBuffer!.ReadJson(_options); result.Should().BeEquivalentTo(FindChannelResponse.Success); } @@ -143,29 +195,795 @@ public async void FindUserChannelReturnsNoChannelFoundForNonExistingChannel() { var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindChannel, FindNonExistingRequest); resultBuffer.Should().NotBeNull(); - var result = resultBuffer!.ReadJson(); + var result = resultBuffer!.ReadJson(_options); result.Should().BeEquivalentTo(FindChannelResponse.Failure(ChannelError.NoChannelFound)); } + [Fact] + public async Task FindIntentReturnsAppIntent() + { + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var appId4IntentMetadata = new Protocol.IntentMetadata() { Name = "intentMetadata4", DisplayName = "displayName4" }; + + var request = new FindIntentRequest() + { + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadata4" + }; + + var expectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = appId4IntentMetadata, + Apps = new AppMetadata[] + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + } + } + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntent, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task FindIntentReturnsIntentDeliveryFailureBecauseOfTheRequest() + { + var expectedResponse = new FindIntentResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntent, null); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task FindIntentReturnsNoAppsFound() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new FindIntentRequest() + { + Fdc3InstanceId = originFdc3InstanceId, + Intent = "noAppShouldReturnIntent", + }; + + var expectedResponse = new FindIntentResponse() + { + Error = ResolveError.NoAppsFound + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntent, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task FindIntentReturnsIntentDeliveryFailureBecauseOfMultipleAppIntentFound() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new FindIntentRequest() + { + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadata8" + }; + + var expectedResponse = new FindIntentResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntent, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task FindIntentsByContextReturnsAppIntent() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = originFdc3InstanceId, + Context = new Context("context2"), + ResultType = "resultType" + }; + + var appId5IntentMetadata = new Protocol.IntentMetadata() { Name = "intentMetadata4", DisplayName = "displayName4" }; + + var expectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new AppIntent[] + { + new() + { + Intent = appId5IntentMetadata, + Apps = new AppMetadata[] + { + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + } + } + } + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntentsByContext, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task FindIntentsByContextReturnsMultipleAppIntent() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = originFdc3InstanceId, + Context = new Context("context9"), + ResultType = "resultWrongApp" + }; + + var appId9IntentMetadata = new Protocol.IntentMetadata() { Name = "intentMetadata9", DisplayName = "displayName9" }; + var appId12IntentMetadata = new Protocol.IntentMetadata() { Name = "intentMetadata11", DisplayName = "displayName11" }; + var expectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent() + { + Intent = appId9IntentMetadata, + Apps = new [] + { + new AppMetadata() { AppId = "wrongappId9", Name = "app9", ResultType = "resultWrongApp" }, + } + }, + new AppIntent() + { + Intent = appId12IntentMetadata, + Apps = new [] + { + new AppMetadata(){ AppId = "appId12", Name = "app12", ResultType = "resultWrongApp" }, + } + } + } + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntentsByContext, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task FindIntentsByContextReturnsIntentDeliveryFailureBecauseOfTheRequest() + { + var expectedResponse = new FindIntentsByContextResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntentsByContext, null); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task FindIntentsByContextReturnsNoAppsFound() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = originFdc3InstanceId, + Context = new Context("context2"), + ResultType = "noAppShouldReturn" + }; + + var expectedResponse = new FindIntentsByContextResponse() + { + Error = ResolveError.NoAppsFound + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.FindIntentsByContext, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task RaiseIntentReturnsIntentDeliveryFailureBecauseOfTheRequest() + { + var expectedResponse = new RaiseIntentResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, null); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task RaiseIntentReturnsErrorAsMessageContainsError() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "dummy", + Selected = false, + Context = new Context(ContextTypes.Nothing), + Error = "dummyError" + }; + + var expectedResponse = new RaiseIntentResponse() + { + Error = "dummyError" + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task RaiseIntentReturnsNoAppsFound() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new RaiseIntentRequest() + { + MessageId = 2, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "noIntentShouldHandle", + Selected = false, + Context = new Context(ContextTypes.Nothing) + }; + + var expectedResponse = new RaiseIntentResponse() + { + Error = ResolveError.NoAppsFound + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task RaiseIntentReturnsIntentDeliveryFailureAsMultipleAppIntentFound() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new RaiseIntentRequest() + { + MessageId = 2, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadata8", //wrongly set up AppDirectory on purpose + Selected = false, + Context = new Context(ContextTypes.Nothing) + }; + + var expectedResponse = new RaiseIntentResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task RaiseIntentReturnsAppIntentWithOneApp() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new RaiseIntentRequest() + { + MessageId = 2, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom") + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(request, _options)); + var app4 = _runningApps.First(application => application.Manifest.Id == "appId4"); + var app4Fdc3InstanceId = Fdc3InstanceIdRetriever.Get(app4); + app4Fdc3InstanceId.Should().Be(resultBuffer!.ReadJson(_options)!.AppMetadata!.First().InstanceId); + app4Fdc3InstanceId.Should().NotBeNull(); + + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + + var expectedResponse = new RaiseIntentResponse() + { + MessageId = result!.MessageId, + Intent = "intentMetadataCustom", + AppMetadata = new AppMetadata[] + { + new(){ AppId = "appId4", InstanceId = app4Fdc3InstanceId, Name = "app4", ResultType = null } + } + }; + + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task RaiseIntentReturnsAppIntentWithOneExistingAppAndPublishesContextToHandle() + { + var origin = await _moduleLoader.StartModule(new StartRequest("appId1")); + var target = await _moduleLoader.StartModule(new StartRequest("appId4")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var addIntentListenerRequest = + MessageBuffer.Factory.CreateJson( + new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }, + _options); + + var addIntentListenerResult = await _messageRouter.InvokeAsync(Fdc3Topic.AddIntentListener, addIntentListenerRequest); + addIntentListenerResult.Should().NotBeNull(); + addIntentListenerResult!.ReadJson(_options).Should().BeEquivalentTo(IntentListenerResponse.SubscribeSuccess()); + + var request = new RaiseIntentRequest() + { + MessageId = 2, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(request, _options)); + + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + + var expectedResponse = new RaiseIntentResponse() + { + MessageId = result!.MessageId, + Intent = "intentMetadataCustom", + AppMetadata = new AppMetadata[] + { + new() { AppId = "appId4", InstanceId = targetFdc3InstanceId, Name = "app4", ResultType = null } + } + }; + + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task RaiseIntentReturnsAppIntentWithMultipleApps() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new RaiseIntentRequest() + { + MessageId = 2, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2") + }; + + var expectedResponse = new RaiseIntentResponse() + { + MessageId = "2", + Intent = "intentMetadata4", + AppMetadata = new AppMetadata[] + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + } + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task StoreIntentResultReturnsIntentDeliveryFailureAsRequestIsNull() + { + var expectedResponse = new StoreIntentResultResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.SendIntentResult, null); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result!.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task StoreIntentResultReturnsIntentDeliveryFailureAsRequestNotContainsInformation() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new StoreIntentResultRequest() + { + MessageId = string.Empty, + Intent = "dummyIntent", + OriginFdc3InstanceId = originFdc3InstanceId, + TargetFdc3InstanceId = null + }; + + var expectedResponse = new StoreIntentResultResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.SendIntentResult, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result!.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task StoreIntentResultReturnsSuccessfully() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 2, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom") + }; + + var raiseIntentResultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(raiseIntentRequest, _options)); + raiseIntentResultBuffer.Should().NotBeNull(); + var raiseIntentResult = raiseIntentResultBuffer!.ReadJson(_options); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + raiseIntentResult.AppMetadata!.First().InstanceId.Should().NotBeNull(); + + var testContext = new Context("testContextType"); + + var request = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadataCustom", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + Context = testContext + }; + + var expectedResponse = new StoreIntentResultResponse() + { + Stored = true + }; + + var app4 = _runningApps.First(application => application.Manifest.Id == "appId4"); + var app4Fdc3InstanceId = Fdc3InstanceIdRetriever.Get(app4); + app4Fdc3InstanceId.Should().Be(raiseIntentResult!.AppMetadata!.First().InstanceId); + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.SendIntentResult, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result!.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task GetIntentResultReturnsIntentDeliveryFailureAsRequestIsNull() + { + var expectedResponse = new GetIntentResultResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.GetIntentResult, null); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result!.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task GetIntentResultReturnsIntentDeliveryFailureAsRequestDoesNotContainInformation() + { + var request = new GetIntentResultRequest() + { + MessageId = "dummy", + Intent = "dummy", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1" } + }; + + var expectedResponse = new GetIntentResultResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.GetIntentResult, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result!.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task GetIntentResultReturnsIntentDeliveryFailureAsNoIntentResultFound() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new GetIntentResultRequest() + { + MessageId = "dummy", + Intent = "testIntent", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1", InstanceId = originFdc3InstanceId } + }; + + var expectedResponse = new GetIntentResultResponse() + { + Error = ResolveError.IntentDeliveryFailed + }; + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.GetIntentResult, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result!.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task GetIntentResultReturnsSuccessfully() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 2, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom") + }; + + var resultRaiseIntentBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, MessageBuffer.Factory.CreateJson(raiseIntentRequest, _options)); + var raiseIntentResult = resultRaiseIntentBuffer!.ReadJson(_options); + + var testContext = new Context("testContextType"); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult!.MessageId!, + Intent = "intentMetadataCustom", + OriginFdc3InstanceId = raiseIntentResult!.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + Context = testContext + }; + + await _messageRouter.InvokeAsync(Fdc3Topic.SendIntentResult, MessageBuffer.Factory.CreateJson(storeIntentRequest, _options)); + + var request = new GetIntentResultRequest() + { + MessageId = raiseIntentResult!.MessageId!, + Intent = "intentMetadataCustom", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = raiseIntentResult!.AppMetadata!.First().InstanceId! } + }; + + var expectedResponse = new GetIntentResultResponse() + { + Context = testContext + }; + + var app4 = _runningApps.First(application => application.Manifest.Id == "appId4"); + var app4Fdc3InstanceId = Fdc3InstanceIdRetriever.Get(app4); + app4Fdc3InstanceId.Should().Be(raiseIntentResult!.AppMetadata!.First().InstanceId); + + var resultBuffer = await _messageRouter.InvokeAsync(Fdc3Topic.GetIntentResult, MessageBuffer.Factory.CreateJson(request, _options)); + resultBuffer.Should().NotBeNull(); + var result = resultBuffer!.ReadJson(_options); + result!.Should().BeEquivalentTo(expectedResponse); + } + + [Fact] + public async Task AddIntentListenerReturnsPayloadNullError() + { + var result = await _messageRouter.InvokeAsync(Fdc3Topic.AddIntentListener, null, new()); + result.Should().NotBeNull(); + result!.ReadJson(_options).Should().BeEquivalentTo(IntentListenerResponse.Failure(Fdc3DesktopAgentErrors.PayloadNull)); + } + + [Fact] + public async Task AddIntentListenerReturnsMissingIdError() + { + var instance = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + var request = new IntentListenerRequest() { Intent = "dummy", Fdc3InstanceId = originFdc3InstanceId, State = SubscribeState.Unsubscribe }; + var expectedResponse = await _messageRouter.InvokeAsync(Fdc3Topic.AddIntentListener, MessageBuffer.Factory.CreateJson(request, _options)); + expectedResponse.Should().NotBeNull(); + expectedResponse!.ReadJson(_options).Should().BeEquivalentTo(IntentListenerResponse.Failure(Fdc3DesktopAgentErrors.MissingId)); + } + + [Fact] + public async Task AddIntentListenerSubscribesWithExistingAppPerRaisedIntent() + { + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _moduleLoader.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _moduleLoader.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = MessageBuffer.Factory.CreateJson( + new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }, _options); + + var raiseIntentResult = await _messageRouter.InvokeAsync(Fdc3Topic.RaiseIntent, raiseIntentRequest); + + raiseIntentResult.Should().NotBeNull(); + var raiseIntentResponse = raiseIntentResult!.ReadJson(_options)!; + raiseIntentResponse.AppMetadata.Should().HaveCount(1); + raiseIntentResponse.AppMetadata!.First()!.AppId.Should().Be("appId4"); + + var addIntentListenerRequest = MessageBuffer.Factory.CreateJson( + new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }, _options); + + var addIntentListenerResult = await _messageRouter.InvokeAsync(Fdc3Topic.AddIntentListener, addIntentListenerRequest); + addIntentListenerResult.Should().NotBeNull(); + + var addIntentListenerResponse = addIntentListenerResult!.ReadJson(_options); + addIntentListenerResponse!.Stored.Should().BeTrue(); + + var app4 = _runningApps.First(application => application.Manifest.Id == "appId4"); + var app4Fdc3InstanceId = Fdc3InstanceIdRetriever.Get(app4); + app4Fdc3InstanceId.Should().Be(raiseIntentResult!.ReadJson(_options)!.AppMetadata!.First().InstanceId); + } + + [Fact] + public async Task AddIntentListenerSubscribesWithNewApp() + { + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _moduleLoader.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var addIntentListenerRequest = MessageBuffer.Factory.CreateJson( + new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }, _options); + + var addIntentListenerResult = await _messageRouter.InvokeAsync(Fdc3Topic.AddIntentListener, addIntentListenerRequest); + addIntentListenerResult.Should().NotBeNull(); + + var addIntentListenerResponse = addIntentListenerResult!.ReadJson(_options); + addIntentListenerResponse!.Stored.Should().BeTrue(); + } + + [Fact] + public async Task AddIntentListenerUnsubscribes() + { + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _moduleLoader.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var addIntentListenerRequest = MessageBuffer.Factory.CreateJson( + new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }, _options); + + var addIntentListenerResult = await _messageRouter.InvokeAsync(Fdc3Topic.AddIntentListener, addIntentListenerRequest); + addIntentListenerResult.Should().NotBeNull(); + + var addIntentListnerResponse = addIntentListenerResult!.ReadJson(_options); + addIntentListnerResponse!.Stored.Should().BeTrue(); + + addIntentListenerRequest = MessageBuffer.Factory.CreateJson( + new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Unsubscribe + }, _options); + + addIntentListenerResult = await _messageRouter.InvokeAsync(Fdc3Topic.AddIntentListener, addIntentListenerRequest); + addIntentListenerResult.Should().NotBeNull(); + + addIntentListnerResponse = addIntentListenerResult!.ReadJson(_options); + addIntentListnerResponse!.Stored.Should().BeFalse(); + addIntentListnerResponse!.Error.Should().BeNull(); + } + private int _counter = 0; private MessageBuffer EmptyContextType => MessageBuffer.Factory.CreateJson(new GetCurrentContextRequest()); private MessageBuffer ContextType => - MessageBuffer.Factory.CreateJson(new GetCurrentContextRequest {ContextType = new Contact().Type}); + MessageBuffer.Factory.CreateJson(new GetCurrentContextRequest { ContextType = new Contact().Type }); private MessageBuffer OtherContextType => - MessageBuffer.Factory.CreateJson(new GetCurrentContextRequest {ContextType = new Email(null).Type}); + MessageBuffer.Factory.CreateJson(new GetCurrentContextRequest { ContextType = new Email(null).Type }); private MessageBuffer GetContext() => MessageBuffer.Factory.CreateJson( new Contact( - new ContactID() {Email = $"test{_counter}@test.org", FdsId = $"test{_counter++}"}, + new ContactID() { Email = $"test{_counter}@test.org", FdsId = $"test{_counter++}" }, "Testy Tester")); private MessageBuffer FindRequest => MessageBuffer.Factory.CreateJson( - new FindChannelRequest {ChannelId = TestChannel, ChannelType = ChannelType.User}); + new FindChannelRequest { ChannelId = TestChannel, ChannelType = ChannelType.User }); private MessageBuffer FindNonExistingRequest => MessageBuffer.Factory.CreateJson( - new FindChannelRequest {ChannelId = "nonexisting", ChannelType = ChannelType.User}); + new FindChannelRequest { ChannelId = "nonexisting", ChannelType = ChannelType.User }); } } \ No newline at end of file diff --git a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Fdc3DesktopAgentTests.cs b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Fdc3DesktopAgentTests.cs index b92f456da..f9dc4fec3 100644 --- a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Fdc3DesktopAgentTests.cs +++ b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Fdc3DesktopAgentTests.cs @@ -12,31 +12,590 @@ * and limitations under the License. */ -using Microsoft.Extensions.Logging.Abstractions; -using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; + +using MorganStanley.ComposeUI.Fdc3.AppDirectory; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.TestUtils; +using MorganStanley.Fdc3.AppDirectory; +using AppMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppMetadata; +using AppIntent = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIntent; +using AppIdentifier = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIdentifier; using MorganStanley.ComposeUI.Fdc3.DesktopAgent.DependencyInjection; +using Microsoft.Extensions.Logging.Abstractions; using MorganStanley.Fdc3; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; +using MorganStanley.Fdc3.Context; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.Helpers; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; +using MorganStanley.ComposeUI.ModuleLoader; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests; public class Fdc3DesktopAgentTests { - private Fdc3DesktopAgent _fdc3 = new Fdc3DesktopAgent( - new Fdc3DesktopAgentOptions(), - new Mock().Object, - NullLoggerFactory.Instance); - private const string TestChannel = "testChannel"; + private readonly MockModuleLoader _mockModuleLoader = new(); + private readonly IAppDirectory _appDirectory = new AppDirectory.AppDirectory( + new AppDirectoryOptions() + { + Source = new Uri($"file:\\\\{Directory.GetCurrentDirectory()}\\TestUtils\\appDirectorySample.json") + }); + private readonly IFdc3DesktopAgentBridge _fdc3; + + + public Fdc3DesktopAgentTests() + { + _fdc3 = new Fdc3DesktopAgent(_appDirectory, _mockModuleLoader.Object, new Fdc3DesktopAgentOptions(), NullLoggerFactory.Instance); + } + + [Fact] + public async Task AddUserChannel_wont_throw_and_adds_channel() + { + var mockMessageService = new Mock(); + mockMessageService.Setup(_ => _.ConnectAsync(It.IsAny())) + .Returns((CancellationToken cancellationToken) => ValueTask.CompletedTask); + + var mockUserChannel = new Mock( + "test", + mockMessageService.Object, + NullLogger.Instance); + + var action = async () => await _fdc3.AddUserChannel(mockUserChannel.Object); + await action.Should().NotThrowAsync(); + + var channelExists = _fdc3.FindChannel("test", ChannelType.User); + channelExists.Should().BeTrue(); + } + + [Fact] + public void FindChannel_returns_false() + { + var result = _fdc3.FindChannel("testChannelId", ChannelType.User); + result.Should().BeFalse(); + } [Fact] - public async void UserChannelAddedCanBeFound() + public async Task FindChannel_returns_true() { - await _fdc3.AddUserChannel(TestChannel); + var mockMessageService = new Mock(); + mockMessageService.Setup(_ => _.ConnectAsync(It.IsAny())) + .Returns((CancellationToken cancellationToken) => ValueTask.CompletedTask); - var result = await _fdc3.FindChannel(Fdc3Topic.FindChannel, FindTestChannel, new MessageContext()); + var mockUserChannel = new Mock( + "testChannelId", + mockMessageService.Object, + NullLogger.Instance); + await _fdc3.AddUserChannel(mockUserChannel.Object); + var result = _fdc3.FindChannel("testChannelId", ChannelType.User); + result.Should().BeTrue(); + } + + [Fact] + public async Task FindIntent_returns_NoAppsFound() + { + var request = new FindIntentRequest() + { + Intent = "testIntent", + Fdc3InstanceId = Guid.NewGuid().ToString() + }; + + var result = await _fdc3.FindIntent(request); + result.Should().NotBeNull(); + result.Error.Should().Be(ResolveError.NoAppsFound); + } + + [Fact] + public async Task FindIntent_returns_IntentDeliveryFailed() + { + var request = new FindIntentRequest() + { + Intent = "intentMetadata8", //wrongly setup MockAppDirectory in purpose + Fdc3InstanceId = Guid.NewGuid().ToString() + }; + + var result = await _fdc3.FindIntent(request); + result.Should().NotBeNull(); + result.Error.Should().Be(ResolveError.IntentDeliveryFailed); + } + + [Fact] + public async Task FindIntent_returns() + { + var request = new FindIntentRequest() + { + Intent = "intentMetadata4", + Context = new Context("context2"), + ResultType = "resultType", + Fdc3InstanceId = Guid.NewGuid().ToString() + }; + + var result = await _fdc3.FindIntent(request); result.Should().NotBeNull(); - result.ReadJson().Should().BeEquivalentTo(FindChannelResponse.Success); + result.AppIntent.Should().BeEquivalentTo( + new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata4", DisplayName = "displayName4" }, + Apps = new[] + { + new AppMetadata() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new AppMetadata() { AppId = "appId6", Name = "app6", ResultType = "resultType"}, + } + }); } - private MessageBuffer FindTestChannel => MessageBuffer.Factory.CreateJson(new FindChannelRequest() { ChannelId = "testChannel", ChannelType = ChannelType.User }); + [Fact] + public async Task FindIntentsByContext_returns_NoAppsFound() + { + var request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("context9"), //This relates to multiple appId + ResultType = "noAppShouldReturn" + }; + var result = await _fdc3.FindIntentsByContext(request); + result.Should().NotBeNull(); + result.Error.Should().Be(ResolveError.NoAppsFound); + } + + [Fact] + public async Task FindIntentsByContext_returns() + { + var request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context(ContextTypes.Nothing), + ResultType = "resultWrongApp" + }; + + var result = await _fdc3.FindIntentsByContext(request); + result.Should().NotBeNull(); + + result.AppIntents.Should().BeEquivalentTo( + new[] + { + new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata9", DisplayName = "displayName9" }, + Apps = new [] + { + new AppMetadata() { AppId = "wrongappId9", Name = "app9", ResultType = "resultWrongApp" }, + } + }, + + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata11", DisplayName = "displayName11" }, + Apps = new [] + { + new AppMetadata() { AppId = "appId12", Name = "app12", ResultType = "resultWrongApp" } + } + }, + }); + } + + [Fact] + public async Task GetIntentResult_returns() + { + await _fdc3.StartAsync(CancellationToken.None); + + var originFdc3InstanceId = Guid.NewGuid().ToString(); + var context = new Context("test"); + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = + new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResponse = await _fdc3.RaiseIntent(raiseIntentRequest); + + raiseIntentResponse.Should().NotBeNull(); + raiseIntentResponse!.Response.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResponse.Response.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResponse.Response.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + Context = context + }; + + var storeResult = await _fdc3.StoreIntentResult(storeIntentRequest); + storeResult.Should().NotBeNull(); + + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = raiseIntentResponse.Response.MessageId!, + Intent = "intentMetadata4", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1", InstanceId = raiseIntentResponse.Response.AppMetadata!.First().InstanceId! } + }; + + var result = await _fdc3.GetIntentResult(getIntentResultRequest); + result.Should().NotBeNull(); + result.Context.Should().Be(context); + } + + [Fact] + public async Task GetIntentResult_fails() + { + await _fdc3.StartAsync(CancellationToken.None); + var originFdc3InstanceId = Guid.NewGuid().ToString(); + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var context = new Context("test"); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResponse = await _fdc3.RaiseIntent(raiseIntentRequest); + raiseIntentResponse!.Response.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResponse.Response.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResponse.Response.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + Context = context + }; + + var storeResponse = await _fdc3.StoreIntentResult(storeIntentRequest); + storeResponse.Error.Should().BeNull(); + + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = raiseIntentResponse.Response.MessageId!, + Intent = "dummy", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1", InstanceId = raiseIntentResponse.Response.AppMetadata!.First().InstanceId! }, + Version = "1.0" + }; + + var result = await _fdc3.GetIntentResult(getIntentResultRequest); + result.Should().BeEquivalentTo(new GetIntentResultResponse() { Error = ResolveError.IntentDeliveryFailed }); + } + + [Fact] + public async Task StoreIntentResult_throws() + { + var request = new StoreIntentResultRequest() + { + MessageId = "dummy", + Intent = "dummy", + OriginFdc3InstanceId = Guid.NewGuid().ToString(), + TargetFdc3InstanceId = Guid.NewGuid().ToString(), + ChannelId = "dummyChannelId", + ChannelType = ChannelType.User + }; + + var action = async () => await _fdc3.StoreIntentResult(request); + + await action.Should() + .ThrowAsync(); + } + + [Fact] + public async Task StoreIntentResult_returns() + { + await _fdc3.StartAsync(CancellationToken.None); + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResponse = await _fdc3.RaiseIntent(raiseIntentRequest); + raiseIntentResponse!.Response.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResponse!.Response.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResponse.Response.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = Guid.NewGuid().ToString(), + ChannelId = "dummyChannelId", + ChannelType = ChannelType.User + }; + + var result = await _fdc3.StoreIntentResult(storeIntentRequest); + result.Should().NotBeNull(); + result.Should().BeEquivalentTo(new StoreIntentResultResponse() { Stored = true }); + } + + [Fact] + public async Task AddIntentListener_subscribes() + { + await _fdc3.StartAsync(CancellationToken.None); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _mockModuleLoader.Object.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResponse = await _fdc3.RaiseIntent(raiseIntentRequest); + raiseIntentResponse.Should().NotBeNull(); + raiseIntentResponse!.Response.AppMetadata.Should().HaveCount(1); + raiseIntentResponse!.Response.AppMetadata!.First()!.AppId.Should().Be("appId4"); + raiseIntentResponse!.Response.AppMetadata!.First()!.InstanceId.Should().Be(targetFdc3InstanceId); + raiseIntentResponse!.RaiseIntentResolutionMessages.Should().BeEmpty(); + + var addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }; + + var addIntentListenerResponse = await _fdc3.AddIntentListener(addIntentListenerRequest); + addIntentListenerResponse.Should().NotBeNull(); + + addIntentListenerResponse!.Response.Stored.Should().BeTrue(); + addIntentListenerResponse!.RaiseIntentResolutionMessages.Should().NotBeEmpty(); + } + + [Fact] + public async Task AddIntentListener_unsubscribes() + { + await _fdc3.StartAsync(CancellationToken.None); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _mockModuleLoader.Object.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResponse = await _fdc3.RaiseIntent(raiseIntentRequest); + raiseIntentResponse.Should().NotBeNull(); + raiseIntentResponse!.Response.AppMetadata.Should().HaveCount(1); + raiseIntentResponse!.Response.AppMetadata!.First()!.AppId.Should().Be("appId4"); + raiseIntentResponse!.Response.AppMetadata!.First()!.InstanceId.Should().Be(targetFdc3InstanceId); + raiseIntentResponse!.RaiseIntentResolutionMessages.Should().BeEmpty(); + + var addIntentListenerRequest1 = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }; + + var addIntentListenerResponse1 = await _fdc3.AddIntentListener(addIntentListenerRequest1); + addIntentListenerResponse1.Should().NotBeNull(); + addIntentListenerResponse1!.Response.Stored.Should().BeTrue(); + addIntentListenerResponse1!.RaiseIntentResolutionMessages.Should().NotBeEmpty(); + + var addIntentListenerRequest2 = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Unsubscribe + }; + + var addIntentListenerResponse2 = await _fdc3.AddIntentListener(addIntentListenerRequest2); + addIntentListenerResponse2.Should().NotBeNull(); + addIntentListenerResponse2!.Response.Stored.Should().BeFalse(); + addIntentListenerResponse2!.RaiseIntentResolutionMessages.Should().BeEmpty(); + } + + [Fact] + public async Task AddIntentListener_unsubscribe_fails() + { + var addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = Guid.NewGuid().ToString(), + State = SubscribeState.Unsubscribe + }; + + var addIntentListenerResponse = await _fdc3.AddIntentListener(addIntentListenerRequest); + addIntentListenerResponse.Should().NotBeNull(); + addIntentListenerResponse!.Response.Stored.Should().BeFalse(); + addIntentListenerResponse!.RaiseIntentResolutionMessages.Should().BeEmpty(); + addIntentListenerResponse!.Response.Error.Should().Be(Fdc3DesktopAgentErrors.MissingId); + } + + [Fact] + public async Task RaiseIntent_returns_NoAppsFound() + { + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "noAppShouldReturn", + Selected = false, + Context = new Context("context2") + }; + + var result = await _fdc3.RaiseIntent(request); + result.Should().NotBeNull(); + result!.Response.Error.Should().Be(ResolveError.NoAppsFound); + } + + [Fact] + public async Task RaiseIntent_returns_IntentDeliveryFailed() + { + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata8", + Selected = false, + Context = new Context("context7") + }; + + var result = await _fdc3.RaiseIntent(request); + result.Should().NotBeNull(); + result!.Response.Error.Should().Be(ResolveError.IntentDeliveryFailed); + } + + [Fact] + public async Task RaiseIntent_fails_as_request_specifies_error() + { + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "someIntent", + Selected = false, + Error = "Some weird error" + }; + + var result = await _fdc3.RaiseIntent(request); + + result!.Response.Error.Should().Be("Some weird error"); + } + + [Fact] + public async Task RaiseIntent_returns_multiple_apps() + { + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context(ContextTypes.Nothing) + }; + + var result = await _fdc3.RaiseIntent(request); + result.Should().NotBeNull(); + result!.RaiseIntentResolutionMessages.Should().BeEmpty(); + result!.Response!.AppMetadata.Should().HaveCount(3); + result!.Response.AppMetadata.Should().BeEquivalentTo( + new List() + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + }); + } + + [Fact] + public async Task RaiseIntent_fails_as_multiple_AppIntent_found() + { + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata8", //wrongly setup AppDirectory on purpose + Selected = false, + Context = new Context("context7") + }; + + var result = await _fdc3.RaiseIntent(request); + result.Should().NotBeNull(); + result!.Response.Error.Should().Be(ResolveError.IntentDeliveryFailed); + } + + [Fact] + public async Task RaiseIntent_returns_one_running_app() + { + await _fdc3.StartAsync(CancellationToken.None); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _mockModuleLoader.Object.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }; + + var addIntentListnerResponse = await _fdc3.AddIntentListener(addIntentListenerRequest); + addIntentListnerResponse.Should().NotBeNull(); + addIntentListnerResponse!.Response.Stored.Should().BeTrue(); + addIntentListnerResponse.RaiseIntentResolutionMessages.Should().BeEmpty(); + + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var result = await _fdc3.RaiseIntent(request); + + result.Should().NotBeNull(); + result!.Response.AppMetadata.Should().HaveCount(1); + result!.Response.AppMetadata!.First()!.AppId.Should().Be("appId4"); + result!.Response.AppMetadata!.First()!.InstanceId.Should().Be(targetFdc3InstanceId); + result.RaiseIntentResolutionMessages.Should().NotBeEmpty(); + result!.Response!.Intent.Should().Be("intentMetadataCustom"); + result!.RaiseIntentResolutionMessages!.Should().HaveCount(1); + result!.RaiseIntentResolutionMessages!.First().TargetModuleInstanceId.Should().Be(targetFdc3InstanceId); + } } diff --git a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Helpers/Fdc3InstanceIdRetriever.cs b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Helpers/Fdc3InstanceIdRetriever.cs new file mode 100644 index 000000000..61f2712b7 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Helpers/Fdc3InstanceIdRetriever.cs @@ -0,0 +1,41 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; +using MorganStanley.ComposeUI.ModuleLoader; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.Helpers; + +internal static class Fdc3InstanceIdRetriever +{ + public static string Get(IModuleInstance instance) + { + var fdc3InstanceId = instance.StartRequest.Parameters.FirstOrDefault(parameter => parameter.Key == Fdc3StartupParameters.Fdc3InstanceId); + if (string.IsNullOrEmpty(fdc3InstanceId.Value)) + { + if (instance.GetProperties().FirstOrDefault(property => property is Fdc3StartupProperties) is not Fdc3StartupProperties fdc3StartupProperties) + { + throw ThrowHelper.MissingFdc3InstanceId(instance.Manifest.Id); + } + else + { + return fdc3StartupProperties.InstanceId; + } + } + else + { + return fdc3InstanceId.Value; + } + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.Tests.cs b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.Tests.cs new file mode 100644 index 000000000..83fc1b419 --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.Tests.cs @@ -0,0 +1,1444 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Extensions.Logging.Abstractions; +using MorganStanley.ComposeUI.Fdc3.AppDirectory; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Contracts; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Converters; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.DependencyInjection; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Exceptions; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.Helpers; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.TestUtils; +using MorganStanley.ComposeUI.ModuleLoader; +using MorganStanley.Fdc3; +using MorganStanley.Fdc3.AppDirectory; +using MorganStanley.Fdc3.Context; +using IntentMetadata = MorganStanley.Fdc3.AppDirectory.IntentMetadata; +using AppMetadata = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppMetadata; +using AppIntent = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIntent; +using AppIdentifier = MorganStanley.ComposeUI.Fdc3.DesktopAgent.Protocol.AppIdentifier; +using MorganStanley.ComposeUI.Fdc3.DesktopAgent.Infrastructure.Internal; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.Infrastructure.Internal; + +public class Fdc3DesktopAgentMessageRouterServiceTests +{ + private readonly Mock _mockMessageRouter = new(); + private readonly MockModuleLoader _mockModuleLoader = new(); + private readonly IAppDirectory _appDirectory = new AppDirectory.AppDirectory( + new AppDirectoryOptions() + { + Source = new Uri($"file:\\\\{Directory.GetCurrentDirectory()}\\TestUtils\\appDirectorySample.json") + }); + + private readonly Fdc3DesktopAgentMessageRouterService _fdc3; + private const string TestChannel = "testChannel"; + + public Fdc3DesktopAgentMessageRouterServiceTests() + { + _fdc3 = new( + _mockMessageRouter.Object, + new Fdc3DesktopAgent(_appDirectory, _mockModuleLoader.Object, new Fdc3DesktopAgentOptions(), NullLoggerFactory.Instance), + new Fdc3DesktopAgentOptions(), + NullLoggerFactory.Instance); + } + + [Fact] + public async void UserChannelAddedCanBeFound() + { + await _fdc3.HandleAddUserChannel(TestChannel); + + var result = await _fdc3.HandleFindChannel(FindTestChannel, new MessageContext()); + + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(FindChannelResponse.Success); + } + + [Fact] + public async Task RaiseIntent_returns_one_app_by_AppIdentifier() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4" } + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + + result!.AppMetadata.Should().HaveCount(1); + result!.AppMetadata!.First()!.AppId.Should().Be("appId4"); + result!.AppMetadata!.First()!.InstanceId.Should().NotBeNull(); + } + + [Fact] + public async Task RaiseIntent_fails_by_request_delivery_error() + { + var result = await _fdc3.HandleRaiseIntent(null, new MessageContext()); + + result.Should().NotBeNull(); + result!.Error.Should().Be(ResolveError.IntentDeliveryFailed); + } + + [Fact] + public async Task RaiseIntent_returns_one_app_by_Context() + { + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom") + }; + + var result = await _fdc3.HandleRaiseIntent(request, new MessageContext()); + + result.Should().NotBeNull(); + + result!.AppMetadata.Should().HaveCount(1); + result!.AppMetadata!.First()!.AppId.Should().Be("appId4"); + result!.AppMetadata!.First()!.InstanceId.Should().NotBeNull(); + } + + [Fact] + public async Task RaiseIntent_returns_one_app_by_AppIdentifier_and_saves_context_to_resolve_it_when_registers_its_intentHandler() + { + await _fdc3.StartAsync(CancellationToken.None); + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var instance = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(instance); + + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var result = await _fdc3.HandleRaiseIntent(request, new MessageContext()); + + result.Should().NotBeNull(); + + result!.AppMetadata.Should().HaveCount(1); + result!.AppMetadata!.First()!.AppId.Should().Be("appId4"); + result!.AppMetadata!.First()!.InstanceId.Should().Be(targetFdc3InstanceId); + + _mockMessageRouter.Verify( + _ => _.InvokeAsync(Fdc3Topic.AddIntentListener, It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); + + _mockMessageRouter.Verify( + _ => _.InvokeAsync(Fdc3Topic.RaiseIntentResolution("intentMetadataCustom", targetFdc3InstanceId), It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); + } + + [Fact] + public async Task RaiseIntent_returns_one_app_by_AppIdentifier_and_publishes_context_to_resolve_it_when_registers_its_intentHandler() + { + await _fdc3.StartAsync(CancellationToken.None); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _mockModuleLoader.Object.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }; + + var addIntentListenerResult = await _fdc3.HandleAddIntentListener(addIntentListenerRequest, new MessageContext()); + addIntentListenerResult.Should().NotBeNull(); + + addIntentListenerResult!.Stored.Should().BeTrue(); + + var request = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var result = await _fdc3.HandleRaiseIntent(request, new MessageContext()); + result.Should().NotBeNull(); + + result!.AppMetadata.Should().HaveCount(1); + result!.AppMetadata!.First()!.AppId.Should().Be("appId4"); + result!.AppMetadata!.First()!.InstanceId.Should().Be(targetFdc3InstanceId); + + _mockMessageRouter.Verify( + _ => _.PublishAsync(Fdc3Topic.RaiseIntentResolution("intentMetadataCustom", targetFdc3InstanceId), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + } + + [Fact] + public async Task RaiseIntent_returns_multiple_apps_by_Context() + { + var instanceId = Guid.NewGuid().ToString(); + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = instanceId, + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2") + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + + result!.AppMetadata.Should().HaveCount(3); + result!.AppMetadata.Should().BeEquivalentTo( + new List() + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + }); + } + + [Fact] + public async Task RaiseIntent_returns_multiple_apps_by_Context_if_fdc3_nothing() + { + var instanceId = Guid.NewGuid().ToString(); + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = instanceId, + Intent = "intentMetadata4", + Selected = false, + Context = new Context(ContextTypes.Nothing) + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + + result!.AppMetadata.Should().HaveCount(3); + result!.AppMetadata.Should().BeEquivalentTo( + new List() + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + }); + } + + [Fact] + public async Task RaiseIntent_fails_as_no_apps_found_by_AppIdentifier() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "testIntent", + Selected = false, + Context = new Context("contextType"), + TargetAppIdentifier = new AppIdentifier() { AppId = "noAppShouldReturn" } + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Error.Should().Be(ResolveError.NoAppsFound); + } + + [Fact] + public async Task RaiseIntent_fails_as_no_apps_found_by_Context() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("noAppShouldReturn") + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + + result.Should().NotBeNull(); + result!.Error.Should().Be(ResolveError.NoAppsFound); + } + + [Fact] + public async Task RaiseIntent_fails_as_no_apps_found_by_Intent() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "noAppShouldReturn", + Selected = false, + Context = new Context("context2") + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + + result.Should().NotBeNull(); + result!.Error.Should().Be(ResolveError.NoAppsFound); + } + + [Fact] + public async Task RaiseIntent_fails_as_multiple_IAppIntents_found() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata8", + Selected = false, + Context = new Context("context7") + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + + result.Should().NotBeNull(); + result!.Error.Should().Be(ResolveError.IntentDeliveryFailed); + } + + [Fact] + public async Task RaiseIntent_fails_as_request_specifies_error() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "someIntent", + Selected = false, + Error = "Some weird error" + }; + + var result = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + + result!.Error.Should().Be("Some weird error"); + } + + [Fact] + public async Task StoreIntentResult_fails_due_the_request() + { + var result = await _fdc3.HandleStoreIntentResult(null, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new StoreIntentResultResponse() { Error = ResolveError.IntentDeliveryFailed, Stored = false }); + } + + [Fact] + public async Task StoreIntentResult_fails_due_the_request_contains_no_information() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4" } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "dummy", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = null, + ChannelId = "dummyChannelId", + ChannelType = ChannelType.User, + }; + + var result = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new StoreIntentResultResponse() { Error = ResolveError.IntentDeliveryFailed, Stored = false }); + } + + [Fact] + public async Task StoreIntentResult_fails_due_the_previosly_no_saved_raiseIntent_could_handle() + { + var originFdc3InstanceId = Guid.NewGuid().ToString(); + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = "dummy", + Intent = "dummy", + OriginFdc3InstanceId = originFdc3InstanceId, + TargetFdc3InstanceId = Guid.NewGuid().ToString(), + ChannelId = "dummyChannelId", + ChannelType = ChannelType.User + }; + + var action = async () => await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + + await action.Should() + .ThrowAsync(); + } + + [Fact] + public async Task StoreIntentResult_succeeds_with_channel() + { + await _fdc3.StartAsync(CancellationToken.None); + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult!.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = Guid.NewGuid().ToString(), + ChannelId = "dummyChannelId", + ChannelType = ChannelType.User + }; + + var result = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new StoreIntentResultResponse() { Stored = true }); + } + + [Fact] + public async Task StoreIntentResult_succeeds_with_context() + { + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = true, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4" } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = Guid.NewGuid().ToString(), + ChannelId = null, + ChannelType = null, + Context = new Context("test") + }; + + var result = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new StoreIntentResultResponse() { Stored = true }); + } + + [Fact] + public async Task StoreIntentResult_succeeds_with_voidResult() + { + await _fdc3.StartAsync(CancellationToken.None); + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = Guid.NewGuid().ToString(), + ChannelId = null, + ChannelType = null, + Context = null, + VoidResult = true + }; + + var result = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new StoreIntentResultResponse() { Stored = true }); + } + + [Fact] + public async Task GetIntentResult_fails_due_the_request() + { + var result = await _fdc3.HandleGetIntentResult(null, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new GetIntentResultResponse() { Error = ResolveError.IntentDeliveryFailed }); + } + + [Fact] + public async Task GetIntentResult_fails_intent_not_found() + { + //Version should be the Intent's schema version + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = "dummy", + Intent = "dummy", + TargetAppIdentifier = new AppIdentifier() { AppId = "dummy", InstanceId = Guid.NewGuid().ToString() }, + Version = "1.0" + }; + + var result = await _fdc3.HandleGetIntentResult(getIntentResultRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new GetIntentResultResponse() { Error = ResolveError.IntentDeliveryFailed }); + } + + [Fact] + public async Task GetIntentResult_fails_due_InstanceId_is_null() + { + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = "dummy", + Intent = "dummy", + TargetAppIdentifier = new AppIdentifier() { AppId = "dummy" }, + Version = "1.0" + }; + + var result = await _fdc3.HandleGetIntentResult(getIntentResultRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new GetIntentResultResponse() { Error = ResolveError.IntentDeliveryFailed }); + } + + [Fact] + public async Task GetIntentResult_fails_due_no_intent_found() + { + await _fdc3.StartAsync(CancellationToken.None); + var originFdc3InstanceId = Guid.NewGuid().ToString(); + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var context = new Context("test"); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + Context = context + }; + + var storeResult = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + storeResult.Should().NotBeNull(); + storeResult!.Should().BeEquivalentTo(StoreIntentResultResponse.Success()); + + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "dummy", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1", InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId! }, + Version = "1.0" + }; + + var result = await _fdc3.HandleGetIntentResult(getIntentResultRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(new GetIntentResultResponse() { Error = ResolveError.IntentDeliveryFailed }); + } + + [Fact] + public async Task GetIntentResult_succeeds_with_context() + { + await _fdc3.StartAsync(CancellationToken.None); + var originFdc3InstanceId = Guid.NewGuid().ToString(); + var context = new Context("test"); + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + Context = context + }; + + var storeResult = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + + storeResult.Should().NotBeNull(); + storeResult!.Should().BeEquivalentTo(StoreIntentResultResponse.Success()); + + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1", InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId! } + }; + + var result = await _fdc3.HandleGetIntentResult(getIntentResultRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(GetIntentResultResponse.Success(context: context)); + } + + [Fact] + public async Task GetIntentResult_succeeds_with_channel() + { + await _fdc3.StartAsync(CancellationToken.None); + var originFdc3InstanceId = Guid.NewGuid().ToString(); + var channelType = ChannelType.User; + var channelId = "dummyChannelId"; + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest =new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + ChannelType = channelType, + ChannelId = channelId + }; + + var storeResult = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + + storeResult.Should().NotBeNull(); + storeResult!.Should().BeEquivalentTo(StoreIntentResultResponse.Success()); + + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1", InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId! } + }; + + var result = await _fdc3.HandleGetIntentResult(getIntentResultRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(GetIntentResultResponse.Success(channelType: channelType, channelId: channelId)); + } + + [Fact] + public async Task GetIntentResult_succeeds_with_voidResult() + { + await _fdc3.StartAsync(CancellationToken.None); + var originFdc3InstanceId = Guid.NewGuid().ToString(); + + var target = await _mockModuleLoader.Object.StartModule(new("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = int.MaxValue, + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Selected = false, + Context = new Context("context2"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + + var storeIntentRequest = new StoreIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + OriginFdc3InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId!, + TargetFdc3InstanceId = originFdc3InstanceId, + VoidResult = true + }; + + var storeResult = await _fdc3.HandleStoreIntentResult(storeIntentRequest, new MessageContext()); + storeResult.Should().NotBeNull(); + storeResult!.Should().BeEquivalentTo(StoreIntentResultResponse.Success()); + + var getIntentResultRequest = new GetIntentResultRequest() + { + MessageId = raiseIntentResult.MessageId!, + Intent = "intentMetadata4", + TargetAppIdentifier = new AppIdentifier() { AppId = "appId1", InstanceId = raiseIntentResult.AppMetadata!.First().InstanceId! } + }; + + var result = await _fdc3.HandleGetIntentResult(getIntentResultRequest, new MessageContext()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(GetIntentResultResponse.Success(voidResult: true)); + } + + [Fact] + public async Task AddIntentListener_fails_due_no_payload() + { + var result = await _fdc3.HandleAddIntentListener(null, new()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(IntentListenerResponse.Failure(Fdc3DesktopAgentErrors.PayloadNull)); + } + + [Fact] + public async Task AddIntentListener_fails_due_missing_id() + { + var request = new IntentListenerRequest() + { + Intent = "dummy", + Fdc3InstanceId = Guid.NewGuid().ToString(), + State = SubscribeState.Unsubscribe + }; + var result = await _fdc3.HandleAddIntentListener(request, new()); + result.Should().NotBeNull(); + result!.Should().BeEquivalentTo(IntentListenerResponse.Failure(Fdc3DesktopAgentErrors.MissingId)); + } + + [Fact] + public async Task AddIntentListener_subscribes_to_existing_raised_intent() + { + await _fdc3.StartAsync(CancellationToken.None); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _mockModuleLoader.Object.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + raiseIntentResult!.AppMetadata!.First()!.AppId.Should().Be("appId4"); + raiseIntentResult!.AppMetadata!.First()!.InstanceId.Should().Be(targetFdc3InstanceId); + + var addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }; + + var addIntentListenerResult = await _fdc3.HandleAddIntentListener(addIntentListenerRequest, new MessageContext()); + addIntentListenerResult.Should().NotBeNull(); + addIntentListenerResult!.Stored.Should().BeTrue(); + + _mockMessageRouter.Verify( + _ => _.PublishAsync(Fdc3Topic.RaiseIntentResolution("intentMetadataCustom", targetFdc3InstanceId), It.IsAny(), It.IsAny(), It.IsAny())); + } + + [Fact] + public async Task AddIntentListener_subscribes() + { + await _fdc3.StartAsync(CancellationToken.None); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _mockModuleLoader.Object.StartModule(new StartRequest("appId1")); + var originFdc3InstanceId = Fdc3InstanceIdRetriever.Get(origin); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }; + + var addIntentListenerResult = await _fdc3.HandleAddIntentListener(addIntentListenerRequest, new MessageContext()); + addIntentListenerResult.Should().NotBeNull(); + addIntentListenerResult!.Stored.Should().BeTrue(); + + var raiseIntentRequest = new RaiseIntentRequest() + { + MessageId = 1, + Fdc3InstanceId = originFdc3InstanceId, + Intent = "intentMetadataCustom", + Selected = false, + Context = new Context("contextCustom"), + TargetAppIdentifier = new AppIdentifier() { AppId = "appId4", InstanceId = targetFdc3InstanceId } + }; + + var raiseIntentResult = await _fdc3.HandleRaiseIntent(raiseIntentRequest, new MessageContext()); + raiseIntentResult.Should().NotBeNull(); + raiseIntentResult!.AppMetadata.Should().HaveCount(1); + raiseIntentResult!.AppMetadata!.First()!.AppId.Should().Be("appId4"); + raiseIntentResult!.AppMetadata!.First()!.InstanceId.Should().Be(targetFdc3InstanceId); + + _mockMessageRouter.Verify( + _ => _.PublishAsync(Fdc3Topic.RaiseIntentResolution("intentMetadataCustom", targetFdc3InstanceId), It.IsAny(), It.IsAny(), It.IsAny())); + } + + [Fact] + public async Task AddIntentListener_unsubscribes() + { + await _fdc3.StartAsync(CancellationToken.None); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var origin = await _mockModuleLoader.Object.StartModule(new StartRequest("appId1")); + + //TODO: should add some identifier to the query => "fdc3:" + instance.Manifest.Id + var target = await _mockModuleLoader.Object.StartModule(new StartRequest("appId4")); + var targetFdc3InstanceId = Fdc3InstanceIdRetriever.Get(target); + + var addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Subscribe + }; + + var addIntentListenerResult = await _fdc3.HandleAddIntentListener(addIntentListenerRequest, new MessageContext()); + addIntentListenerResult.Should().NotBeNull(); + addIntentListenerResult!.Stored.Should().BeTrue(); + + addIntentListenerRequest = new IntentListenerRequest() + { + Intent = "intentMetadataCustom", + Fdc3InstanceId = targetFdc3InstanceId, + State = SubscribeState.Unsubscribe + }; + + addIntentListenerResult = await _fdc3.HandleAddIntentListener(addIntentListenerRequest, new MessageContext()); + addIntentListenerResult.Should().NotBeNull(); + addIntentListenerResult!.Stored.Should().BeFalse(); + addIntentListenerResult!.Error.Should().BeNull(); + } + + private FindChannelRequest FindTestChannel => new FindChannelRequest() { ChannelId = "testChannel", ChannelType = ChannelType.User }; + + + [Theory] + [ClassData(typeof(FindIntentTheoryData))] + public async Task FindIntent_edge_case_tests(FindIntentTestCase testCase) + { + var request = testCase.Request; + var result = await _fdc3.HandleFindIntent(request, new MessageContext()); + + result.Should().NotBeNull(); + + if (testCase.ExpectedAppCount > 0) + { + result!.AppIntent!.Apps.Should().HaveCount(testCase.ExpectedAppCount); + } + + result!.Should().BeEquivalentTo(testCase.ExpectedResponse); + } + + [Theory] + [ClassData(typeof(FindIntentsByContextTheoryData))] + public async Task FindIntentsByContext_edge_case_tests(FindIntentsByContextTestCase testCase) + { + var request = testCase.Request; + var result = await _fdc3.HandleFindIntentsByContext(request, new MessageContext()); + + result.Should().NotBeNull(); + + if (testCase.ExpectedAppIntentsCount > 0) + { + result!.AppIntents!.Should().HaveCount(testCase.ExpectedAppIntentsCount); + } + + result!.Should().BeEquivalentTo(testCase.ExpectedResponse); + } + + public class FindIntentsByContextTheoryData : TheoryData + { + public FindIntentsByContextTheoryData() + { + // Returning one AppIntent with one app by just passing Context + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("contextCustom") + },//This relates to the appId4 only + ExpectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadataCustom", DisplayName = "intentMetadataCustom" }, + Apps = new [] + { + new AppMetadata(){ AppId ="appId4", Name = "app4", ResultType = null } + } + } + } + }, + ExpectedAppIntentsCount = 1 + }); + + // Returning one AppIntent with multiple app by just passing Context + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("context2") + }, //This relates to the appId4, appId5, appId6, + ExpectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata4", DisplayName = "displayName4" }, + Apps = new AppMetadata[] + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + } + } + } + }, + ExpectedAppIntentsCount = 1 + }); + + // Returning multiple appIntent by just passing Context + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("context9") + },//This relates to the wrongappId9 and an another wrongAppId9 with 2 individual IntentMetadata + ExpectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata9", DisplayName = "displayName9" }, + Apps = new [] + { + new AppMetadata() + { + AppId = "wrongappId9", Name = "app9", ResultType = "resultWrongApp" + }, + } + }, + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata10", DisplayName = "displayName10" }, + Apps = new [] + { + new AppMetadata(){ AppId = "appId11", Name = "app11", ResultType = "channel" }, + } + }, + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata11", DisplayName = "displayName11" }, + Apps = new [] + { + new AppMetadata() { AppId = "appId12", Name = "app12", ResultType = "resultWrongApp"}, + } + } + } + }, + ExpectedAppIntentsCount = 3 + }); + + // Returning error no apps found by just passing Context + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("noAppShouldReturn") + },// no app should have this context type + ExpectedResponse = new FindIntentsByContextResponse() + { + Error = ResolveError.NoAppsFound + }, + ExpectedAppIntentsCount = 0 + }); + + // Returning one AppIntent with one app by ResultType + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("context2"), //This relates to multiple appId + ResultType = "resultType" + }, + ExpectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent(){ + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata4", DisplayName = "displayName4" }, // it should just return appId5 + Apps = new [] + { + new AppMetadata(){ AppId = "appId5", Name = "app5", ResultType = "resultType" } + } + } + } + }, + ExpectedAppIntentsCount = 1 + }); + + // Returning one AppIntent with multiple apps by ResultType + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("context2"), //This relates to multiple appId + ResultType = "resultType" + }, + ExpectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata4", DisplayName = "displayName4" }, + Apps = new[] + { + new AppMetadata(){ AppId ="appId5", Name = "app5", ResultType = "resultType" }, + new AppMetadata(){ AppId ="appId6", Name = "app6", ResultType = "resultType" } + } + }, + } + }, + ExpectedAppIntentsCount = 1 + }); + + // Returning multiple AppIntent by ResultType + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("context9"), //This relates to multiple appId + ResultType = "resultWrongApp" + }, + ExpectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata9", DisplayName = "displayName9" }, + Apps = new [] + { + new AppMetadata() { AppId = "wrongappId9", Name = "app9", ResultType = "resultWrongApp" }, + } + }, + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata11", DisplayName = "displayName11" }, + Apps = new [] + { + new AppMetadata() { AppId = "appId12", Name = "app12", ResultType = "resultWrongApp" } + } + } + } + }, + ExpectedAppIntentsCount = 2 + }); + + // Returning no apps found error by using ResultType + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context("context9"), //This relates to multiple appId + ResultType = "noAppShouldReturn" + }, + ExpectedResponse = new FindIntentsByContextResponse() + { + Error = ResolveError.NoAppsFound + }, + ExpectedAppIntentsCount = 0 + }); + + // Returning intent delivery error + AddRow(new FindIntentsByContextTestCase() + { + Request = null, + ExpectedResponse = new FindIntentsByContextResponse() + { + Error = ResolveError.IntentDeliveryFailed + }, + ExpectedAppIntentsCount = 0 + }); + + // Returning all the apps that are using the ResultType by adding fdc3.nothing. + AddRow(new FindIntentsByContextTestCase() + { + Request = new FindIntentsByContextRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Context = new Context(ContextTypes.Nothing), + ResultType = "resultWrongApp" + }, + ExpectedResponse = new FindIntentsByContextResponse() + { + AppIntents = new[] + { + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata9", DisplayName = "displayName9" }, + Apps = new [] + { + new AppMetadata() { AppId = "wrongappId9", Name = "app9", ResultType = "resultWrongApp" }, + } + }, + + new AppIntent() + { + Intent = new Protocol.IntentMetadata () { Name = "intentMetadata11", DisplayName = "displayName11" }, + Apps = new [] + { + new AppMetadata() { AppId = "appId12", Name = "app12", ResultType = "resultWrongApp" } + } + }, + } + }, + ExpectedAppIntentsCount = 2 + }); + } + } + + public class FindIntentsByContextTestCase + { + internal FindIntentsByContextRequest Request { get; set; } + internal FindIntentsByContextResponse ExpectedResponse { get; set; } + public int ExpectedAppIntentsCount { get; set; } + } + + private class FindIntentTheoryData : TheoryData + { + public FindIntentTheoryData() + { + //As per the documentation : https://github.com/morganstanley/fdc3-dotnet/blob/main/src/Fdc3/IIntentMetadata.cs + //name is unique for the intents, so it should be unique for every app, or the app should have the same intentMetadata? + //if so we should return multiple appIntents and do not return error message for the client. + //We have setup a test case for wrongappId9 which contains wrongly setted up intentMetadata. + AddRow( + new FindIntentTestCase() + { + ExpectedAppCount = 0, + ExpectedResponse = new FindIntentResponse() + { + Error = ResolveError.IntentDeliveryFailed + }, + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata8" + } + }); + + AddRow( + new FindIntentTestCase() + { + ExpectedAppCount = 0, + ExpectedResponse = new FindIntentResponse() + { + Error = ResolveError.NoAppsFound + }, + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata2", + Context = new Context("noAppShouldBeReturned") + } + }); + + AddRow( + new FindIntentTestCase() + { + ExpectedAppCount = 0, + ExpectedResponse = new FindIntentResponse() + { + Error = ResolveError.IntentDeliveryFailed + }, + Request = null + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata7", + Context = new Context("context8"), + ResultType = "resultType2" + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadat7", DisplayName = "displayName7" }, + Apps = new[] + { + new AppMetadata(){ AppId = "appId7", Name = "app7", ResultType = "resultType2" } + } + } + }, + ExpectedAppCount = 1 + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Context = new Context("context2"), + ResultType = "resultType" + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata4", DisplayName = "displayName4" }, + Apps = new[] + { + new AppMetadata() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new AppMetadata() { AppId = "appId6", Name = "app6", ResultType = "resultType"}, + + } + } + }, + ExpectedAppCount = 2 + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata7", + ResultType = "resultType2" + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadat7", DisplayName = "displayName7" }, + Apps = new[] + { + new AppMetadata() { AppId = "appId7", Name = "app7", ResultType = "resultType2"} + } + } + }, + ExpectedAppCount = 1 + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + ResultType = "resultType" + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata4", DisplayName = "displayName4" }, + Apps = new[] + { + new AppMetadata() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new AppMetadata() { AppId = "appId6", Name = "app6", ResultType = "resultType" }, + } + } + }, + ExpectedAppCount = 2 + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata1", + Context = new Context("context1") + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata1", DisplayName = "displayName1" }, + Apps = new[] + { + new AppMetadata() { AppId = "appId1", Name = "app1", ResultType = null } + } + } + }, + ExpectedAppCount = 1 + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4", + Context = new Context("context2") + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata4", DisplayName = "displayName4" }, + Apps = new AppMetadata[] + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + } + } + }, + ExpectedAppCount = 3 + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata2" + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata2", DisplayName = "displayName2" }, + Apps = new[] + { + new AppMetadata() { AppId = "appId2", Name = "app2", ResultType = null } + } + } + }, + ExpectedAppCount = 1 + }); + + AddRow(new FindIntentTestCase() + { + Request = new FindIntentRequest() + { + Fdc3InstanceId = Guid.NewGuid().ToString(), + Intent = "intentMetadata4" + }, + ExpectedResponse = new FindIntentResponse() + { + AppIntent = new AppIntent() + { + Intent = new Protocol.IntentMetadata() { Name = "intentMetadata4", DisplayName = "displayName4" }, + Apps = new AppMetadata[] + { + new() { AppId = "appId4", Name = "app4", ResultType = null }, + new() { AppId = "appId5", Name = "app5", ResultType = "resultType" }, + new() { AppId = "appId6", Name = "app6", ResultType = "resultType" } + } + } + }, + ExpectedAppCount = 3 + }); + } + } + + public class FindIntentTestCase + { + internal FindIntentRequest Request { get; set; } + internal FindIntentResponse ExpectedResponse { get; set; } + public int ExpectedAppCount { get; set; } + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/MockModuleLoader.cs b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/MockModuleLoader.cs new file mode 100644 index 000000000..0285c3ade --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/MockModuleLoader.cs @@ -0,0 +1,107 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using System.Reactive.Subjects; +using MorganStanley.ComposeUI.ModuleLoader; + +namespace MorganStanley.ComposeUI.Fdc3.DesktopAgent.Tests.TestUtils; + +public class MockModuleLoader : Mock +{ + public MockModuleLoader() + { + Setup(_ => _.StartModule(It.IsAny())) + .Returns(async(StartRequest startRequest) => await HandleStartRequest(startRequest)); + + Setup(_ => _.StopModule(It.IsAny())) + .Callback(async (StopRequest stopRequest) => await HandleStopRequest(stopRequest)); + + Setup(_ => _.LifetimeEvents) + .Returns(() => LifetimeEvents); + } + + public IObservable LifetimeEvents => _subject; + private List _startRequests = new(); + private readonly object _lock = new(); + private Subject _subject = new(); + + private Task HandleStartRequest(StartRequest startRequest) + { + IModuleInstance instance = new MockModuleInstance( + startRequest, + new MockModuleManifest() { Id = startRequest.ModuleId }); + + lock (_lock) + { + _startRequests.Add(instance); + _subject.OnNext(new LifetimeEvent.Starting(instance)); + _subject.OnNext(new LifetimeEvent.Started(instance)); + } + + return Task.FromResult(instance); + + } + + private Task HandleStopRequest(StopRequest stopRequest) + { + lock (_lock) + { + var instance = _startRequests.FirstOrDefault(inst => inst.InstanceId == stopRequest.InstanceId); + if (instance != null) + { + _startRequests.Remove(instance); + _subject.OnNext(new LifetimeEvent.Stopping(instance)); + _subject.OnNext(new LifetimeEvent.Stopped(instance)); + } + } + + return Task.CompletedTask; + } + + private class MockModuleInstance : IModuleInstance + { + private readonly IModuleManifest _moduleManifest; + private readonly StartRequest _startRequest; + + public Guid InstanceId => _instanceId; + private readonly Guid _instanceId = Guid.NewGuid(); + private readonly string _fdc3InstanceId = Guid.NewGuid().ToString(); + public IModuleManifest Manifest => _moduleManifest; + + public StartRequest StartRequest => _startRequest; + + public IEnumerable GetProperties() + { + return new object[] + { + new Fdc3StartupProperties() { InstanceId = _fdc3InstanceId }, + }; + } + + public MockModuleInstance(StartRequest startRequest, IModuleManifest moduleManifest) + { + _moduleManifest = moduleManifest; + _startRequest = startRequest; + } + } + + private class MockModuleManifest : IModuleManifest + { + public string Id { get; set; } + + public string Name { get; set; } + + public string ModuleType { get; set; } + } +} diff --git a/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/appDirectorySample.json b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/appDirectorySample.json new file mode 100644 index 000000000..4e30d8dcb --- /dev/null +++ b/src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/appDirectorySample.json @@ -0,0 +1,256 @@ +{ + "applications": [ + { + "appId": "appId1", + "name": "app1", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata1": { + "name": "intentMetadata1", + "displayName": "displayName1", + "contexts": [ + "context1" + ] + } + } + } + } + }, + { + "appId": "appId2", + "name": "app2", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata2": { + "name": "intentMetadata2", + "displayName": "displayName2", + "contexts": [ + "dummyContext" + ] + } + } + } + } + }, + { + "appId": "appId3", + "name": "app3", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": {} + } + }, + { + "appId": "appId4", + "name": "app4", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata4": { + "name": "intentMetadata4", + "displayName": "displayName4", + "contexts": [ + "context2" + ] + }, + "intentMetadataCustom": { + "name": "intentMetadataCustom", + "displayName": "intentMetadataCustom", + "contexts": [ + "contextCustom" + ] + } + } + } + } + }, + { + "appId": "appId5", + "name": "app5", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata4": { + "name": "intentMetadata4", + "displayName": "displayName4", + "contexts": [ + "context2", + "context5" + ], + "resultType": "resultType" + } + } + } + } + }, + { + "appId": "appId6", + "name": "app6", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata1": { + "name": "intentMetadata1", + "displayName": "displayName1", + "contexts": [ + "context6" + ], + "resultType": "res66" + }, + "intentMetadata4": { + "name": "intentMetadata4", + "displayName": "displayName4", + "contexts": [ + "context2" + ], + "resultType": "resultType" + } + } + } + } + }, + { + "appId": "appId7", + "name": "app7", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata7": { + "name": "intentMetadat7", + "displayName": "displayName7", + "contexts": [ + "context8" + ], + "resultType": "resultType2" + }, + "intentMetadata8": { + "name": "intentMetadata8", + "displayName": "displayName8", + "contexts": [ + "context7" + ], + "resultType": "resultType2" + } + } + } + } + }, + { + "appId": "appId8", + "name": "app8", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata8": { + "name": "intentMetadat8", + "displayName": "displayName8", + "contexts": [ + "context7" + ], + "resultType": "resultType2" + } + } + } + } + }, + { + "appId": "wrongappId9", + "name": "app9", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata9": { + "name": "intentMetadata9", + "displayName": "displayName9", + "contexts": [ + "context9" + ], + "resultType": "resultWrongApp" + } + } + } + } + }, + { + "appId": "appId11", + "name": "app11", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata10": { + "name": "intentMetadata10", + "displayName": "displayName10", + "contexts": [ + "context9" + ], + "resultType": "channel" + } + } + } + } + }, + { + "appId": "appId12", + "name": "app12", + "type": 1, + "details": { + "url": "http://customurl.com" + }, + "interop": { + "intents": { + "listensFor": { + "intentMetadata10": { + "name": "intentMetadata11", + "displayName": "displayName11", + "contexts": [ + "context9" + ], + "resultType": "resultWrongApp" + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/jest.config.ts b/src/fdc3/js/composeui-fdc3/jest.config.ts index 564bdb3bd..a0805c77f 100644 --- a/src/fdc3/js/composeui-fdc3/jest.config.ts +++ b/src/fdc3/js/composeui-fdc3/jest.config.ts @@ -18,4 +18,6 @@ export default { // A preset that is used as a base for Jest's configuration preset: "ts-jest", + + testEnvironment: "jsdom" }; \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/package.json b/src/fdc3/js/composeui-fdc3/package.json index fd838cfc6..347e6dbab 100644 --- a/src/fdc3/js/composeui-fdc3/package.json +++ b/src/fdc3/js/composeui-fdc3/package.json @@ -11,7 +11,7 @@ "clean": "npm run clean:dist && npm run clean:output", "bundle": "rollup -c", "build": "npm run clean && tsc && npm run bundle", - "test": "jest" + "test": "jest --env=jsdom" }, "author": "Morgan Stanley", "license": "Apache-2.0", @@ -19,16 +19,18 @@ "@finos/fdc3": "^2.0.0", "@morgan-stanley/composeui-messaging-client": "*", "@types/node": "^18.11.18", + "jest-environment-jsdom": "^29.7.0", "rxjs": "^7.8.1" }, "devDependencies": { + "@rollup/plugin-commonjs": "24.0.1", + "@rollup/plugin-node-resolve": "15.0.1", "@types/jest": "^29.4.0", "@types/node": "^18.11.18", "jest": "^29.4.3", + "jsdom": "^22.1.0", "rimraf": "4.1.2", "rollup": "^3.14.0", - "@rollup/plugin-commonjs": "24.0.1", - "@rollup/plugin-node-resolve": "15.0.1", "ts-jest": "29.1.0", "ts-node": "10.9.1", "tslib": "^2.4.0", diff --git a/src/fdc3/js/composeui-fdc3/src/ComposeUIDesktopAgent.ts b/src/fdc3/js/composeui-fdc3/src/ComposeUIDesktopAgent.ts index 103a6b32e..d8b094b7d 100644 --- a/src/fdc3/js/composeui-fdc3/src/ComposeUIDesktopAgent.ts +++ b/src/fdc3/js/composeui-fdc3/src/ComposeUIDesktopAgent.ts @@ -24,15 +24,38 @@ import { IntentHandler, IntentResolution, Listener, - PrivateChannel -} from '@finos/fdc3' -import { MessageRouter, TopicMessage } from '@morgan-stanley/composeui-messaging-client'; + PrivateChannel, + ResolveError +} from '@finos/fdc3'; + +import { MessageRouter } from '@morgan-stanley/composeui-messaging-client'; import { ComposeUIChannel } from './infrastructure/ComposeUIChannel'; import { ChannelType } from './infrastructure/ChannelType'; -import { ComposeUIListener } from './infrastructure/ComposeUIListener'; +import { ComposeUIContextListener } from './infrastructure/ComposeUIContextListener'; import { Fdc3FindChannelRequest } from './infrastructure/messages/Fdc3FindChannelRequest'; import { Fdc3FindChannelResponse } from './infrastructure/messages/Fdc3FindChannelResponse'; import { ComposeUITopic } from './infrastructure/ComposeUITopic'; +import { ComposeUIIntentListener } from './infrastructure/ComposeUIIntentListener'; +import { Fdc3RaiseIntentRequest } from './infrastructure/messages/Fdc3RaiseIntentRequest'; +import { ComposeUIIntentResolution } from './infrastructure/ComposeUIIntentResolution'; +import { Fdc3RaiseIntentResponse } from './infrastructure/messages/Fdc3RaiseIntentResponse'; +import { Fdc3FindIntentRequest } from './infrastructure/messages/Fdc3FindIntentRequest'; +import { Fdc3FindIntentResponse } from './infrastructure/messages/Fdc3FindIntentResponse'; +import { Fdc3FindIntentsByContextRequest } from './infrastructure/messages/Fdc3FindIntentsByContextRequest'; +import { Fdc3FindIntentsByContextResponse } from './infrastructure/messages/Fdc3FindIntentsByContextResponse'; +import { ComposeUIErrors } from './infrastructure/ComposeUIErrors'; +import { Fdc3IntentListenerRequest } from './infrastructure/messages/Fdc3IntentListenerRequest'; +import { Fdc3IntentListenerResponse } from './infrastructure/messages/Fdc3IntentListenerResponse'; + +declare global { + interface Window { + composeui: { + fdc3: { + config: AppIdentifier | undefined; + } + } + } +} export class ComposeUIDesktopAgent implements DesktopAgent { private appChannels: ComposeUIChannel[] = []; @@ -40,8 +63,10 @@ export class ComposeUIDesktopAgent implements DesktopAgent { private privateChannels: ComposeUIChannel[] = []; private currentChannel?: ComposeUIChannel; private messageRouterClient: MessageRouter; - private currentChannelListeners: ComposeUIListener[] = []; + private currentChannelListeners: ComposeUIContextListener[] = []; + private intentListeners: ComposeUIIntentListener[] = []; + //TODO: we should enable passing multiple channelId to the ctor. constructor(channelId: string, messageRouterClient: MessageRouter) { this.messageRouterClient = messageRouterClient; const channel = new ComposeUIChannel( @@ -49,21 +74,46 @@ export class ComposeUIDesktopAgent implements DesktopAgent { "user", this.messageRouterClient); this.addChannel(channel); - } + if (!window.composeui.fdc3.config || !window.composeui.fdc3.config.instanceId) throw new Error(ComposeUIErrors.InstanceIdNotFound);} //TODO public open(app?: string | AppIdentifier, context?: Context): Promise { throw new Error("Not implemented"); } - //TODO public findIntent(intent: string, context?: Context, resultType?: string): Promise { - throw new Error("Not implemented"); + return new Promise(async(resolve, reject) => { + const request = new Fdc3FindIntentRequest(window.composeui.fdc3.config!.instanceId!, intent, context, resultType); + const message = await this.messageRouterClient.invoke(ComposeUITopic.findIntent(), JSON.stringify(request)); + if (!message) { + return reject(new Error(ComposeUIErrors.NoAnswerWasProvided)); + } + + const findIntentResponse = JSON.parse(message); + if (findIntentResponse.error) { + return reject(new Error(findIntentResponse.error)); + } + else { + return resolve(findIntentResponse.appIntent!); + } + }); } - //TODO public findIntentsByContext(context: Context, resultType?: string): Promise> { - throw new Error("Not implemented"); + return new Promise(async (resolve, reject) => { + const request = new Fdc3FindIntentsByContextRequest(window.composeui.fdc3.config!.instanceId!, context, resultType); + const message = await this.messageRouterClient.invoke(ComposeUITopic.findIntentsByContext(), JSON.stringify(request)); + if (!message) { + return reject(new Error(ComposeUIErrors.NoAnswerWasProvided)); + } + + const findIntentsByContextResponse = JSON.parse(message); + if (findIntentsByContextResponse.error) { + return reject(new Error(findIntentsByContextResponse.error)); + } + + return resolve(findIntentsByContextResponse.appIntents!); + }); } //TODO @@ -74,16 +124,54 @@ export class ComposeUIDesktopAgent implements DesktopAgent { public broadcast(context: Context): Promise { return new Promise((resolve, reject) => { if (!this.currentChannel) { - reject(new Error("The current channel have not been set.")); + return reject(new Error(ComposeUIErrors.CurrentChannelNotSet)); } else { - resolve(this.currentChannel.broadcast(context)); + return resolve(this.currentChannel.broadcast(context)); } }); } - //TODO public raiseIntent(intent: string, context: Context, app?: string | AppIdentifier): Promise { - throw new Error("Not implemented"); + return new Promise(async(resolve, reject) => { + if (typeof app != 'string') { + const messageId = Math.floor(Math.random() * 10000); + const message = new Fdc3RaiseIntentRequest(messageId, window.composeui.fdc3.config!.instanceId!, intent, false, context, app); + const responseFromService = await this.messageRouterClient.invoke(ComposeUITopic.raiseIntent(), JSON.stringify(message)); + if (!responseFromService) { + return reject(new Error(ComposeUIErrors.NoAnswerWasProvided)); + } + + const response = JSON.parse(responseFromService); + + if (response.error) { + return reject(new Error(response.error)); + } + + if (response.appMetadata!.length <= 1) { + const intentResolution = new ComposeUIIntentResolution(response.messageId, this.messageRouterClient, response.intent!, response.appMetadata![0]); + return resolve(intentResolution); + } else if (response.appMetadata!.length > 1) { + //TODO: integrationtest + //TODO: Now we are just selecting the first item + //TODO: Show window where the user could select the app from response.appMetadatas, right now we are selecting the first item from the list + //TODO: Handle cancel event by sending the ResolveError.UserCancelled error message in the error field + const request = new Fdc3RaiseIntentRequest(messageId, window.composeui.fdc3.config!.instanceId!, intent, true, context, response.appMetadata![0]); + const responseFromServiceSelectedApp = await this.messageRouterClient.invoke(ComposeUITopic.raiseIntent(), JSON.stringify(request)); + if (!responseFromServiceSelectedApp) { + return reject(new Error(ResolveError.ResolverUnavailable)); + } + + const result = JSON.parse(responseFromServiceSelectedApp); + if (result.error) { + return reject(new Error(result.error)); + } + + const intentResolution = new ComposeUIIntentResolution(result.messageId, this.messageRouterClient, result.intent!, result.appMetadata![0]); + return resolve(intentResolution); + } + } + return reject(new Error("Using string type for app argument is not supported. Please use undefined | AppIdentifier types!")); + }); } //TODO @@ -91,24 +179,43 @@ export class ComposeUIDesktopAgent implements DesktopAgent { throw new Error("Not implemented"); } - //TODO public addIntentListener(intent: string, handler: IntentHandler): Promise { - throw new Error("Not implemented"); + return new Promise(async(resolve, reject) => { + const listener = new ComposeUIIntentListener(this.messageRouterClient, intent, window.composeui.fdc3.config!.instanceId!, handler); + await listener.registerIntentHandler(); + + const message = new Fdc3IntentListenerRequest(intent, window.composeui.fdc3.config!.instanceId!, "Subscribe"); + const response = await this.messageRouterClient.invoke(ComposeUITopic.addIntentListener(), JSON.stringify(message)); + if (!response) { + return reject(new Error(ComposeUIErrors.NoAnswerWasProvided)); + } else { + const result = JSON.parse(response); + if (result.error) { + await this.unsubscribe(listener); + return reject(new Error(result.error)); + } else if (!result.stored) { + await this.unsubscribe(listener); + return reject(new Error(ComposeUIErrors.SubscribeFailure)); + } else { + this.intentListeners.push(listener); + return resolve(listener); + } + } + }); } public addContextListener(contextType?: string | null | ContextHandler, handler?: ContextHandler): Promise { - return new Promise(async (resolve, reject) => { + return new Promise(async (resolve, reject) => { if (!this.currentChannel) { - reject(new Error("The current channel have not been set.")); - return; + return reject(new Error(ComposeUIErrors.CurrentChannelNotSet)); } - + if (contextType !=null && typeof contextType != 'string') { handler = contextType; contextType = null; } - const listener = await this.currentChannel!.addContextListener(contextType ?? null, handler!); + const listener = await this.currentChannel!.addContextListener(contextType ?? null, handler!); const resultContext = await this.currentChannel!.getCurrentContext(contextType ?? undefined) listener.latestContext = this.currentChannel!.retrieveCurrentContext(contextType ?? undefined); if (resultContext != listener.latestContext) { @@ -118,7 +225,7 @@ export class ComposeUIDesktopAgent implements DesktopAgent { await listener.handleContextMessage(resultContext); } this.currentChannelListeners.push(listener); - resolve(listener); + return resolve(listener); }); } @@ -130,20 +237,20 @@ export class ComposeUIDesktopAgent implements DesktopAgent { public joinUserChannel(channelId: string): Promise { return new Promise(async (resolve, reject) => { if (this.currentChannel) { - reject(new Error(ChannelError.AccessDenied)); + return reject(new Error(ChannelError.AccessDenied)); } let channel = this.userChannels.find(innerChannel => innerChannel.id == channelId); if (!channel) { try{ await this.invokeChannelCreationMessage(ComposeUITopic.joinUserChannel(), channelId, "user"); - resolve(); + return resolve(); } catch(error) { - reject(error); + return reject(error); } } else { this.currentChannel = channel; - resolve(); + return resolve(); } }); } @@ -183,16 +290,17 @@ export class ComposeUIDesktopAgent implements DesktopAgent { this.currentChannelListeners.forEach(listener => { const isUnsubscribed = listener.unsubscribe(); if (!isUnsubscribed) { - reject(new Error(`Listener couldn't unsubscribe. IsSubscribed: ${isUnsubscribed}, Listener: ${listener}`)); + return reject(new Error(`Listener couldn't unsubscribe. IsSubscribed: ${isUnsubscribed}, Listener: ${listener}`)); } }); this.currentChannelListeners = []; - resolve(); + return resolve(); }); } + //TODO(Lilla): we should ask the backend to give the current appMetadata back public getInfo(): Promise { - return new Promise((resolve) => { + return new Promise(async (resolve, reject) => { const metadata = { fdc3Version: "2.0", provider: "ComposeUI", @@ -220,34 +328,29 @@ export class ComposeUIDesktopAgent implements DesktopAgent { public joinChannel(channelId: string): Promise { return new Promise((resolve, reject) => { if (this.currentChannel) { - reject(new Error(ChannelError.CreationFailed)); - return; + return reject(new Error(ChannelError.CreationFailed)); } let channel = this.findChannel(channelId, "user"); if (channel) { this.currentChannel = channel; - resolve(); - return; + return resolve(); } channel = this.findChannel(channelId, "app"); if (channel) { this.currentChannel = channel; - resolve(); - return; + return resolve(); } channel = this.findChannel(channelId, "private"); if (channel) { this.currentChannel = channel; - resolve(); - return; + return resolve(); } if (!channel) { - reject(new Error(`No channel is found with id: ${channelId}`)); - return; + return reject(new Error(`No channel is found with id: ${channelId}`)); } }); } @@ -290,17 +393,25 @@ export class ComposeUIDesktopAgent implements DesktopAgent { const message = JSON.stringify(new Fdc3FindChannelRequest(channelId, channelType)); const response = await this.messageRouterClient.invoke(topic, message); if(response) { - const message = JSON.parse(response); - if(message.payload) { - const fdc3Message = JSON.parse(message.payload); - if(fdc3Message.error) { - throw new Error(fdc3Message.error); //Type of the message should be created. - } - if (fdc3Message.found){ - this.currentChannel = new ComposeUIChannel(channelId, channelType, this.messageRouterClient); - this.addChannel(this.currentChannel); - } + const fdc3Message = JSON.parse(response); + if(fdc3Message.error) { + throw new Error(fdc3Message.error); + } + if (fdc3Message.found){ + this.currentChannel = new ComposeUIChannel(channelId, channelType, this.messageRouterClient); + this.addChannel(this.currentChannel); } } } + + private async unsubscribe(listener: ComposeUIIntentListener): Promise { + return new Promise(async (resolve, reject) => { + try{ + await listener.unsubscribe(); + } catch(err) { + console.log("Listener could not unsubscribe: ", err); + } + return resolve(); + }); + } } \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/Fdc3ComposeUI.spec.ts b/src/fdc3/js/composeui-fdc3/src/Fdc3ComposeUI.spec.ts index 4e3515f5e..af60d0af8 100644 --- a/src/fdc3/js/composeui-fdc3/src/Fdc3ComposeUI.spec.ts +++ b/src/fdc3/js/composeui-fdc3/src/Fdc3ComposeUI.spec.ts @@ -14,11 +14,16 @@ import { jest } from '@jest/globals'; import { ComposeUIChannel } from './infrastructure/ComposeUIChannel'; import { MessageRouter } from '@morgan-stanley/composeui-messaging-client'; -import { ComposeUIListener } from './infrastructure/ComposeUIListener'; +import { ComposeUIContextListener } from './infrastructure/ComposeUIContextListener'; import { ComposeUIDesktopAgent } from './ComposeUIDesktopAgent'; import { ComposeUITopic } from './infrastructure/ComposeUITopic'; -import { Channel, ChannelError, Context } from '@finos/fdc3'; +import { Channel, ChannelError, Context, IntentHandler } from '@finos/fdc3'; import { Fdc3FindChannelRequest } from './infrastructure/messages/Fdc3FindChannelRequest'; +import { ComposeUIErrors } from './infrastructure/ComposeUIErrors'; +import { Fdc3FindIntentsByContextResponse } from './infrastructure/messages/Fdc3FindIntentsByContextResponse'; +import { Fdc3RaiseIntentResponse } from './infrastructure/messages/Fdc3RaiseIntentResponse'; +import { ComposeUIIntentResolution } from './infrastructure/ComposeUIIntentResolution'; +import { ComposeUIIntentListener } from './infrastructure/ComposeUIIntentListener'; const dummyContext = {type: "dummyContextType"}; const dummyChannelId = "dummyId"; @@ -49,7 +54,7 @@ describe('Tests for ComposeUIChannel implementation API', () => { registerService: jest.fn(() => { return Promise.resolve() }), unregisterService: jest.fn(() => { return Promise.resolve() }), invoke: jest.fn(() => { return Promise.resolve(JSON.stringify(dummyContext))}) - } + }; }); it('broadcast will call messageRouters publish method', async() => { @@ -93,23 +98,23 @@ describe('Tests for ComposeUIChannel implementation API', () => { expect(result).toBe(null); }); - it('addContextListener will result a ComposeUIListener', async() => { + it('addContextListener will result a ComposeUIContextListener', async() => { const testChannel = new ComposeUIChannel(dummyChannelId, "user", messageRouterClient); await testChannel.broadcast(testInstrument); const resultListener = await testChannel.addContextListener('fdc3.instrument', contextMessageHandlerMock); - expect(resultListener).toBeInstanceOf(ComposeUIListener); + expect(resultListener).toBeInstanceOf(ComposeUIContextListener); expect(contextMessageHandlerMock).toHaveBeenCalledTimes(0); //as per the standard }); it('addContextListener will treat contexType is ContextHandler as all types', async() => { const testChannel = new ComposeUIChannel(dummyChannelId, "user", messageRouterClient); const resultListener = await testChannel.addContextListener(test => {}); - expect(resultListener).toBeInstanceOf(ComposeUIListener); + expect(resultListener).toBeInstanceOf(ComposeUIContextListener); expect(messageRouterClient.subscribe).toBeCalledTimes(1); }); }); -describe('Tests for ComposeUIListener implementation API', () => { +describe('Tests for ComposeUIContextListener implementation API', () => { beforeEach(() => { messageRouterClient = { clientId: "dummy", @@ -123,24 +128,24 @@ describe('Tests for ComposeUIListener implementation API', () => { registerService: jest.fn(() => { return Promise.resolve() }), unregisterService: jest.fn(() => { return Promise.resolve() }), invoke: jest.fn(() => { return Promise.resolve(JSON.stringify({context: "", payload: `${JSON.stringify(dummyContext)}` })) }) - } + }; }); it('subscribe will call messagerouter subscribe method', async() => { - const testListener = new ComposeUIListener(messageRouterClient, instrument => { console.log(instrument); }, "dummyChannelId", "user", "fdc3.instrument"); + const testListener = new ComposeUIContextListener(messageRouterClient, instrument => { console.log(instrument); }, "dummyChannelId", "user", "fdc3.instrument"); await testListener.subscribe(); expect(messageRouterClient.subscribe).toHaveBeenCalledTimes(1); }); it('handleContextMessage will trigger the handler', async() => { - const testListener = new ComposeUIListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); + const testListener = new ComposeUIContextListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); await testListener.subscribe(); await testListener.handleContextMessage(testInstrument); expect(contextMessageHandlerMock).toHaveBeenCalledWith(testInstrument); }); - it('handleContextMessage will resolve the LatestContext saved for ComposeUIListener', async() => { - const testListener = new ComposeUIListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); + it('handleContextMessage will resolve the LatestContext saved for ComposeUIContextListener', async() => { + const testListener = new ComposeUIContextListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); await testListener.subscribe(); testListener.latestContext = testInstrument; await testListener.handleContextMessage(); @@ -148,28 +153,28 @@ describe('Tests for ComposeUIListener implementation API', () => { }); it('handleContextMessage will resolve an empty context', async() => { - const testListener = new ComposeUIListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); + const testListener = new ComposeUIContextListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); await testListener.subscribe(); await testListener.handleContextMessage(); expect(contextMessageHandlerMock).toHaveBeenCalledWith({type: ""}); }); it('handleContextMessage will be rejected with Error as no handler', async() => { - const testListener = new ComposeUIListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); + const testListener = new ComposeUIContextListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); await expect(testListener.handleContextMessage(testInstrument)) .rejects .toThrow("The current listener is not subscribed."); }); it('unsubscribe will be true', async() => { - const testListener = new ComposeUIListener(messageRouterClient, contextMessageHandlerMock, "dummyChannelId", "user", "fdc3.instrument"); + const testListener = new ComposeUIContextListener(messageRouterClient, contextMessageHandlerMock, "dummyChannelId", "user", "fdc3.instrument"); await testListener.subscribe(); const resultUnsubscription = testListener.unsubscribe(); expect(resultUnsubscription).toBeTruthy(); }); it('unsubscribe will be false', async() => { - const testListener = new ComposeUIListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); + const testListener = new ComposeUIContextListener(messageRouterClient, contextMessageHandlerMock, "", "user", "fdc3.instrument"); const resultUnsubscription = testListener.unsubscribe(); expect(resultUnsubscription).toBeFalsy(); }); @@ -190,7 +195,22 @@ describe('Tests for ComposeUIDesktopAgent implementation API', () => { registerService: jest.fn(() => { return Promise.resolve() }), unregisterService: jest.fn(() => { return Promise.resolve() }), invoke: jest.fn(() => { return Promise.resolve(JSON.stringify({context: "", payload: `${JSON.stringify(dummyContext)}` })) }) - } + }; + + window.composeui = { + fdc3: { + config: { + appId: "testAppId", + instanceId: "testInstanceId" + } + } + }; + }); + + it('ComposeUIDesktoAgent could not be created as no instanceId found on window object', async() => { + window.composeui.fdc3.config = undefined; + expect(() => new ComposeUIDesktopAgent("dummyPath", messageRouterClient)) + .toThrowError(ComposeUIErrors.InstanceIdNotFound); }); it('broadcast will trigger publish method of the messageRouter', async() => { @@ -213,7 +233,7 @@ describe('Tests for ComposeUIDesktopAgent implementation API', () => { await testDesktopAgent.joinUserChannel("dummyPath"); await testDesktopAgent.broadcast(testInstrument); //this will set the last context const resultListener = await testDesktopAgent.addContextListener("fdc3.instrument", contextMessageHandlerMock); - expect(resultListener).toBeInstanceOf(ComposeUIListener); + expect(resultListener).toBeInstanceOf(ComposeUIContextListener); expect(messageRouterClient.subscribe).toBeCalledTimes(1); }); @@ -229,7 +249,7 @@ describe('Tests for ComposeUIDesktopAgent implementation API', () => { const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClient); await testDesktopAgent.joinUserChannel("dummyPath"); var resultListener = await testDesktopAgent.addContextListener(contextMessageHandlerMock) - expect(resultListener).toBeInstanceOf(ComposeUIListener); + expect(resultListener).toBeInstanceOf(ComposeUIContextListener); expect(messageRouterClient.subscribe).toBeCalledTimes(1); }); @@ -253,27 +273,6 @@ describe('Tests for ComposeUIDesktopAgent implementation API', () => { expect(messageRouterClient.invoke).toHaveBeenCalledWith(ComposeUITopic.joinUserChannel(), JSON.stringify(new Fdc3FindChannelRequest("dummyPath2", "user"))); }); - it('joinUserChannel will throw the error from the response of the invoke method', async() => { - const messageRouterClientMock = { - clientId: "dummy", - subscribe: jest.fn(() => { - return Promise.resolve({unsubscribe: () => {}});}), - - publish: jest.fn(() => { return Promise.resolve() }), - connect: jest.fn(() => { return Promise.resolve() }), - registerEndpoint: jest.fn(() => { return Promise.resolve() }), - unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), - registerService: jest.fn(() => { return Promise.resolve() }), - unregisterService: jest.fn(() => { return Promise.resolve() }), - invoke: jest.fn(() => { return Promise.resolve(JSON.stringify({context: "", payload: `${JSON.stringify({error: "Error happens..."})}` })) }) - }; - const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); - await expect(testDesktopAgent.joinUserChannel("dummyPath2")) - .rejects - .toThrow(new Error("Error happens...")); - expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.joinUserChannel(), JSON.stringify(new Fdc3FindChannelRequest("dummyPath2", "user"))); - }); - it('joinUserChannel will set the current user channel', async() => { const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClient); await testDesktopAgent.joinUserChannel("dummyPath"); @@ -351,4 +350,380 @@ describe('Tests for ComposeUIDesktopAgent implementation API', () => { .rejects .toThrow(ChannelError.CreationFailed); }); +}); + +describe ('Tests for ComposeUIDesktopAgent\'s intent handling', () => { + + beforeEach(() => { + window.composeui = { + fdc3: { + config: { + appId: "testAppId", + instanceId: "testInstanceId" + } + } + }; + }); + + it('findIntent will throw error as no answer was provided by the DesktopAgent backend', async() => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(undefined) }) + }; + + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + await expect(testDesktopAgent.findIntent("testIntent")) + .rejects + .toThrow(ComposeUIErrors.NoAnswerWasProvided); + }); + + it('findIntent will throw error as it got error from the DesktopAgent backend', async() => { + const fdc3IntentResponse = { + appIntent: [], + error: "Error happens..." + }; + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}` ) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + await expect(testDesktopAgent.findIntent("testIntent")) + .rejects + .toThrow("Error happens..."); + + expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntent(), JSON.stringify({fdc3InstanceId: window?.composeui?.fdc3.config?.instanceId, intent: "testIntent"})); + }); + + it('findIntent will return AppIntent', async() => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify({appIntent: { itent: "dummyIntent", apps: [{appId: "appId1"}, {appId: "appdId2"}]}})}`)}) + }; + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + var resultAppIntent = await testDesktopAgent.findIntent("dummyIntent"); + expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntent(), JSON.stringify({fdc3InstanceId: window?.composeui?.fdc3.config?.instanceId, intent: "dummyIntent"})); + expect(resultAppIntent).toMatchObject({itent: "dummyIntent", apps: [{appId: "appId1"}, {appId: "appdId2"}]}); + }); + + it('findIntentsByContext throws error no response came from the DesktopAgent service, undefined message', async() => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(undefined) }) + }; + + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + await expect(testDesktopAgent.findIntentsByContext({ type: "fdc3.Instrument" })) + .rejects + .toThrow(ComposeUIErrors.NoAnswerWasProvided); + }); + + it('findIntentsByContext throws error as it got error message from the DesktopAgent service', async() => { + const fdc3IntentResponse : Fdc3FindIntentsByContextResponse = { + appIntents: [], + error: "Error happens..." + }; + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}` ) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + await expect(testDesktopAgent.findIntentsByContext({ type: "testType" })) + .rejects + .toThrow(fdc3IntentResponse.error); + + expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntentsByContext(), JSON.stringify( { fdc3InstanceId: window.composeui.fdc3.config?.instanceId, context: { type: "testType" } })); + }); + + it('findIntentsByContext resolves and calls the invoke method of the messageRouterClient', async() => { + const request = { + fdc3InstanceId: window?.composeui?.fdc3.config?.instanceId, + context: { + type: 'fdc3.Instrument' + } + }; + + const response : Fdc3FindIntentsByContextResponse = { + appIntents: [ + { + intent: { name: 'fdc3.Instrument', displayName: 'fdc3.Instrument' }, + apps: [ + { appId: "appId1" }, + { appId: "appId2" } + ] + }, + { + intent: { name: 'fdc3.Instrument2', displayName: 'fdc3.Instrument2' }, + apps: [ + { appId: "appId3" }, + { appId: "appId4" } + ] + } + ] + }; + + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(response)}` ) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + var resultAppIntent = await testDesktopAgent.findIntentsByContext({type: "fdc3.Instrument"}); + + expect(messageRouterClientMock.invoke).toHaveBeenCalledWith(ComposeUITopic.findIntentsByContext(), JSON.stringify(request)); + expect(resultAppIntent).toMatchObject(response.appIntents!); + }); + + it('raiseIntent will throw exception, due no answer came from the DesktopAgent service', async() => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(undefined) }) + }; + + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + await expect(testDesktopAgent.raiseIntent("testIntent", { type: "fdc3.Instrument" })) + .rejects + .toThrow(ComposeUIErrors.NoAnswerWasProvided); + + expect(messageRouterClientMock.invoke).toHaveBeenCalledTimes(1); + }); + + it('raiseIntent will throw exception, due error was defined by the DesktopAgent service', async() => { + const fdc3IntentResponse : Fdc3RaiseIntentResponse = { + messageId: "1", + error: "Error happens..." + }; + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}` ) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + await expect(testDesktopAgent.raiseIntent("testIntent", { type: "testType" })) + .rejects + .toThrow(fdc3IntentResponse.error); + + expect(messageRouterClientMock.invoke).toHaveBeenCalledTimes(1); + }); + + it('raiseIntent will resolve the first item, due the DesktopAgent service sent just one application', async() => { + const fdc3IntentResponse : Fdc3RaiseIntentResponse = { + messageId: "1", + intent: "test", + appMetadata: [ + {appId: "test1"} + ] + }; + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}` ) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + var result = await testDesktopAgent.raiseIntent("test", { type: "test"} ); + expect(messageRouterClientMock.invoke).toHaveBeenCalledTimes(1); + expect(result).toMatchObject(new ComposeUIIntentResolution("1", messageRouterClientMock, "test", fdc3IntentResponse.appMetadata?.at(0)!)); + }); + + it('raiseIntent will call invoke of the messageRouter once again, due the DesktopAgent service sent multiple possible solution', async() => { + const fdc3IntentResponse : Fdc3RaiseIntentResponse = { + messageId: "1", + intent: "test", + appMetadata: [ + {appId: "test1"}, + {appId: "test2"} + ] + }; + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify(fdc3IntentResponse)}`) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent("dummyPath", messageRouterClientMock); + var result = await testDesktopAgent.raiseIntent("test", { type: "test"} ); + expect(messageRouterClientMock.invoke).toHaveBeenCalledTimes(2); + expect(result).toMatchObject(new ComposeUIIntentResolution("1", messageRouterClientMock, "test", fdc3IntentResponse.appMetadata?.at(0)!)); + }); + + it('addIntentListener will resolve an intentListener', async () => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify({stored: true})}`) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent('dummyPath', messageRouterClientMock); + const intentHandler : IntentHandler = (context, metadata) => { + return; + }; + const result = await testDesktopAgent.addIntentListener("testIntent", intentHandler); + + expect(messageRouterClientMock.subscribe).toHaveBeenCalledTimes(1); + expect(result).toBeInstanceOf(ComposeUIIntentListener); + }); + + it('addIntentListener will fail as no answer provided', async () => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve("") }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent('dummyPath', messageRouterClientMock); + const intentHandler : IntentHandler = (context, metadata) => { + return; + }; + + await expect(testDesktopAgent.addIntentListener("testIntent", intentHandler)) + .rejects + .toThrow(ComposeUIErrors.NoAnswerWasProvided); + }); + + it('addIntentListener will fail as the service not stored', async () => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify({ stored: false, error: undefined })}`) }) + }; + const testDesktopAgent = new ComposeUIDesktopAgent('dummyPath', messageRouterClientMock); + const intentHandler : IntentHandler = (context, metadata) => { + return; + }; + + await expect(testDesktopAgent.addIntentListener("testIntent", intentHandler)) + .rejects + .toThrow(ComposeUIErrors.SubscribeFailure); + }); + + it('addIntentListener will fail as service provided error', async () => { + const messageRouterClientMock = { + clientId: "dummy", + subscribe: jest.fn(() => { + return Promise.resolve({unsubscribe: () => {}});}), + + publish: jest.fn(() => { return Promise.resolve() }), + connect: jest.fn(() => { return Promise.resolve() }), + registerEndpoint: jest.fn(() => { return Promise.resolve() }), + unregisterEndpoint: jest.fn(() => { return Promise.resolve() }), + registerService: jest.fn(() => { return Promise.resolve() }), + unregisterService: jest.fn(() => { return Promise.resolve() }), + invoke: jest.fn(() => { return Promise.resolve(`${JSON.stringify({ stored: false, error: "dummy" })}`) }) + }; + + const testDesktopAgent = new ComposeUIDesktopAgent('dummyPath', messageRouterClientMock); + const intentHandler : IntentHandler = (context, metadata) => { + return; + }; + + await expect(testDesktopAgent.addIntentListener("testIntent", intentHandler)) + .rejects + .toThrow("dummy"); + }); }); \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIChannel.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIChannel.ts index 7fa0556cd..72901d07e 100644 --- a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIChannel.ts +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIChannel.ts @@ -14,7 +14,7 @@ import { Channel, Context, ContextHandler, DisplayMetadata, Listener } from "@finos/fdc3"; import { MessageRouter, TopicMessage } from "@morgan-stanley/composeui-messaging-client"; import { ChannelType } from "./ChannelType"; -import { ComposeUIListener } from "./ComposeUIListener"; +import { ComposeUIContextListener } from "./ComposeUIContextListener"; import { Fdc3GetCurrentContextRequest } from "./messages/Fdc3GetCurrentContextRequest"; import { ComposeUITopic } from "./ComposeUITopic"; @@ -80,7 +80,7 @@ export class ComposeUIChannel implements Channel { contextType = null; } - const listener = new ComposeUIListener(this.messageRouterClient, handler, this.id, this.type, contextType); + const listener = new ComposeUIContextListener(this.messageRouterClient, handler, this.id, this.type, contextType); await listener.subscribe(); return listener; } diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIListener.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIContextListener.ts similarity index 95% rename from src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIListener.ts rename to src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIContextListener.ts index cd16bf6b6..21864af27 100644 --- a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIListener.ts +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIContextListener.ts @@ -17,7 +17,7 @@ import { ChannelType } from "./ChannelType"; import { Unsubscribable } from "rxjs"; import { ComposeUITopic } from "./ComposeUITopic"; -export class ComposeUIListener implements Listener { +export class ComposeUIContextListener implements Listener { private messageRouterClient: MessageRouter; private unsubscribable?: Unsubscribable; private handler: ContextHandler; @@ -42,7 +42,7 @@ export class ComposeUIListener implements Listener { this.unsubscribable = await this.messageRouterClient.subscribe(subscribeTopic, (topicMessage: TopicMessage) => { if(topicMessage.context.sourceId == this.messageRouterClient.clientId) return; //TODO: integration test - const context = JSON.parse(topicMessage.payload!) as Context; + const context = JSON.parse(topicMessage.payload!); if(!this.contextType || this.contextType == context!.type) { this.handler!(context!); } diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIErrors.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIErrors.ts new file mode 100644 index 000000000..0f369715c --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIErrors.ts @@ -0,0 +1,20 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +export enum ComposeUIErrors { + NoAnswerWasProvided = 'No answer was provided by the DesktopAgent backend.', + InstanceIdNotFound = 'InstanceId was not found on window object. To run Fdc3\'s ComposeUI implementation instance config should be set on window config.', + CurrentChannelNotSet = 'The current channel have not been set.', + UnsubscribeFailure = 'The IntentListener could not unsubscribe.', + SubscribeFailure = 'The IntentListener could not subscribe.' +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentListener.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentListener.ts new file mode 100644 index 000000000..f1cde10bc --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentListener.ts @@ -0,0 +1,103 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { IntentHandler, Listener, Context, Channel, IntentResult, ResultError } from "@finos/fdc3"; +import { MessageRouter, TopicMessage } from "@morgan-stanley/composeui-messaging-client"; +import { Unsubscribable } from "rxjs"; +import { ComposeUITopic } from "./ComposeUITopic"; +import { Fdc3RaiseIntentResolutionRequest } from "./messages/Fdc3RaiseIntentResolutionRequest"; +import { Fdc3StoreIntentResultRequest } from "./messages/Fdc3StoreIntentResultRequest"; +import { Fdc3StoreIntentResultResponse } from "./messages/Fdc3StoreIntentResultResponse"; +import { Fdc3IntentListenerRequest } from "./messages/Fdc3IntentListenerRequest"; +import { Fdc3IntentListenerResponse } from "./messages/Fdc3IntentListenerResponse"; +import { ComposeUIErrors } from "./ComposeUIErrors"; + +export class ComposeUIIntentListener implements Listener { + private unsubscribable?: Unsubscribable; + private isSubscribed: boolean = false; + + constructor( + private messageRouterClient: MessageRouter, + private intent: string, + private instanceId: string, + private intentHandler: IntentHandler) { + } + + public async registerIntentHandler(): Promise { + const topic = ComposeUITopic.raiseIntent(this.intent, this.instanceId); + //Applications register the intents and context data combinations they support in the App Directory. + //https://fdc3.finos.org/docs/intents/spec + this.unsubscribable = await this.messageRouterClient.subscribe( + topic, + async (topicMessage: TopicMessage) => { + const message = (JSON.parse(topicMessage.payload!)); + //TODO: integrationtest + //TODO: test + let request: Fdc3StoreIntentResultRequest; + try { + const result = this.intentHandler(message.context, message.contextMetadata); + if (result && (typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') { + const intentResult = await result; + if ('id' in intentResult) { + const channel = intentResult; + request = new Fdc3StoreIntentResultRequest(message.messageId, this.intent, this.instanceId, message.contextMetadata.source.instanceId!, channel.id, channel.type); + } else if ('type' in intentResult) { + const context = intentResult; + request = new Fdc3StoreIntentResultRequest(message.messageId, this.intent, this.instanceId, message.contextMetadata.source.instanceId!, undefined, undefined, context); + } else { + throw new Error("Cannot detect return type of the IntentHandler."); + } + } else { //its a void + request = new Fdc3StoreIntentResultRequest(message.messageId, this.intent, this.instanceId, message.contextMetadata.source.instanceId!, undefined, undefined, undefined, true); + } + + } catch(error) { + request = new Fdc3StoreIntentResultRequest(message.messageId, this.intent, this.instanceId, message.contextMetadata.source.instanceId!, undefined, undefined, undefined, false, ResultError.IntentHandlerRejected); + } + + const result = await this.messageRouterClient.invoke(ComposeUITopic.sendIntentResult(), JSON.stringify(request)); + if (!result) { + return; + } else { + const response = (JSON.parse(result)); + if (response.error || !response.stored) { + console.log("Error while resolving the intent.", response.error); + } + } + }); + + this.isSubscribed = true; + } + + public unsubscribe(): Promise { + return new Promise(async(resolve, reject) => { + if (!this.isSubscribed) return; + const message = new Fdc3IntentListenerRequest(this.intent, this.instanceId, "Unsubscribe"); + const response = await this.messageRouterClient.invoke(ComposeUITopic.addIntentListener(), JSON.stringify(message)); + if (!response) { + return reject(ComposeUIErrors.NoAnswerWasProvided); + } else { + const result = JSON.parse(response); + if (result.error) { + return reject(result.error); + } else if (result.stored) { + return reject(ComposeUIErrors.UnsubscribeFailure); + } else { + this.unsubscribable?.unsubscribe(); + this.isSubscribed = false; + return resolve(); + } + } + }); + } +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentResolution.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentResolution.ts new file mode 100644 index 000000000..6d077d78a --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentResolution.ts @@ -0,0 +1,71 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ +import { AppMetadata, IntentResolution, IntentResult } from "@finos/fdc3"; +import { MessageRouter } from "@morgan-stanley/composeui-messaging-client"; +import { ComposeUIChannel } from "./ComposeUIChannel"; +import { ComposeUIErrors } from "./ComposeUIErrors"; +import { ComposeUITopic } from "./ComposeUITopic"; +import { Fdc3FindChannelRequest } from "./messages/Fdc3FindChannelRequest"; +import { Fdc3FindChannelResponse } from "./messages/Fdc3FindChannelResponse"; +import { Fdc3GetIntentResultRequest } from "./messages/Fdc3GetIntentResultRequest"; +import { Fdc3GetIntentResultResponse } from "./messages/Fdc3GetIntentResultResponse"; + +export class ComposeUIIntentResolution implements IntentResolution { + private messageRouterClient: MessageRouter; + public source: AppMetadata; + public intent: string + public messageId: string; + + constructor(messageId: string, messageRouterClient: MessageRouter, intent: string, source: AppMetadata) { + this.messageId = messageId; + this.intent = intent; + this.source = source; + this.messageRouterClient = messageRouterClient; + } + + getResult(): Promise { + return new Promise(async(resolve, reject) => { + const intentResolutionRequest = new Fdc3GetIntentResultRequest(this.messageId, this.intent, this.source, this.source.version); + const response = await this.messageRouterClient.invoke(ComposeUITopic.getIntentResult(), JSON.stringify(intentResolutionRequest)); + if (!response) { + return reject(new Error(ComposeUIErrors.NoAnswerWasProvided)); + } else { + const result = (JSON.parse(response)); + if (result.error) { + return reject(new Error(result.error)); + } else { + if (result.channelId && result.channelType) { + const message = JSON.stringify(new Fdc3FindChannelRequest(result.channelId, result.channelType)); + const response = await this.messageRouterClient.invoke(ComposeUITopic.findChannel(), message); + if(response) { + const fdc3Message = JSON.parse(response); + if(fdc3Message.error) { + return reject(new Error(fdc3Message.error)); + } + if (fdc3Message.found){ + const channel = new ComposeUIChannel(result.channelId, result.channelType, this.messageRouterClient); + return resolve(channel); + } + } + } else if (result.context) { + return resolve(result.context); + } else if (result.voidResult) { + console.log("Backend suspects that the IntentListener returned void. ", result.voidResult); + return resolve(); + } + return reject(new Error(ComposeUIErrors.NoAnswerWasProvided)); + } + } + }); + } +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUITopic.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUITopic.ts index 79f39e4ca..3bc384172 100644 --- a/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUITopic.ts +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUITopic.ts @@ -24,28 +24,67 @@ export class ComposeUITopic { private static readonly getCurrentContextSuffix = "getCurrentContext"; private static readonly joinUserChannelSuffix = "joinUserChannel"; private static readonly getOrCreateChannelSuffix = "getOrCreateChannel"; + private static readonly raiseIntentSuffix = "raiseIntent"; + private static readonly addIntentListenerSuffix = "addIntentListener"; + private static readonly getIntentSuffix = "getIntentResult"; + private static readonly findIntentSuffix = "findIntent"; + private static readonly findIntentsByContextSuffix = "findIntentsByContext"; + private static readonly sendIntentResultSuffix = "sendIntentResult"; + private static readonly findChannelSuffix = "findChannel"; - public static broadcast(channelId: string, channelType: ChannelType = "user") { + public static broadcast(channelId: string, channelType: ChannelType = "user") : string { return `${this.getChannelsTopicRootWithTopicId(channelId, channelType)}/${this.broadcastSuffix}`; } - public static getCurrentContext(channelId: string, channelType: ChannelType = "user") { + public static getCurrentContext(channelId: string, channelType: ChannelType = "user") : string { return `${this.getChannelsTopicRootWithTopicId(channelId, channelType)}/${this.getCurrentContextSuffix}`; } - public static joinUserChannel() { + public static joinUserChannel(): string { return `${this.topicRoot}/${this.joinUserChannelSuffix}`; } - public static getOrCreateChannel() { + public static getOrCreateChannel(): string { return `${this.topicRoot}/${this.getOrCreateChannelSuffix}`; } - private static getChannelsTopicRootWithTopicId(topicId: string, channelType: ChannelType = "user") { + public static raiseIntent(intent?: string, instanceId?: string): string { + if (intent && instanceId) { + return `${this.topicRoot}/${this.raiseIntentSuffix}/${intent}/${instanceId}`; + } else { + return `${this.topicRoot}/${this.raiseIntentSuffix}`; + } + } + + public static addIntentListener(): string { + return `${this.topicRoot}/${this.addIntentListenerSuffix}`; + } + + public static getIntentResult(): string { + return `${this.topicRoot}/${this.getIntentSuffix}`; + } + + public static sendIntentResult(): string { + return `${this.topicRoot}/${this.sendIntentResultSuffix}`; + } + + public static findIntent(): string { + return `${this.topicRoot}/${this.findIntentSuffix}`; + } + + public static findIntentsByContext(): string { + return `${this.topicRoot}/${this.findIntentsByContextSuffix}`; + } + + public static findChannel(): string { + return `${this.topicRoot}/${this.findChannelSuffix}`; + } + + private static getChannelsTopicRootWithTopicId(topicId: string, channelType: ChannelType) : string { return `${this.getChannelsTopicRoot(channelType)}/${topicId}`; } - private static getChannelsTopicRoot(channelType: ChannelType = "user") { + private static getChannelsTopicRoot(channelType: ChannelType): string { switch(channelType) { case "user": return `${this.topicRoot}/${this.userChannels}`; diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentRequest.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentRequest.ts new file mode 100644 index 000000000..9cecd2486 --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentRequest.ts @@ -0,0 +1,24 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { Context, Channel } from "@finos/fdc3"; + +export class Fdc3FindIntentRequest { + constructor( + public readonly fdc3InstanceId: string, + public readonly intent: string, + public readonly context?: Context, + public readonly resultType?: string) { + + } +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentResponse.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentResponse.ts new file mode 100644 index 000000000..caac34804 --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentResponse.ts @@ -0,0 +1,19 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { AppIntent } from "@finos/fdc3"; + +export interface Fdc3FindIntentResponse { + appIntent?: AppIntent; + error?: string; +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextRequest.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextRequest.ts new file mode 100644 index 000000000..c6444722e --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextRequest.ts @@ -0,0 +1,23 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { Context } from "@finos/fdc3"; + +export class Fdc3FindIntentsByContextRequest { + constructor( + public readonly fdc3InstanceId: string, + public readonly context?: Context, + public readonly resultType?: string) { + + } +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextResponse.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextResponse.ts new file mode 100644 index 000000000..b9c0f1c1e --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextResponse.ts @@ -0,0 +1,19 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { AppIntent } from "@finos/fdc3"; + +export interface Fdc3FindIntentsByContextResponse { + appIntents?: AppIntent[]; + error?: string; +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultRequest.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultRequest.ts new file mode 100644 index 000000000..d0a0e2b60 --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultRequest.ts @@ -0,0 +1,23 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { AppIdentifier } from "@finos/fdc3"; + +export class Fdc3GetIntentResultRequest { + constructor( + public readonly messageId: string, + public readonly intent: string, + public readonly targetAppIdentifier: AppIdentifier, + public readonly version?: string) { + } +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultResponse.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultResponse.ts new file mode 100644 index 000000000..b03df688d --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultResponse.ts @@ -0,0 +1,23 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { Context } from "@finos/fdc3"; +import { ChannelType } from "../ChannelType"; + +export class Fdc3GetIntentResultResponse { + public channelId?: string; + public channelType?: ChannelType; + public context?: Context; + public error?: string; + public voidResult: boolean = false; +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerRequest.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerRequest.ts new file mode 100644 index 000000000..c79498a2c --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerRequest.ts @@ -0,0 +1,22 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +export class Fdc3IntentListenerRequest { + constructor( + public readonly intent: string, + public readonly fdc3InstanceId: string, + public readonly state: SubscribeState) { + } +} + +export type SubscribeState = "Subscribe" | "Unsubscribe"; \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerResponse.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerResponse.ts new file mode 100644 index 000000000..416317a1c --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerResponse.ts @@ -0,0 +1,17 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +export interface Fdc3IntentListenerResponse { + stored: boolean; + error?: string; +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentRequest.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentRequest.ts new file mode 100644 index 000000000..e9e56324e --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentRequest.ts @@ -0,0 +1,27 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { AppIdentifier } from "@finos/fdc3"; +import { Context } from "vm"; + +export class Fdc3RaiseIntentRequest { + constructor( + public readonly messageId: number, + public readonly fdc3InstanceId: string, + public readonly intent: string, + public readonly selected: boolean, + public readonly context: Context, + public readonly targetAppIdentifier?: AppIdentifier, + public readonly error?: string) { + } +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResolutionRequest.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResolutionRequest.ts new file mode 100644 index 000000000..89c912880 --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResolutionRequest.ts @@ -0,0 +1,20 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { Context, ContextMetadata } from "@finos/fdc3"; + +export interface Fdc3RaiseIntentResolutionRequest { + messageId: string; + context: Context; + contextMetadata: ContextMetadata; +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResponse.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResponse.ts new file mode 100644 index 000000000..77d946863 --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResponse.ts @@ -0,0 +1,21 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { AppMetadata } from "@finos/fdc3"; + +export interface Fdc3RaiseIntentResponse { + messageId: string; + intent?: string; + appMetadata?: AppMetadata[]; + error?: string; +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultRequest.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultRequest.ts new file mode 100644 index 000000000..42cdc6301 --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultRequest.ts @@ -0,0 +1,29 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +import { Context } from "@finos/fdc3"; +import { ChannelType } from "../ChannelType"; + +export class Fdc3StoreIntentResultRequest { + constructor( + public messageId: string, + public intent: string, + public originFdc3InstanceId: string, + public targetFdc3InstanceId: string, + public channelId?: string, + public channelType?: ChannelType, + public context?: Context, + public voidResult: boolean = false, + public error?: string + ) {} +} \ No newline at end of file diff --git a/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultResponse.ts b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultResponse.ts new file mode 100644 index 000000000..7f6b7bd78 --- /dev/null +++ b/src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultResponse.ts @@ -0,0 +1,17 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + * + */ + +export class Fdc3StoreIntentResultResponse { + public stored?: boolean; + public error?: string; +} \ No newline at end of file diff --git a/src/package-lock.json b/src/package-lock.json new file mode 100644 index 000000000..871a4907a --- /dev/null +++ b/src/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "src", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/src/shared/dotnet/MorganStanley.ComposeUI.Shared.sln b/src/shared/dotnet/MorganStanley.ComposeUI.Shared.sln new file mode 100644 index 000000000..c73c52e13 --- /dev/null +++ b/src/shared/dotnet/MorganStanley.ComposeUI.Shared.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32616.157 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{8E838164-6370-4320-ACD5-CD1E6631C09C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{51355F98-9BDE-42CA-B284-296AAE6B6B38}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Utilities", "src\MorganStanley.ComposeUI.Utilities\MorganStanley.ComposeUI.Utilities.csproj", "{13B9FB01-144E-4BBE-9920-1C69B44FB711}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Utilities.Tests", "tests\MorganStanley.ComposeUI.Utilities.Tests\MorganStanley.ComposeUI.Utilities.Tests.csproj", "{ED668A15-0186-41CD-B79D-2D9F18A6F15B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {13B9FB01-144E-4BBE-9920-1C69B44FB711}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13B9FB01-144E-4BBE-9920-1C69B44FB711}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13B9FB01-144E-4BBE-9920-1C69B44FB711}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13B9FB01-144E-4BBE-9920-1C69B44FB711}.Release|Any CPU.Build.0 = Release|Any CPU + {ED668A15-0186-41CD-B79D-2D9F18A6F15B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ED668A15-0186-41CD-B79D-2D9F18A6F15B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED668A15-0186-41CD-B79D-2D9F18A6F15B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ED668A15-0186-41CD-B79D-2D9F18A6F15B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {13B9FB01-144E-4BBE-9920-1C69B44FB711} = {8E838164-6370-4320-ACD5-CD1E6631C09C} + {ED668A15-0186-41CD-B79D-2D9F18A6F15B} = {51355F98-9BDE-42CA-B284-296AAE6B6B38} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EF62D6D0-E133-4C3A-A1AF-79C44BAD39C4} + EndGlobalSection +EndGlobal diff --git a/src/shell/dotnet/Shell/Utilities/CommandLineParser.cs b/src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/CommandLineParser.cs similarity index 98% rename from src/shell/dotnet/Shell/Utilities/CommandLineParser.cs rename to src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/CommandLineParser.cs index f57bcbf0a..16bf5cbab 100644 --- a/src/shell/dotnet/Shell/Utilities/CommandLineParser.cs +++ b/src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/CommandLineParser.cs @@ -21,7 +21,7 @@ using System.Linq; using System.Reflection; -namespace MorganStanley.ComposeUI.Shell.Utilities; +namespace MorganStanley.ComposeUI.Utilities; /// /// Simple helper class that parses strongly typed objects from command line arguments. diff --git a/src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/MorganStanley.ComposeUI.Utilities.csproj b/src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/MorganStanley.ComposeUI.Utilities.csproj new file mode 100644 index 000000000..251879003 --- /dev/null +++ b/src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/MorganStanley.ComposeUI.Utilities.csproj @@ -0,0 +1,12 @@ + + + + net6.0 + enable + true + + + + + + diff --git a/src/shell/dotnet/Shell/Utilities/ResourceReader.cs b/src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/ResourceReader.cs similarity index 84% rename from src/shell/dotnet/Shell/Utilities/ResourceReader.cs rename to src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/ResourceReader.cs index 63e620a55..3d119fc76 100644 --- a/src/shell/dotnet/Shell/Utilities/ResourceReader.cs +++ b/src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/ResourceReader.cs @@ -16,15 +16,13 @@ using System.IO; using System.Reflection; -namespace MorganStanley.ComposeUI.Shell.Utilities; +namespace MorganStanley.ComposeUI.Utilities; -//TODO: Later we should move this under a new project //`src/shared/dotnet` public static class ResourceReader { public static string ReadResource(string resourcePath) { - var assembly = Assembly.GetExecutingAssembly(); - + var assembly = Assembly.GetCallingAssembly(); using var stream = assembly.GetManifestResourceStream(resourcePath) ?? throw new InvalidOperationException("Resource not found"); using var reader = new StreamReader(stream); return reader.ReadToEnd(); diff --git a/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserAttributedPropertyTests.cs b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserAttributedPropertyTests.cs new file mode 100644 index 000000000..2d397469a --- /dev/null +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserAttributedPropertyTests.cs @@ -0,0 +1,57 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Utilities; +using System.ComponentModel.DataAnnotations; + +namespace MorganStanley.ComposeUI.Utilities.Tests; + +public class CommandLineParserAttributedPropertyTests +{ + public class AttributedOptions + { + [Display(Name = "opt", Description = "Option with overwritten name")] + public string RenamedOption { get; set; } + + [Display(Description = "Just a description")] + public string Option { get; set; } + } + + [Fact] + public void TestParsingRenamedOption() + { + var testValue = Guid.NewGuid().ToString(); + var options = CommandLineParser.Parse(new[] { "--opt", testValue }); + Assert.NotNull(options); + Assert.Equal(testValue.ToString(), options.RenamedOption); + } + + [Fact] + public void TestParsingRenamedOptionWithOriginalName() + { + var testValue = Guid.NewGuid().ToString(); + var options = CommandLineParser.Parse(new[] { "--renamedOption", testValue }); + Assert.NotNull(options); + Assert.Null(options.RenamedOption); + } + + [Fact] + public void TestParsingOptionWithDescription() + { + var testValue = Guid.NewGuid().ToString(); + var options = CommandLineParser.Parse(new[] { "--option", testValue }); + Assert.NotNull(options); + Assert.Equal(testValue.ToString(), options.Option); + } +} diff --git a/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyDoubleTests.cs b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyDoubleTests.cs new file mode 100644 index 000000000..067fb5be6 --- /dev/null +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyDoubleTests.cs @@ -0,0 +1,84 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Utilities; + +namespace MorganStanley.ComposeUI.Utilities.Tests; + +public class CommandLineParserCustomPropertyDoubleTests +{ + private static readonly Random Random = new Random(); + private static readonly double Default = Random.NextDouble(); + + /// + /// Get a test value that's different from the default value + /// + /// + private static double GetTestValue() + { + var x = Random.NextDouble(); + while (x == Default) { x = Random.NextDouble(); } + return x; + } + + public class CustomPropertyDoubleOptions + { + private double _option = Default; + public double? Option + { + get { return _option; } + set { _option = value ?? Default; } + } + } + + [Fact] + public void TestParseCustomPropertyDoubleWithEmptyParameterList() + { + var options = CommandLineParser.Parse(new string[0]); + Assert.NotNull(options); + Assert.Equal(Default, options.Option); + } + + [Fact] + public void TestParseCustomPropertyDoubleWithValueProvided() + { + var testValue = GetTestValue(); + var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); + Assert.NotNull(options); + Assert.Equal(testValue, options.Option); + } + + [Fact] + public void TestParseCustomPropertyDoubleWithoutValue() + { + Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); + } + + [Fact] + public void TestParseCustomPropertyDoubleWithOnlyDifferentParameter() + { + var options = CommandLineParser.Parse(new[] { "--stuff", GetTestValue().ToString() }); + Assert.NotNull(options); + Assert.Equal(Default, options.Option); + } + + [Fact] + public void TestParseCustomPropertyDoubleWithOtherParameters() + { + var testValue = GetTestValue(); + var options = CommandLineParser.Parse(new[] { "--firstParam", GetTestValue().ToString(), "--option", testValue.ToString(), "--lastParam", GetTestValue().ToString() }); + Assert.NotNull(options); + Assert.Equal(testValue, options.Option); + } +} \ No newline at end of file diff --git a/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyStringTests.cs b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyStringTests.cs new file mode 100644 index 000000000..afbb11c5e --- /dev/null +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyStringTests.cs @@ -0,0 +1,72 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Utilities; + +namespace MorganStanley.ComposeUI.Utilities.Tests; + +public class CommandLineParserCustomPropertyStringTests +{ + private const string Default = "default"; + public class CustomPropertyStringOptions + { + private string? _option = null; + public string? Option + { + get { return _option ?? Default; } + set { _option = value; } + } + } + + [Fact] + public void TestParseSimpleStringWithEmptyParameterList() + { + var options = CommandLineParser.Parse(new string[0]); + Assert.NotNull(options); + Assert.Equal(Default, options.Option); + } + + [Fact] + public void TestParseSimpleStringWithValueProvided() + { + var testValue = Guid.NewGuid(); + var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); + Assert.NotNull(options); + Assert.Equal(testValue.ToString(), options.Option); + } + + [Fact] + public void TestParseSimpleStringWithoutValue() + { + var testValue = Guid.NewGuid(); + Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); + } + + [Fact] + public void TestParseSimpleStringWithOnlyDifferentParameter() + { + var options = CommandLineParser.Parse(new[] { "--stuff", "irrelevant" }); + Assert.NotNull(options); + Assert.Equal(Default, options.Option); + } + + [Fact] + public void TestParseSimpleStringWithOtherParameters() + { + var testValue = Guid.NewGuid(); + var options = CommandLineParser.Parse(new[] { "--firstParam", "irrelevant", "--option", testValue.ToString(), "--lastParam", "irrelevant" }); + Assert.NotNull(options); + Assert.Equal(testValue.ToString(), options.Option); + } +} \ No newline at end of file diff --git a/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleDoubleTests.cs b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleDoubleTests.cs new file mode 100644 index 000000000..59d327dcd --- /dev/null +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleDoubleTests.cs @@ -0,0 +1,68 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Utilities; +using System.Globalization; + +namespace MorganStanley.ComposeUI.Utilities.Tests; + +public class CommandLineParserSimpleDoubleTests +{ + private static readonly Random Random = new Random(); + + public class SimpleDoubleOptions + { + public double? Option { get; set; } + } + + [Fact] + public void TestParseSimpleDoubleWithEmptyParameterList() + { + var options = CommandLineParser.Parse(new string[0]); + Assert.NotNull(options); + Assert.Null(options.Option); + } + + [Fact] + public void TestParseSimpleDoubleWithValueProvided() + { + var testValue = Random.NextDouble(); + var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); + Assert.NotNull(options); + Assert.Equal(testValue, options.Option); + } + + [Fact] + public void TestParseSimpleDoubleWithoutValue() + { + Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); + } + + [Fact] + public void TestParseSimpleDoubleWithOnlyDifferentParameter() + { + var options = CommandLineParser.Parse(new[] { "--stuff", Random.NextDouble().ToString() }); + Assert.NotNull(options); + Assert.Null(options.Option); + } + + [Fact] + public void TestParseSimpleDoubleWithOtherParameters() + { + var testValue = Random.NextDouble(); + var options = CommandLineParser.Parse(new[] { "--firstParam", Random.NextDouble().ToString(), "--option", testValue.ToString(), "--lastParam", Random.NextDouble().ToString() }); + Assert.NotNull(options); + Assert.Equal(testValue, options.Option); + } +} \ No newline at end of file diff --git a/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleStringTests.cs b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleStringTests.cs new file mode 100644 index 000000000..ce7f8a3f5 --- /dev/null +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleStringTests.cs @@ -0,0 +1,66 @@ +/* + * Morgan Stanley makes this available to you under the Apache License, + * Version 2.0 (the "License"). You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Unless required by applicable law or agreed + * to in writing, software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions + * and limitations under the License. + */ + +using MorganStanley.ComposeUI.Utilities; + +namespace MorganStanley.ComposeUI.Utilities.Tests; + +public class CommandLineParserSimpleStringTests +{ + public class SimpleStringOptions + { + public string? Option { get; set; } + } + + [Fact] + public void TestParseSimpleStringWithEmptyParameterList() + { + var options = CommandLineParser.Parse(new string[0]); + Assert.NotNull(options); + Assert.Null(options.Option); + } + + [Fact] + public void TestParseSimpleStringWithValueProvided() + { + var testValue = Guid.NewGuid(); + var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); + Assert.NotNull(options); + Assert.Equal(testValue.ToString(), options.Option); + } + + [Fact] + public void TestParseSimpleStringWithoutValue() + { + var testValue = Guid.NewGuid(); + Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); + } + + [Fact] + public void TestParseSimpleStringWithOnlyDifferentParameter() + { + var options = CommandLineParser.Parse(new[] { "--stuff", "irrelevant" }); + Assert.NotNull(options); + Assert.Null(options.Option); + } + + [Fact] + public void TestParseSimpleStringWithOtherParameters() + { + var testValue = Guid.NewGuid(); + var options = CommandLineParser.Parse(new[] { "--firstParam", "irrelevant", "--option", testValue.ToString(), "--lastParam", "irrelevant" }); + Assert.NotNull(options); + Assert.Equal(testValue.ToString(), options.Option); + } +} \ No newline at end of file diff --git a/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/MorganStanley.ComposeUI.Utilities.Tests.csproj b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/MorganStanley.ComposeUI.Utilities.Tests.csproj new file mode 100644 index 000000000..db5aa97d6 --- /dev/null +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/MorganStanley.ComposeUI.Utilities.Tests.csproj @@ -0,0 +1,35 @@ + + + + net6.0 + enable + enable + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + $(ComposeUIRepositoryRoot)\src\shared\dotnet\tests\TestUtils\test.js + + + + + + + diff --git a/src/shell/dotnet/tests/Shell.Tests/ResourceReaderTests.cs b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/ResourceReaderTests.cs similarity index 66% rename from src/shell/dotnet/tests/Shell.Tests/ResourceReaderTests.cs rename to src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/ResourceReaderTests.cs index d56766396..52dbeebd0 100644 --- a/src/shell/dotnet/tests/Shell.Tests/ResourceReaderTests.cs +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/ResourceReaderTests.cs @@ -12,18 +12,17 @@ * and limitations under the License. */ -using MorganStanley.ComposeUI.Shell.Utilities; +using System.Reflection; -namespace MorganStanley.ComposeUI.Shell.Tests +namespace MorganStanley.ComposeUI.Utilities.Tests; + +public class ReadResourceTests { - public class ReadResourceTests + [Fact] + public void TestFdc3BundleResourceIsFound() { - [Fact] - public void TestFdc3BundleResourceIsFound() - { - var resource = ResourceReader.ReadResource(ResourceNames.Fdc3Bundle); + var resource = ResourceReader.ReadResource(@$"{Assembly.GetExecutingAssembly().ManifestModule.Assembly.GetName()?.Name}.test.js"); - Assert.NotNull(resource); - } + Assert.NotNull(resource); } } diff --git a/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/Usings.cs b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/Usings.cs new file mode 100644 index 000000000..8c927eb74 --- /dev/null +++ b/src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/src/shared/dotnet/tests/TestUtils/test.js b/src/shared/dotnet/tests/TestUtils/test.js new file mode 100644 index 000000000..e69de29bb diff --git a/src/shell/dotnet/Shell.sln b/src/shell/dotnet/Shell.sln index 89bb7e34b..70e994768 100644 --- a/src/shell/dotnet/Shell.sln +++ b/src/shell/dotnet/Shell.sln @@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Mod EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.ModuleLoader", "..\..\module-loader\dotnet\src\MorganStanley.ComposeUI.ModuleLoader\MorganStanley.ComposeUI.ModuleLoader.csproj", "{1D387A56-DC64-4EB0-870D-3872BE4716B4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MorganStanley.ComposeUI.Utilities", "..\..\shared\dotnet\src\MorganStanley.ComposeUI.Utilities\MorganStanley.ComposeUI.Utilities.csproj", "{990C5E01-FA98-4E26-A746-88731A78D502}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -73,6 +75,10 @@ Global {1D387A56-DC64-4EB0-870D-3872BE4716B4}.Debug|Any CPU.Build.0 = Debug|Any CPU {1D387A56-DC64-4EB0-870D-3872BE4716B4}.Release|Any CPU.ActiveCfg = Release|Any CPU {1D387A56-DC64-4EB0-870D-3872BE4716B4}.Release|Any CPU.Build.0 = Release|Any CPU + {990C5E01-FA98-4E26-A746-88731A78D502}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {990C5E01-FA98-4E26-A746-88731A78D502}.Debug|Any CPU.Build.0 = Debug|Any CPU + {990C5E01-FA98-4E26-A746-88731A78D502}.Release|Any CPU.ActiveCfg = Release|Any CPU + {990C5E01-FA98-4E26-A746-88731A78D502}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -87,6 +93,7 @@ Global {70EAC402-B711-4528-B4DE-34081EB8676E} = {E7A2C581-4BF4-47A5-8A11-59B2DEBADCA7} {F94A14A9-38B2-4573-A74B-979044428152} = {E7A2C581-4BF4-47A5-8A11-59B2DEBADCA7} {1D387A56-DC64-4EB0-870D-3872BE4716B4} = {E7A2C581-4BF4-47A5-8A11-59B2DEBADCA7} + {990C5E01-FA98-4E26-A746-88731A78D502} = {E7A2C581-4BF4-47A5-8A11-59B2DEBADCA7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4C901E6C-4B9A-48C2-AB16-461040DC57B4} diff --git a/src/shell/dotnet/Shell/App.xaml.cs b/src/shell/dotnet/Shell/App.xaml.cs index b42d3cfc8..821fd9da6 100644 --- a/src/shell/dotnet/Shell/App.xaml.cs +++ b/src/shell/dotnet/Shell/App.xaml.cs @@ -14,6 +14,7 @@ using System; using System.Diagnostics; +using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows; @@ -30,6 +31,7 @@ using MorganStanley.ComposeUI.Shell.Messaging; using MorganStanley.ComposeUI.Shell.Modules; using MorganStanley.ComposeUI.Shell.Utilities; +using MorganStanley.ComposeUI.Utilities; namespace MorganStanley.ComposeUI.Shell; @@ -172,14 +174,11 @@ void ConfigureFdc3() { services.AddFdc3DesktopAgent(); services.AddFdc3AppDirectory(); - services.Configure(fdc3ConfigurationSection); services.Configure( fdc3ConfigurationSection.GetSection(nameof(fdc3Options.DesktopAgent))); services.Configure( fdc3ConfigurationSection.GetSection(nameof(fdc3Options.AppDirectory))); - - services.AddTransient(); } } } diff --git a/src/shell/dotnet/Shell/Shell.csproj b/src/shell/dotnet/Shell/Shell.csproj index 1b99faea9..52b0a8f1f 100644 --- a/src/shell/dotnet/Shell/Shell.csproj +++ b/src/shell/dotnet/Shell/Shell.csproj @@ -21,7 +21,6 @@ - @@ -43,32 +42,11 @@ - - - - $(ComposeUIRepositoryRoot)\src\fdc3\js\composeui-fdc3\dist\fdc3-iife-bundle.js - - - - + - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/shell/dotnet/Shell/WebWindow.xaml.cs b/src/shell/dotnet/Shell/WebWindow.xaml.cs index a9a5a90a6..78a6ba9cc 100644 --- a/src/shell/dotnet/Shell/WebWindow.xaml.cs +++ b/src/shell/dotnet/Shell/WebWindow.xaml.cs @@ -1,4 +1,18 @@ -using System; +// /* +// * Morgan Stanley makes this available to you under the Apache License, +// * Version 2.0 (the "License"). You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0. +// * +// * See the NOTICE file distributed with this work for additional information +// * regarding copyright ownership. Unless required by applicable law or agreed +// * to in writing, software distributed under the License is distributed on an +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// * or implied. See the License for the specific language governing permissions +// * and limitations under the License. +// */ + +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -19,6 +33,7 @@ namespace MorganStanley.ComposeUI.Shell; /// /// Interaction logic for WebWindow.xaml /// + public partial class WebWindow : Window { public WebWindow( @@ -202,7 +217,7 @@ private async void OnNewWindowRequested(CoreWebView2NewWindowRequestedEventArgs using var deferral = e.GetDeferral(); e.Handled = true; - var windowOptions = new WebWindowOptions {Url = e.Uri}; + var windowOptions = new WebWindowOptions { Url = e.Uri }; if (e.WindowFeatures.HasSize) { @@ -210,7 +225,7 @@ private async void OnNewWindowRequested(CoreWebView2NewWindowRequestedEventArgs windowOptions.Height = e.WindowFeatures.Height; } - var constructorArgs = new List {windowOptions}; + var constructorArgs = new List { windowOptions }; // For now, we only inject the module-specific information when the window was created // in response to a start request. Later we might allow the page to open a new window diff --git a/src/shell/dotnet/Shell/WebWindowOptions.cs b/src/shell/dotnet/Shell/WebWindowOptions.cs index dd95a6d84..117b6980e 100644 --- a/src/shell/dotnet/Shell/WebWindowOptions.cs +++ b/src/shell/dotnet/Shell/WebWindowOptions.cs @@ -1,4 +1,18 @@ -using System.ComponentModel.DataAnnotations; +// /* +// * Morgan Stanley makes this available to you under the Apache License, +// * Version 2.0 (the "License"). You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0. +// * +// * See the NOTICE file distributed with this work for additional information +// * regarding copyright ownership. Unless required by applicable law or agreed +// * to in writing, software distributed under the License is distributed on an +// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +// * or implied. See the License for the specific language governing permissions +// * and limitations under the License. +// */ + +using System.ComponentModel.DataAnnotations; namespace MorganStanley.ComposeUI.Shell; diff --git a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserAttributedPropertyTests.cs b/src/shell/dotnet/tests/Shell.Tests/CommandLineParserAttributedPropertyTests.cs deleted file mode 100644 index dcc93c84f..000000000 --- a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserAttributedPropertyTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Morgan Stanley makes this available to you under the Apache License, - * Version 2.0 (the "License"). You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. Unless required by applicable law or agreed - * to in writing, software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -using MorganStanley.ComposeUI.Shell.Utilities; -using System.ComponentModel.DataAnnotations; - -namespace MorganStanley.ComposeUI.Shell.Tests -{ - public class CommandLineParserAttributedPropertyTests - { - public class AttributedOptions - { - [Display(Name = "opt", Description = "Option with overwritten name")] - public string RenamedOption { get; set; } - - [Display(Description = "Just a description")] - public string Option { get; set; } - } - - [Fact] - public void TestParsingRenamedOption() - { - var testValue = Guid.NewGuid().ToString(); - var options = CommandLineParser.Parse(new[] { "--opt", testValue }); - Assert.NotNull(options); - Assert.Equal(testValue.ToString(), options.RenamedOption); - } - - [Fact] - public void TestParsingRenamedOptionWithOriginalName() - { - var testValue = Guid.NewGuid().ToString(); - var options = CommandLineParser.Parse(new[] { "--renamedOption", testValue }); - Assert.NotNull(options); - Assert.Null(options.RenamedOption); - } - - [Fact] - public void TestParsingOptionWithDescription() - { - var testValue = Guid.NewGuid().ToString(); - var options = CommandLineParser.Parse(new[] { "--option", testValue }); - Assert.NotNull(options); - Assert.Equal(testValue.ToString(), options.Option); - } - } -} diff --git a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyDoubleTests.cs b/src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyDoubleTests.cs deleted file mode 100644 index 8c7f6636d..000000000 --- a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyDoubleTests.cs +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Morgan Stanley makes this available to you under the Apache License, - * Version 2.0 (the "License"). You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. Unless required by applicable law or agreed - * to in writing, software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -using MorganStanley.ComposeUI.Shell.Utilities; - -namespace MorganStanley.ComposeUI.Shell.Tests -{ - public class CommandLineParserCustomPropertyDoubleTests - { - private static readonly Random Random = new Random(); - private static readonly double Default = Random.NextDouble(); - - /// - /// Get a test value that's different from the default value - /// - /// - private static double GetTestValue() - { - var x = Random.NextDouble(); - while (x == Default) { x = Random.NextDouble(); } - return x; - } - - public class CustomPropertyDoubleOptions - { - private double _option = Default; - public double? Option - { - get { return _option; } - set { _option = value ?? Default; } - } - } - - [Fact] - public void TestParseCustomPropertyDoubleWithEmptyParameterList() - { - var options = CommandLineParser.Parse(new string[0]); - Assert.NotNull(options); - Assert.Equal(Default, options.Option); - } - - [Fact] - public void TestParseCustomPropertyDoubleWithValueProvided() - { - var testValue = GetTestValue(); - var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); - Assert.NotNull(options); - Assert.Equal(testValue, options.Option); - } - - [Fact] - public void TestParseCustomPropertyDoubleWithoutValue() - { - Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); - } - - [Fact] - public void TestParseCustomPropertyDoubleWithOnlyDifferentParameter() - { - var options = CommandLineParser.Parse(new[] { "--stuff", GetTestValue().ToString() }); - Assert.NotNull(options); - Assert.Equal(Default, options.Option); - } - - [Fact] - public void TestParseCustomPropertyDoubleWithOtherParameters() - { - var testValue = GetTestValue(); - var options = CommandLineParser.Parse(new[] { "--firstParam", GetTestValue().ToString(), "--option", testValue.ToString(), "--lastParam", GetTestValue().ToString() }); - Assert.NotNull(options); - Assert.Equal(testValue, options.Option); - } - } -} \ No newline at end of file diff --git a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyStringTests.cs b/src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyStringTests.cs deleted file mode 100644 index 4d80531a0..000000000 --- a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyStringTests.cs +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Morgan Stanley makes this available to you under the Apache License, - * Version 2.0 (the "License"). You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. Unless required by applicable law or agreed - * to in writing, software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -using MorganStanley.ComposeUI.Shell.Utilities; - -namespace MorganStanley.ComposeUI.Shell.Tests -{ - public class CommandLineParserCustomPropertyStringTests - { - private const string Default = "default"; - public class CustomPropertyStringOptions - { - private string? _option = null; - public string? Option - { - get { return _option ?? Default; } - set { _option = value; } - } - } - - [Fact] - public void TestParseSimpleStringWithEmptyParameterList() - { - var options = CommandLineParser.Parse(new string[0]); - Assert.NotNull(options); - Assert.Equal(Default, options.Option); - } - - [Fact] - public void TestParseSimpleStringWithValueProvided() - { - var testValue = Guid.NewGuid(); - var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); - Assert.NotNull(options); - Assert.Equal(testValue.ToString(), options.Option); - } - - [Fact] - public void TestParseSimpleStringWithoutValue() - { - var testValue = Guid.NewGuid(); - Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); - } - - [Fact] - public void TestParseSimpleStringWithOnlyDifferentParameter() - { - var options = CommandLineParser.Parse(new[] { "--stuff", "irrelevant" }); - Assert.NotNull(options); - Assert.Equal(Default, options.Option); - } - - [Fact] - public void TestParseSimpleStringWithOtherParameters() - { - var testValue = Guid.NewGuid(); - var options = CommandLineParser.Parse(new[] { "--firstParam", "irrelevant", "--option", testValue.ToString(), "--lastParam", "irrelevant" }); - Assert.NotNull(options); - Assert.Equal(testValue.ToString(), options.Option); - } - } -} \ No newline at end of file diff --git a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleDoubleTests.cs b/src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleDoubleTests.cs deleted file mode 100644 index aae55b258..000000000 --- a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleDoubleTests.cs +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Morgan Stanley makes this available to you under the Apache License, - * Version 2.0 (the "License"). You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. Unless required by applicable law or agreed - * to in writing, software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -using MorganStanley.ComposeUI.Shell.Utilities; -using System.Globalization; - -namespace MorganStanley.ComposeUI.Shell.Tests -{ - public class CommandLineParserSimpleDoubleTests - { - private static readonly Random Random = new Random(); - - public class SimpleDoubleOptions - { - public double? Option { get; set; } - } - - [Fact] - public void TestParseSimpleDoubleWithEmptyParameterList() - { - var options = CommandLineParser.Parse(new string[0]); - Assert.NotNull(options); - Assert.Null(options.Option); - } - - [Fact] - public void TestParseSimpleDoubleWithValueProvided() - { - var testValue = Random.NextDouble(); - var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); - Assert.NotNull(options); - Assert.Equal(testValue, options.Option); - } - - [Fact] - public void TestParseSimpleDoubleWithoutValue() - { - Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); - } - - [Fact] - public void TestParseSimpleDoubleWithOnlyDifferentParameter() - { - var options = CommandLineParser.Parse(new[] { "--stuff", Random.NextDouble().ToString() }); - Assert.NotNull(options); - Assert.Null(options.Option); - } - - [Fact] - public void TestParseSimpleDoubleWithOtherParameters() - { - var testValue = Random.NextDouble(); - var options = CommandLineParser.Parse(new[] { "--firstParam", Random.NextDouble().ToString(), "--option", testValue.ToString(), "--lastParam", Random.NextDouble().ToString() }); - Assert.NotNull(options); - Assert.Equal(testValue, options.Option); - } - } -} \ No newline at end of file diff --git a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleStringTests.cs b/src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleStringTests.cs deleted file mode 100644 index 0e86d10ec..000000000 --- a/src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleStringTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Morgan Stanley makes this available to you under the Apache License, - * Version 2.0 (the "License"). You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. Unless required by applicable law or agreed - * to in writing, software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions - * and limitations under the License. - */ - -using MorganStanley.ComposeUI.Shell.Utilities; - -namespace MorganStanley.ComposeUI.Shell.Tests -{ - public class CommandLineParserSimpleStringTests - { - public class SimpleStringOptions - { - public string? Option { get; set; } - } - - [Fact] - public void TestParseSimpleStringWithEmptyParameterList() - { - var options = CommandLineParser.Parse(new string[0]); - Assert.NotNull(options); - Assert.Null(options.Option); - } - - [Fact] - public void TestParseSimpleStringWithValueProvided() - { - var testValue = Guid.NewGuid(); - var options = CommandLineParser.Parse(new[] { "--option", testValue.ToString() }); - Assert.NotNull(options); - Assert.Equal(testValue.ToString(), options.Option); - } - - [Fact] - public void TestParseSimpleStringWithoutValue() - { - var testValue = Guid.NewGuid(); - Assert.Throws(() => CommandLineParser.Parse(new[] { "--option" })); - } - - [Fact] - public void TestParseSimpleStringWithOnlyDifferentParameter() - { - var options = CommandLineParser.Parse(new[] { "--stuff", "irrelevant" }); - Assert.NotNull(options); - Assert.Null(options.Option); - } - - [Fact] - public void TestParseSimpleStringWithOtherParameters() - { - var testValue = Guid.NewGuid(); - var options = CommandLineParser.Parse(new[] { "--firstParam", "irrelevant", "--option", testValue.ToString(), "--lastParam", "irrelevant" }); - Assert.NotNull(options); - Assert.Equal(testValue.ToString(), options.Option); - } - } -} \ No newline at end of file