From cb5188c5e0a6954f0a0b004973d71fd58ed13caf Mon Sep 17 00:00:00 2001 From: lilla28 <36889371+lilla28@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:31:21 +0200 Subject: [PATCH] feat(fdc3): Implement RaiseIntent, AddIntentListener, FindIntent and FindIntentsByContext (#383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(fdc3): Implement RaiseIntent, AddIntentListener, FindIntent and FindIntentsByContext * feat(fdc3): Corrections based on PR feedback, bugfixes, more tests * feat(fdc3): Added ModuleLoader to EndToEndTests, hardcoded testcases for EndToEnd tests, restructured methods, internal sealed contracts, added Fdc3StartupParameters, messageIds to messages, fixed locking * feat(fdc3) - Hard coded expected test results for unit tests, mocking ModuleLoader, using AppDirectory, validating the config in ComposeUIDesktopAgent.ts's ctor, fixed Fdc3StartupAction to insert Fdc3StartupProperties always * feat(fdc3): Fix package-lock.json file after merge conflict * fix(fdc3) - Separated communication and Fdc3DesktopAgentBridge, removed extra locks * feat(fdc3) - Adjust PR feedback, corrected comments, typos, docs, separated methods * feat(fdc3): Fix naming conventions, removed comments, fixed test * fix(fdc3) - Removed AppDirectorySample.cs file, added sample appdirectory json file under examples, corrected boolean argument for ts files * Removed unnecessary partial keywords * Moved running module shutdown logic to DisposeAsync * Removed static resources from Fdc3DesktopAgentTests * Removed static state from Fdc3DesktopAgentMessageRouterService.Tests * fix(fdc3): Renamed classes, TimeSpan instead of int, fixed sentences, removed boilerplate code, renamed methods, other fixes based on the feedback (used suggested changes, logging error instead of warnings, JsonSerializerOptions, fixed tests for that) * fix(fdc3): Moved business logic leftover to the DesktopAgent from the MessageRouterService --------- Co-authored-by: Róbert Zöldi-Kovács <13298643+ZKRobi@users.noreply.github.com> --- .../fdc3-appdirectory/apps-with-intents.json | 70 + package-lock.json | 3927 ++++++----------- .../Hosts/BackgroundModuleHost.cs | 2 +- .../ModuleLoader/Hosts/ModuleHostBase.cs | 1 - .../ModuleLoader/Hosts/WebpageModuleHost.cs | 3 - .../ModuleLoader/Hosts/WindowedModuleHost.cs | 2 +- .../dotnet/ModuleLoader/ModuleLoader.cs | 1 - .../ModuleLoader/Modules/ProcessInfo.cs | 2 +- prototypes/process-explorer/.gitignore | 42 + prototypes/process-explorer/js/.gitignore | 42 + src/fdc3/dotnet/DesktopAgent/DesktopAgent.sln | 37 +- .../Contracts/FindChannelRequest.cs | 2 +- .../Contracts/FindChannelResponse.cs | 2 +- .../Contracts/FindIntentRequest.cs | 44 + .../Contracts/FindIntentResponse.cs | 36 + .../Contracts/FindIntentsByContextRequest.cs | 39 + .../Contracts/FindIntentsByContextResponse.cs | 38 + .../Contracts/GetCurrentContextRequest.cs | 9 +- .../Contracts/GetIntentResultRequest.cs | 44 + .../Contracts/GetIntentResultResponse.cs | 80 + .../Contracts/IntentListenerRequest.cs | 40 + .../Contracts/IntentListenerResponse.cs | 35 + .../Contracts/RaiseIntentRequest.cs | 60 + .../Contracts/RaiseIntentResolutionRequest.cs | 40 + .../Contracts/RaiseIntentResponse.cs | 50 + .../Contracts/StoreIntentResultRequest.cs | 70 + .../Contracts/StoreIntentResultResponse.cs | 35 + .../DesktopAgent/Contracts/SubscribeState.cs | 30 + .../Converters/AppIntentJsonConverter.cs | 33 + .../Converters/AppMetadataJsonConverter.cs | 33 + .../Converters/IconJsonConverter.cs | 33 + .../Converters/ImageJsonConverter.cs | 33 + .../Converters/IntentMetadataJsonConverter.cs | 33 + .../Fdc3DesktopAgentOptions.cs | 7 + .../ServiceCollectionExtensions.cs | 8 +- .../src/DesktopAgent/DesktopAgent.csproj | 29 + .../Exceptions/Fdc3DesktopAgentErrors.cs | 48 + .../Exceptions/Fdc3DesktopAgentException.cs | 33 + .../DesktopAgent/Exceptions/ThrowHelper.cs | 38 + .../src/DesktopAgent/Fdc3DesktopAgent.cs | 685 ++- .../src/DesktopAgent/Fdc3StartupAction.cs | 73 + .../src/DesktopAgent/Fdc3StartupParameters.cs | 23 + .../src/DesktopAgent/Fdc3StartupProperties.cs | 23 + .../src/DesktopAgent/Fdc3Topic.cs | 15 +- .../Fdc3DesktopAgentMessageRouterService.cs | 201 + .../Internal/IFdc3DesktopAgentBridge.cs | 92 + .../RaiseIntentResolutionInvocation.cs | 53 + .../Internal/RaiseIntentResolutionMessage.cs | 33 + .../Internal/RaiseIntentResult.cs | 30 + .../Internal/RaisedIntentRequestHandler.cs | 116 + .../DesktopAgent/Protocol/AppIdentifier.cs | 22 + .../src/DesktopAgent/Protocol/AppIntent.cs | 24 + .../src/DesktopAgent/Protocol/AppMetadata.cs | 43 + .../DesktopAgent/Protocol/ContextMetadata.cs | 22 + .../DesktopAgent/Protocol/DisplayMetadata.cs | 24 + .../src/DesktopAgent/Protocol/Icon.cs} | 30 +- .../Protocol/ImplementationMetadata.cs | 30 + .../DesktopAgent/Protocol/IntentMetadata.cs | 22 + .../src/DesktopAgent/Protocol/Screenshot.cs | 37 + .../src/DesktopAgent}/ResourceNames.cs | 5 +- .../src/DesktopAgent/UserChannel.cs | 17 +- .../DesktopAgent.Tests.csproj | 8 + .../tests/DesktopAgent.Tests/EndToEndTests.cs | 836 +++- .../Fdc3DesktopAgentTests.cs | 583 ++- .../Helpers/Fdc3InstanceIdRetriever.cs | 41 + ...3DesktopAgentMessageRouterService.Tests.cs | 1444 ++++++ .../TestUtils/MockModuleLoader.cs | 107 + .../TestUtils/appDirectorySample.json | 256 ++ src/fdc3/js/composeui-fdc3/jest.config.ts | 2 + src/fdc3/js/composeui-fdc3/package.json | 8 +- .../src/ComposeUIDesktopAgent.ts | 209 +- .../composeui-fdc3/src/Fdc3ComposeUI.spec.ts | 455 +- .../src/infrastructure/ComposeUIChannel.ts | 4 +- ...istener.ts => ComposeUIContextListener.ts} | 4 +- .../src/infrastructure/ComposeUIErrors.ts | 20 + .../infrastructure/ComposeUIIntentListener.ts | 103 + .../ComposeUIIntentResolution.ts | 71 + .../src/infrastructure/ComposeUITopic.ts | 51 +- .../messages/Fdc3FindIntentRequest.ts | 24 + .../messages/Fdc3FindIntentResponse.ts | 19 + .../Fdc3FindIntentsByContextRequest.ts | 23 + .../Fdc3FindIntentsByContextResponse.ts | 19 + .../messages/Fdc3GetIntentResultRequest.ts | 23 + .../messages/Fdc3GetIntentResultResponse.ts | 23 + .../messages/Fdc3IntentListenerRequest.ts | 22 + .../messages/Fdc3IntentListenerResponse.ts | 17 + .../messages/Fdc3RaiseIntentRequest.ts | 27 + .../Fdc3RaiseIntentResolutionRequest.ts | 20 + .../messages/Fdc3RaiseIntentResponse.ts | 21 + .../messages/Fdc3StoreIntentResultRequest.ts | 29 + .../messages/Fdc3StoreIntentResultResponse.ts | 17 + src/package-lock.json | 6 + .../dotnet/MorganStanley.ComposeUI.Shared.sln | 39 + .../CommandLineParser.cs | 2 +- .../MorganStanley.ComposeUI.Utilities.csproj | 12 + .../ResourceReader.cs | 6 +- ...ommandLineParserAttributedPropertyTests.cs | 57 + ...mandLineParserCustomPropertyDoubleTests.cs | 84 + ...mandLineParserCustomPropertyStringTests.cs | 72 + .../CommandLineParserSimpleDoubleTests.cs | 68 + .../CommandLineParserSimpleStringTests.cs | 66 + ...anStanley.ComposeUI.Utilities.Tests.csproj | 35 + .../ResourceReaderTests.cs | 17 +- .../Usings.cs | 1 + src/shared/dotnet/tests/TestUtils/test.js | 0 src/shell/dotnet/Shell.sln | 7 + src/shell/dotnet/Shell/App.xaml.cs | 5 +- src/shell/dotnet/Shell/Shell.csproj | 24 +- src/shell/dotnet/Shell/WebWindow.xaml.cs | 21 +- src/shell/dotnet/Shell/WebWindowOptions.cs | 16 +- ...ommandLineParserAttributedPropertyTests.cs | 58 - ...mandLineParserCustomPropertyDoubleTests.cs | 85 - ...mandLineParserCustomPropertyStringTests.cs | 73 - .../CommandLineParserSimpleDoubleTests.cs | 69 - .../CommandLineParserSimpleStringTests.cs | 67 - 115 files changed, 8915 insertions(+), 3192 deletions(-) create mode 100644 examples/fdc3-appdirectory/apps-with-intents.json create mode 100644 prototypes/process-explorer/.gitignore create mode 100644 prototypes/process-explorer/js/.gitignore create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentRequest.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentResponse.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextRequest.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/FindIntentsByContextResponse.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultRequest.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/GetIntentResultResponse.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerRequest.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/IntentListenerResponse.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentRequest.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResolutionRequest.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/RaiseIntentResponse.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultRequest.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/StoreIntentResultResponse.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Contracts/SubscribeState.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppIntentJsonConverter.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/AppMetadataJsonConverter.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IconJsonConverter.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/ImageJsonConverter.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Converters/IntentMetadataJsonConverter.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentErrors.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/Fdc3DesktopAgentException.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Exceptions/ThrowHelper.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupAction.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupParameters.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Fdc3StartupProperties.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/IFdc3DesktopAgentBridge.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionInvocation.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResolutionMessage.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaiseIntentResult.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Infrastructure/Internal/RaisedIntentRequestHandler.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIdentifier.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppIntent.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/AppMetadata.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ContextMetadata.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/DisplayMetadata.cs rename src/{shell/dotnet/Shell/Fdc3/Fdc3StartupAction.cs => fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Icon.cs} (51%) create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/ImplementationMetadata.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/IntentMetadata.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/src/DesktopAgent/Protocol/Screenshot.cs rename src/{shell/dotnet/Shell/Utilities => fdc3/dotnet/DesktopAgent/src/DesktopAgent}/ResourceNames.cs (73%) create mode 100644 src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Helpers/Fdc3InstanceIdRetriever.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/Infrastructure/Internal/Fdc3DesktopAgentMessageRouterService.Tests.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/MockModuleLoader.cs create mode 100644 src/fdc3/dotnet/DesktopAgent/tests/DesktopAgent.Tests/TestUtils/appDirectorySample.json rename src/fdc3/js/composeui-fdc3/src/infrastructure/{ComposeUIListener.ts => ComposeUIContextListener.ts} (95%) create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIErrors.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentListener.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/ComposeUIIntentResolution.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentRequest.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentResponse.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextRequest.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3FindIntentsByContextResponse.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultRequest.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3GetIntentResultResponse.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerRequest.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3IntentListenerResponse.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentRequest.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResolutionRequest.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3RaiseIntentResponse.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultRequest.ts create mode 100644 src/fdc3/js/composeui-fdc3/src/infrastructure/messages/Fdc3StoreIntentResultResponse.ts create mode 100644 src/package-lock.json create mode 100644 src/shared/dotnet/MorganStanley.ComposeUI.Shared.sln rename src/{shell/dotnet/Shell/Utilities => shared/dotnet/src/MorganStanley.ComposeUI.Utilities}/CommandLineParser.cs (98%) create mode 100644 src/shared/dotnet/src/MorganStanley.ComposeUI.Utilities/MorganStanley.ComposeUI.Utilities.csproj rename src/{shell/dotnet/Shell/Utilities => shared/dotnet/src/MorganStanley.ComposeUI.Utilities}/ResourceReader.cs (84%) create mode 100644 src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserAttributedPropertyTests.cs create mode 100644 src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyDoubleTests.cs create mode 100644 src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserCustomPropertyStringTests.cs create mode 100644 src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleDoubleTests.cs create mode 100644 src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/CommandLineParserSimpleStringTests.cs create mode 100644 src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/MorganStanley.ComposeUI.Utilities.Tests.csproj rename src/{shell/dotnet/tests/Shell.Tests => shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests}/ResourceReaderTests.cs (66%) create mode 100644 src/shared/dotnet/tests/MorganStanley.ComposeUI.Utilities.Tests/Usings.cs create mode 100644 src/shared/dotnet/tests/TestUtils/test.js delete mode 100644 src/shell/dotnet/tests/Shell.Tests/CommandLineParserAttributedPropertyTests.cs delete mode 100644 src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyDoubleTests.cs delete mode 100644 src/shell/dotnet/tests/Shell.Tests/CommandLineParserCustomPropertyStringTests.cs delete mode 100644 src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleDoubleTests.cs delete mode 100644 src/shell/dotnet/tests/Shell.Tests/CommandLineParserSimpleStringTests.cs 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