From 57d650f0c18318c4f863d33f7bf4bd70d3e69f22 Mon Sep 17 00:00:00 2001 From: Tareq Imbasher Date: Sat, 1 Jun 2024 07:54:49 +0300 Subject: [PATCH] Solution restructure When I started this project I knew I wanted to work towards these minimum requirements: 1. Must support Windows, macOS and Linux 2. Must support at least .NET 6 or higher 3. Must run with as little hassle as possible for end users. I initially took a layered approach to structuring the solution, this helped me clearly understand the different components, abstractions and dependencies that will make up the app during development. Its time for a simpler structure however that's easier to understand and maintain. This restructure aims to: 1. Make the solution easier to maintain by reducing separation between components and bringing more related functionality together. 2. Make the solution easier to review by the community and easier to understand and contribute to. I plan to add documentation explaining the high level concepts and structure of the solution to help facilitate review and contribution. Some notable technical changes: - Reduced number of projects. Most of the core functionality of NetPad is now in a new NetPad.Runtime project - The concept of a "ScriptRuntime" is now called a "ScriptRunner" and is part of the "Execution Model" - Use Directory.Build.props file and C# 12 features - No refactoring was done to the JS app - Fix web version 'process' pollyfill - Passing --swagger flag to NetPad.Apps.App generates Swagger client code Refactoring that is also planned soon: - Refactoring of the JS app - Changing the name of the NetPad.Apps.App project and the folder containing the JS client app, currently named "App" --- src/.editorconfig => .editorconfig | 1 - .gitignore | 9 +- Directory.Build.props | 13 + global.json | 6 + .../App/src/core/@common/utils/system.ts | 13 +- .../App/src/core/@domain/api.ts | 149 ++++---- .../syntax-tree-view/syntax-tree-view.html | 5 +- .../src/windows/main/work-area/work-area.ts | 4 +- .../App/src/windows/settings/about/about.html | 4 - .../NetPad.Apps.App/App/webpack.config.js | 1 + .../AppSetupAndCleanupBackgroundService.cs | 42 +-- .../BackgroundServices/BackgroundService.cs | 3 - .../DebugAssemblyUnloadBackgroundService.cs | 11 +- .../EventForwardToIpcBackgroundService.cs | 42 +-- .../EventHandlerBackgroundService.cs | 15 +- .../ScriptEnvironmentBackgroundService.cs | 56 ++- .../ScriptsFileWatcherBackgroundService.cs | 7 +- .../Controllers/AppController.cs | 19 +- .../Controllers/AssembliesController.cs | 13 +- .../Controllers/CodeController.cs | 1 - .../Controllers/DataConnectionsController.cs | 31 +- .../Controllers/FilesController.cs | 1 - .../Controllers/PackagesController.cs | 29 +- .../Controllers/ScriptsController.cs | 63 ++-- .../Controllers/SessionController.cs | 30 +- .../Controllers/SettingsController.cs | 23 +- .../Controllers/TypesController.cs | 14 +- .../Controllers/WindowController.cs | 18 +- .../NetPad.Apps.App/Dtos/CreateScriptDto.cs | 2 - src/Apps/NetPad.Apps.App/Dtos/ErrorResult.cs | 12 +- .../NetPad.Apps.App/Dtos/RunOptionsDto.cs | 30 -- src/Apps/NetPad.Apps.App/GlobalUsings.cs | 3 + .../Middlewares/ExceptionHandlerMiddleware.cs | 24 +- .../NetPad.Apps.App/NetPad.Apps.App.csproj | 30 +- .../NetPad.Apps.App/Pages/Error.cshtml.cs | 9 +- src/Apps/NetPad.Apps.App/Program.cs | 95 ++++- .../Properties/launchSettings.json | 40 +++ ...DataConnectionResourcesGeneratorFactory.cs | 27 -- ...tabaseConnectionMetadataProviderFactory.cs | 27 -- .../Services/MediatorRequestPipeline.cs | 2 +- .../ScriptEnvironmentIpcOutputWriter.cs | 21 +- .../NetPad.Apps.App/Services/ScriptService.cs | 64 ++++ src/Apps/NetPad.Apps.App/Startup.cs | 117 +++--- .../Swagger/OperationProcessors.cs | 22 +- .../Swagger/SwaggerCodeGenerationStartup.cs | 104 ++++++ .../NetPad.Apps.App/Swagger/SwaggerSetup.cs | 9 +- .../Swagger/TypeScriptClientCodeTransform.cs | 1 - src/Apps/NetPad.Apps.App/global.json | 7 - .../CQs/ActivateLastActiveScriptCommand.cs | 16 + .../CQs/ActivateScriptCommand.cs | 18 + .../AlertUserAboutMissingAppDependencies.cs | 8 + .../CQs/AlertUserCommand.cs | 6 + src/Apps/NetPad.Apps.Common/CQs/Bases.cs | 19 + .../CQs/CheckAppDependenciesQuery.cs | 28 +- .../CQs/CloseScriptCommand.cs | 35 ++ .../CQs/ConfirmSaveCommand.cs | 9 + .../CQs/ConfirmWithUserCommand.cs | 8 + .../CQs/CreateScriptCommand.cs | 28 ++ .../CQs/DeleteDataConnectionCommand.cs | 33 ++ .../CQs/DuplicateScriptCommand.cs | 34 ++ .../CQs/GetActiveScriptEnviornmentQuery.cs | 16 + .../CQs/GetAllScriptsQuery.cs | 16 + .../CQs/GetDataConnectionQuery.cs | 18 + .../CQs/GetDataConnectionsQuery.cs | 16 + .../GetDatabaseConnectionStructureQuery.cs | 20 ++ .../CQs/GetOpenedScriptEnvironmentQuery.cs | 27 ++ .../CQs/GetOpenedScriptEnvironmentsQuery.cs | 14 +- .../CQs/OpenScriptCommand.cs | 23 +- .../CQs/OpenWindowCommand.cs | 17 +- .../CQs/PromptUserCommand.cs | 7 + .../CQs/PromptUserForInputCommand.cs | 6 + .../CQs/RefreshDataConnectionCommand.cs | 40 +++ .../CQs/RenameScriptCommand.cs | 39 ++ .../CQs/RequestNewScriptNameCommand.cs | 6 + .../CQs/RunScriptCommand.cs | 27 ++ .../CQs/SaveDataConnectionCommand.cs | 40 +-- .../CQs/SaveScriptCommand.cs | 34 ++ .../CQs/SetScriptDataConnectionCommand.cs | 33 ++ .../CQs/StopScriptCommand.cs | 24 ++ .../CQs/UpdateScriptCodeCommand.cs | 33 ++ .../CQs/UpdateScriptNamespacesCommand.cs | 26 +- .../UpdateScriptOptimizationLevelCommand.cs | 34 ++ .../CQs/UpdateScriptReferencesCommand.cs | 26 +- .../CQs/UpdateScriptTargetFrameworkCommand.cs | 28 +- .../CQs/UpdateScriptUseAspNetCommand.cs | 33 ++ .../CQs/UpdateSettingsCommand.cs | 32 +- .../FileSystemSettingsRepository.cs | 13 +- .../EntityFrameworkDatabaseConnection.cs | 31 +- ...tyFrameworkRelationalDatabaseConnection.cs | 20 +- ...meworkSchemaChangeDetectionStrategyBase.cs | 21 +- .../MsSqlServerDatabaseConnection.cs | 17 +- ...erDatabaseSchemaChangeDetectionStrategy.cs | 26 +- .../PostgreSqlDatabaseConnection.cs | 17 +- ...qlDatabaseSchemaChangeDetectionStrategy.cs | 26 +- .../SQLiteDatabaseConnection.cs | 17 +- ...teDatabaseSchemaChangeDetectionStrategy.cs | 26 +- .../EntityFrameworkCore/DatabaseContext.cs | 9 +- .../DependencyInjection.cs | 24 ++ ...meworkConnectionMetadataProviderFactory.cs | 19 + ...workConnectionResourcesGeneratorFactory.cs | 19 + ...eworkDatabaseConnectionMetadataProvider.cs | 36 +- .../EntityFrameworkPackageUtils.cs | 3 +- .../EntityFrameworkResourcesGenerator.cs | 67 ++-- .../EntityFrameworkUtils.cs | 34 +- .../EntityFrameworkDatabaseScaffolder.cs | 61 ++-- .../Scaffolding/ScaffoldOptions.cs | 8 +- .../Scaffolding/ScaffoldedDatabaseModel.cs | 11 +- .../Scaffolding/ScaffoldedSourceFile.cs | 12 + .../AnyDatabaseProviderTransform.cs | 5 +- .../Transforms/IScaffoldedModelTransform.cs | 2 +- .../Transforms/PostgresSqlTransform.cs | 2 +- .../FileSystemDataConnectionRepository.cs | 27 +- ...temDataConnectionResourcesCache.Helpers.cs | 48 ++- .../FileSystemDataConnectionResourcesCache.cs | 73 ++-- ...SystemDataConnectionResourcesRepository.cs | 35 +- .../Data}/FileSystemTrivialDataStore.cs | 7 +- src/Apps/NetPad.Apps.Common/GlobalUsings.cs | 6 + src/Apps/NetPad.Apps.Common/HostInfo.cs | 19 + .../NetPad.Apps.Common.csproj | 23 ++ .../NetPad.Apps.Common}/Plugins/IPlugin.cs | 2 +- .../Plugins/IPluginManager.cs | 2 +- .../Plugins/PluginInitialization.cs | 2 +- .../Plugins/PluginManager.cs | 15 +- .../Plugins/PluginRegistration.cs | 2 +- .../Resources/ILogoService.cs | 2 +- .../Resources/LogoService.cs | 10 + .../FileSystemAutoSaveScriptRepository.cs | 7 +- .../Scripts/FileSystemScriptRepository.cs | 10 +- .../Scripts/ScriptSerializer.cs | 21 +- .../NetPad.Apps.Common/Shells/IShell.cs} | 9 +- .../UiInterop/IIpcService.cs | 4 +- .../UiInterop/IUiDialogService.cs | 2 +- .../UiInterop/IUiWindowService.cs | 2 +- .../NetPad.Apps.Common}/UiInterop/IpcHub.cs | 2 +- .../UiInterop/IpcMessage.cs | 2 +- .../UiInterop/IpcMessageBatch.cs | 6 + .../UiInterop/IpcResponsePromise.cs | 2 +- .../UiInterop/IpcResponseQueue.cs | 5 +- .../UiInterop/SignalRIpcService.cs | 15 +- .../UiInterop/YesNoCancel.cs | 2 +- .../NotificationBackgroundService.cs | 22 +- .../ElectronShell.cs} | 17 +- .../NetPad.Apps.Shells.Electron.csproj} | 5 +- .../UiInterop/BrowserWindowInfo.cs | 15 + .../UiInterop/ElectronDialogService.cs | 25 +- .../UiInterop/ElectronIpcService.cs | 17 +- .../UiInterop/ElectronUtil.cs | 2 +- .../UiInterop/ElectronWindowService.cs | 60 ++-- .../UiInterop/WindowManager.cs | 22 +- .../UiInterop/WindowState.cs | 2 +- .../NetPad.Apps.Shells.Web.csproj | 12 + .../UiInterop/WebDialogService.cs | 29 ++ .../UiInterop/WebWindowService.cs | 25 +- .../WebBrowserShell.cs} | 14 +- .../Application/AppStatusMessagePublisher.cs | 25 -- .../Application/ApplicationInfo.cs | 3 - .../Application/ApplicationType.cs | 7 - .../CQs/ActivateLastActiveScriptCommand.cs | 23 -- .../CQs/ActivateScriptCommand.cs | 30 -- .../AlertUserAboutMissingAppDependencies.cs | 13 - .../CQs/AlertUserCommand.cs | 11 - src/Core/NetPad.Application/CQs/Bases.cs | 35 -- .../CQs/CloseScriptCommand.cs | 78 ---- .../CQs/ConfirmSaveCommand.cs | 14 - .../CQs/ConfirmWithUserCommand.cs | 13 - .../CQs/CreateScriptCommand.cs | 34 -- .../CQs/DeleteDataConnectionCommand.cs | 44 --- .../CQs/DuplicateScriptCommand.cs | 54 --- .../CQs/GetActiveScriptEnviornmentQuery.cs | 23 -- .../CQs/GetAllScriptsQuery.cs | 22 -- .../CQs/GetDataConnectionQuery.cs | 29 -- .../CQs/GetDataConnectionsQuery.cs | 22 -- .../GetDatabaseConnectionStructureQuery.cs | 31 -- .../CQs/GetOpenedScriptEnvironmentQuery.cs | 40 --- .../CQs/PromptUserCommand.cs | 13 - .../CQs/PromptUserForInputCommand.cs | 11 - .../CQs/RefreshDataConnectionCommand.cs | 57 --- .../CQs/RenameScriptCommand.cs | 58 --- .../CQs/RequestNewScriptNameCommand.cs | 11 - .../CQs/RunScriptCommand.cs | 40 --- .../CQs/SaveScriptCommand.cs | 65 ---- .../CQs/SetScriptDataConnectionCommand.cs | 45 --- .../CQs/StopScriptCommand.cs | 37 -- .../CQs/UpdateScriptCodeCommand.cs | 45 --- .../UpdateScriptOptimizationLevelCommand.cs | 47 --- .../CQs/UpdateScriptUseAspNetCommand.cs | 46 --- .../Events/ActiveEnvironmentChangedEvent.cs | 11 - .../Events/AppStatusMessagePublishedEvent.cs | 13 - .../Events/DataConnectionDeletedEvent.cs | 13 - ...ataConnectionResourcesUpdateFailedEvent.cs | 17 - .../DataConnectionResourcesUpdatedEvent.cs | 21 -- .../DataConnectionResourcesUpdatingEvent.cs | 15 - .../Events/DataConnectionSavedEvent.cs | 13 - ...onnectionSchemaValidationCompletedEvent.cs | 11 - ...aConnectionSchemaValidationStartedEvent.cs | 11 - .../Events/EnvironmentsAddedEvent.cs | 13 - .../Events/EnvironmentsRemovedEvent.cs | 13 - .../Events/ScriptClosedEvent.cs | 13 - .../Events/ScriptCodeUpdatedEvent.cs | 17 - .../Events/ScriptCreatedEvent.cs | 14 - .../ScriptDataConnectionChangedEvent.cs | 16 - .../Events/ScriptDirectoryChangedEvent.cs | 13 - .../Events/ScriptNamespacesUpdatedEvent.cs | 17 - .../Events/ScriptOpenedEvent.cs | 13 - .../ScriptOptimizationLevelUpdatedEvent.cs | 18 - .../Events/ScriptOutputEmittedEvent.cs | 17 - .../Events/ScriptRanEvent.cs | 13 - .../Events/ScriptReferencesUpdatedEvent.cs | 18 - .../Events/ScriptRunCancelledEvent.cs | 13 - .../Events/ScriptSavedEvent.cs | 14 - ...criptTargetFrameworkVersionUpdatedEvent.cs | 18 - .../Events/ScriptUseAspNetUpdatedEvent.cs | 17 - .../Events/SettingsUpdatedEvent.cs | 13 - src/Core/NetPad.Application/GlobalUsings.cs | 1 - src/Core/NetPad.Application/HostInfo.cs | 25 -- .../NetPad.Application.csproj | 26 -- .../Resources/LogoService.cs | 17 - .../DefaultScriptEnvironmentFactory.cs | 19 - .../Scripts/IScriptEnvironmentFactory.cs | 6 - .../UiInterop/IpcMessageBatch.cs | 11 - .../CodeAnalysis/SyntaxNodeOrTokenSlim.cs | 35 -- .../CodeAnalysis/SyntaxTriviaSlim.cs | 18 - .../Common/JsonConverterWithCtorArgs.cs | 24 -- .../Compilation/CSharp/CSharpCodeParser.cs | 103 ------ .../Compilation/CompilationInput.cs | 62 ---- .../Compilation/CompilationResult.cs | 23 -- .../NetPad.Domain/Compilation/GlobalUsings.cs | 1 - .../Compilation/ParsedCodeInformation.cs | 15 - .../Compilation/PreprocessorSymbols.cs | 13 - ...ionSchemaChangeDetectionStrategyFactory.cs | 22 -- .../Data/DataConnectionSourceCode.cs | 18 - .../NetPad.Domain/Data/DatabaseStructure.cs | 167 --------- .../DotNet/AssemblyFileReference.cs | 22 -- .../DotNet/AssemblyImageReference.cs | 19 - .../DotNet/DotNetFrameworkVersionUtil.cs | 103 ------ src/Core/NetPad.Domain/DotNet/Namespace.cs | 70 ---- .../NetPad.Domain/DotNet/SourceCodeElement.cs | 33 -- .../NetPad.Domain/Events/DisposableToken.cs | 18 - .../Events/EnvironmentPropertyChangedEvent.cs | 14 - .../Events/PropertyChangedEvent.cs | 15 - .../ScriptConfigPropertyChangedEvent.cs | 14 - .../Events/ScriptPropertyChangedEvent.cs | 14 - .../EnvironmentNotFoundException.cs | 10 - .../Exceptions/InvalidReferenceException.cs | 14 - .../InvalidScriptFormatException.cs | 20 -- .../Exceptions/ScriptRuntimeException.cs | 10 - src/Core/NetPad.Domain/GlobalUsings.cs | 3 - .../NetPad.Domain/IO/ActionInputReader.cs | 21 -- .../NetPad.Domain/IO/ActionOutputWriter.cs | 31 -- .../IO/AsyncActionInputReader.cs | 21 -- .../IO/AsyncActionOutputWriter.cs | 30 -- src/Core/NetPad.Domain/IO/ProcessHandler.cs | 238 ------------- src/Core/NetPad.Domain/IO/ProcessIO.cs | 57 --- src/Core/NetPad.Domain/NetPad.Domain.csproj | 18 - .../NetPad.Domain/Packages/CachedPackage.cs | 11 - .../Runtimes/IScriptRuntimeFactory.cs | 8 - src/Core/NetPad.Domain/Runtimes/RunOptions.cs | 52 --- .../NetPad.Domain/Scripts/ScriptSummary.cs | 19 - src/Core/NetPad.Domain/Utilities/Accessor.cs | 20 -- src/Core/NetPad.Domain/ValueObject.cs | 53 --- .../NetPad.Presentation.csproj | 28 -- .../Application/AppDependencyCheckResult.cs | 0 .../Application/AppIdentifier.cs | 3 +- .../Application/AppStatusMessage.cs | 21 +- .../Application/AppStatusMessagePublisher.cs | 27 ++ .../Events/AppStatusMessagePublishedEvent.cs | 8 + .../Application/IAppStatusMessagePublisher.cs | 0 .../Assemblies/AssemblyInfoReader.cs | 2 - .../Assemblies/IAssemblyLoader.cs | 2 - .../Assemblies/UnloadableAssemblyLoader.cs | 36 +- .../CodeAnalysis/CodeAnalysisExtensions.cs | 17 + .../CodeAnalysis/CodeAnalysisService.cs | 20 +- .../CodeAnalysis/ICodeAnalysisService.cs | 3 +- .../CodeAnalysis/SyntaxNodeOrTokenSlim.cs | 29 ++ .../CodeAnalysis/SyntaxTriviaSlim.cs | 11 + .../Common/GlobalConsts.cs | 5 +- .../Common/INotifyOnPropertyChanged.cs | 21 +- .../Common/JsonConverterWithCtorArgs.cs | 14 + .../Common/JsonInheritanceConverter.cs | 5 +- .../Common/JsonSerializer.cs | 1 - .../Compilation/CSharp/CSharpCodeCompiler.cs | 47 ++- .../Compilation/CodeParsingOptions.cs | 2 +- .../Compilation/CodeParsingResult.cs | 24 +- .../Compilation/CompilationInput.cs | 51 +++ .../Compilation/CompilationResult.cs | 19 + .../Compilation/FrameworkAssemblies.cs} | 13 +- .../Compilation/ICodeCompiler.cs | 0 .../Compilation/ICodeParser.cs | 9 +- .../Compilation/PreprocessorSymbols.cs | 12 + .../Configuration/AppDataProvider.cs | 1 - .../Configuration/AppearanceOptions.cs | 1 - .../Configuration/EditorOptions.cs | 1 - .../Events/SettingsUpdatedEvent.cs | 8 + .../Configuration/ISettingsOptions.cs | 0 .../Configuration/ISettingsRepository.cs | 1 - .../Configuration/KeyboardShortcutOptions.cs | 14 +- .../Configuration/OmniSharpOptions.cs | 1 - .../Configuration/ResultsOptions.cs | 0 .../Configuration/Settings.cs | 3 +- .../Configuration/StyleOptions.cs | 0 .../Configuration/Theme.cs | 0 .../Data/ConnectionStringBuilder.cs | 10 +- .../Data/DataConnection.cs | 18 +- .../Data/DataConnectionResourceComponent.cs | 0 .../Data/DataConnectionResources.cs | 14 +- ...ionSchemaChangeDetectionStrategyFactory.cs | 13 + .../Data/DataConnectionSourceCode.cs | 11 + .../Data/DataConnectionTestResult.cs | 11 +- .../Data/DataConnectionType.cs | 0 .../Data/DataProtector.cs | 10 +- .../Data/DatabaseConnection.cs | 8 +- .../NetPad.Runtime/Data/DatabaseStructure.cs | 117 ++++++ .../Data/Events/DataConnectionDeletedEvent.cs | 8 + ...ataConnectionResourcesUpdateFailedEvent.cs | 14 + .../DataConnectionResourcesUpdatedEvent.cs | 17 + .../DataConnectionResourcesUpdatingEvent.cs | 12 + .../Data/Events/DataConnectionSavedEvent.cs | 8 + ...onnectionSchemaValidationCompletedEvent.cs | 8 + ...aConnectionSchemaValidationStartedEvent.cs | 8 + .../FakeDataConnectionPasswordProtector.cs | 0 .../Data/IDataConnectionPasswordProtector.cs | 0 .../Data/IDataConnectionRepository.cs | 4 - .../Data/IDataConnectionResourcesCache.cs | 2 - .../Data/IDataConnectionResourcesGenerator.cs | 1 - ...DataConnectionResourcesGeneratorFactory.cs | 0 .../IDataConnectionResourcesRepository.cs | 2 - ...ConnectionSchemaChangeDetectionStrategy.cs | 2 - ...ionSchemaChangeDetectionStrategyFactory.cs | 2 - .../IDatabaseConnectionMetadataProvider.cs | 2 - ...tabaseConnectionMetadataProviderFactory.cs | 0 .../Data/ITrivialDataStore.cs | 0 .../Data/SchemaCompareInfo.cs | 10 +- .../NetPad.Runtime/DependencyInjection.cs | 60 ++++ .../DotNet/AssemblyFileReference.cs | 16 + .../DotNet/AssemblyImage.cs | 1 - .../DotNet/AssemblyImageReference.cs | 15 + .../DotNet/Code.cs | 18 +- .../DotNet/DotNetCSharpProject.cs | 7 +- .../DotNet/DotNetFrameworkVersion.cs | 2 - .../DotNet/DotNetFrameworkVersionUtil.cs | 113 ++++++ .../DotNet/DotNetInfo.cs | 27 +- .../DotNet/DotNetRuntimeVersion.cs | 0 .../DotNet/DotNetSdkPack.cs | 0 .../DotNet/DotNetSdkVersion.cs | 0 .../DotNet/IDotNetInfo.cs | 0 src/Core/NetPad.Runtime/DotNet/Namespace.cs | 47 +++ .../DotNet/PackageReference.cs | 12 +- .../DotNet/ProjectOutputType.cs | 0 .../DotNet/Reference.cs | 0 .../DotNet/ReferenceAsset.cs | 0 .../DotNet/SourceCode.cs | 72 ++-- .../DotNet/SourceCodeCollection.cs | 17 +- .../DotNet/SourceCodeElement.cs | 18 + .../DotNet/Using.cs | 50 +-- .../NetPad.Runtime/Events/DisposableToken.cs | 9 + .../Events/EventBus.cs | 55 ++- .../Events/IEvent.cs | 4 +- .../Events/IEventBus.cs | 9 +- .../EnvironmentNotFoundException.cs | 3 + .../Exceptions/InvalidReferenceException.cs | 8 + .../InvalidScriptFormatException.cs | 14 + .../Exceptions/ScriptNotFoundException.cs | 2 - .../Exceptions/ScriptRuntimeException.cs | 3 + .../ExecutionModel/DependencyInjection.cs | 38 ++ .../External/EmbeddedCode/Program.cs | 127 +++++++ .../External}/EmbeddedCode/SqlAccessCode.cs | 6 +- .../ExternalRunnerCSharpCodeParser.cs | 85 +++++ .../External/ExternalScriptRunner.IO.cs} | 20 +- .../External/ExternalScriptRunner.Setup.cs | 306 ++++++++++++++++ .../External/ExternalScriptRunner.cs} | 113 +++--- .../External/ExternalScriptRunnerFactory.cs | 29 ++ .../External/ExternalScriptRunnerOptions.cs | 7 + .../ExecutionModel/External/FileAssetCopy.cs | 11 + .../External/Interface/ActionTextReader.cs | 11 + .../External/Interface/ActionTextWriter.cs | 24 ++ .../Interface/ExternalProcessDumpSink.cs | 93 +++++ .../Interface}/ExternalProcessOutput.cs | 4 +- .../ExternalProcessOutputConsoleWriter.cs | 25 ++ .../ExternalProcessOutputHtmlWriter.cs | 12 +- .../ExternalProcessOutputTextWriter.cs | 26 ++ .../IExternalProcessOutputWriter.cs | 2 +- .../External/Interface}/UserScript.cs | 2 +- .../External/ParseAndCompile.cs | 126 +++++++ .../External}/RawOutputHandler.cs | 8 +- .../ExecutionModel/IScriptRunner.cs} | 20 +- .../ExecutionModel/IScriptRunnerFactory.cs | 8 + .../InMemoryRunnerCSharpCodeParser.cs} | 19 +- .../InMemory/InMemoryScriptRunner.cs} | 57 ++- .../InMemory/InMemoryScriptRunnerFactory.cs | 24 ++ .../ExecutionModel/InMemory/README.md | 1 + .../ExecutionModel/RunOptions.cs | 13 + .../ExecutionModel}/RunResult.cs | 24 +- src/Core/NetPad.Runtime/GlobalUsings.cs | 11 + .../NetPad.Runtime/INetPadRuntimeMarker.cs | 6 + .../IO/AbsolutePath.cs | 3 - .../NetPad.Runtime/IO/ActionInputReader.cs | 11 + .../NetPad.Runtime/IO/ActionOutputWriter.cs | 17 + .../IO/AsyncActionInputReader.cs | 11 + .../IO/AsyncActionOutputWriter.cs | 16 + .../IO/DirectoryPath.cs | 10 +- .../IO/FilePath.cs | 10 +- .../IO/IInputReader.cs | 4 +- .../IO/IOutputWriter.cs | 3 - src/Core/NetPad.Runtime/IO/ProcessHelper.cs | 129 +++++++ .../IO/RelativePath.cs | 4 +- .../Media/Audio.cs | 0 .../Media/Image.cs | 0 .../Media/MediaFile.cs | 12 +- .../Media/MediaFileExtensions.cs | 4 +- .../Media/Video.cs | 0 src/Core/NetPad.Runtime/NetPad.Runtime.csproj | 41 +++ .../NetPad.Runtime/Packages/CachedPackage.cs | 7 + .../Packages/IPackageProvider.cs | 5 +- .../Packages/NuGet}/NuGetPackageProvider.cs | 72 ++-- .../Packages/NuGet}/PackageDependencyTree.cs | 17 +- .../NuGet}/RuntimeProvidedPackages.cs | 4 +- .../Packages/PackageAsset.cs | 0 .../Packages/PackageDependencySet.cs | 0 .../Packages/PackageIdentity.cs | 0 .../Packages/PackageInstallInfo.cs | 15 +- .../Packages/PackageMetadata.cs | 20 +- .../Presentation/Console/ConsolePresenter.cs | 0 .../Presentation}/DumpExtension.cs | 39 +- .../Presentation/DumpOptions.cs | 2 +- .../Presentation/Html/AudioHtmlConverter.cs | 4 +- .../Presentation/Html/HtmlPresenter.cs | 2 +- .../Presentation/Html/ImageHtmlConverter.cs | 4 +- .../Html/MediaFileCollectionConverter.cs | 0 .../Html/MediaFileHtmlConverter.cs | 0 .../Presentation/Html/VideoHtmlConverter.cs | 4 +- .../NetPad.Runtime/Presentation/IDumpSink.cs | 7 + .../Presentation/NullDumpSink.cs | 15 + .../Presentation/PresentationSettings.cs | 1 + .../Presentation}/ScriptOutput.cs | 2 +- .../Presentation/Text/TextPresenter.cs | 0 .../Scripts/DefaultScriptNameGenerator.cs | 11 +- .../Events/EnvironmentPropertyChangedEvent.cs | 7 + .../Scripts}/Events/IScriptEvent.cs | 4 +- .../Scripts/Events/PropertyChangedEvent.cs | 10 + .../Scripts/Events/ScriptClosedEvent.cs | 8 + .../Scripts/Events/ScriptCodeUpdatedEvent.cs | 10 + .../ScriptConfigPropertyChangedEvent.cs | 7 + .../Scripts/Events/ScriptCreatedEvent.cs | 7 + .../ScriptDataConnectionChangedEvent.cs | 10 + .../Events/ScriptDirectoryChangedEvent.cs | 8 + .../Events/ScriptNamespacesUpdatedEvent.cs | 11 + .../Scripts/Events/ScriptOpenedEvent.cs | 8 + .../ScriptOptimizationLevelUpdatedEvent.cs | 12 + .../Events/ScriptOutputEmittedEvent.cs | 11 + .../Events/ScriptPropertyChangedEvent.cs | 7 + .../Scripts/Events/ScriptRanEvent.cs | 8 + .../Events/ScriptReferencesUpdatedEvent.cs | 12 + .../Scripts/Events/ScriptRunCancelledEvent.cs | 8 + .../Scripts/Events/ScriptSavedEvent.cs | 7 + ...criptTargetFrameworkVersionUpdatedEvent.cs | 15 + .../Events/ScriptUseAspNetUpdatedEvent.cs | 10 + .../Scripts/IAutoSaveScriptRepository.cs | 4 - .../Scripts/IScriptNameGenerator.cs | 0 .../Scripts/IScriptRepository.cs | 4 - .../Scripts/Script.cs | 5 +- .../Scripts/ScriptConfig.cs | 74 ++-- .../Scripts/ScriptEnvironment.cs | 101 ++---- .../Scripts/ScriptKind.cs | 0 .../Scripts/ScriptStatus.cs | 0 .../NetPad.Runtime/Scripts/ScriptSummary.cs | 9 + .../SemanticVersion.cs | 1 - .../Events/ActiveEnvironmentChangedEvent.cs | 8 + .../Sessions/Events/EnvironmentsAddedEvent.cs | 9 + .../Events/EnvironmentsRemovedEvent.cs | 9 + .../Sessions/ISession.cs | 0 .../Sessions/Session.cs | 44 +-- src/Core/NetPad.Runtime/Utilities/Accessor.cs | 15 + .../Utilities/AssemblyUtil.cs | 2 - .../Utilities/AsyncUtil.cs | 5 - .../Utilities/CollectionUtil.cs | 4 - .../Utilities/DelegateUtil.cs | 4 - .../Utilities/FileSystemUtil.cs | 1 - .../Utilities/GCUtil.cs | 2 - .../Utilities/HttpClientUtil.cs | 3 - .../Utilities/PlatformUtil.cs | 8 +- .../Utilities/ProcessUtil.cs | 3 +- .../Utilities/ReferenceUtil.cs | 15 +- .../Utilities/Retry.cs | 6 - .../Utilities/StreamUtil.cs | 3 - .../Utilities/StringUtil.cs | 11 +- .../Utilities/Try.cs | 6 +- .../Utilities/TypeUtil.cs | 2 - .../NetPad.Runtime/Utilities/WindowsNative.cs | 36 ++ .../ActionTextReader.cs | 16 - .../ActionTextWriter.cs | 30 -- .../ExternalProcessOutputConsoleWriter.cs | 35 -- .../ExternalProcessOutputFormat.cs | 8 - .../ExternalProcessOutputTextWriter.cs | 37 -- ...ernalProcessScriptRuntime.Interface.csproj | 24 -- .../ScriptRuntimeServices.cs | 78 ---- ...aultExternalProcessScriptRuntimeFactory.cs | 32 -- .../DependencyInjection.cs | 13 - .../EmbeddedCode/Program.cs | 57 --- .../ExternalProcessRuntimeCSharpCodeParser.cs | 87 ----- .../ExternalProcessScriptRuntime.Setup.cs | 335 ------------------ ...NetPad.ExternalProcessScriptRuntime.csproj | 23 -- .../DefaultInMemoryScriptRuntimeFactory.cs | 29 -- .../DependencyInjection.cs | 13 - .../NetPad.InMemoryScriptRuntime.csproj | 14 - .../Performance/PerformanceTests.cs | 44 +-- src/External/O2Html/HtmlConverter.cs | 2 - .../Stdio/IO/RequestResponseQueue.cs | 7 +- .../UiInterop/BrowserWindowInfo.cs | 24 -- .../Scaffolding/ScaffoldedSourceFile.cs | 19 - .../NetPad.Infrastructure/GlobalUsings.cs | 1 - .../NetPad.Infrastructure.csproj | 24 -- .../NetPad.Web/NetPad.Web.csproj | 13 - .../NetPad.Web/UiInterop/WebDialogService.cs | 36 -- src/NetPad.sln | 117 ++---- .../DiagnosticsEventsBackgroundService.cs | 35 +- .../EventForwardToIpcBackgroundService.cs | 17 +- .../ServerManagementBackgroundService.cs | 54 ++- ...mniSharpAsyncBufferUpdateCompletedEvent.cs | 9 +- .../Events/OmniSharpDiagnosticsEvent.cs | 12 +- .../Events/OmniSharpServerRestartedEvent.cs | 9 +- .../Events/OmniSharpServerStartedEvent.cs | 9 +- .../Events/OmniSharpServerStoppedEvent.cs | 9 +- .../Features/Bases.cs | 47 +-- .../BlockStructure/GetBlockStructureQuery.cs | 19 +- .../CodeActions/GetCodeActionsQuery.cs | 20 +- .../CodeActions/RunCodeActionCommand.cs | 20 +- .../Features/CodeChecking/CheckCodeQuery.cs | 20 +- .../CodeFormatting/CodeFormatQuery.cs | 20 +- .../FormatAfterKeystrokeQuery.cs | 20 +- .../CodeFormatting/FormatRangeQuery.cs | 20 +- .../CodeStructure/CodeStructureResponse.cs | 36 +- .../CodeStructure/GetCodeStructureQuery.cs | 19 +- .../FileOperation/FileOperationResponse.cs | 36 +- .../GetCompletionAfterInsertQuery.cs | 18 +- .../Completion/GetCompletionsQuery.cs | 20 +- .../Completion/ResolveCompletionQuery.cs | 18 +- .../Diagnostics/StartDiagnosticsCommand.cs | 19 +- .../FindImplementationsQuery.cs | 20 +- .../Features/FindUsages/FindUsagesQuery.cs | 20 +- .../InlayHinting/GetInlayHintsQuery.cs | 20 +- .../InlayHinting/ResolveInlayHintQuery.cs | 18 +- .../Features/QuickInfo/GetQuickInfoQuery.cs | 20 +- .../Features/Rename/RenameQuery.cs | 20 +- .../GetSemanticHighlightsQuery.cs | 20 +- .../RestartOmniSharpServerCommand.cs | 26 +- .../SignatureHelp/GetSignatureHelpQuery.cs | 20 +- .../NetPad.Plugins.OmniSharp.csproj | 7 +- .../OmniSharpController.cs | 49 ++- .../OmniSharpMediatorPipeline.cs | 18 +- .../OmniSharpProject.cs | 2 +- .../NetPad.Plugins.OmniSharp/Plugin.cs | 1 + .../Services/AppOmniSharpServer.cs | 159 ++++----- .../Services/OmniSharpServerCatalog.cs | 62 ++-- .../Services/OmniSharpServerDownloader.cs | 37 +- .../Services/OmniSharpServerLocation.cs | 14 +- .../Services/OmniSharpServerLocator.cs | 22 +- .../ApplicationInfoTests.cs | 15 - .../NetPad.Application.Tests/HostInfoTests.cs | 41 --- .../NetPad.Application.Tests.csproj | 37 -- .../Scripts/ScriptEnvironmentFactoryTests.cs | 36 -- .../CSharp/CSharpCodeParserTests.cs | 119 ------- .../Core/NetPad.Domain.Tests/appsettings.json | 9 - .../NetPad.Presentation.Tests.csproj | 30 -- .../ScriptRuntimeServicesTests.cs | 59 --- .../NetPad.Runtimes.Tests.csproj | 40 --- .../NetPad.Runtimes.Tests/appsettings.json | 9 - .../DataConnections/CommonTests.cs | 35 -- .../MsSqlServerDatabaseConnectionTests.cs | 58 --- .../PostgreSqlDatabaseConnectionTests.cs | 59 --- .../SqlLiteDatabaseConnectionTests.cs | 61 ---- .../DataConnections/CommonTests.cs | 28 ++ .../MsSqlServerDatabaseConnectionTests.cs | 51 +++ .../PostgreSqlDatabaseConnectionTests.cs | 52 +++ .../SqlLiteDatabaseConnectionTests.cs | 54 +++ .../NullDataConnectionPasswordProtector.cs | 2 +- .../NetPad.Apps.Common.Tests.csproj} | 13 +- .../UiInterop/TransactionQueueTests.cs | 14 +- .../Usings.cs} | 0 .../Application/AppIdentifierTests.cs | 2 +- .../Assemblies/AssemblyInfoReaderTests.cs | 6 +- .../CodeAnalysis/CodeAnalysisServiceTests.cs | 9 +- .../Common/JsonConverterWithCtorArgsTests.cs | 2 +- .../Common/JsonInheritanceConverterTests.cs | 5 +- .../CSharp/CSharpCodeCompilerTests.cs | 13 +- .../Data/ConnectionStringBuilderTests.cs | 2 +- .../Data/DatabaseStructureTests.cs | 11 +- .../NetPad.Runtime.Tests/DotNet/CodeTests.cs | 52 +++ .../DotNet/NamespaceTests.cs | 57 +++ .../DotNet/SourceCodeTests.cs | 47 +++ .../NetPad.Runtime.Tests/DotNet/UsingTests.cs | 65 ++++ .../Exceptions/ExceptionsTests.cs | 5 +- .../ExternalRunnerCSharpCodeParserTests.cs | 97 +++++ .../InMemoryScriptRunner.Console.Tests.cs} | 35 +- .../InMemory/InMemoryScriptRunnerTests.cs} | 47 +-- .../Html/HtmlPresenterTests.cs | 4 +- .../NetPad.Runtime.Tests.csproj} | 10 +- .../Runtimes/RunResultTests.cs | 10 +- .../DefaultScriptNameGeneratorTests.cs | 12 +- .../Scripts/EnumTests.cs | 13 +- .../Scripts/ScriptEnvironmentTests.cs | 16 +- .../Scripts/ScriptTests.cs | 3 +- .../SemanticVersionTests.cs | 10 +- .../Sessions/SessionTests.cs | 11 +- .../SettingsTests.cs | 5 +- .../Utilities/StringUtilTests.cs | 2 +- .../appsettings.json | 0 .../NetPad.Tests/Helpers/ScriptTestHelper.cs | 1 - .../NetPad.Tests/Helpers/SessionTestHelper.cs | 4 +- src/Tests/NetPad.Tests/Logging/XUnitLogger.cs | 32 +- .../Logging/XUnitLoggerProvider.cs | 10 +- src/Tests/NetPad.Tests/NetPad.Tests.csproj | 9 +- .../NullDataConnectionResourcesCache.cs | 2 - .../Services/NullPackageProvider.cs | 6 +- src/Tests/NetPad.Tests/TestBase.cs | 1 - 614 files changed, 5650 insertions(+), 7945 deletions(-) rename src/.editorconfig => .editorconfig (99%) create mode 100644 Directory.Build.props create mode 100644 global.json delete mode 100644 src/Apps/NetPad.Apps.App/Dtos/RunOptionsDto.cs create mode 100644 src/Apps/NetPad.Apps.App/Properties/launchSettings.json delete mode 100644 src/Apps/NetPad.Apps.App/Services/Data/DataConnectionResourcesGeneratorFactory.cs delete mode 100644 src/Apps/NetPad.Apps.App/Services/Data/DatabaseConnectionMetadataProviderFactory.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.App}/Services/MediatorRequestPipeline.cs (97%) create mode 100644 src/Apps/NetPad.Apps.App/Services/ScriptService.cs create mode 100644 src/Apps/NetPad.Apps.App/Swagger/SwaggerCodeGenerationStartup.cs delete mode 100644 src/Apps/NetPad.Apps.App/global.json create mode 100644 src/Apps/NetPad.Apps.Common/CQs/ActivateLastActiveScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/ActivateScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/AlertUserAboutMissingAppDependencies.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/AlertUserCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/Bases.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/CheckAppDependenciesQuery.cs (52%) create mode 100644 src/Apps/NetPad.Apps.Common/CQs/CloseScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/ConfirmSaveCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/ConfirmWithUserCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/CreateScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/DeleteDataConnectionCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/DuplicateScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/GetActiveScriptEnviornmentQuery.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/GetAllScriptsQuery.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/GetDataConnectionQuery.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/GetDataConnectionsQuery.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/GetDatabaseConnectionStructureQuery.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/GetOpenedScriptEnvironmentQuery.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/GetOpenedScriptEnvironmentsQuery.cs (55%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/OpenScriptCommand.cs (56%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/OpenWindowCommand.cs (57%) create mode 100644 src/Apps/NetPad.Apps.Common/CQs/PromptUserCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/PromptUserForInputCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/RefreshDataConnectionCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/RenameScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/RequestNewScriptNameCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/RunScriptCommand.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/SaveDataConnectionCommand.cs (67%) create mode 100644 src/Apps/NetPad.Apps.Common/CQs/SaveScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/SetScriptDataConnectionCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/StopScriptCommand.cs create mode 100644 src/Apps/NetPad.Apps.Common/CQs/UpdateScriptCodeCommand.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/UpdateScriptNamespacesCommand.cs (51%) create mode 100644 src/Apps/NetPad.Apps.Common/CQs/UpdateScriptOptimizationLevelCommand.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/UpdateScriptReferencesCommand.cs (51%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/UpdateScriptTargetFrameworkCommand.cs (51%) create mode 100644 src/Apps/NetPad.Apps.Common/CQs/UpdateScriptUseAspNetCommand.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/CQs/UpdateSettingsCommand.cs (52%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Configuration/FileSystemSettingsRepository.cs (87%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/EntityFrameworkDatabaseConnection.cs (61%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/EntityFrameworkRelationalDatabaseConnection.cs (69%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/EntityFrameworkSchemaChangeDetectionStrategyBase.cs (61%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/MsSqlServerDatabaseConnection.cs (78%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/MsSqlServerDatabaseSchemaChangeDetectionStrategy.cs (71%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/PostgreSqlDatabaseConnection.cs (78%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/PostgreSqlDatabaseSchemaChangeDetectionStrategy.cs (76%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/SQLiteDatabaseConnection.cs (69%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DataConnections/SQLiteDatabaseSchemaChangeDetectionStrategy.cs (72%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/DatabaseContext.cs (62%) create mode 100644 src/Apps/NetPad.Apps.Common/Data/EntityFrameworkCore/DependencyInjection.cs create mode 100644 src/Apps/NetPad.Apps.Common/Data/EntityFrameworkCore/EntityFrameworkConnectionMetadataProviderFactory.cs create mode 100644 src/Apps/NetPad.Apps.Common/Data/EntityFrameworkCore/EntityFrameworkConnectionResourcesGeneratorFactory.cs rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/EntityFrameworkDatabaseConnectionMetadataProvider.cs (63%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/EntityFrameworkPackageUtils.cs (89%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/EntityFrameworkResourcesGenerator.cs (81%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/EntityFrameworkUtils.cs (96%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/Scaffolding/EntityFrameworkDatabaseScaffolder.cs (84%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/Scaffolding/ScaffoldOptions.cs (54%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/Scaffolding/ScaffoldedDatabaseModel.cs (75%) create mode 100644 src/Apps/NetPad.Apps.Common/Data/EntityFrameworkCore/Scaffolding/ScaffoldedSourceFile.cs rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/Scaffolding/Transforms/AnyDatabaseProviderTransform.cs (96%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/Scaffolding/Transforms/IScaffoldedModelTransform.cs (58%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/EntityFrameworkCore/Scaffolding/Transforms/PostgresSqlTransform.cs (83%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/FileSystemDataConnectionRepository.cs (75%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/FileSystemDataConnectionResourcesCache.Helpers.cs (66%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/FileSystemDataConnectionResourcesCache.cs (67%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Data/FileSystemDataConnectionResourcesRepository.cs (85%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common/Data}/FileSystemTrivialDataStore.cs (94%) create mode 100644 src/Apps/NetPad.Apps.Common/GlobalUsings.cs create mode 100644 src/Apps/NetPad.Apps.Common/HostInfo.cs create mode 100644 src/Apps/NetPad.Apps.Common/NetPad.Apps.Common.csproj rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/Plugins/IPlugin.cs (95%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/Plugins/IPluginManager.cs (92%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/Plugins/PluginInitialization.cs (85%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/Plugins/PluginManager.cs (86%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/Plugins/PluginRegistration.cs (75%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/Resources/ILogoService.cs (88%) create mode 100644 src/Apps/NetPad.Apps.Common/Resources/LogoService.cs rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Scripts/FileSystemAutoSaveScriptRepository.cs (97%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Scripts/FileSystemScriptRepository.cs (96%) rename src/{Infrastructure/NetPad.Infrastructure => Apps/NetPad.Apps.Common}/Scripts/ScriptSerializer.cs (92%) rename src/{Core/NetPad.Application/Application/IApplicationConfigurator.cs => Apps/NetPad.Apps.Common/Shells/IShell.cs} (64%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/IIpcService.cs (90%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/IUiDialogService.cs (90%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/IUiWindowService.cs (91%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/IpcHub.cs (90%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/IpcMessage.cs (93%) create mode 100644 src/Apps/NetPad.Apps.Common/UiInterop/IpcMessageBatch.cs rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/IpcResponsePromise.cs (96%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/IpcResponseQueue.cs (86%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/SignalRIpcService.cs (77%) rename src/{Core/NetPad.Application => Apps/NetPad.Apps.Common}/UiInterop/YesNoCancel.cs (63%) rename src/{Infrastructure/NetPad.Electron => Apps/NetPad.Apps.Shells.Electron}/BackgroundServices/NotificationBackgroundService.cs (58%) rename src/{Infrastructure/NetPad.Electron/NetPadElectronConfigurator.cs => Apps/NetPad.Apps.Shells.Electron/ElectronShell.cs} (80%) rename src/{Infrastructure/NetPad.Electron/NetPad.Electron.csproj => Apps/NetPad.Apps.Shells.Electron/NetPad.Apps.Shells.Electron.csproj} (60%) create mode 100644 src/Apps/NetPad.Apps.Shells.Electron/UiInterop/BrowserWindowInfo.cs rename src/{Infrastructure/NetPad.Electron => Apps/NetPad.Apps.Shells.Electron}/UiInterop/ElectronDialogService.cs (64%) rename src/{Infrastructure/NetPad.Electron => Apps/NetPad.Apps.Shells.Electron}/UiInterop/ElectronIpcService.cs (72%) rename src/{Infrastructure/NetPad.Electron => Apps/NetPad.Apps.Shells.Electron}/UiInterop/ElectronUtil.cs (77%) rename src/{Infrastructure/NetPad.Electron => Apps/NetPad.Apps.Shells.Electron}/UiInterop/ElectronWindowService.cs (71%) rename src/{Infrastructure/NetPad.Electron => Apps/NetPad.Apps.Shells.Electron}/UiInterop/WindowManager.cs (80%) rename src/{Infrastructure/NetPad.Electron => Apps/NetPad.Apps.Shells.Electron}/UiInterop/WindowState.cs (78%) create mode 100644 src/Apps/NetPad.Apps.Shells.Web/NetPad.Apps.Shells.Web.csproj create mode 100644 src/Apps/NetPad.Apps.Shells.Web/UiInterop/WebDialogService.cs rename src/{Infrastructure/NetPad.Web => Apps/NetPad.Apps.Shells.Web}/UiInterop/WebWindowService.cs (78%) rename src/{Infrastructure/NetPad.Web/NetPadWebConfigurator.cs => Apps/NetPad.Apps.Shells.Web/WebBrowserShell.cs} (68%) delete mode 100644 src/Core/NetPad.Application/Application/AppStatusMessagePublisher.cs delete mode 100644 src/Core/NetPad.Application/Application/ApplicationInfo.cs delete mode 100644 src/Core/NetPad.Application/Application/ApplicationType.cs delete mode 100644 src/Core/NetPad.Application/CQs/ActivateLastActiveScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/ActivateScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/AlertUserAboutMissingAppDependencies.cs delete mode 100644 src/Core/NetPad.Application/CQs/AlertUserCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/Bases.cs delete mode 100644 src/Core/NetPad.Application/CQs/CloseScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/ConfirmSaveCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/ConfirmWithUserCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/CreateScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/DeleteDataConnectionCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/DuplicateScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/GetActiveScriptEnviornmentQuery.cs delete mode 100644 src/Core/NetPad.Application/CQs/GetAllScriptsQuery.cs delete mode 100644 src/Core/NetPad.Application/CQs/GetDataConnectionQuery.cs delete mode 100644 src/Core/NetPad.Application/CQs/GetDataConnectionsQuery.cs delete mode 100644 src/Core/NetPad.Application/CQs/GetDatabaseConnectionStructureQuery.cs delete mode 100644 src/Core/NetPad.Application/CQs/GetOpenedScriptEnvironmentQuery.cs delete mode 100644 src/Core/NetPad.Application/CQs/PromptUserCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/PromptUserForInputCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/RefreshDataConnectionCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/RenameScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/RequestNewScriptNameCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/RunScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/SaveScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/SetScriptDataConnectionCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/StopScriptCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/UpdateScriptCodeCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/UpdateScriptOptimizationLevelCommand.cs delete mode 100644 src/Core/NetPad.Application/CQs/UpdateScriptUseAspNetCommand.cs delete mode 100644 src/Core/NetPad.Application/Events/ActiveEnvironmentChangedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/AppStatusMessagePublishedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/DataConnectionDeletedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/DataConnectionResourcesUpdateFailedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/DataConnectionResourcesUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/DataConnectionResourcesUpdatingEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/DataConnectionSavedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/DataConnectionSchemaValidationCompletedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/DataConnectionSchemaValidationStartedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/EnvironmentsAddedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/EnvironmentsRemovedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptClosedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptCodeUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptCreatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptDataConnectionChangedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptDirectoryChangedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptNamespacesUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptOpenedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptOptimizationLevelUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptOutputEmittedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptRanEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptReferencesUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptRunCancelledEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptSavedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptTargetFrameworkVersionUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/ScriptUseAspNetUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/Events/SettingsUpdatedEvent.cs delete mode 100644 src/Core/NetPad.Application/GlobalUsings.cs delete mode 100644 src/Core/NetPad.Application/HostInfo.cs delete mode 100644 src/Core/NetPad.Application/NetPad.Application.csproj delete mode 100644 src/Core/NetPad.Application/Resources/LogoService.cs delete mode 100644 src/Core/NetPad.Application/Scripts/DefaultScriptEnvironmentFactory.cs delete mode 100644 src/Core/NetPad.Application/Scripts/IScriptEnvironmentFactory.cs delete mode 100644 src/Core/NetPad.Application/UiInterop/IpcMessageBatch.cs delete mode 100644 src/Core/NetPad.Domain/CodeAnalysis/SyntaxNodeOrTokenSlim.cs delete mode 100644 src/Core/NetPad.Domain/CodeAnalysis/SyntaxTriviaSlim.cs delete mode 100644 src/Core/NetPad.Domain/Common/JsonConverterWithCtorArgs.cs delete mode 100644 src/Core/NetPad.Domain/Compilation/CSharp/CSharpCodeParser.cs delete mode 100644 src/Core/NetPad.Domain/Compilation/CompilationInput.cs delete mode 100644 src/Core/NetPad.Domain/Compilation/CompilationResult.cs delete mode 100644 src/Core/NetPad.Domain/Compilation/GlobalUsings.cs delete mode 100644 src/Core/NetPad.Domain/Compilation/ParsedCodeInformation.cs delete mode 100644 src/Core/NetPad.Domain/Compilation/PreprocessorSymbols.cs delete mode 100644 src/Core/NetPad.Domain/Data/DataConnectionSchemaChangeDetectionStrategyFactory.cs delete mode 100644 src/Core/NetPad.Domain/Data/DataConnectionSourceCode.cs delete mode 100644 src/Core/NetPad.Domain/Data/DatabaseStructure.cs delete mode 100644 src/Core/NetPad.Domain/DotNet/AssemblyFileReference.cs delete mode 100644 src/Core/NetPad.Domain/DotNet/AssemblyImageReference.cs delete mode 100644 src/Core/NetPad.Domain/DotNet/DotNetFrameworkVersionUtil.cs delete mode 100644 src/Core/NetPad.Domain/DotNet/Namespace.cs delete mode 100644 src/Core/NetPad.Domain/DotNet/SourceCodeElement.cs delete mode 100644 src/Core/NetPad.Domain/Events/DisposableToken.cs delete mode 100644 src/Core/NetPad.Domain/Events/EnvironmentPropertyChangedEvent.cs delete mode 100644 src/Core/NetPad.Domain/Events/PropertyChangedEvent.cs delete mode 100644 src/Core/NetPad.Domain/Events/ScriptConfigPropertyChangedEvent.cs delete mode 100644 src/Core/NetPad.Domain/Events/ScriptPropertyChangedEvent.cs delete mode 100644 src/Core/NetPad.Domain/Exceptions/EnvironmentNotFoundException.cs delete mode 100644 src/Core/NetPad.Domain/Exceptions/InvalidReferenceException.cs delete mode 100644 src/Core/NetPad.Domain/Exceptions/InvalidScriptFormatException.cs delete mode 100644 src/Core/NetPad.Domain/Exceptions/ScriptRuntimeException.cs delete mode 100644 src/Core/NetPad.Domain/GlobalUsings.cs delete mode 100644 src/Core/NetPad.Domain/IO/ActionInputReader.cs delete mode 100644 src/Core/NetPad.Domain/IO/ActionOutputWriter.cs delete mode 100644 src/Core/NetPad.Domain/IO/AsyncActionInputReader.cs delete mode 100644 src/Core/NetPad.Domain/IO/AsyncActionOutputWriter.cs delete mode 100644 src/Core/NetPad.Domain/IO/ProcessHandler.cs delete mode 100644 src/Core/NetPad.Domain/IO/ProcessIO.cs delete mode 100644 src/Core/NetPad.Domain/NetPad.Domain.csproj delete mode 100644 src/Core/NetPad.Domain/Packages/CachedPackage.cs delete mode 100644 src/Core/NetPad.Domain/Runtimes/IScriptRuntimeFactory.cs delete mode 100644 src/Core/NetPad.Domain/Runtimes/RunOptions.cs delete mode 100644 src/Core/NetPad.Domain/Scripts/ScriptSummary.cs delete mode 100644 src/Core/NetPad.Domain/Utilities/Accessor.cs delete mode 100644 src/Core/NetPad.Domain/ValueObject.cs delete mode 100644 src/Core/NetPad.Presentation/NetPad.Presentation.csproj rename src/Core/{NetPad.Application => NetPad.Runtime}/Application/AppDependencyCheckResult.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Application/AppIdentifier.cs (90%) rename src/Core/{NetPad.Application => NetPad.Runtime}/Application/AppStatusMessage.cs (66%) create mode 100644 src/Core/NetPad.Runtime/Application/AppStatusMessagePublisher.cs create mode 100644 src/Core/NetPad.Runtime/Application/Events/AppStatusMessagePublishedEvent.cs rename src/Core/{NetPad.Application => NetPad.Runtime}/Application/IAppStatusMessagePublisher.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Assemblies/AssemblyInfoReader.cs (98%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Assemblies/IAssemblyLoader.cs (88%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Assemblies/UnloadableAssemblyLoader.cs (83%) create mode 100644 src/Core/NetPad.Runtime/CodeAnalysis/CodeAnalysisExtensions.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/CodeAnalysis/CodeAnalysisService.cs (84%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/CodeAnalysis/ICodeAnalysisService.cs (90%) create mode 100644 src/Core/NetPad.Runtime/CodeAnalysis/SyntaxNodeOrTokenSlim.cs create mode 100644 src/Core/NetPad.Runtime/CodeAnalysis/SyntaxTriviaSlim.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Common/GlobalConsts.cs (96%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Common/INotifyOnPropertyChanged.cs (71%) create mode 100644 src/Core/NetPad.Runtime/Common/JsonConverterWithCtorArgs.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Common/JsonInheritanceConverter.cs (99%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Common/JsonSerializer.cs (99%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Compilation/CSharp/CSharpCodeCompiler.cs (66%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Compilation/CodeParsingOptions.cs (98%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Compilation/CodeParsingResult.cs (52%) create mode 100644 src/Core/NetPad.Runtime/Compilation/CompilationInput.cs create mode 100644 src/Core/NetPad.Runtime/Compilation/CompilationResult.cs rename src/Core/{NetPad.Domain/Compilation/SystemAssemblies.cs => NetPad.Runtime/Compilation/FrameworkAssemblies.cs} (92%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Compilation/ICodeCompiler.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Compilation/ICodeParser.cs (63%) create mode 100644 src/Core/NetPad.Runtime/Compilation/PreprocessorSymbols.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/AppDataProvider.cs (99%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/AppearanceOptions.cs (99%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/EditorOptions.cs (98%) create mode 100644 src/Core/NetPad.Runtime/Configuration/Events/SettingsUpdatedEvent.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/ISettingsOptions.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/ISettingsRepository.cs (89%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/KeyboardShortcutOptions.cs (89%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/OmniSharpOptions.cs (99%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/ResultsOptions.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/Settings.cs (99%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/StyleOptions.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Configuration/Theme.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/ConnectionStringBuilder.cs (84%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/DataConnection.cs (83%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/DataConnectionResourceComponent.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/DataConnectionResources.cs (64%) create mode 100644 src/Core/NetPad.Runtime/Data/DataConnectionSchemaChangeDetectionStrategyFactory.cs create mode 100644 src/Core/NetPad.Runtime/Data/DataConnectionSourceCode.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/DataConnectionTestResult.cs (57%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/DataConnectionType.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/DataProtector.cs (80%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/DatabaseConnection.cs (70%) create mode 100644 src/Core/NetPad.Runtime/Data/DatabaseStructure.cs create mode 100644 src/Core/NetPad.Runtime/Data/Events/DataConnectionDeletedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Data/Events/DataConnectionResourcesUpdateFailedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Data/Events/DataConnectionResourcesUpdatedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Data/Events/DataConnectionResourcesUpdatingEvent.cs create mode 100644 src/Core/NetPad.Runtime/Data/Events/DataConnectionSavedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Data/Events/DataConnectionSchemaValidationCompletedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Data/Events/DataConnectionSchemaValidationStartedEvent.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/FakeDataConnectionPasswordProtector.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionPasswordProtector.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionRepository.cs (75%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionResourcesCache.cs (97%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionResourcesGenerator.cs (94%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionResourcesGeneratorFactory.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionResourcesRepository.cs (95%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionSchemaChangeDetectionStrategy.cs (94%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDataConnectionSchemaChangeDetectionStrategyFactory.cs (85%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDatabaseConnectionMetadataProvider.cs (84%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/IDatabaseConnectionMetadataProviderFactory.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/ITrivialDataStore.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Data/SchemaCompareInfo.cs (73%) create mode 100644 src/Core/NetPad.Runtime/DependencyInjection.cs create mode 100644 src/Core/NetPad.Runtime/DotNet/AssemblyFileReference.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/AssemblyImage.cs (98%) create mode 100644 src/Core/NetPad.Runtime/DotNet/AssemblyImageReference.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/Code.cs (59%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/DotNetCSharpProject.cs (99%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/DotNetFrameworkVersion.cs (81%) create mode 100644 src/Core/NetPad.Runtime/DotNet/DotNetFrameworkVersionUtil.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/DotNetInfo.cs (94%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/DotNetRuntimeVersion.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/DotNetSdkPack.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/DotNetSdkVersion.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/IDotNetInfo.cs (100%) create mode 100644 src/Core/NetPad.Runtime/DotNet/Namespace.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/PackageReference.cs (66%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/ProjectOutputType.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/Reference.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/ReferenceAsset.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/SourceCode.cs (52%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/SourceCodeCollection.cs (76%) create mode 100644 src/Core/NetPad.Runtime/DotNet/SourceCodeElement.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/DotNet/Using.cs (50%) create mode 100644 src/Core/NetPad.Runtime/Events/DisposableToken.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Events/EventBus.cs (92%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Events/IEvent.cs (72%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Events/IEventBus.cs (97%) create mode 100644 src/Core/NetPad.Runtime/Exceptions/EnvironmentNotFoundException.cs create mode 100644 src/Core/NetPad.Runtime/Exceptions/InvalidReferenceException.cs create mode 100644 src/Core/NetPad.Runtime/Exceptions/InvalidScriptFormatException.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Exceptions/ScriptNotFoundException.cs (95%) create mode 100644 src/Core/NetPad.Runtime/Exceptions/ScriptRuntimeException.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/DependencyInjection.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/EmbeddedCode/Program.cs rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime => NetPad.Runtime/ExecutionModel/External}/EmbeddedCode/SqlAccessCode.cs (90%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/ExternalRunnerCSharpCodeParser.cs rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/ExternalProcessScriptRuntime.IO.cs => NetPad.Runtime/ExecutionModel/External/ExternalScriptRunner.IO.cs} (85%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/ExternalScriptRunner.Setup.cs rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/ExternalProcessScriptRuntime.cs => NetPad.Runtime/ExecutionModel/External/ExternalScriptRunner.cs} (61%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/ExternalScriptRunnerFactory.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/ExternalScriptRunnerOptions.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/FileAssetCopy.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/Interface/ActionTextReader.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/Interface/ActionTextWriter.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/Interface/ExternalProcessDumpSink.cs rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface => NetPad.Runtime/ExecutionModel/External/Interface}/ExternalProcessOutput.cs (81%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/Interface/ExternalProcessOutputConsoleWriter.cs rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface => NetPad.Runtime/ExecutionModel/External/Interface}/ExternalProcessOutputHtmlWriter.cs (83%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/Interface/ExternalProcessOutputTextWriter.cs rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface => NetPad.Runtime/ExecutionModel/External/Interface}/IExternalProcessOutputWriter.cs (81%) rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface => NetPad.Runtime/ExecutionModel/External/Interface}/UserScript.cs (84%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/External/ParseAndCompile.cs rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime => NetPad.Runtime/ExecutionModel/External}/RawOutputHandler.cs (88%) rename src/Core/{NetPad.Domain/Runtimes/IScriptRuntime.cs => NetPad.Runtime/ExecutionModel/IScriptRunner.cs} (54%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/IScriptRunnerFactory.cs rename src/Core/{ScriptRuntimes/NetPad.InMemoryScriptRuntime/InMemoryRuntimeCSharpCodeParser.cs => NetPad.Runtime/ExecutionModel/InMemory/InMemoryRunnerCSharpCodeParser.cs} (88%) rename src/Core/{ScriptRuntimes/NetPad.InMemoryScriptRuntime/InMemoryScriptRuntime.cs => NetPad.Runtime/ExecutionModel/InMemory/InMemoryScriptRunner.cs} (81%) create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/InMemory/InMemoryScriptRunnerFactory.cs create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/InMemory/README.md create mode 100644 src/Core/NetPad.Runtime/ExecutionModel/RunOptions.cs rename src/Core/{NetPad.Domain/Runtimes => NetPad.Runtime/ExecutionModel}/RunResult.cs (71%) create mode 100644 src/Core/NetPad.Runtime/GlobalUsings.cs create mode 100644 src/Core/NetPad.Runtime/INetPadRuntimeMarker.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/IO/AbsolutePath.cs (94%) create mode 100644 src/Core/NetPad.Runtime/IO/ActionInputReader.cs create mode 100644 src/Core/NetPad.Runtime/IO/ActionOutputWriter.cs create mode 100644 src/Core/NetPad.Runtime/IO/AsyncActionInputReader.cs create mode 100644 src/Core/NetPad.Runtime/IO/AsyncActionOutputWriter.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/IO/DirectoryPath.cs (89%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/IO/FilePath.cs (86%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/IO/IInputReader.cs (77%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/IO/IOutputWriter.cs (90%) create mode 100644 src/Core/NetPad.Runtime/IO/ProcessHelper.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/IO/RelativePath.cs (93%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Media/Audio.cs (100%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Media/Image.cs (100%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Media/MediaFile.cs (95%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Media/MediaFileExtensions.cs (92%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Media/Video.cs (100%) create mode 100644 src/Core/NetPad.Runtime/NetPad.Runtime.csproj create mode 100644 src/Core/NetPad.Runtime/Packages/CachedPackage.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Packages/IPackageProvider.cs (94%) rename src/{Infrastructure/NetPad.Infrastructure/Packages => Core/NetPad.Runtime/Packages/NuGet}/NuGetPackageProvider.cs (94%) rename src/{Infrastructure/NetPad.Infrastructure/Packages => Core/NetPad.Runtime/Packages/NuGet}/PackageDependencyTree.cs (58%) rename src/{Infrastructure/NetPad.Infrastructure/Packages => Core/NetPad.Runtime/Packages/NuGet}/RuntimeProvidedPackages.cs (98%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Packages/PackageAsset.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Packages/PackageDependencySet.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Packages/PackageIdentity.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Packages/PackageInstallInfo.cs (52%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Packages/PackageMetadata.cs (74%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Console/ConsolePresenter.cs (100%) rename src/Core/{ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface => NetPad.Runtime/Presentation}/DumpExtension.cs (69%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/DumpOptions.cs (95%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Html/AudioHtmlConverter.cs (87%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Html/HtmlPresenter.cs (99%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Html/ImageHtmlConverter.cs (87%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Html/MediaFileCollectionConverter.cs (100%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Html/MediaFileHtmlConverter.cs (100%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Html/VideoHtmlConverter.cs (87%) create mode 100644 src/Core/NetPad.Runtime/Presentation/IDumpSink.cs create mode 100644 src/Core/NetPad.Runtime/Presentation/NullDumpSink.cs rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/PresentationSettings.cs (98%) rename src/Core/{NetPad.Domain/Runtimes => NetPad.Runtime/Presentation}/ScriptOutput.cs (98%) rename src/Core/{NetPad.Presentation => NetPad.Runtime}/Presentation/Text/TextPresenter.cs (100%) rename src/Core/{NetPad.Application => NetPad.Runtime}/Scripts/DefaultScriptNameGenerator.cs (51%) create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/EnvironmentPropertyChangedEvent.cs rename src/Core/{NetPad.Domain => NetPad.Runtime/Scripts}/Events/IScriptEvent.cs (57%) create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/PropertyChangedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptClosedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptCodeUpdatedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptConfigPropertyChangedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptCreatedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptDataConnectionChangedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptDirectoryChangedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptNamespacesUpdatedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptOpenedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptOptimizationLevelUpdatedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptOutputEmittedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptPropertyChangedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptRanEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptReferencesUpdatedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptRunCancelledEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptSavedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptTargetFrameworkVersionUpdatedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Scripts/Events/ScriptUseAspNetUpdatedEvent.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Scripts/IAutoSaveScriptRepository.cs (76%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Scripts/IScriptNameGenerator.cs (100%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Scripts/IScriptRepository.cs (82%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Scripts/Script.cs (96%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Scripts/ScriptConfig.cs (57%) rename src/Core/{NetPad.Application => NetPad.Runtime}/Scripts/ScriptEnvironment.cs (66%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Scripts/ScriptKind.cs (100%) rename src/Core/{NetPad.Application => NetPad.Runtime}/Scripts/ScriptStatus.cs (100%) create mode 100644 src/Core/NetPad.Runtime/Scripts/ScriptSummary.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/SemanticVersion.cs (99%) create mode 100644 src/Core/NetPad.Runtime/Sessions/Events/ActiveEnvironmentChangedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Sessions/Events/EnvironmentsAddedEvent.cs create mode 100644 src/Core/NetPad.Runtime/Sessions/Events/EnvironmentsRemovedEvent.cs rename src/Core/{NetPad.Application => NetPad.Runtime}/Sessions/ISession.cs (100%) rename src/Core/{NetPad.Application => NetPad.Runtime}/Sessions/Session.cs (71%) create mode 100644 src/Core/NetPad.Runtime/Utilities/Accessor.cs rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/AssemblyUtil.cs (96%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/AsyncUtil.cs (97%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/CollectionUtil.cs (93%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/DelegateUtil.cs (96%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/FileSystemUtil.cs (98%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/GCUtil.cs (92%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/HttpClientUtil.cs (95%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/PlatformUtil.cs (82%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/ProcessUtil.cs (97%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/ReferenceUtil.cs (63%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/Retry.cs (94%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/StreamUtil.cs (94%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/StringUtil.cs (95%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/Try.cs (94%) rename src/Core/{NetPad.Domain => NetPad.Runtime}/Utilities/TypeUtil.cs (99%) create mode 100644 src/Core/NetPad.Runtime/Utilities/WindowsNative.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface/ActionTextReader.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface/ActionTextWriter.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface/ExternalProcessOutputConsoleWriter.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface/ExternalProcessOutputFormat.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface/ExternalProcessOutputTextWriter.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface/NetPad.ExternalProcessScriptRuntime.Interface.csproj delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime.Interface/ScriptRuntimeServices.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/DefaultExternalProcessScriptRuntimeFactory.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/DependencyInjection.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/EmbeddedCode/Program.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/ExternalProcessRuntimeCSharpCodeParser.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/ExternalProcessScriptRuntime.Setup.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.ExternalProcessScriptRuntime/NetPad.ExternalProcessScriptRuntime.csproj delete mode 100644 src/Core/ScriptRuntimes/NetPad.InMemoryScriptRuntime/DefaultInMemoryScriptRuntimeFactory.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.InMemoryScriptRuntime/DependencyInjection.cs delete mode 100644 src/Core/ScriptRuntimes/NetPad.InMemoryScriptRuntime/NetPad.InMemoryScriptRuntime.csproj delete mode 100644 src/Infrastructure/NetPad.Electron/UiInterop/BrowserWindowInfo.cs delete mode 100644 src/Infrastructure/NetPad.Infrastructure/Data/EntityFrameworkCore/Scaffolding/ScaffoldedSourceFile.cs delete mode 100644 src/Infrastructure/NetPad.Infrastructure/GlobalUsings.cs delete mode 100644 src/Infrastructure/NetPad.Infrastructure/NetPad.Infrastructure.csproj delete mode 100644 src/Infrastructure/NetPad.Web/NetPad.Web.csproj delete mode 100644 src/Infrastructure/NetPad.Web/UiInterop/WebDialogService.cs delete mode 100644 src/Tests/Core/NetPad.Application.Tests/ApplicationInfoTests.cs delete mode 100644 src/Tests/Core/NetPad.Application.Tests/HostInfoTests.cs delete mode 100644 src/Tests/Core/NetPad.Application.Tests/NetPad.Application.Tests.csproj delete mode 100644 src/Tests/Core/NetPad.Application.Tests/Scripts/ScriptEnvironmentFactoryTests.cs delete mode 100644 src/Tests/Core/NetPad.Domain.Tests/Compilation/CSharp/CSharpCodeParserTests.cs delete mode 100644 src/Tests/Core/NetPad.Domain.Tests/appsettings.json delete mode 100644 src/Tests/Core/NetPad.Presentation.Tests/NetPad.Presentation.Tests.csproj delete mode 100644 src/Tests/Core/NetPad.Runtimes.Tests/ExternalProcessScriptRuntime/ScriptRuntimeServicesTests.cs delete mode 100644 src/Tests/Core/NetPad.Runtimes.Tests/NetPad.Runtimes.Tests.csproj delete mode 100644 src/Tests/Core/NetPad.Runtimes.Tests/appsettings.json delete mode 100644 src/Tests/Infrastructure/NetPad.Infrastructure.Tests/Data/EntityFrameworkCore/DataConnections/CommonTests.cs delete mode 100644 src/Tests/Infrastructure/NetPad.Infrastructure.Tests/Data/EntityFrameworkCore/DataConnections/MsSqlServerDatabaseConnectionTests.cs delete mode 100644 src/Tests/Infrastructure/NetPad.Infrastructure.Tests/Data/EntityFrameworkCore/DataConnections/PostgreSqlDatabaseConnectionTests.cs delete mode 100644 src/Tests/Infrastructure/NetPad.Infrastructure.Tests/Data/EntityFrameworkCore/DataConnections/SqlLiteDatabaseConnectionTests.cs create mode 100644 src/Tests/NetPad.Apps.Common.Tests/Data/EntityFrameworkCore/DataConnections/CommonTests.cs create mode 100644 src/Tests/NetPad.Apps.Common.Tests/Data/EntityFrameworkCore/DataConnections/MsSqlServerDatabaseConnectionTests.cs create mode 100644 src/Tests/NetPad.Apps.Common.Tests/Data/EntityFrameworkCore/DataConnections/PostgreSqlDatabaseConnectionTests.cs create mode 100644 src/Tests/NetPad.Apps.Common.Tests/Data/EntityFrameworkCore/DataConnections/SqlLiteDatabaseConnectionTests.cs rename src/Tests/{Infrastructure/NetPad.Infrastructure.Tests => NetPad.Apps.Common.Tests}/Data/NullDataConnectionPasswordProtector.cs (93%) rename src/Tests/{Infrastructure/NetPad.Infrastructure.Tests/NetPad.Infrastructure.Tests.csproj => NetPad.Apps.Common.Tests/NetPad.Apps.Common.Tests.csproj} (72%) rename src/Tests/{Core/NetPad.Application.Tests => NetPad.Apps.Common.Tests}/UiInterop/TransactionQueueTests.cs (74%) rename src/Tests/{Core/NetPad.Presentation.Tests/GlobalUsings.cs => NetPad.Apps.Common.Tests/Usings.cs} (100%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Application/AppIdentifierTests.cs (92%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Assemblies/AssemblyInfoReaderTests.cs (94%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/CodeAnalysis/CodeAnalysisServiceTests.cs (80%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Common/JsonConverterWithCtorArgsTests.cs (94%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Common/JsonInheritanceConverterTests.cs (98%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Compilation/CSharp/CSharpCodeCompilerTests.cs (93%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Data/ConnectionStringBuilderTests.cs (95%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Data/DatabaseStructureTests.cs (94%) create mode 100644 src/Tests/NetPad.Runtime.Tests/DotNet/CodeTests.cs create mode 100644 src/Tests/NetPad.Runtime.Tests/DotNet/NamespaceTests.cs create mode 100644 src/Tests/NetPad.Runtime.Tests/DotNet/SourceCodeTests.cs create mode 100644 src/Tests/NetPad.Runtime.Tests/DotNet/UsingTests.cs rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Exceptions/ExceptionsTests.cs (92%) create mode 100644 src/Tests/NetPad.Runtime.Tests/ExecutionModel/External/ExternalRunnerCSharpCodeParserTests.cs rename src/Tests/{Core/NetPad.Runtimes.Tests/ScriptRuntime.Console.Tests.cs => NetPad.Runtime.Tests/ExecutionModel/InMemory/InMemoryScriptRunner.Console.Tests.cs} (62%) rename src/Tests/{Core/NetPad.Runtimes.Tests/ScriptRuntimeTests.cs => NetPad.Runtime.Tests/ExecutionModel/InMemory/InMemoryScriptRunnerTests.cs} (74%) rename src/Tests/{Core/NetPad.Presentation.Tests => NetPad.Runtime.Tests}/Html/HtmlPresenterTests.cs (97%) rename src/Tests/{Core/NetPad.Domain.Tests/NetPad.Domain.Tests.csproj => NetPad.Runtime.Tests/NetPad.Runtime.Tests.csproj} (83%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Runtimes/RunResultTests.cs (89%) rename src/Tests/{Core/NetPad.Application.Tests => NetPad.Runtime.Tests}/Scripts/DefaultScriptNameGeneratorTests.cs (92%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Scripts/EnumTests.cs (73%) rename src/Tests/{Core/NetPad.Application.Tests => NetPad.Runtime.Tests}/Scripts/ScriptEnvironmentTests.cs (70%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Scripts/ScriptTests.cs (98%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/SemanticVersionTests.cs (94%) rename src/Tests/{Core/NetPad.Application.Tests => NetPad.Runtime.Tests}/Sessions/SessionTests.cs (96%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/SettingsTests.cs (89%) rename src/Tests/{Core/NetPad.Domain.Tests => NetPad.Runtime.Tests}/Utilities/StringUtilTests.cs (98%) rename src/Tests/{Core/NetPad.Application.Tests => NetPad.Runtime.Tests}/appsettings.json (100%) diff --git a/src/.editorconfig b/.editorconfig similarity index 99% rename from src/.editorconfig rename to .editorconfig index cffde480..9d2e9100 100644 --- a/src/.editorconfig +++ b/.editorconfig @@ -14,4 +14,3 @@ trim_trailing_whitespace = false [*.{razor,cshtml}] charset = utf-8-bom - diff --git a/.gitignore b/.gitignore index 07f9ca24..130f4ede 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,6 @@ BenchmarkDotNet.Artifacts/ project.lock.json project.fragment.lock.json artifacts/ -**/Properties/launchSettings.json # optional local settings appsettings.Local.json @@ -225,7 +224,7 @@ ClientBin/ *.publishsettings orleans.codegen.cs -# Including strong name files can present a security risk +# Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk @@ -321,7 +320,7 @@ __pycache__/ # OpenCover UI analysis results OpenCover/ -# Azure Stream Analytics local run output +# Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log @@ -330,7 +329,7 @@ ASALocalRun/ # NVidia Nsight GPU debugger configuration file *.nvuser -# MFractors (Xamarin productivity tool) working folder +# MFractors (Xamarin productivity tool) working folder .mfractor/ *.DS_Store @@ -348,4 +347,4 @@ src/Apps/Web/Blink.Apps.WebApp/global.json NuGetScratch/ VBCSCompiler/ .dotnet/ -dist/ \ No newline at end of file +dist/ diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 00000000..828b1338 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,13 @@ + + + net6.0 + net6.0 + latest + True + Enable + True + https://github.com/tareqimbasher/netpad + https://github.com/tareqimbasher/netpad + Tareq Imbasher + + diff --git a/global.json b/global.json new file mode 100644 index 00000000..bad9dc3b --- /dev/null +++ b/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestMinor" + } +} diff --git a/src/Apps/NetPad.Apps.App/App/src/core/@common/utils/system.ts b/src/Apps/NetPad.Apps.App/App/src/core/@common/utils/system.ts index d7747dfd..fe03f885 100644 --- a/src/Apps/NetPad.Apps.App/App/src/core/@common/utils/system.ts +++ b/src/Apps/NetPad.Apps.App/App/src/core/@common/utils/system.ts @@ -1,5 +1,3 @@ -import * as process from "process"; - export class System { /** * Opens a URL in system-configured default browser. @@ -15,9 +13,14 @@ export class System { } public static getPlatform() { - try { - return process.platform; - } catch { + if (this.isRunningInElectron()) { + try { + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require("process").platform; + } catch { + return undefined; + } + } else { return undefined; } } diff --git a/src/Apps/NetPad.Apps.App/App/src/core/@domain/api.ts b/src/Apps/NetPad.Apps.App/App/src/core/@domain/api.ts index 68d6a949..36a86303 100644 --- a/src/Apps/NetPad.Apps.App/App/src/core/@domain/api.ts +++ b/src/Apps/NetPad.Apps.App/App/src/core/@domain/api.ts @@ -1324,7 +1324,7 @@ export interface IScriptsApiClient { save(id: string, signal?: AbortSignal | undefined): Promise; - run(id: string, dto: RunOptionsDto, signal?: AbortSignal | undefined): Promise; + run(id: string, options: RunOptions, signal?: AbortSignal | undefined): Promise; stop(id: string, signal?: AbortSignal | undefined): Promise; @@ -1541,14 +1541,14 @@ export class ScriptsApiClient extends ApiClientBase implements IScriptsApiClient return Promise.resolve(null); } - run(id: string, dto: RunOptionsDto, signal?: AbortSignal | undefined): Promise { + run(id: string, options: RunOptions, signal?: AbortSignal | undefined): Promise { let url_ = this.baseUrl + "/scripts/{id}/run"; if (id === undefined || id === null) throw new Error("The parameter 'id' must be defined."); url_ = url_.replace("{id}", encodeURIComponent("" + id)); url_ = url_.replace(/[?&]$/, ""); - const content_ = JSON.stringify(dto); + const content_ = JSON.stringify(options); let options_ = { body: content_, @@ -2249,7 +2249,7 @@ export interface ISettingsApiClient { get(signal?: AbortSignal | undefined): Promise; - update(settings: Settings, signal?: AbortSignal | undefined): Promise; + update(update: Settings, signal?: AbortSignal | undefined): Promise; openSettingsWindow(tab: string | null | undefined, signal?: AbortSignal | undefined): Promise; @@ -2302,11 +2302,11 @@ export class SettingsApiClient extends ApiClientBase implements ISettingsApiClie return Promise.resolve(null); } - update(settings: Settings, signal?: AbortSignal | undefined): Promise { + update(update: Settings, signal?: AbortSignal | undefined): Promise { let url_ = this.baseUrl + "/settings"; url_ = url_.replace(/[?&]$/, ""); - const content_ = JSON.stringify(settings); + const content_ = JSON.stringify(update); let options_ = { body: content_, @@ -2669,12 +2669,19 @@ export interface IAppDependencyCheckResult { isSupportedDotNetEfToolInstalled: boolean; } +/** An implementation of semantic versioning (https://semver.org) */ export class SemanticVersion implements ISemanticVersion { + /** The major version number, never negative. */ major!: number; + /** The minor version number, never negative. */ minor!: number; + /** The patch version, -1 if not specified. */ patch!: number; + /** PreReleaseLabel position in the SymVer string 'major.minor.patch-PreReleaseLabel+BuildLabel'. */ preReleaseLabel?: string | undefined; + /** BuildLabel position in the SymVer string 'major.minor.patch-PreReleaseLabel+BuildLabel'. */ buildLabel?: string | undefined; + /** String representation. */ string!: string; constructor(data?: ISemanticVersion) { @@ -2723,12 +2730,19 @@ export class SemanticVersion implements ISemanticVersion { } } +/** An implementation of semantic versioning (https://semver.org) */ export interface ISemanticVersion { + /** The major version number, never negative. */ major: number; + /** The minor version number, never negative. */ minor: number; + /** The patch version, -1 if not specified. */ patch: number; + /** PreReleaseLabel position in the SymVer string 'major.minor.patch-PreReleaseLabel+BuildLabel'. */ preReleaseLabel?: string | undefined; + /** BuildLabel position in the SymVer string 'major.minor.patch-PreReleaseLabel+BuildLabel'. */ buildLabel?: string | undefined; + /** String representation. */ string: string; } @@ -3188,6 +3202,7 @@ export class SyntaxNodeOrTokenSlim implements ISyntaxNodeOrTokenSlim { isToken!: boolean; isNode!: boolean; kind!: SyntaxKind; + type!: string; span!: LinePositionSpan; isMissing!: boolean; valueText?: string | undefined; @@ -3215,6 +3230,7 @@ export class SyntaxNodeOrTokenSlim implements ISyntaxNodeOrTokenSlim { this.isToken = _data["isToken"]; this.isNode = _data["isNode"]; this.kind = _data["kind"]; + this.type = _data["type"]; this.span = _data["span"] ? LinePositionSpan.fromJS(_data["span"]) : new LinePositionSpan(); this.isMissing = _data["isMissing"]; this.valueText = _data["valueText"]; @@ -3248,6 +3264,7 @@ export class SyntaxNodeOrTokenSlim implements ISyntaxNodeOrTokenSlim { data["isToken"] = this.isToken; data["isNode"] = this.isNode; data["kind"] = this.kind; + data["type"] = this.type; data["span"] = this.span ? this.span.toJSON() : undefined; data["isMissing"] = this.isMissing; data["valueText"] = this.valueText; @@ -3281,6 +3298,7 @@ export interface ISyntaxNodeOrTokenSlim { isToken: boolean; isNode: boolean; kind: SyntaxKind; + type: string; span: LinePositionSpan; isMissing: boolean; valueText?: string | undefined; @@ -4234,7 +4252,7 @@ export interface IPackageIdentity { version: string; } -export type DotNetFrameworkVersion = "DotNet2" | "DotNet3" | "DotNet5" | "DotNet6" | "DotNet7" | "DotNet8" | "DotNet9"; +export type DotNetFrameworkVersion = "DotNet5" | "DotNet6" | "DotNet7" | "DotNet8" | "DotNet9"; export class ScriptSummary implements IScriptSummary { id!: string; @@ -4344,11 +4362,13 @@ export interface ICreateScriptDto { runImmediately: boolean; } -export class RunOptionsDto implements IRunOptionsDto { +/** Options that configure the running of a script. */ +export class RunOptions implements IRunOptions { + /** If not null, this code will run instead of script code. Typically used to only run code that user has +highlighted in the editor. */ specificCodeToRun?: string | undefined; - additionalCode?: SourceCodeDto[] | undefined; - constructor(data?: IRunOptionsDto) { + constructor(data?: IRunOptions) { if (data) { for (var property in data) { if (data.hasOwnProperty(property)) @@ -4360,17 +4380,12 @@ export class RunOptionsDto implements IRunOptionsDto { init(_data?: any) { if (_data) { this.specificCodeToRun = _data["specificCodeToRun"]; - if (Array.isArray(_data["additionalCode"])) { - this.additionalCode = [] as any; - for (let item of _data["additionalCode"]) - this.additionalCode!.push(SourceCodeDto.fromJS(item)); - } } } - static fromJS(data: any): RunOptionsDto { + static fromJS(data: any): RunOptions { data = typeof data === 'object' ? data : {}; - let result = new RunOptionsDto(); + let result = new RunOptions(); result.init(data); return result; } @@ -4378,80 +4393,22 @@ export class RunOptionsDto implements IRunOptionsDto { toJSON(data?: any) { data = typeof data === 'object' ? data : {}; data["specificCodeToRun"] = this.specificCodeToRun; - if (Array.isArray(this.additionalCode)) { - data["additionalCode"] = []; - for (let item of this.additionalCode) - data["additionalCode"].push(item.toJSON()); - } return data; } - clone(): RunOptionsDto { + clone(): RunOptions { const json = this.toJSON(); - let result = new RunOptionsDto(); + let result = new RunOptions(); result.init(json); return result; } } -export interface IRunOptionsDto { +/** Options that configure the running of a script. */ +export interface IRunOptions { + /** If not null, this code will run instead of script code. Typically used to only run code that user has +highlighted in the editor. */ specificCodeToRun?: string | undefined; - additionalCode?: SourceCodeDto[] | undefined; -} - -export class SourceCodeDto implements ISourceCodeDto { - usings?: string[] | undefined; - code?: string | undefined; - - constructor(data?: ISourceCodeDto) { - if (data) { - for (var property in data) { - if (data.hasOwnProperty(property)) - (this)[property] = (data)[property]; - } - } - } - - init(_data?: any) { - if (_data) { - if (Array.isArray(_data["usings"])) { - this.usings = [] as any; - for (let item of _data["usings"]) - this.usings!.push(item); - } - this.code = _data["code"]; - } - } - - static fromJS(data: any): SourceCodeDto { - data = typeof data === 'object' ? data : {}; - let result = new SourceCodeDto(); - result.init(data); - return result; - } - - toJSON(data?: any) { - data = typeof data === 'object' ? data : {}; - if (Array.isArray(this.usings)) { - data["usings"] = []; - for (let item of this.usings) - data["usings"].push(item); - } - data["code"] = this.code; - return data; - } - - clone(): SourceCodeDto { - const json = this.toJSON(); - let result = new SourceCodeDto(); - result.init(json); - return result; - } -} - -export interface ISourceCodeDto { - usings?: string[] | undefined; - code?: string | undefined; } export type OptimizationLevel = "Debug" | "Release"; @@ -5163,6 +5120,7 @@ export interface IKeyboardShortcutConfiguration { export type KeyCode = "Unknown" | "Backspace" | "Tab" | "Enter" | "ShiftLeft" | "ShiftRight" | "ControlLeft" | "ControlRight" | "AltLeft" | "AltRight" | "Pause" | "CapsLock" | "Escape" | "Space" | "PageUp" | "PageDown" | "End" | "Home" | "ArrowLeft" | "ArrowUp" | "ArrowRight" | "ArrowDown" | "PrintScreen" | "Insert" | "Delete" | "Digit0" | "Digit1" | "Digit2" | "Digit3" | "Digit4" | "Digit5" | "Digit6" | "Digit7" | "Digit8" | "Digit9" | "KeyA" | "KeyB" | "KeyC" | "KeyD" | "KeyE" | "KeyF" | "KeyG" | "KeyH" | "KeyI" | "KeyJ" | "KeyK" | "KeyL" | "KeyM" | "KeyN" | "KeyO" | "KeyP" | "KeyQ" | "KeyR" | "KeyS" | "KeyT" | "KeyU" | "KeyV" | "KeyW" | "KeyX" | "KeyY" | "KeyZ" | "MetaLeft" | "MetaRight" | "ContextMenu" | "Numpad0" | "Numpad1" | "Numpad2" | "Numpad3" | "Numpad4" | "Numpad5" | "Numpad6" | "Numpad7" | "Numpad8" | "Numpad9" | "NumpadMultiply" | "NumpadAdd" | "NumpadSubtract" | "NumpadDecimal" | "NumpadDivide" | "F1" | "F2" | "F3" | "F4" | "F5" | "F6" | "F7" | "F8" | "F9" | "F10" | "F11" | "F12" | "NumLock" | "ScrollLock" | "Semicolon" | "Equal" | "Comma" | "Minus" | "Period" | "Slash" | "Backquote" | "BracketLeft" | "Backslash" | "BracketRight" | "Quote"; +/** This should be moved to the OmniSharp plugin */ export class OmniSharpOptions implements IOmniSharpOptions { enabled!: boolean; executablePath?: string | undefined; @@ -5227,6 +5185,7 @@ export class OmniSharpOptions implements IOmniSharpOptions { } } +/** This should be moved to the OmniSharp plugin */ export interface IOmniSharpOptions { enabled: boolean; executablePath?: string | undefined; @@ -5713,8 +5672,11 @@ export interface IErrorResult { details?: string | undefined; } +/** A base class for all script output */ export abstract class ScriptOutput implements IScriptOutput { + /** The body of the output. */ body?: any | undefined; + /** The order this output was emitted. A value of 0 indicates no order. */ order!: number; constructor(data?: IScriptOutput) { @@ -5750,11 +5712,15 @@ export abstract class ScriptOutput implements IScriptOutput { } } +/** A base class for all script output */ export interface IScriptOutput { + /** The body of the output. */ body?: any | undefined; + /** The order this output was emitted. A value of 0 indicates no order. */ order: number; } +/** A base class for script output with an HTML-formatted string as the body. */ export abstract class HtmlScriptOutput extends ScriptOutput implements IHtmlScriptOutput { body?: string | undefined; @@ -5786,10 +5752,12 @@ export abstract class HtmlScriptOutput extends ScriptOutput implements IHtmlScri } } +/** A base class for script output with an HTML-formatted string as the body. */ export interface IHtmlScriptOutput extends IScriptOutput { body?: string | undefined; } +/** Results script output represented as HTML. */ export class HtmlResultsScriptOutput extends HtmlScriptOutput implements IHtmlResultsScriptOutput { constructor(data?: IHtmlResultsScriptOutput) { @@ -5821,9 +5789,11 @@ export class HtmlResultsScriptOutput extends HtmlScriptOutput implements IHtmlRe } } +/** Results script output represented as HTML. */ export interface IHtmlResultsScriptOutput extends IHtmlScriptOutput { } +/** Error script output represented as HTML. */ export class HtmlErrorScriptOutput extends HtmlScriptOutput implements IHtmlErrorScriptOutput { constructor(data?: IHtmlErrorScriptOutput) { @@ -5855,9 +5825,11 @@ export class HtmlErrorScriptOutput extends HtmlScriptOutput implements IHtmlErro } } +/** Error script output represented as HTML. */ export interface IHtmlErrorScriptOutput extends IHtmlScriptOutput { } +/** Raw script output represented as HTML. */ export class HtmlRawScriptOutput extends HtmlScriptOutput implements IHtmlRawScriptOutput { constructor(data?: IHtmlRawScriptOutput) { @@ -5889,9 +5861,11 @@ export class HtmlRawScriptOutput extends HtmlScriptOutput implements IHtmlRawScr } } +/** Raw script output represented as HTML. */ export interface IHtmlRawScriptOutput extends IHtmlScriptOutput { } +/** SQL script output represented as HTML. */ export class HtmlSqlScriptOutput extends HtmlScriptOutput implements IHtmlSqlScriptOutput { constructor(data?: IHtmlSqlScriptOutput) { @@ -5923,6 +5897,7 @@ export class HtmlSqlScriptOutput extends HtmlScriptOutput implements IHtmlSqlScr } } +/** SQL script output represented as HTML. */ export interface IHtmlSqlScriptOutput extends IHtmlScriptOutput { } @@ -6018,11 +5993,17 @@ export interface IAppStatusMessagePublishedEvent { message: AppStatusMessage; } +/** Represents a status change in the application. */ export class AppStatusMessage implements IAppStatusMessage { + /** The ID of the script this message relates to. */ scriptId?: string | undefined; + /** The text of this message. */ text!: string; + /** The priority of this message. */ priority!: AppStatusMessagePriority; + /** Whether this status message should be persistant or it should clear out after a timeout. */ persistant!: boolean; + /** The DateTime of when this message was created. */ createdDate!: Date; constructor(data?: IAppStatusMessage) { @@ -6069,11 +6050,17 @@ export class AppStatusMessage implements IAppStatusMessage { } } +/** Represents a status change in the application. */ export interface IAppStatusMessage { + /** The ID of the script this message relates to. */ scriptId?: string | undefined; + /** The text of this message. */ text: string; + /** The priority of this message. */ priority: AppStatusMessagePriority; + /** Whether this status message should be persistant or it should clear out after a timeout. */ persistant: boolean; + /** The DateTime of when this message was created. */ createdDate: Date; } diff --git a/src/Apps/NetPad.Apps.App/App/src/windows/main/panes/code-pane/syntax-tree-view/syntax-tree-view.html b/src/Apps/NetPad.Apps.App/App/src/windows/main/panes/code-pane/syntax-tree-view/syntax-tree-view.html index b5ebb80a..f4455e78 100644 --- a/src/Apps/NetPad.Apps.App/App/src/windows/main/panes/code-pane/syntax-tree-view/syntax-tree-view.html +++ b/src/Apps/NetPad.Apps.App/App/src/windows/main/panes/code-pane/syntax-tree-view/syntax-tree-view.html @@ -37,7 +37,10 @@ - ${syntaxNode.kind} + + ${syntaxNode.kind} + { const document = viewable.textDocument; - const runOptions = new RunOptionsDto(); + const runOptions = new RunOptions(); if (document.selection && !document.selection.isEmpty()) { runOptions.specificCodeToRun = document.textModel.getValueInRange(document.selection); diff --git a/src/Apps/NetPad.Apps.App/App/src/windows/settings/about/about.html b/src/Apps/NetPad.Apps.App/App/src/windows/settings/about/about.html index feadca34..a2c86402 100644 --- a/src/Apps/NetPad.Apps.App/App/src/windows/settings/about/about.html +++ b/src/Apps/NetPad.Apps.App/App/src/windows/settings/about/about.html @@ -19,8 +19,4 @@ GitHub - -
- Build: v${appId.productVersion} -
diff --git a/src/Apps/NetPad.Apps.App/App/webpack.config.js b/src/Apps/NetPad.Apps.App/App/webpack.config.js index 91c1427d..c6c5798c 100644 --- a/src/Apps/NetPad.Apps.App/App/webpack.config.js +++ b/src/Apps/NetPad.Apps.App/App/webpack.config.js @@ -58,6 +58,7 @@ module.exports = function (env, {analyze}) { ], fallback: { "fs": false, + "process": false, "path": require.resolve("path-browserify"), }, alias: { diff --git a/src/Apps/NetPad.Apps.App/BackgroundServices/AppSetupAndCleanupBackgroundService.cs b/src/Apps/NetPad.Apps.App/BackgroundServices/AppSetupAndCleanupBackgroundService.cs index 95c5b747..06586247 100644 --- a/src/Apps/NetPad.Apps.App/BackgroundServices/AppSetupAndCleanupBackgroundService.cs +++ b/src/Apps/NetPad.Apps.App/BackgroundServices/AppSetupAndCleanupBackgroundService.cs @@ -1,54 +1,40 @@ using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; using NetPad.Application; +using NetPad.Apps.Plugins; using NetPad.Configuration; -using NetPad.Plugins; using NetPad.Scripts; using NetPad.Sessions; namespace NetPad.BackgroundServices; -public class AppSetupAndCleanupBackgroundService : BackgroundService +public class AppSetupAndCleanupBackgroundService( + ISession session, + IAutoSaveScriptRepository autoSaveScriptRepository, + IPluginManager pluginManager, + IAppStatusMessagePublisher appStatusMessagePublisher, + ILoggerFactory loggerFactory) + : BackgroundService(loggerFactory) { - private readonly ISession _session; - private readonly IAutoSaveScriptRepository _autoSaveScriptRepository; - private readonly IPluginManager _pluginManager; - private readonly IAppStatusMessagePublisher _appStatusMessagePublisher; - - public AppSetupAndCleanupBackgroundService( - ISession session, - IAutoSaveScriptRepository autoSaveScriptRepository, - IPluginManager pluginManager, - IAppStatusMessagePublisher appStatusMessagePublisher, - ILoggerFactory loggerFactory) : base(loggerFactory) - { - _session = session; - _autoSaveScriptRepository = autoSaveScriptRepository; - _pluginManager = pluginManager; - _appStatusMessagePublisher = appStatusMessagePublisher; - } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - var autoSavedScripts = await _autoSaveScriptRepository.GetScriptsAsync(); + var autoSavedScripts = await autoSaveScriptRepository.GetScriptsAsync(); - await _session.OpenAsync(autoSavedScripts); + await session.OpenAsync(autoSavedScripts); } protected override async Task StoppingAsync(CancellationToken cancellationToken) { - await _appStatusMessagePublisher.PublishAsync("Stopping...", AppStatusMessagePriority.Normal, true); + await appStatusMessagePublisher.PublishAsync("Stopping...", AppStatusMessagePriority.Normal, true); - var environments = _session.Environments; + var environments = session.Environments; - await _session.CloseAsync(environments.Select(e => e.Script.Id).ToArray()); + await session.CloseAsync(environments.Select(e => e.Script.Id).ToArray()); AppDataProvider.ExternalProcessesDirectoryPath.DeleteIfExists(); AppDataProvider.TypedDataContextTempDirectoryPath.DeleteIfExists(); - foreach (var registration in _pluginManager.PluginRegistrations) + foreach (var registration in pluginManager.PluginRegistrations) { await registration.Plugin.CleaupAsync(); } diff --git a/src/Apps/NetPad.Apps.App/BackgroundServices/BackgroundService.cs b/src/Apps/NetPad.Apps.App/BackgroundServices/BackgroundService.cs index 75f04b93..a6030962 100644 --- a/src/Apps/NetPad.Apps.App/BackgroundServices/BackgroundService.cs +++ b/src/Apps/NetPad.Apps.App/BackgroundServices/BackgroundService.cs @@ -1,6 +1,3 @@ -using System; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace NetPad.BackgroundServices; diff --git a/src/Apps/NetPad.Apps.App/BackgroundServices/DebugAssemblyUnloadBackgroundService.cs b/src/Apps/NetPad.Apps.App/BackgroundServices/DebugAssemblyUnloadBackgroundService.cs index f874c42a..62c30715 100644 --- a/src/Apps/NetPad.Apps.App/BackgroundServices/DebugAssemblyUnloadBackgroundService.cs +++ b/src/Apps/NetPad.Apps.App/BackgroundServices/DebugAssemblyUnloadBackgroundService.cs @@ -1,21 +1,14 @@ -using System; using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace NetPad.BackgroundServices; /// /// Periodically outputs the compiled script assemblies loaded by the program into memory. This is -/// mainly used to debug assembly unloading after script execution (when using InMemoryScriptRuntime only). +/// mainly used to debug assembly unloading after script execution (when using InMemoryScriptRunner only). /// -public class DebugAssemblyUnloadBackgroundService : BackgroundService +public class DebugAssemblyUnloadBackgroundService(ILoggerFactory loggerFactory) : BackgroundService(loggerFactory) { - public DebugAssemblyUnloadBackgroundService(ILoggerFactory loggerFactory) : base(loggerFactory) - { - } - protected override Task ExecuteAsync(CancellationToken stoppingToken) { Task.Run(async () => diff --git a/src/Apps/NetPad.Apps.App/BackgroundServices/EventForwardToIpcBackgroundService.cs b/src/Apps/NetPad.Apps.App/BackgroundServices/EventForwardToIpcBackgroundService.cs index 0805fe08..dc6030bf 100644 --- a/src/Apps/NetPad.Apps.App/BackgroundServices/EventForwardToIpcBackgroundService.cs +++ b/src/Apps/NetPad.Apps.App/BackgroundServices/EventForwardToIpcBackgroundService.cs @@ -1,30 +1,26 @@ -using System; using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using NetPad.Application.Events; +using NetPad.Apps.UiInterop; +using NetPad.Configuration.Events; +using NetPad.Data.Events; using NetPad.Events; using NetPad.Scripts; -using NetPad.UiInterop; +using NetPad.Scripts.Events; +using NetPad.Sessions.Events; namespace NetPad.BackgroundServices; /// /// Forwards specific events to IPC clients. /// -public class EventForwardToIpcBackgroundService : BackgroundService +public class EventForwardToIpcBackgroundService( + IEventBus eventBus, + IIpcService ipcService, + ILoggerFactory loggerFactory) + : BackgroundService(loggerFactory) { - private readonly IEventBus _eventBus; - private readonly IIpcService _ipcService; - private readonly Dictionary> _environmentSubscriptionTokens; - - public EventForwardToIpcBackgroundService(IEventBus eventBus, IIpcService ipcService, ILoggerFactory loggerFactory) - : base(loggerFactory) - { - _eventBus = eventBus; - _ipcService = ipcService; - _environmentSubscriptionTokens = new Dictionary>(); - } + private readonly Dictionary> _environmentSubscriptionTokens = new(); protected override Task ExecuteAsync(CancellationToken stoppingToken) { @@ -52,7 +48,7 @@ private void ForwardApplicationLevelEvents() private void ForwardEnvironmentLevelEvents() { - _eventBus.Subscribe(ev => + eventBus.Subscribe(ev => { foreach (var environment in ev.Environments) { @@ -78,7 +74,7 @@ private void ForwardEnvironmentLevelEvents() return Task.CompletedTask; }); - _eventBus.Subscribe(ev => + eventBus.Subscribe(ev => { Unsubscribe(ev.Environments); return Task.CompletedTask; @@ -87,20 +83,20 @@ private void ForwardEnvironmentLevelEvents() private void SubscribeAndForwardToIpc() where TEvent : class, IEvent { - _eventBus.Subscribe(async ev => { await _ipcService.SendAsync(ev); }); + eventBus.Subscribe(async ev => { await ipcService.SendAsync(ev); }); } private void SubscribeAndForwardToIpc(ScriptEnvironment environment, Func? predicate = null) where TEvent : class, IScriptEvent { - var token = _eventBus.Subscribe(async ev => + var token = eventBus.Subscribe(async ev => { if (predicate != null && !predicate(ev)) { return; } - await _ipcService.SendAsync(ev); + await ipcService.SendAsync(ev); }); AddEnvironmentEventToken(environment, token); @@ -110,7 +106,7 @@ private void AddEnvironmentEventToken(ScriptEnvironment environment, EventSubscr { if (!_environmentSubscriptionTokens.TryGetValue(environment.Script.Id, out var tokens)) { - tokens = new List(); + tokens = []; _environmentSubscriptionTokens.Add(environment.Script.Id, tokens); } @@ -128,7 +124,7 @@ private void Unsubscribe(ScriptEnvironment[] environments) foreach (var token in tokens) { - _eventBus.Unsubscribe(token); + eventBus.Unsubscribe(token); } _environmentSubscriptionTokens.Remove(environment.Script.Id); diff --git a/src/Apps/NetPad.Apps.App/BackgroundServices/EventHandlerBackgroundService.cs b/src/Apps/NetPad.Apps.App/BackgroundServices/EventHandlerBackgroundService.cs index f91343ba..3b445308 100644 --- a/src/Apps/NetPad.Apps.App/BackgroundServices/EventHandlerBackgroundService.cs +++ b/src/Apps/NetPad.Apps.App/BackgroundServices/EventHandlerBackgroundService.cs @@ -1,23 +1,16 @@ -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using NetPad.Configuration.Events; using NetPad.Events; using NetPad.Presentation.Html; namespace NetPad.BackgroundServices; -public class EventHandlerBackgroundService : BackgroundService +public class EventHandlerBackgroundService(IEventBus eventBus, ILoggerFactory loggerFactory) + : BackgroundService(loggerFactory) { - private readonly IEventBus _eventBus; - - public EventHandlerBackgroundService(IEventBus eventBus, ILoggerFactory loggerFactory) : base(loggerFactory) - { - _eventBus = eventBus; - } - protected override Task ExecuteAsync(CancellationToken stoppingToken) { - _eventBus.Subscribe(ev => + eventBus.Subscribe(ev => { HtmlPresenter.UpdateSerializerSettings(ev.Settings.Results.MaxSerializationDepth, ev.Settings.Results.MaxCollectionSerializeLength); diff --git a/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptEnvironmentBackgroundService.cs b/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptEnvironmentBackgroundService.cs index 99d3c52d..54b38a1f 100644 --- a/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptEnvironmentBackgroundService.cs +++ b/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptEnvironmentBackgroundService.cs @@ -1,41 +1,29 @@ -using System; using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using NetPad.CQs; +using NetPad.Apps.CQs; +using NetPad.Apps.UiInterop; using NetPad.Events; using NetPad.IO; using NetPad.Scripts; +using NetPad.Scripts.Events; using NetPad.Services; -using NetPad.UiInterop; +using NetPad.Sessions.Events; namespace NetPad.BackgroundServices; /// /// Handles automations that occur when a script environment is added to removed from the session. /// -public class ScriptEnvironmentBackgroundService : BackgroundService +public class ScriptEnvironmentBackgroundService( + IEventBus eventBus, + IIpcService ipcService, + IAutoSaveScriptRepository autoSaveScriptRepository, + ILoggerFactory loggerFactory) + : BackgroundService(loggerFactory) { - private readonly IEventBus _eventBus; - private readonly IIpcService _ipcService; - private readonly IAutoSaveScriptRepository _autoSaveScriptRepository; - private readonly ILoggerFactory _loggerFactory; - - private readonly Dictionary> _environmentSubscriptionTokens; - - public ScriptEnvironmentBackgroundService( - IEventBus eventBus, - IIpcService ipcService, - IAutoSaveScriptRepository autoSaveScriptRepository, - ILoggerFactory loggerFactory) : base(loggerFactory) - { - _eventBus = eventBus; - _ipcService = ipcService; - _autoSaveScriptRepository = autoSaveScriptRepository; - _loggerFactory = loggerFactory; - _environmentSubscriptionTokens = new Dictionary>(); - } + private readonly ILoggerFactory _loggerFactory = loggerFactory; + + private readonly Dictionary> _environmentSubscriptionTokens = new(); protected override Task ExecuteAsync(CancellationToken stoppingToken) { @@ -46,7 +34,7 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken) private void ListenToEnvironmentsChanges() { - _eventBus.Subscribe(ev => + eventBus.Subscribe(ev => { foreach (var environment in ev.Environments) { @@ -54,12 +42,12 @@ private void ListenToEnvironmentsChanges() var inputReader = new AsyncActionInputReader( // TODO There should be a way to cancel the wait when the environment stops using a CancellationToken - async () => await _ipcService.SendAndReceiveAsync(new PromptUserForInputCommand(environment.Script.Id))); + async () => await ipcService.SendAndReceiveAsync(new PromptUserForInputCommand(environment.Script.Id))); var outputWriter = new ScriptEnvironmentIpcOutputWriter( environment, - _ipcService, - _eventBus, + ipcService, + eventBus, _loggerFactory.CreateLogger()); environment.SetIO(inputReader, outputWriter); @@ -70,7 +58,7 @@ private void ListenToEnvironmentsChanges() return Task.CompletedTask; }); - _eventBus.Subscribe(ev => + eventBus.Subscribe(ev => { foreach (var environment in ev.Environments) { @@ -88,17 +76,17 @@ private void AutoSaveScriptChanges(ScriptEnvironment environment) if (scriptId != environment.Script.Id || !environment.Script.IsDirty) return; - await _autoSaveScriptRepository.SaveAsync(environment.Script); + await autoSaveScriptRepository.SaveAsync(environment.Script); }).DebounceAsync(3000); - var scriptPropChangeToken = _eventBus.Subscribe(ev => + var scriptPropChangeToken = eventBus.Subscribe(ev => { autoSave(ev.ScriptId); return Task.CompletedTask; }); AddEnvironmentEventToken(environment, scriptPropChangeToken); - var scriptConfigPropChangeToken = _eventBus.Subscribe(ev => + var scriptConfigPropChangeToken = eventBus.Subscribe(ev => { autoSave(ev.ScriptId); return Task.CompletedTask; @@ -110,7 +98,7 @@ private void AddEnvironmentEventToken(ScriptEnvironment environment, IDisposable { if (!_environmentSubscriptionTokens.TryGetValue(environment.Script.Id, out var tokens)) { - tokens = new List(); + tokens = []; _environmentSubscriptionTokens.Add(environment.Script.Id, tokens); } diff --git a/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptsFileWatcherBackgroundService.cs b/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptsFileWatcherBackgroundService.cs index e9400450..55ff1480 100644 --- a/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptsFileWatcherBackgroundService.cs +++ b/src/Apps/NetPad.Apps.App/BackgroundServices/ScriptsFileWatcherBackgroundService.cs @@ -1,12 +1,9 @@ -using System; using System.IO; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using NetPad.Apps.UiInterop; using NetPad.Configuration; -using NetPad.Events; using NetPad.Scripts; -using NetPad.UiInterop; +using NetPad.Scripts.Events; namespace NetPad.BackgroundServices; diff --git a/src/Apps/NetPad.Apps.App/Controllers/AppController.cs b/src/Apps/NetPad.Apps.App/Controllers/AppController.cs index 2d9753f9..ff93a36a 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/AppController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/AppController.cs @@ -1,33 +1,24 @@ -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Http; using System.Text.Json; -using System.Threading.Tasks; using MediatR; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using NetPad.Application; +using NetPad.Apps.CQs; +using NetPad.Apps.UiInterop; using NetPad.Configuration; -using NetPad.CQs; using NetPad.Filters; -using NetPad.UiInterop; namespace NetPad.Controllers; [ApiController] [Route("app")] -public class AppController : ControllerBase +public class AppController(ILogger logger) : ControllerBase { - private readonly ILogger _logger; - - public AppController(ILogger logger) - { - _logger = logger; - } - [HttpGet("identifier")] public AppIdentifier GetIdentifier([FromServices] AppIdentifier appIdentifier) { @@ -67,7 +58,7 @@ public AppIdentifier GetIdentifier([FromServices] AppIdentifier appIdentifier) } catch (Exception ex) { - _logger.LogError(ex, "Error getting latest version"); + logger.LogError(ex, "Error getting latest version"); } return null; @@ -155,7 +146,7 @@ public void OpenPackageCacheFolder([FromServices] Settings settings) { var message = log.Message ?? string.Empty; - foreach (var logOptionalParam in log.OptionalParams ??= Array.Empty()) + foreach (var logOptionalParam in log.OptionalParams ??= []) { message += $" {logOptionalParam}"; } diff --git a/src/Apps/NetPad.Apps.App/Controllers/AssembliesController.cs b/src/Apps/NetPad.Apps.App/Controllers/AssembliesController.cs index 95e2c9b1..41df94ff 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/AssembliesController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/AssembliesController.cs @@ -1,7 +1,5 @@ -using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NetPad.Assemblies; using NetPad.Common; @@ -12,15 +10,8 @@ namespace NetPad.Controllers; [ApiController] [Route("assemblies")] -public class AssembliesController : ControllerBase +public class AssembliesController(IPackageProvider packageProvider) : ControllerBase { - private readonly IPackageProvider _packageProvider; - - public AssembliesController(IPackageProvider packageProvider) - { - _packageProvider = packageProvider; - } - [HttpPatch("namespaces")] public async Task> GetNamespaces([FromBody] Reference reference) { @@ -36,7 +27,7 @@ public async Task> GetNamespaces([FromBody] Reference ref if (reference is PackageReference packageReference) { - var assets = await _packageProvider.GetCachedPackageAssetsAsync( + var assets = await packageProvider.GetCachedPackageAssetsAsync( packageReference.PackageId, packageReference.Version, GlobalConsts.AppDotNetFrameworkVersion); diff --git a/src/Apps/NetPad.Apps.App/Controllers/CodeController.cs b/src/Apps/NetPad.Apps.App/Controllers/CodeController.cs index c14e2288..85b2ef4a 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/CodeController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/CodeController.cs @@ -1,4 +1,3 @@ -using System; using System.Text.Json; using Microsoft.AspNetCore.Mvc; using NetPad.CodeAnalysis; diff --git a/src/Apps/NetPad.Apps.App/Controllers/DataConnectionsController.cs b/src/Apps/NetPad.Apps.App/Controllers/DataConnectionsController.cs index a328fcc8..57c05287 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/DataConnectionsController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/DataConnectionsController.cs @@ -1,28 +1,19 @@ -using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using MediatR; using Microsoft.AspNetCore.Mvc; +using NetPad.Apps.CQs; +using NetPad.Apps.Data.EntityFrameworkCore.DataConnections; +using NetPad.Apps.UiInterop; using NetPad.Common; -using NetPad.CQs; using NetPad.Data; -using NetPad.Data.EntityFrameworkCore.DataConnections; -using NetPad.UiInterop; namespace NetPad.Controllers; [ApiController] [Route("data-connections")] -public class DataConnectionsController : ControllerBase +public class DataConnectionsController(IMediator mediator) : ControllerBase { - private readonly IMediator _mediator; - - public DataConnectionsController(IMediator mediator) - { - _mediator = mediator; - } - [HttpPatch("open")] public async Task OpenDataConnectionWindow([FromServices] IUiWindowService uiWindowService, [FromQuery] Guid? dataConnectionId = null, [FromQuery] bool copy = false) { @@ -30,12 +21,12 @@ public async Task OpenDataConnectionWindow([FromServices] IUiWindowService uiWin } [HttpGet] - public async Task> GetAll() => await _mediator.Send(new GetDataConnectionsQuery()); + public async Task> GetAll() => await mediator.Send(new GetDataConnectionsQuery()); [HttpGet("{id:guid}")] public async Task> Get(Guid id) { - var connection = await _mediator.Send(new GetDataConnectionQuery(id)); + var connection = await mediator.Send(new GetDataConnectionQuery(id)); if (connection == null) return connection; @@ -60,13 +51,13 @@ public async Task> GetAllNames() } [HttpPut] - public async Task Save(DataConnection dataConnection) => await _mediator.Send(new SaveDataConnectionCommand(dataConnection)); + public async Task Save(DataConnection dataConnection) => await mediator.Send(new SaveDataConnectionCommand(dataConnection)); [HttpPatch("{id:guid}/refresh")] - public async Task Refresh(Guid id) => await _mediator.Send(new RefreshDataConnectionCommand(id)); + public async Task Refresh(Guid id) => await mediator.Send(new RefreshDataConnectionCommand(id)); [HttpDelete("{id:guid}")] - public async Task Delete(Guid id) => await _mediator.Send(new DeleteDataConnectionCommand(id)); + public async Task Delete(Guid id) => await mediator.Send(new DeleteDataConnectionCommand(id)); [HttpPost("connection-string")] public string GetConnectionString( @@ -102,13 +93,13 @@ public async Task> GetAllNames() [HttpPatch("{id:guid}/database-structure")] public async Task GetDatabaseStructure(Guid id) { - var dataConnection = await _mediator.Send(new GetDataConnectionQuery(id)); + var dataConnection = await mediator.Send(new GetDataConnectionQuery(id)); if (dataConnection is not DatabaseConnection databaseConnection) { throw new InvalidOperationException($"Cannot get database structure except on connections of type {nameof(DatabaseConnection)}."); } - return await _mediator.Send(new GetDatabaseConnectionStructureQuery(databaseConnection)); + return await mediator.Send(new GetDatabaseConnectionStructureQuery(databaseConnection)); } } diff --git a/src/Apps/NetPad.Apps.App/Controllers/FilesController.cs b/src/Apps/NetPad.Apps.App/Controllers/FilesController.cs index 370a3c15..f11a6f29 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/FilesController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/FilesController.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using Microsoft.AspNetCore.Mvc; diff --git a/src/Apps/NetPad.Apps.App/Controllers/PackagesController.cs b/src/Apps/NetPad.Apps.App/Controllers/PackagesController.cs index 647e38a8..aaee9802 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/PackagesController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/PackagesController.cs @@ -1,7 +1,5 @@ using System.Collections.Generic; using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NetPad.Common; using NetPad.DotNet; @@ -11,25 +9,18 @@ namespace NetPad.Controllers; [ApiController] [Route("packages")] -public class PackagesController : ControllerBase +public class PackagesController(IPackageProvider packageProvider) : ControllerBase { - private readonly IPackageProvider _packageProvider; - - public PackagesController(IPackageProvider packageProvider) - { - _packageProvider = packageProvider; - } - [HttpGet("cache")] public async Task>> GetCachedPackages([FromQuery] bool loadMetadata) { - return Ok(await _packageProvider.GetCachedPackagesAsync(loadMetadata)); + return Ok(await packageProvider.GetCachedPackagesAsync(loadMetadata)); } [HttpGet("cache/explicitly-installed")] public async Task>> GetExplicitlyInstalledCachedPackages([FromQuery] bool loadMetadata) { - return Ok(await _packageProvider.GetExplicitlyInstalledCachedPackagesAsync(loadMetadata)); + return Ok(await packageProvider.GetExplicitlyInstalledCachedPackagesAsync(loadMetadata)); } [HttpDelete("cache")] @@ -40,27 +31,27 @@ public async Task DeleteCachedPackage([FromQuery] string packageI if (string.IsNullOrWhiteSpace(packageVersion)) return BadRequest($"{nameof(packageVersion)} is required."); - await _packageProvider.DeleteCachedPackageAsync(packageId, packageVersion); + await packageProvider.DeleteCachedPackageAsync(packageId, packageVersion); return Ok(); } [HttpPatch("cache/purge")] public async Task PurgePackageCache() { - await _packageProvider.PurgePackageCacheAsync(); + await packageProvider.PurgePackageCacheAsync(); return Ok(); } [HttpGet("versions")] public async Task GetPackageVersionsAsync([FromQuery] string packageId, [FromQuery] bool includePrerelease = false) { - return await _packageProvider.GetPackageVersionsAsync(packageId, includePrerelease); + return await packageProvider.GetPackageVersionsAsync(packageId, includePrerelease); } [HttpPost("metadata")] public async Task GetPackageMetadata([FromBody] PackageIdentity[] packages, CancellationToken cancellationToken) { - return (await _packageProvider.GetExtendedMetadataAsync(packages, cancellationToken)) + return (await packageProvider.GetExtendedMetadataAsync(packages, cancellationToken)) .Values .Where(x => x != null) .ToArray()!; @@ -73,7 +64,7 @@ public async Task GetPackageMetadata([FromBody] PackageIdenti [FromQuery] int? take = null, [FromQuery] bool? includePrerelease = null) { - var packages = await _packageProvider.SearchPackagesAsync( + var packages = await packageProvider.SearchPackagesAsync( term, skip ?? 0, take ?? 30, @@ -95,11 +86,11 @@ public async Task GetPackageMetadata([FromBody] PackageIdenti if (string.IsNullOrWhiteSpace(packageVersion)) return BadRequest($"{nameof(packageVersion)} is required."); - var installInfo = await _packageProvider.GetPackageInstallInfoAsync(packageId, packageVersion); + var installInfo = await packageProvider.GetPackageInstallInfoAsync(packageId, packageVersion); if (installInfo?.InstallReason == PackageInstallReason.Explicit) return Ok(); - await _packageProvider.InstallPackageAsync(packageId, packageVersion, dotNetFrameworkVersion ?? GlobalConsts.AppDotNetFrameworkVersion); + await packageProvider.InstallPackageAsync(packageId, packageVersion, dotNetFrameworkVersion ?? GlobalConsts.AppDotNetFrameworkVersion); return Ok(); } } diff --git a/src/Apps/NetPad.Apps.App/Controllers/ScriptsController.cs b/src/Apps/NetPad.Apps.App/Controllers/ScriptsController.cs index bcbdffa6..ffbc6d31 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/ScriptsController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/ScriptsController.cs @@ -1,59 +1,51 @@ -using System; using System.Collections.Generic; -using System.Threading.Tasks; using MediatR; using Microsoft.AspNetCore.Mvc; using Microsoft.CodeAnalysis; -using NetPad.CQs; +using NetPad.Apps.CQs; +using NetPad.Apps.UiInterop; using NetPad.Data; using NetPad.DotNet; using NetPad.Dtos; using NetPad.Exceptions; -using NetPad.Runtimes; +using NetPad.ExecutionModel; using NetPad.Scripts; -using NetPad.UiInterop; +using NetPad.Services; namespace NetPad.Controllers; [ApiController] [Route("scripts")] -public class ScriptsController : ControllerBase +public class ScriptsController(IMediator mediator) : ControllerBase { - private readonly IMediator _mediator; - - public ScriptsController(IMediator mediator) - { - _mediator = mediator; - } - [HttpGet] public async Task> GetScripts() { - return await _mediator.Send(new GetAllScriptsQuery()); + return await mediator.Send(new GetAllScriptsQuery()); } [HttpPatch("create")] public async Task Create([FromBody] CreateScriptDto dto, [FromServices] IDataConnectionRepository dataConnectionRepository) { - var script = await _mediator.Send(new CreateScriptCommand()); + var script = await mediator.Send(new CreateScriptCommand()); bool hasSeedCode = !string.IsNullOrWhiteSpace(dto.Code); if (hasSeedCode) { - await _mediator.Send(new UpdateScriptCodeCommand(script, dto.Code)); + await mediator.Send(new UpdateScriptCodeCommand(script, dto.Code)); } if (dto.DataConnectionId != null) { var dataConnection = await dataConnectionRepository.GetAsync(dto.DataConnectionId.Value); - await _mediator.Send(new SetScriptDataConnectionCommand(script, dataConnection)); + await mediator.Send(new SetScriptDataConnectionCommand(script, dataConnection)); } - await _mediator.Send(new OpenScriptCommand(script)); + await mediator.Send(new OpenScriptCommand(script)); if (hasSeedCode && dto.RunImmediately) { - await _mediator.Send(new RunScriptCommand(script.Id, new RunOptions())); + await mediator.Send(new RunScriptCommand(script.Id, new RunOptions())); } } @@ -61,41 +53,40 @@ public async Task Create([FromBody] CreateScriptDto dto, [FromServices] IDataCon public async Task Rename(Guid id, [FromBody] string newName) { var environment = await GetScriptEnvironmentAsync(id); - await _mediator.Send(new RenameScriptCommand(environment.Script, newName)); + await mediator.Send(new RenameScriptCommand(environment.Script, newName)); } [HttpPatch("{id:guid}/duplicate")] public async Task Duplicate(Guid id) { var environment = await GetScriptEnvironmentAsync(id); - var script = await _mediator.Send(new DuplicateScriptCommand(environment.Script)); - await _mediator.Send(new OpenScriptCommand(script)); + var script = await mediator.Send(new DuplicateScriptCommand(environment.Script)); + await mediator.Send(new OpenScriptCommand(script)); } [HttpPatch("{id:guid}/save")] - public async Task Save(Guid id) + public async Task Save(Guid id, [FromServices] ScriptService scriptService) { - var environment = await GetScriptEnvironmentAsync(id); - await _mediator.Send(new SaveScriptCommand(environment.Script)); + await scriptService.SaveScriptAsync(id); } [HttpPatch("{id:guid}/run")] - public async Task Run(Guid id, [FromBody] RunOptionsDto dto) + public async Task Run(Guid id, [FromBody] RunOptions options) { - await _mediator.Send(new RunScriptCommand(id, dto.ToRunOptions())); + await mediator.Send(new RunScriptCommand(id, options)); } [HttpPatch("{id:guid}/stop")] public async Task Stop(Guid id) { - await _mediator.Send(new StopScriptCommand(id)); + await mediator.Send(new StopScriptCommand(id)); } [HttpPut("{id:guid}/code")] public async Task UpdateCode(Guid id, [FromBody] string code) { var environment = await GetScriptEnvironmentAsync(id); - await _mediator.Send(new UpdateScriptCodeCommand(environment.Script, code)); + await mediator.Send(new UpdateScriptCodeCommand(environment.Script, code)); } [HttpPatch("{id:guid}/open-config")] @@ -111,7 +102,7 @@ public async Task SetScriptNamespaces(Guid id, [FromBody] IEnumer { var environment = await GetScriptEnvironmentAsync(id); - await _mediator.Send(new UpdateScriptNamespacesCommand(environment.Script, namespaces)); + await mediator.Send(new UpdateScriptNamespacesCommand(environment.Script, namespaces)); return NoContent(); } @@ -121,7 +112,7 @@ public async Task SetReferences(Guid id, [FromBody] IEnumerable SetTargetFrameworkVersion(Guid id, [FromBody] D { var environment = await GetScriptEnvironmentAsync(id); - await _mediator.Send(new UpdateScriptTargetFrameworkCommand(environment.Script, targetFrameworkVersion)); + await mediator.Send(new UpdateScriptTargetFrameworkCommand(environment.Script, targetFrameworkVersion)); return NoContent(); } @@ -149,7 +140,7 @@ public async Task SetOptimizationLevel(Guid id, [FromBody] Optimi { var environment = await GetScriptEnvironmentAsync(id); - await _mediator.Send(new UpdateScriptOptimizationLevelCommand(environment.Script, optimizationLevel)); + await mediator.Send(new UpdateScriptOptimizationLevelCommand(environment.Script, optimizationLevel)); return NoContent(); } @@ -159,7 +150,7 @@ public async Task SetUseAspNet(Guid id, [FromBody] bool useAspNet { var environment = await GetScriptEnvironmentAsync(id); - await _mediator.Send(new UpdateScriptUseAspNetCommand(environment.Script, useAspNet)); + await mediator.Send(new UpdateScriptUseAspNetCommand(environment.Script, useAspNet)); return NoContent(); } @@ -179,13 +170,13 @@ public async Task SetUseAspNet(Guid id, [FromBody] bool useAspNet dataConnection = await dataConnectionRepository.GetAsync(dataConnectionId.Value); } - await _mediator.Send(new SetScriptDataConnectionCommand(environment.Script, dataConnection)); + await mediator.Send(new SetScriptDataConnectionCommand(environment.Script, dataConnection)); return NoContent(); } private async Task GetScriptEnvironmentAsync(Guid id) { - return await _mediator.Send(new GetOpenedScriptEnvironmentQuery(id, true)) + return await mediator.Send(new GetOpenedScriptEnvironmentQuery(id, true)) ?? throw new ScriptNotFoundException(id); } } diff --git a/src/Apps/NetPad.Apps.App/Controllers/SessionController.cs b/src/Apps/NetPad.Apps.App/Controllers/SessionController.cs index 8950aa38..a62a46b9 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/SessionController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/SessionController.cs @@ -1,66 +1,58 @@ -using System; using System.Collections.Generic; -using System.Threading.Tasks; using MediatR; using Microsoft.AspNetCore.Mvc; -using NetPad.CQs; +using NetPad.Apps.CQs; using NetPad.Exceptions; using NetPad.Scripts; +using NetPad.Services; namespace NetPad.Controllers; [ApiController] [Route("session")] -public class SessionController : ControllerBase +public class SessionController(IMediator mediator) : ControllerBase { - private readonly IMediator _mediator; - - public SessionController(IMediator mediator) - { - _mediator = mediator; - } - [HttpGet("environments/{scriptId:guid}")] public async Task GetEnvironment(Guid scriptId) { - return await _mediator.Send(new GetOpenedScriptEnvironmentQuery(scriptId)) + return await mediator.Send(new GetOpenedScriptEnvironmentQuery(scriptId)) ?? throw new EnvironmentNotFoundException(scriptId); } [HttpGet("environments")] public async Task> GetEnvironments() { - return await _mediator.Send(new GetOpenedScriptEnvironmentsQuery()); + return await mediator.Send(new GetOpenedScriptEnvironmentsQuery()); } [HttpPatch("open/path")] public async Task OpenByPath([FromBody] string scriptPath) { - await _mediator.Send(new OpenScriptCommand(scriptPath)); + await mediator.Send(new OpenScriptCommand(scriptPath)); } [HttpPatch("{scriptId:guid}/close")] - public async Task Close(Guid scriptId) + public async Task Close(Guid scriptId, [FromServices] ScriptService scriptService) { - await _mediator.Send(new CloseScriptCommand(scriptId)); + await scriptService.CloseScriptAsync(scriptId); } [HttpGet("active")] public async Task GetActive() { - var active = await _mediator.Send(new GetActiveScriptEnvironmentQuery()); + var active = await mediator.Send(new GetActiveScriptEnvironmentQuery()); return active?.Script.Id; } [HttpPatch("{scriptId:guid}/activate")] public async Task Activate(Guid scriptId) { - await _mediator.Send(new ActivateScriptCommand(scriptId)); + await mediator.Send(new ActivateScriptCommand(scriptId)); } [HttpPatch("activate-last-active")] public async Task ActivateLastActive() { - await _mediator.Send(new ActivateLastActiveScriptCommand()); + await mediator.Send(new ActivateLastActiveScriptCommand()); } } diff --git a/src/Apps/NetPad.Apps.App/Controllers/SettingsController.cs b/src/Apps/NetPad.Apps.App/Controllers/SettingsController.cs index 05895817..bd873d57 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/SettingsController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/SettingsController.cs @@ -1,37 +1,26 @@ using System.IO; -using System.Threading.Tasks; using MediatR; using Microsoft.AspNetCore.Mvc; +using NetPad.Apps.CQs; +using NetPad.Apps.UiInterop; using NetPad.Configuration; -using NetPad.CQs; -using NetPad.UiInterop; namespace NetPad.Controllers; [ApiController] [Route("settings")] -public class SettingsController : ControllerBase +public class SettingsController(Settings settings, IMediator mediator) : ControllerBase { - private readonly Settings _settings; - private readonly IMediator _mediator; - - public SettingsController(Settings settings, IMediator mediator) - { - _settings = settings; - _mediator = mediator; - } - [HttpGet] public Settings Get() { - return _settings; + return settings; } [HttpPut] - public async Task Update([FromBody] Settings settings) + public async Task Update([FromBody] Settings update) { - await _mediator.Send(new UpdateSettingsCommand(settings)); - + await mediator.Send(new UpdateSettingsCommand(update)); return NoContent(); } diff --git a/src/Apps/NetPad.Apps.App/Controllers/TypesController.cs b/src/Apps/NetPad.Apps.App/Controllers/TypesController.cs index 04c9f1f8..16ea8712 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/TypesController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/TypesController.cs @@ -1,11 +1,15 @@ using Microsoft.AspNetCore.Mvc; -using NetPad.CQs; -using NetPad.Data.EntityFrameworkCore.DataConnections; +using NetPad.Application.Events; +using NetPad.Apps.CQs; +using NetPad.Apps.Data.EntityFrameworkCore.DataConnections; +using NetPad.Apps.UiInterop; +using NetPad.Configuration.Events; +using NetPad.Data.Events; using NetPad.Dtos; -using NetPad.Events; -using NetPad.Runtimes; +using NetPad.Presentation; using NetPad.Scripts; -using NetPad.UiInterop; +using NetPad.Scripts.Events; +using NetPad.Sessions.Events; namespace NetPad.Controllers; diff --git a/src/Apps/NetPad.Apps.App/Controllers/WindowController.cs b/src/Apps/NetPad.Apps.App/Controllers/WindowController.cs index 79bf5cda..ff4130c8 100644 --- a/src/Apps/NetPad.Apps.App/Controllers/WindowController.cs +++ b/src/Apps/NetPad.Apps.App/Controllers/WindowController.cs @@ -1,29 +1,21 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using NetPad.UiInterop; +using Microsoft.AspNetCore.Mvc; +using NetPad.Apps.UiInterop; namespace NetPad.Controllers; [ApiController] [Route("window")] -public class WindowController : ControllerBase +public class WindowController(IUiWindowService uiWindowService) : ControllerBase { - private readonly IUiWindowService _uiWindowService; - - public WindowController(IUiWindowService uiWindowService) - { - _uiWindowService = uiWindowService; - } - [HttpPatch("open-output-window")] public async Task OpenOutputWindow() { - await _uiWindowService.OpenOutputWindowAsync(); + await uiWindowService.OpenOutputWindowAsync(); } [HttpPatch("open-code-window")] public async Task OpenCodeWindow() { - await _uiWindowService.OpenCodeWindowAsync(); + await uiWindowService.OpenCodeWindowAsync(); } } diff --git a/src/Apps/NetPad.Apps.App/Dtos/CreateScriptDto.cs b/src/Apps/NetPad.Apps.App/Dtos/CreateScriptDto.cs index c42bc464..f1d6ee44 100644 --- a/src/Apps/NetPad.Apps.App/Dtos/CreateScriptDto.cs +++ b/src/Apps/NetPad.Apps.App/Dtos/CreateScriptDto.cs @@ -1,5 +1,3 @@ -using System; - namespace NetPad.Dtos; public class CreateScriptDto diff --git a/src/Apps/NetPad.Apps.App/Dtos/ErrorResult.cs b/src/Apps/NetPad.Apps.App/Dtos/ErrorResult.cs index 14ac6b9a..35cb6857 100644 --- a/src/Apps/NetPad.Apps.App/Dtos/ErrorResult.cs +++ b/src/Apps/NetPad.Apps.App/Dtos/ErrorResult.cs @@ -1,13 +1,7 @@ namespace NetPad.Dtos; -public class ErrorResult +public class ErrorResult(string message, string? details = null) { - public ErrorResult(string message, string? details = null) - { - Message = message; - Details = details; - } - - public string Message { get; } - public string? Details { get; } + public string Message { get; } = message; + public string? Details { get; } = details; } diff --git a/src/Apps/NetPad.Apps.App/Dtos/RunOptionsDto.cs b/src/Apps/NetPad.Apps.App/Dtos/RunOptionsDto.cs deleted file mode 100644 index 6a360350..00000000 --- a/src/Apps/NetPad.Apps.App/Dtos/RunOptionsDto.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using NetPad.DotNet; -using NetPad.Runtimes; - -namespace NetPad.Dtos; - -public class RunOptionsDto -{ - public string? SpecificCodeToRun { get; set; } - public SourceCodeDto[]? AdditionalCode { get; set; } - - public RunOptions ToRunOptions() - { - AdditionalCode ??= Array.Empty(); - - var runOptions = new RunOptions(SpecificCodeToRun); - - runOptions.AdditionalCode.AddRange(AdditionalCode.Select(c => new SourceCode(c.Code, c.Usings))); - - return runOptions; - } - - public class SourceCodeDto - { - public HashSet? Usings { get; set; } - public string? Code { get; set; } - } -} diff --git a/src/Apps/NetPad.Apps.App/GlobalUsings.cs b/src/Apps/NetPad.Apps.App/GlobalUsings.cs index caec0c26..be2adcdb 100644 --- a/src/Apps/NetPad.Apps.App/GlobalUsings.cs +++ b/src/Apps/NetPad.Apps.App/GlobalUsings.cs @@ -1 +1,4 @@ +global using System; +global using System.Threading; +global using System.Threading.Tasks; global using NetPad.Utilities; diff --git a/src/Apps/NetPad.Apps.App/Middlewares/ExceptionHandlerMiddleware.cs b/src/Apps/NetPad.Apps.App/Middlewares/ExceptionHandlerMiddleware.cs index 17cb7f2c..cde39a29 100644 --- a/src/Apps/NetPad.Apps.App/Middlewares/ExceptionHandlerMiddleware.cs +++ b/src/Apps/NetPad.Apps.App/Middlewares/ExceptionHandlerMiddleware.cs @@ -1,6 +1,4 @@ -using System; using System.Net; -using System.Threading.Tasks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Hosting; @@ -10,30 +8,22 @@ namespace NetPad.Middlewares; -public class ExceptionHandlerMiddleware +public class ExceptionHandlerMiddleware( + RequestDelegate next, + IWebHostEnvironment webHostEnvironment, + ILogger logger) { - private readonly RequestDelegate _next; - private readonly IWebHostEnvironment _webHostEnvironment; - private readonly ILogger _logger; - - public ExceptionHandlerMiddleware(RequestDelegate next, IWebHostEnvironment webHostEnvironment, ILogger logger) - { - _next = next; - _webHostEnvironment = webHostEnvironment; - _logger = logger; - } - public async Task InvokeAsync(HttpContext httpContext) { try { - await _next(httpContext); + await next(httpContext); } catch (Exception ex) { - _logger.LogError(ex, "An error occurred in request pipeline"); + logger.LogError(ex, "An error occurred in request pipeline"); - var result = new ErrorResult(ex.Message, _webHostEnvironment.IsProduction() ? null : ex.ToString()); + var result = new ErrorResult(ex.Message, webHostEnvironment.IsProduction() ? null : ex.ToString()); httpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; httpContext.Response.ContentType = "application/json"; diff --git a/src/Apps/NetPad.Apps.App/NetPad.Apps.App.csproj b/src/Apps/NetPad.Apps.App/NetPad.Apps.App.csproj index 2bc67a83..f7048306 100644 --- a/src/Apps/NetPad.Apps.App/NetPad.Apps.App.csproj +++ b/src/Apps/NetPad.Apps.App/NetPad.Apps.App.csproj @@ -1,20 +1,17 @@  - net6.0 - true - Latest + $(DefaultTargetFramework) + NetPad + 0.7.1 + 0.7.1 + 0.7.1 false App\ $(DefaultItemExcludes);$(SpaRoot)node_modules\** - + true + Latest false Linux - NetPad - enable - 0.7.1 - 0.7.1 - 0.7.1 - 11 @@ -31,8 +28,8 @@ - + PreserveNewest @@ -73,15 +70,12 @@ - - - - + - - - + + + diff --git a/src/Apps/NetPad.Apps.App/Pages/Error.cshtml.cs b/src/Apps/NetPad.Apps.App/Pages/Error.cshtml.cs index 99d6f7a5..c48e5367 100644 --- a/src/Apps/NetPad.Apps.App/Pages/Error.cshtml.cs +++ b/src/Apps/NetPad.Apps.App/Pages/Error.cshtml.cs @@ -6,14 +6,9 @@ namespace NetPad.Pages; [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] -public class ErrorModel : PageModel +public class ErrorModel(ILogger logger) : PageModel { - private readonly ILogger _logger; - - public ErrorModel(ILogger logger) - { - _logger = logger; - } + private readonly ILogger _logger = logger; public string? RequestId { get; set; } diff --git a/src/Apps/NetPad.Apps.App/Program.cs b/src/Apps/NetPad.Apps.App/Program.cs index 6aec2d19..f81724b0 100644 --- a/src/Apps/NetPad.Apps.App/Program.cs +++ b/src/Apps/NetPad.Apps.App/Program.cs @@ -1,34 +1,96 @@ -using System; using System.IO; using System.Linq; +using System.Net.Http; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using NetPad.Application; +using NetPad.Apps; +using NetPad.Apps.Shells; +using NetPad.Apps.Shells.Electron; +using NetPad.Apps.Shells.Web; using NetPad.Configuration; -using NetPad.Electron; -using NetPad.Web; +using NetPad.Swagger; using Serilog; namespace NetPad; public static class Program { - internal static IApplicationConfigurator ApplicationConfigurator { get; private set; } = null!; + internal static IShell Shell { get; private set; } = null!; + private static bool _isSwaggerCodeGenMode; - public static int Main(string[] args) + public static async Task Main(string[] args) + { + if (args.Contains("--swagger")) + { + _isSwaggerCodeGenMode = true; + return await GenerateSwaggerClientCodeAsync(args); + } + + return RunApp(args); + } + + private static async Task GenerateSwaggerClientCodeAsync(string[] args) + { + try + { + Console.WriteLine("Starting host..."); + var host = CreateHostBuilder(args).Build(); + _ = host.RunAsync(); + + var hostInfo = host.Services.GetRequiredService(); + + string[] docs = + [ + "/swagger/NetPad/swagger.json", + "/swagger/netpad.plugins.omnisharp/swagger.json" + ]; + + var maxLength = docs.Select(x => x.Length).Max(); + + using var client = new HttpClient(); + + foreach (var doc in docs) + { + var url = $"{hostInfo.HostUrl}{doc}"; + + Console.Write($"* Generating client code for: {doc.PadRight(maxLength)} ... "); + var response = await client.GetAsync(url); + var success = response.IsSuccessStatusCode; + Console.WriteLine(success ? "DONE" : "FAIL"); + + if (!success) + { + var content = await response.Content.ReadAsStringAsync(); + Console.WriteLine(content); + return 1; + } + } + + await host.StopAsync(); + return 0; + } + catch (Exception e) + { + Console.WriteLine(e); + return 1; + } + } + + private static int RunApp(string[] args) { try { - // Configure as an Electron app or a web app - ApplicationConfigurator = args.Any(a => a.ContainsIgnoreCase("/ELECTRONPORT")) - ? new NetPadElectronConfigurator() - : new NetPadWebConfigurator(); + // Select a shell + Shell = args.Any(a => a.ContainsIgnoreCase("/ELECTRONPORT")) + ? new ElectronShell() + : new WebBrowserShell(); var host = CreateHostBuilder(args).Build(); - Console.WriteLine($"Starting NetPad. App type: {host.Services.GetRequiredService().Type}"); + Console.WriteLine($"Starting app. Shell: {Shell.GetType().Name}"); host.Run(); return 0; @@ -36,7 +98,7 @@ public static int Main(string[] args) catch (IOException ioException) when (ioException.Message.ContainsIgnoreCase("address already in use")) { Console.WriteLine($"Another instance is already running. {ioException.Message}"); - ApplicationConfigurator.ShowErrorDialog( + Shell.ShowErrorDialog( $"{AppIdentifier.AppName} Already Running", $"{AppIdentifier.AppName} is already running. You cannot open multiple instances of {AppIdentifier.AppName}."); return 1; @@ -59,8 +121,15 @@ public static int Main(string[] args) .UseSerilog((ctx, config) => { ConfigureLogging(config, ctx.Configuration); }) .ConfigureWebHostDefaults(webBuilder => { - ApplicationConfigurator.ConfigureWebHost(webBuilder, args); - webBuilder.UseStartup(); + if (_isSwaggerCodeGenMode) + { + webBuilder.UseStartup(); + } + else + { + Shell.ConfigureWebHost(webBuilder, args); + webBuilder.UseStartup(); + } }); private static void ConfigureLogging(LoggerConfiguration serilogConfig, IConfiguration appConfig) diff --git a/src/Apps/NetPad.Apps.App/Properties/launchSettings.json b/src/Apps/NetPad.Apps.App/Properties/launchSettings.json new file mode 100644 index 00000000..b3c0bc98 --- /dev/null +++ b/src/Apps/NetPad.Apps.App/Properties/launchSettings.json @@ -0,0 +1,40 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:18454", + "sslPort": 44349 + } + }, + "profiles": { + "Electron.NET App": { + "commandName": "Executable", + "executablePath": "electronize", + "commandLineArgs": "start", + "workingDirectory": "." + }, + "ASP.NET Core App (no Electron)": { + "commandName": "Project", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Generate Swagger Client Code": { + "commandName": "Project", + "commandLineArgs": "--swagger", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/Apps/NetPad.Apps.App/Services/Data/DataConnectionResourcesGeneratorFactory.cs b/src/Apps/NetPad.Apps.App/Services/Data/DataConnectionResourcesGeneratorFactory.cs deleted file mode 100644 index dc41ce95..00000000 --- a/src/Apps/NetPad.Apps.App/Services/Data/DataConnectionResourcesGeneratorFactory.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using NetPad.Data; -using NetPad.Data.EntityFrameworkCore; -using NetPad.Data.EntityFrameworkCore.DataConnections; - -namespace NetPad.Services.Data; - -public class DataConnectionResourcesGeneratorFactory : IDataConnectionResourcesGeneratorFactory -{ - private readonly IServiceProvider _serviceProvider; - - public DataConnectionResourcesGeneratorFactory(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public IDataConnectionResourcesGenerator Create(DataConnection dataConnection) - { - if (dataConnection is EntityFrameworkDatabaseConnection) - { - return _serviceProvider.GetRequiredService(); - } - - throw new NotImplementedException("Only EntityFramework data connections are supported at this time."); - } -} diff --git a/src/Apps/NetPad.Apps.App/Services/Data/DatabaseConnectionMetadataProviderFactory.cs b/src/Apps/NetPad.Apps.App/Services/Data/DatabaseConnectionMetadataProviderFactory.cs deleted file mode 100644 index e256f953..00000000 --- a/src/Apps/NetPad.Apps.App/Services/Data/DatabaseConnectionMetadataProviderFactory.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Microsoft.Extensions.DependencyInjection; -using NetPad.Data; -using NetPad.Data.EntityFrameworkCore; -using NetPad.Data.EntityFrameworkCore.DataConnections; - -namespace NetPad.Services.Data; - -public class DatabaseConnectionMetadataProviderFactory : IDatabaseConnectionMetadataProviderFactory -{ - private readonly IServiceProvider _serviceProvider; - - public DatabaseConnectionMetadataProviderFactory(IServiceProvider serviceProvider) - { - _serviceProvider = serviceProvider; - } - - public IDatabaseConnectionMetadataProvider Create(DatabaseConnection databaseConnection) - { - if (databaseConnection is EntityFrameworkDatabaseConnection) - { - return _serviceProvider.GetRequiredService(); - } - - throw new NotImplementedException("Only EntityFramework database connections are supported at this time."); - } -} diff --git a/src/Core/NetPad.Application/Services/MediatorRequestPipeline.cs b/src/Apps/NetPad.Apps.App/Services/MediatorRequestPipeline.cs similarity index 97% rename from src/Core/NetPad.Application/Services/MediatorRequestPipeline.cs rename to src/Apps/NetPad.Apps.App/Services/MediatorRequestPipeline.cs index 3fad0950..bf1d3549 100644 --- a/src/Core/NetPad.Application/Services/MediatorRequestPipeline.cs +++ b/src/Apps/NetPad.Apps.App/Services/MediatorRequestPipeline.cs @@ -1,5 +1,5 @@ using MediatR; -using NetPad.CQs; +using NetPad.Apps.CQs; namespace NetPad.Services; diff --git a/src/Apps/NetPad.Apps.App/Services/ScriptEnvironmentIpcOutputWriter.cs b/src/Apps/NetPad.Apps.App/Services/ScriptEnvironmentIpcOutputWriter.cs index b9d7faff..ce91cf59 100644 --- a/src/Apps/NetPad.Apps.App/Services/ScriptEnvironmentIpcOutputWriter.cs +++ b/src/Apps/NetPad.Apps.App/Services/ScriptEnvironmentIpcOutputWriter.cs @@ -1,17 +1,14 @@ -using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Logging; +using NetPad.Apps.UiInterop; using NetPad.Events; using NetPad.IO; using NetPad.Presentation; using NetPad.Presentation.Html; -using NetPad.Runtimes; using NetPad.Scripts; -using NetPad.UiInterop; +using NetPad.Scripts.Events; using O2Html; using Timer = System.Timers.Timer; @@ -31,9 +28,9 @@ public sealed record ScriptEnvironmentIpcOutputWriter : IOutputWriter, I private readonly Accessor _ctsAccessor; private readonly ConcurrentQueue _sendMessageQueue; private readonly Timer _sendMessageQueueTimer; - private const int _sendMessageQueueBatchSize = 1000; - private const int _processSendMessageQueueEveryMs = 50; - private const int _maxUserOutputMessagesPerRun = 10100; + private const int SendMessageQueueBatchSize = 1000; + private const int ProcessSendMessageQueueEveryMs = 50; + private const int MaxUserOutputMessagesPerRun = 10100; private int _userOutputMessagesSentThisRun; private bool _outputLimitReachedMessageSent; private readonly object _outputLimitReachedMessageSendLock = new(); @@ -47,19 +44,19 @@ public sealed record ScriptEnvironmentIpcOutputWriter : IOutputWriter, I _scriptEnvironment = scriptEnvironment; _ipcService = ipcService; _logger = logger; - _disposables = new List(); + _disposables = []; _ctsAccessor = new Accessor(new CancellationTokenSource()); _sendMessageQueue = new(); _sendMessageQueueTimer = new Timer() { - Interval = _processSendMessageQueueEveryMs, + Interval = ProcessSendMessageQueueEveryMs, AutoReset = false, Enabled = false }; - _sendMessageQueueTimer.Elapsed += async (_, _) => await ProcessSendMessageQueue(_sendMessageQueueBatchSize); + _sendMessageQueueTimer.Elapsed += async (_, _) => await ProcessSendMessageQueue(SendMessageQueueBatchSize); _disposables.Add(eventBus.Subscribe(msg => { @@ -196,7 +193,7 @@ public async Task WriteAsync(object? output, string? title = null, CancellationT private bool HasReachedUserOutputMessageLimitForThisRun() { - return _userOutputMessagesSentThisRun >= _maxUserOutputMessagesPerRun; + return _userOutputMessagesSentThisRun >= MaxUserOutputMessagesPerRun; } private void QueueMessage(ScriptOutput output, bool isCancellable) diff --git a/src/Apps/NetPad.Apps.App/Services/ScriptService.cs b/src/Apps/NetPad.Apps.App/Services/ScriptService.cs new file mode 100644 index 00000000..02fb9cc0 --- /dev/null +++ b/src/Apps/NetPad.Apps.App/Services/ScriptService.cs @@ -0,0 +1,64 @@ +using MediatR; +using NetPad.Apps.CQs; +using NetPad.Apps.UiInterop; +using NetPad.Exceptions; +using NetPad.Sessions; + +namespace NetPad.Services; + +public class ScriptService(ISession session, IUiDialogService uiDialogService, IMediator mediator) +{ + public async Task CloseScriptAsync(Guid scriptId) + { + var scriptEnvironment = session.Get(scriptId) ?? throw new ScriptNotFoundException(scriptId); + var script = scriptEnvironment.Script; + + bool shouldAskUserToSave = script.IsDirty; + if (script.IsNew && string.IsNullOrEmpty(script.Code)) + { + shouldAskUserToSave = false; + } + + if (shouldAskUserToSave) + { + var response = await uiDialogService.AskUserIfTheyWantToSave(script); + if (response == YesNoCancel.Cancel) + { + return; + } + + if (response == YesNoCancel.Yes) + { + bool saved = await SaveScriptAsync(scriptId); + if (!saved) + { + return; + } + } + } + + await mediator.Send(new CloseScriptCommand(scriptId)); + } + + public async Task SaveScriptAsync(Guid scriptId) + { + var scriptEnvironment = session.Get(scriptId) ?? throw new ScriptNotFoundException(scriptId); + var script = scriptEnvironment.Script; + + if (script.IsNew) + { + var path = await uiDialogService.AskUserForSaveLocation(script); + + if (string.IsNullOrWhiteSpace(path)) + { + return false; + } + + script.SetPath(path); + } + + await mediator.Send(new SaveScriptCommand(script)); + + return true; + } +} diff --git a/src/Apps/NetPad.Apps.App/Startup.cs b/src/Apps/NetPad.Apps.App/Startup.cs index 3db48724..5e491678 100644 --- a/src/Apps/NetPad.Apps.App/Startup.cs +++ b/src/Apps/NetPad.Apps.App/Startup.cs @@ -1,59 +1,55 @@ -using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Reflection; using MediatR; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using NetPad.Application; +using NetPad.Apps; +using NetPad.Apps.Configuration; +using NetPad.Apps.CQs; +using NetPad.Apps.Data; +using NetPad.Apps.Data.EntityFrameworkCore; +using NetPad.Apps.Plugins; +using NetPad.Apps.Resources; +using NetPad.Apps.Scripts; +using NetPad.Apps.UiInterop; using NetPad.Assemblies; using NetPad.BackgroundServices; -using NetPad.CodeAnalysis; using NetPad.Common; -using NetPad.Compilation; -using NetPad.Compilation.CSharp; using NetPad.Configuration; -using NetPad.CQs; using NetPad.Data; -using NetPad.Data.EntityFrameworkCore; -using NetPad.Data.EntityFrameworkCore.DataConnections; -using NetPad.DotNet; -using NetPad.Events; +using NetPad.ExecutionModel; using NetPad.Middlewares; using NetPad.Packages; -using NetPad.Plugins; +using NetPad.Packages.NuGet; using NetPad.Plugins.OmniSharp; -using NetPad.Resources; -using NetPad.Runtimes; using NetPad.Scripts; using NetPad.Services; -using NetPad.Services.Data; using NetPad.Sessions; using NetPad.Swagger; -using NetPad.UiInterop; namespace NetPad; public class Startup { private readonly Assembly[] _pluginAssemblies = - { + [ typeof(Plugin).Assembly - }; + ]; public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment) { Configuration = configuration; WebHostEnvironment = webHostEnvironment; - Console.WriteLine($".NET Version: {Environment.Version.ToString()}"); - Console.WriteLine($"Environment: {webHostEnvironment.EnvironmentName}"); - Console.WriteLine($"WebRootPath: {webHostEnvironment.WebRootPath}"); - Console.WriteLine($"ContentRootPath: {webHostEnvironment.ContentRootPath}"); + Console.WriteLine("Configuration:"); + Console.WriteLine($" - .NET Runtime Version: {Environment.Version.ToString()}"); + Console.WriteLine($" - Environment: {webHostEnvironment.EnvironmentName}"); + Console.WriteLine($" - WebRootPath: {webHostEnvironment.WebRootPath}"); + Console.WriteLine($" - ContentRootPath: {webHostEnvironment.ContentRootPath}"); } public IConfiguration Configuration { get; } @@ -61,51 +57,36 @@ public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironm public void ConfigureServices(IServiceCollection services) { - services.AddSingleton(); + services.AddCoreServices(); + services.AddSingleton(); - services.AddSingleton(_ => - { - var httpClient = new HttpClient(); - httpClient.Timeout = TimeSpan.FromMinutes(1); - return httpClient; - }); services.AddTransient(); services.AddSingleton(sp => sp.GetRequiredService().GetSettingsAsync().Result); services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddTransient(); services.AddTransient(); - services.AddTransient(); services.AddTransient(); - services.AddSingleton(); services.AddSingleton(); - // Scripts + // Script services + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddSingleton(); - services.AddTransient(); - // Select how we will run scripts, using an external process or in-memory - // NOTE: A different app, ex. a CLI version of NetPad, could use AddInMemoryScriptRuntime() - services.AddExternalProcessScriptRuntime(); + // Script execution mechanism + services.AddExternalExecutionModel(options => + { + options.ProcessCliArgs = ["-html"]; + options.RedirectIo = true; + }); // Data connections - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(); - services.AddSingleton(sp => new Lazy(sp.GetRequiredService())); - services.AddTransient(s => - new DataProtector(s.GetRequiredService(), "DataConnectionPasswords")); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + services + .AddDataConnectionFeature< + FileSystemDataConnectionRepository, + FileSystemDataConnectionResourcesRepository, + FileSystemDataConnectionResourcesCache>() + .AddEntityFrameworkCoreDataConnectionDriver(); // Package management services.AddTransient(); @@ -122,10 +103,6 @@ public void ConfigureServices(IServiceCollection services) services.AddHostedService(); services.AddHostedService(); -#if DEBUG - //services.AddHostedService(); -#endif - // Should be the last hosted service so it runs last on app start services.AddHostedService(); @@ -158,6 +135,14 @@ public void ConfigureServices(IServiceCollection services) mvcBuilder.AddApplicationPart(registration.Assembly); } + // HttpClient + services.AddSingleton(_ => + { + var httpClient = new HttpClient(); + httpClient.Timeout = TimeSpan.FromMinutes(1); + return httpClient; + }); + // SignalR services.AddSignalR() .AddJsonProtocol(options => { JsonSerializer.Configure(options.PayloadSerializerOptions); }); @@ -167,24 +152,19 @@ public void ConfigureServices(IServiceCollection services) // Mediator services.AddTransient(typeof(IPipelineBehavior<,>), typeof(MediatorRequestPipeline<,>)); - services.AddMediatR(new[] { typeof(Command).Assembly }.Union(pluginRegistrations.Select(pr => pr.Assembly)).ToArray()); + services.AddMediatR(new[] { typeof(Command).Assembly }.Union(pluginRegistrations.Select(pr => pr.Assembly)) + .ToArray()); // Swagger #if DEBUG SwaggerSetup.AddSwagger(services, WebHostEnvironment, pluginRegistrations); #endif - services.AddDataProtection(options => - { - // A built-in string that identifies NetPad - options.ApplicationDiscriminator = "NETPAD_8C94D5EA-9510-4493-AA43-CADE372ED853"; - }); - - // Allow ApplicationConfigurator to add/modify any service registrations it needs - Program.ApplicationConfigurator.ConfigureServices(services); + // Allow Shell to add/modify any service registrations it needs + Program.Shell.ConfigureServices(services); // We want to always use SignalR for IPC, overriding Electron's IPC service - // This should come after the ApplicationConfigurator adds its services so it overrides it + // This should come after the Shell adds its services so it overrides it services.AddTransient(); } @@ -256,7 +236,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) #endif }); - // Allow ApplicationConfigurator to run any configuration - Program.ApplicationConfigurator.Configure(app, env); + Program.Shell.Initialize(app, env); } } diff --git a/src/Apps/NetPad.Apps.App/Swagger/OperationProcessors.cs b/src/Apps/NetPad.Apps.App/Swagger/OperationProcessors.cs index a6e8350b..73cdbdb9 100644 --- a/src/Apps/NetPad.Apps.App/Swagger/OperationProcessors.cs +++ b/src/Apps/NetPad.Apps.App/Swagger/OperationProcessors.cs @@ -5,32 +5,18 @@ namespace NetPad.Swagger; -internal class IncludeControllersInAssemblies : IOperationProcessor +internal class IncludeControllersInAssemblies(params Assembly[] assemblies) : IOperationProcessor { - private readonly Assembly[] _assemblies; - - public IncludeControllersInAssemblies(params Assembly[] assemblies) - { - _assemblies = assemblies; - } - public bool Process(OperationProcessorContext context) { - return _assemblies.Contains(context.ControllerType.Assembly); + return assemblies.Contains(context.ControllerType.Assembly); } } -internal class ExcludeControllersInAssemblies : IOperationProcessor +internal class ExcludeControllersInAssemblies(params Assembly[] assemblies) : IOperationProcessor { - private readonly Assembly[] _assemblies; - - public ExcludeControllersInAssemblies(params Assembly[] assemblies) - { - _assemblies = assemblies; - } - public bool Process(OperationProcessorContext context) { - return !_assemblies.Contains(context.ControllerType.Assembly); + return !assemblies.Contains(context.ControllerType.Assembly); } } diff --git a/src/Apps/NetPad.Apps.App/Swagger/SwaggerCodeGenerationStartup.cs b/src/Apps/NetPad.Apps.App/Swagger/SwaggerCodeGenerationStartup.cs new file mode 100644 index 00000000..a84d4140 --- /dev/null +++ b/src/Apps/NetPad.Apps.App/Swagger/SwaggerCodeGenerationStartup.cs @@ -0,0 +1,104 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Hosting.Server.Features; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using NetPad.Apps; +using NetPad.Apps.Configuration; +using NetPad.Apps.Plugins; +using NetPad.Common; +using NetPad.Configuration; +using NetPad.Plugins.OmniSharp; + +namespace NetPad.Swagger; + +public class SwaggerCodeGenerationStartup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment) +{ + private readonly Assembly[] _pluginAssemblies = + [ + typeof(Plugin).Assembly + ]; + + public IConfiguration Configuration { get; } = configuration; + public IWebHostEnvironment WebHostEnvironment { get; } = webHostEnvironment; + + public void ConfigureServices(IServiceCollection services) + { + services.AddCoreServices(); + + services.AddSingleton(); + services.AddTransient(); + services.AddSingleton(sp => sp.GetRequiredService().GetSettingsAsync().Result); + + // Plugins + var pluginInitialization = new PluginInitialization(Configuration, WebHostEnvironment); + IPluginManager pluginManager = new PluginManager(pluginInitialization); + services.AddSingleton(pluginInitialization); + services.AddSingleton(pluginManager); + + var pluginRegistrations = new List(); + + // Register plugins + var emptyServices = new ServiceCollection(); // We don't care about plugin service registrations in this scenario + foreach (var pluginAssembly in _pluginAssemblies) + { + try + { + var registration = pluginManager.RegisterPlugin(pluginAssembly, emptyServices); + pluginRegistrations.Add(registration); + + Console.WriteLine("Registered plugin '{0}' from '{1}'", + registration.Plugin.Name, + registration.Assembly.FullName); + } + catch (Exception ex) + { + Console.Error.WriteLine("Could not register plugin: '{0}'. {1}", pluginAssembly.FullName, ex); + } + } + + // MVC + var mvcBuilder = services.AddControllersWithViews() + .AddJsonOptions(options => JsonSerializer.Configure(options.JsonSerializerOptions)); + + foreach (var registration in pluginRegistrations) + { + mvcBuilder.AddApplicationPart(registration.Assembly); + } + + SwaggerSetup.AddSwagger(services, WebHostEnvironment, pluginRegistrations); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + var services = app.ApplicationServices; + app.UseDeveloperExceptionPage(); + + app.UseOpenApi(); + app.UseSwaggerUi3(); + + // Set host url + var hostInfo = services.GetRequiredService(); + hostInfo.SetWorkingDirectory(env.ContentRootPath); + + var serverAddresses = app.ServerFeatures.Get()?.Addresses; + + if (serverAddresses == null || !serverAddresses.Any()) + { + throw new Exception("No server urls specified. Specify the url with the '--urls' parameter"); + } + + var url = serverAddresses.FirstOrDefault(a => a.StartsWith("https:")) ?? + serverAddresses.FirstOrDefault(a => a.StartsWith("http:")); + + if (url == null) + { + throw new Exception("No server urls specified that start with 'http' or 'https'"); + } + + hostInfo.SetHostUrl(url); + } +} diff --git a/src/Apps/NetPad.Apps.App/Swagger/SwaggerSetup.cs b/src/Apps/NetPad.Apps.App/Swagger/SwaggerSetup.cs index 2ee22429..61254df6 100644 --- a/src/Apps/NetPad.Apps.App/Swagger/SwaggerSetup.cs +++ b/src/Apps/NetPad.Apps.App/Swagger/SwaggerSetup.cs @@ -1,10 +1,9 @@ -using System; using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; -using NetPad.Plugins; +using NetPad.Apps.Plugins; using NJsonSchema.CodeGeneration.TypeScript; using NSwag; using NSwag.CodeGeneration.TypeScript; @@ -17,7 +16,7 @@ public static void AddSwagger(IServiceCollection services, IWebHostEnvironment w { services.AddSwaggerDocument(config => { - config.Title = "NetPad"; + config.Title = "NetPad HTTP Interface"; config.DocumentName = "NetPad"; config.OperationProcessors.Insert(0, new ExcludeControllersInAssemblies(pluginRegistrations.Select(p => p.Assembly).ToArray())); @@ -29,8 +28,8 @@ public static void AddSwagger(IServiceCollection services, IWebHostEnvironment w { services.AddSwaggerDocument(config => { - config.Title = $"NetPad Plugin - {pluginRegistration.Plugin.Name}"; - config.DocumentName = config.Title; + config.Title = $"Plugin - {pluginRegistration.Plugin.Name}"; + config.DocumentName = pluginRegistration.Plugin.Id; config.OperationProcessors.Insert(0, new IncludeControllersInAssemblies(pluginRegistration.Assembly)); string pluginDirName = pluginRegistration.Plugin.Name.Replace(" ", "-"); diff --git a/src/Apps/NetPad.Apps.App/Swagger/TypeScriptClientCodeTransform.cs b/src/Apps/NetPad.Apps.App/Swagger/TypeScriptClientCodeTransform.cs index 50447801..1e2a439e 100644 --- a/src/Apps/NetPad.Apps.App/Swagger/TypeScriptClientCodeTransform.cs +++ b/src/Apps/NetPad.Apps.App/Swagger/TypeScriptClientCodeTransform.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Linq; diff --git a/src/Apps/NetPad.Apps.App/global.json b/src/Apps/NetPad.Apps.App/global.json deleted file mode 100644 index 38e49604..00000000 --- a/src/Apps/NetPad.Apps.App/global.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "sdk": { - "version": "7.0.0", - "rollForward": "latestMinor", - "allowPrerelease": true - } -} diff --git a/src/Apps/NetPad.Apps.Common/CQs/ActivateLastActiveScriptCommand.cs b/src/Apps/NetPad.Apps.Common/CQs/ActivateLastActiveScriptCommand.cs new file mode 100644 index 00000000..16c30d4c --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/ActivateLastActiveScriptCommand.cs @@ -0,0 +1,16 @@ +using MediatR; +using NetPad.Sessions; + +namespace NetPad.Apps.CQs; + +public class ActivateLastActiveScriptCommand : Command +{ + public class Handler(ISession session) : IRequestHandler + { + public async Task Handle(ActivateLastActiveScriptCommand request, CancellationToken cancellationToken) + { + await session.ActivateLastActiveScriptAsync(); + return Unit.Value; + } + } +} diff --git a/src/Apps/NetPad.Apps.Common/CQs/ActivateScriptCommand.cs b/src/Apps/NetPad.Apps.Common/CQs/ActivateScriptCommand.cs new file mode 100644 index 00000000..4d4a6ea6 --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/ActivateScriptCommand.cs @@ -0,0 +1,18 @@ +using MediatR; +using NetPad.Sessions; + +namespace NetPad.Apps.CQs; + +public class ActivateScriptCommand(Guid scriptId) : Command +{ + public Guid ScriptId { get; } = scriptId; + + public class Handler(ISession session) : IRequestHandler + { + public async Task Handle(ActivateScriptCommand request, CancellationToken cancellationToken) + { + await session.ActivateAsync(request.ScriptId); + return Unit.Value; + } + } +} diff --git a/src/Apps/NetPad.Apps.Common/CQs/AlertUserAboutMissingAppDependencies.cs b/src/Apps/NetPad.Apps.Common/CQs/AlertUserAboutMissingAppDependencies.cs new file mode 100644 index 00000000..a1bb3d0a --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/AlertUserAboutMissingAppDependencies.cs @@ -0,0 +1,8 @@ +using NetPad.Application; + +namespace NetPad.Apps.CQs; + +public class AlertUserAboutMissingAppDependencies(AppDependencyCheckResult dependencyCheckResult) : Command +{ + public AppDependencyCheckResult DependencyCheckResult { get; } = dependencyCheckResult; +} diff --git a/src/Apps/NetPad.Apps.Common/CQs/AlertUserCommand.cs b/src/Apps/NetPad.Apps.Common/CQs/AlertUserCommand.cs new file mode 100644 index 00000000..abc424be --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/AlertUserCommand.cs @@ -0,0 +1,6 @@ +namespace NetPad.Apps.CQs; + +public class AlertUserCommand(string message) : Command +{ + public string Message { get; } = message; +} diff --git a/src/Apps/NetPad.Apps.Common/CQs/Bases.cs b/src/Apps/NetPad.Apps.Common/CQs/Bases.cs new file mode 100644 index 00000000..deeea385 --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/Bases.cs @@ -0,0 +1,19 @@ +using MediatR; + +namespace NetPad.Apps.CQs; + +public abstract class CommandBase +{ + public Guid Id { get; } = Guid.NewGuid(); +} + +public abstract class Command : CommandBase, IRequest; + +public abstract class Command : CommandBase, IRequest; + +public abstract class QueryBase +{ + public Guid Id { get; } = Guid.NewGuid(); +} + +public abstract class Query : QueryBase, IRequest; diff --git a/src/Core/NetPad.Application/CQs/CheckAppDependenciesQuery.cs b/src/Apps/NetPad.Apps.Common/CQs/CheckAppDependenciesQuery.cs similarity index 52% rename from src/Core/NetPad.Application/CQs/CheckAppDependenciesQuery.cs rename to src/Apps/NetPad.Apps.Common/CQs/CheckAppDependenciesQuery.cs index a9fa674c..6ec3aaf8 100644 --- a/src/Core/NetPad.Application/CQs/CheckAppDependenciesQuery.cs +++ b/src/Apps/NetPad.Apps.Common/CQs/CheckAppDependenciesQuery.cs @@ -3,21 +3,13 @@ using NetPad.Application; using NetPad.DotNet; -namespace NetPad.CQs; +namespace NetPad.Apps.CQs; public class CheckAppDependenciesQuery : Query { - public class Handler : IRequestHandler + public class Handler(IDotNetInfo dotNetInfo, ILogger logger) + : IRequestHandler { - private readonly IDotNetInfo _dotNetInfo; - private readonly ILogger _logger; - - public Handler(IDotNetInfo dotNetInfo, ILogger logger) - { - _dotNetInfo = dotNetInfo; - _logger = logger; - } - public Task Handle(CheckAppDependenciesQuery request, CancellationToken cancellationToken) { @@ -26,29 +18,29 @@ public Handler(IDotNetInfo dotNetInfo, ILogger logger) try { - dotNetSdkVersions = _dotNetInfo.GetDotNetSdkVersions(); + dotNetSdkVersions = dotNetInfo.GetDotNetSdkVersions(); } catch (Exception ex) { - _logger.LogError(ex, "Error getting .NET SDK versions"); + logger.LogError(ex, "Error getting .NET SDK versions"); } try { - var dotNetEfToolExePath = _dotNetInfo.LocateDotNetEfToolExecutable(); + var dotNetEfToolExePath = dotNetInfo.LocateDotNetEfToolExecutable(); dotNetEfToolVersion = dotNetEfToolExePath == null ? null - : _dotNetInfo.GetDotNetEfToolVersion(dotNetEfToolExePath); + : dotNetInfo.GetDotNetEfToolVersion(dotNetEfToolExePath); } catch (Exception ex) { - _logger.LogError(ex, "Error getting .NET Entity Framework Tool version"); + logger.LogError(ex, "Error getting .NET Entity Framework Tool version"); } var result = new AppDependencyCheckResult( - _dotNetInfo.GetCurrentDotNetRuntimeVersion().ToString(), - dotNetSdkVersions?.Select(v => v.Version).ToArray() ?? Array.Empty(), + dotNetInfo.GetCurrentDotNetRuntimeVersion().ToString(), + dotNetSdkVersions?.Select(v => v.Version).ToArray() ?? [], dotNetEfToolVersion ); diff --git a/src/Apps/NetPad.Apps.Common/CQs/CloseScriptCommand.cs b/src/Apps/NetPad.Apps.Common/CQs/CloseScriptCommand.cs new file mode 100644 index 00000000..19ee48a8 --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/CloseScriptCommand.cs @@ -0,0 +1,35 @@ +using MediatR; +using NetPad.Events; +using NetPad.Exceptions; +using NetPad.Scripts; +using NetPad.Scripts.Events; +using NetPad.Sessions; + +namespace NetPad.Apps.CQs; + +public class CloseScriptCommand(Guid scriptId) : Command +{ + public Guid ScriptId { get; } = scriptId; + + public class Handler( + ISession session, + IAutoSaveScriptRepository autoSaveScriptRepository, + IEventBus eventBus) + : IRequestHandler + { + public async Task Handle(CloseScriptCommand request, CancellationToken cancellationToken) + { + var scriptId = request.ScriptId; + + var script = session.Get(scriptId)?.Script ?? throw new ScriptNotFoundException(scriptId); + + await session.CloseAsync(scriptId); + + await autoSaveScriptRepository.DeleteAsync(script); + + await eventBus.PublishAsync(new ScriptClosedEvent(script)); + + return Unit.Value; + } + } +} diff --git a/src/Apps/NetPad.Apps.Common/CQs/ConfirmSaveCommand.cs b/src/Apps/NetPad.Apps.Common/CQs/ConfirmSaveCommand.cs new file mode 100644 index 00000000..5d135422 --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/ConfirmSaveCommand.cs @@ -0,0 +1,9 @@ +using NetPad.Apps.UiInterop; +using NetPad.Scripts; + +namespace NetPad.Apps.CQs; + +public class ConfirmSaveCommand(Script script) : Command +{ + public string Message { get; } = $"You have unsaved changes. Do you want to save '{script.Name}'?"; +} diff --git a/src/Apps/NetPad.Apps.Common/CQs/ConfirmWithUserCommand.cs b/src/Apps/NetPad.Apps.Common/CQs/ConfirmWithUserCommand.cs new file mode 100644 index 00000000..03a9db8a --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/ConfirmWithUserCommand.cs @@ -0,0 +1,8 @@ +using NetPad.Apps.UiInterop; + +namespace NetPad.Apps.CQs; + +public class ConfirmWithUserCommand(string message) : Command +{ + public string Message { get; } = message; +} diff --git a/src/Apps/NetPad.Apps.Common/CQs/CreateScriptCommand.cs b/src/Apps/NetPad.Apps.Common/CQs/CreateScriptCommand.cs new file mode 100644 index 00000000..6fe91a2f --- /dev/null +++ b/src/Apps/NetPad.Apps.Common/CQs/CreateScriptCommand.cs @@ -0,0 +1,28 @@ +using MediatR; +using NetPad.Events; +using NetPad.Scripts; +using NetPad.Scripts.Events; + +namespace NetPad.Apps.CQs; + +public class CreateScriptCommand : Command