elsa-core/src/modules/Elsa.Dsl.ElsaScript
Sipke Schoorstra c60e63c3c6
Integrate shells (#7279)
* Add CShells package references and integrate shell features into the application

* Annotate shell features with `[ShellFeature]` attribute and update `TempElsaFeature` to use `ConfigureElsa`.

* Revert "Annotate shell features with `[ShellFeature]` attribute and update `TempElsaFeature` to use `ConfigureElsa`."

This reverts commit e8a875e8f9d14891c5403df50e8ac7e151db25dd.

* Introduce `Elsa.ModularServer.Web` with a minimal API, restructure shell feature configuration, and remove obsolete `CShells` dependency

* Update `CShells` package references, add Fody weaver, and configure new CShells package sources in `NuGet.Config`.

* Adds CShells integration to Elsa

Integrates CShells to enhance modularity and extensibility.

- Adds CShells related projects to the solution.
- Updates NuGet configuration to include CShells preview feed.
- Creates initial app settings for CShells configuration.
- Adds CShells.AspNetCore project reference.
- Implements CShells extensions in the program file.
- Creates shell feature classes in Elsa.Common.
- Creates shell feature classes in Elsa.Expressions.
- Creates shell feature classes in Elsa.Workflows.Core.
- Creates shell feature classes in Elsa.Workflows.Management.
- Creates shell feature classes in Elsa.Workflows.Runtime.
- Creates shell feature classes in Elsa module.

* Refactor CShells: enhance pipeline configuration and features

Consolidated updates to CShells including a new `ResolverPipelineBuilder` for customizable resolver strategy pipelines. Improved assembly scanning, error handling in web routing, and streamlined shell feature dependencies for better clarity and functionality.

* Add feature registration system and FastEndpoints integration

Introduced a feature registration infrastructure with `IInstalledFeatureProvider` and related implementations. Added shell-based feature configurations such as caching, SAS tokens, workflows management, and a FastEndpoints integration module to support dynamic API registration.

* Refactor shell routing and enhance global route handling

Refactored `ShellEndpointRouteBuilder` to simplify initialization and support a combined shell/global route prefix. Enhanced `ShellEndpointRegistrationHandler` to include global route prefix logic and improved feature discovery using pre-resolved descriptors. Updated `Program.cs` for consistent middleware setup.

* Refactor feature endpoints to use `IInstalledFeatureProvider` for improved dependency management and simplified implementation

* Add display names, descriptions, and dependency enhancements to shell features

Standardized `ShellFeature` attributes across `ElsaFeature`, `WorkflowRuntimeFeature`, and `WorkflowManagementFeature` by adding display names, descriptions, and improving dependency declarations. Updated `ElsaFeature` to register `IInstalledFeatureProvider` for feature bridging.

* Add FastEndpoints references and update package versions

Added project references to CShells.FastEndpoints and related projects in multiple csproj files. Updated FastEndpoints package versions in `Directory.Packages.props` for compatibility with .NET 8/9/10. Removed obsolete folder references from Elsa.Caching.csproj and refined the namespace in CShells.AspNetCore.Abstractions.

* Add Identity and DefaultAuthentication features to appsettings.json configuration

* Add project references for Elsa.Identity and CShells.FastEndpoints.Abstractions

* Add `Identity` and `DefaultAuthentication` shell features with enhanced authentication and authorization support

* Set default signing key in `IdentityTokenOptions` for identity configuration

* Add service exclusion infrastructure for shell-specific contexts

Introduce `IShellServiceExclusionProvider` and `IShellServiceExclusionRegistry` to manage excluded service types per-shell. Implement ASP.NET Core-specific providers for authentication and authorization to enable shell-specific configurations. Refactor `DefaultShellHost` to use the new exclusion registry for service inheritance filtering.

* Refactor CShells authentication and authorization APIs

Renamed and unified methods for shell authentication and authorization and added a new combined method `WithAuthenticationAndAuthorization`. Enhanced `AddShells` to automatically register a default configuration provider if none is specified. Updated usage in Elsa.ModularServer to utilize the new API.

* Add Elsa-specific FastEndpoints configurator and feature

Introduce `ElsaFastEndpointsConfigurator` to customize FastEndpoints serialization and value parsing for Elsa workflows. Register this functionality through the new `ElsaFastEndpointsFeature`, which integrates with the shell's dependency injection system using an `IFastEndpointsConfigurator` interface.

* Update Workflow API feature dependency to `ElsaFastEndpoints`

* Pass `cancellationToken` to `ReadToEndAsync` in `PostEndpoint` for improved request handling.

* Add project references for CShells.AspNetCore and CShells.FastEndpoints.Abstractions

* Update CShells package versions to `0.0.6-preview.30` and add `CShells.FastEndpoints.Abstractions`

* Configures shell routing and features

Enables path routing for shells to allow proper routing within each shell.

Configures the ElsaFastEndpoints feature to depend on the FastEndpoints feature.
This ensures that FastEndpoints is properly configured before Elsa's FastEndpoints configurations are applied.

Registers activity types within the WorkflowManagementFeature.
This ensures activities are available for workflow construction and execution.

* Add shell lifecycle management and notification handlers

Introduced interfaces and handlers for shell activation (`IShellActivatedHandler`) and deactivation (`IShellDeactivatingHandler`) to manage shell lifecycles. Added `ShellStartupHostedService` to coordinate shell activation on startup and deactivation on shutdown. Updated notification system to support new shell lifecycle events and renamed existing notification records for consistency.

* Introduces EF Core persistence layer

Adds base classes and implementations for EF Core persistence, including database provider configuration and shell feature integration.

This change introduces a generic approach to configuring EF Core persistence for various Elsa modules, promoting code reuse and simplifying the process of supporting different database providers.

It includes:

- Base classes for database provider configurators and shell features.
- Implementations for Sqlite, SQL Server, MySql, PostgreSql, and Oracle.
- Shell features for Alterations, Identity, Labels, Management (Workflow Definitions and Instances), Runtime, and Tenants modules.

* Add comprehensive feature configuration validation system

Introduce a feature configuration system with support for binding, auto-configuration, and validation using DataAnnotations, FluentValidation, and composite patterns. Includes new validators, binding logic, and extensions to simplify configuration tasks while ensuring robustness and flexibility.

* Add persistence shell features for MySql, Oracle, PostgreSql, and Sqlite

Introduced new shell features to configure MySql, Oracle, PostgreSql, and Sqlite persistence for workflow definitions and runtime data. Updated `appsettings.json` to replace individual Sqlite features with a unified `SqliteWorkflowPersistence`. Made minor code cleanup in `FastEndpointsFeature`.

* Configure shell features for persistence

Added `IServiceCollection` configuration for MySql, Oracle, PostgreSql, and Sqlite shell features to set up persistence services.

* Remove DatabaseProviderConfigurators and refactor persistence shell features

Deleted DatabaseProviderConfigurator classes and restructured persistence shell features by integrating direct configuration logic for MySql, Oracle, PostgreSql, Sqlite, and SqlServer. Simplified configuration by inheriting from abstract shell feature base classes and removed redundant code.

* Correct IWorkflowDefinitionPublisher registration to use WorkflowDefinitionPublisher implementation

* Add resilience feature and scoped services configuration for Sqlite persistence

- Integrated `Microsoft.Extensions.DependencyInjection` to shell features for Sqlite persistence.
- Updated `appsettings.json` and project references to include a new 'Resilience' feature.
- Changed `ICommitStateHandler` service registration in `WorkflowRuntimeFeature` to use an implementation.

* Add `ResilienceShellFeature` for configuring resilience strategies

- Implemented new `ResilienceShellFeature` class to manage services related to resilience features.
- Added scoped and singleton service registrations for resilience strategies, exception detection, and activity invocation.
- Configured expression options for resilience handling in workflows.

* Add new shell features: Alterations, Blob Storage, Caching, Clustering, CSharp, Distributed Runtime, ElsaScript, Flowchart, HTTP, JavaScript, Key-Value, and Labels

* Switch project references to package references for CShells libraries and update to version 0.0.7.

* Potential fix for pull request finding 'Call to 'System.IO.Path.Combine' may silently drop its earlier arguments'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

* Fix shell feature discovery and remove duplicate service registrations (#7285)

* Initial plan

* Address PR review comments: Add ShellFeature attributes, fix duplicates, and improve security

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

* Update dependencies and fix scoped services registration in `WorkflowRuntimeFeature`

* Fix null reference and typo in shell feature provider (#7286)

* Initial plan

* Fix null StartupType guard in Find() and typo in variable descriptor

Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
2026-02-12 20:30:02 +01:00
..
Ast Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
Compiler Bugfix: error thrown in ReadSyntheticInputs 2026-01-20 13:27:55 +01:00
Contracts Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
Extensions Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
Features Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
Helpers Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
Materializers Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
Parser Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
ShellFeatures Integrate shells (#7279) 2026-02-12 20:30:02 +01:00
Elsa.Dsl.ElsaScript.csproj Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
FodyWeavers.xml Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00
README.md Add Elsa Script DSL (#7076) 2025-11-25 19:57:50 +01:00

ElsaScript DSL Implementation

This document provides an overview of the ElsaScript DSL implementation for Elsa Workflows.

Overview

ElsaScript is a JavaScript-inspired textual DSL for authoring Elsa 3 workflows. It provides a concise, code-centric alternative to C# WorkflowBuilder APIs and JSON workflow definitions.

Features Implemented

Parser (ElsaScriptParser)

The parser uses a simplified regex-based approach to parse ElsaScript source code into an Abstract Syntax Tree (AST).

Supported Syntax:

  • use statements for namespaces and expression language configuration
  • workflow "Name" { ... } declarations
  • Variable declarations: var, let, const
  • Activity invocations with positional and named arguments
  • Expression literals (strings, numbers, booleans, arrays)
  • Expression language prefixes (=>, js =>, cs =>, py =>, liquid =>)
  • listen keyword for workflow triggers (partial support)

AST Nodes

Complete set of AST node types:

  • WorkflowNode - Root workflow definition
  • StatementNode base class with implementations:
    • VariableDeclarationNode
    • ActivityInvocationNode
    • BlockNode (for sequences)
    • IfNode, ForEachNode, ForNode, WhileNode, SwitchNode
    • FlowchartNode, ListenNode
  • ExpressionNode base class with implementations:
    • LiteralNode, IdentifierNode, ArrayLiteralNode
    • ElsaExpressionNode (with language support)
    • TemplateStringNode, BinaryExpressionNode, UnaryExpressionNode
  • ArgumentNode for activity parameters
  • UseNode for import/configuration statements

Compiler (ElsaScriptCompiler)

Compiles AST to Elsa workflow activities:

  • Traverses AST and constructs Elsa activity graphs
  • Maps DSL constructs to Elsa activities:
    • Blocks → Sequence
    • Variables → Variable instances
    • Activity invocations → Elsa activity instances
    • Control flow nodes → corresponding Elsa activities
  • Resolves activities via IActivityRegistry
  • Binds expressions to Elsa expression system with language support
  • Maps expression languages (js, cs, py, liquid) to Elsa providers

Dependency Injection

Integration with Elsa's module system:

  • ElsaScriptFeature for service registration
  • ModuleExtensions.UseElsaScript() for easy setup
  • Registers IElsaScriptParser and IElsaScriptCompiler services

Example Usage

use Elsa.Activities.Console;
use expressions js;

workflow "HelloWorld" {
  var greeting = "Hello";
  WriteLine(=> greeting + " World");
  WriteLine("Great to meet you!");
}

Integration Tests

Six integration tests demonstrate the implementation:

  1. Parser can parse a simple workflow definition - Verifies basic workflow parsing
  2. Parser can parse variable declarations - Tests var/let/const parsing
  3. Parser can parse activity invocations with named arguments - Tests argument parsing
  4. Compiler service is registered and available - Verifies DI setup
  5. Compiler can parse and analyze a workflow AST - Tests AST analysis
  6. Compiler recognizes variable declarations in AST - Tests variable compilation

Known Limitations

This is a foundation implementation with several areas for future enhancement:

Parser Limitations

  1. Uses regex instead of Parlot for parsing (simpler but less robust)
  2. Control flow parsing (if/foreach/while/for/switch) needs completion
  3. Block/sequence parsing needs enhancement
  4. Flowchart syntax not yet implemented
  5. Template string parsing incomplete

Compiler Limitations

  1. Dynamic activity instantiation needs refinement
  2. Control flow compilation stubs need full implementation
  3. For loop compilation not implemented
  4. Flowchart compilation not implemented
  5. Error handling and diagnostics minimal

Runtime Limitations

  1. End-to-end workflow execution not fully working
  2. Activity property setting needs enhancement
  3. Complex expression evaluation untested

Future Enhancements

Short Term

  1. Complete parser using Parlot for robust parsing
  2. Implement full control flow parsing and compilation
  3. Fix dynamic activity instantiation for runtime execution
  4. Add comprehensive error messages and diagnostics

Medium Term

  1. Implement flowchart parsing and compilation
  2. Support template strings with interpolation
  3. Add output capture syntax (let result = Activity())
  4. Implement switch fallthrough options
  5. Add try/catch/finally support

Long Term

  1. IDE support (syntax highlighting, IntelliSense)
  2. Debugging support
  3. Performance optimizations
  4. Extended DSL features (custom operators, macros, etc.)

Testing Strategy

Current tests focus on:

  • Parser correctness for basic constructs
  • AST structure validation
  • Compiler service availability
  • Variable and activity node recognition

Additional testing needed for:

  • Control flow execution
  • Expression evaluation
  • Error handling
  • Edge cases and invalid syntax

Architecture Decisions

Why Regex-Based Parser?

The simplified regex-based parser was chosen to deliver a working proof-of-concept quickly. While less robust than a full Parlot implementation, it demonstrates the DSL concept and can be replaced with a more sophisticated parser later.

Why Separate AST and Compiler?

The separation allows for:

  • Multiple compilation targets (if needed)
  • AST analysis and transformation
  • Better error reporting
  • Easier testing of each component

Why Reuse Elsa's Expression System?

Rather than creating a new expression language, ElsaScript wraps Elsa's existing expression providers (JavaScript, C#, Python, Liquid). This provides:

  • Consistency with existing Elsa workflows
  • Proven expression evaluation
  • No additional dependencies
  • Familiar syntax for Elsa users

Files Added

Source Files

  • src/modules/Elsa.Dsl.ElsaScript/
    • Ast/ - AST node definitions
    • Compiler/ - AST to Elsa workflow compiler
    • Contracts/ - Service interfaces
    • Extensions/ - DI extension methods
    • Features/ - Elsa feature module
    • Parser/ - ElsaScript parser
    • Elsa.Dsl.ElsaScript.csproj - Project file

Test Files

  • test/integration/Elsa.Dsl.ElsaScript.IntegrationTests/
    • ParserTests.cs - Parser integration tests
    • CompilerTests.cs - Compiler integration tests
    • Elsa.Dsl.ElsaScript.IntegrationTests.csproj - Test project

Configuration

  • Directory.Packages.props - Added Parlot package reference

Summary

The ElsaScript DSL provides a solid foundation for text-based workflow authoring in Elsa 3. While this initial implementation has limitations, it demonstrates the core concepts and provides a framework for future enhancements. The modular architecture integrates cleanly with Elsa's existing systems and can be extended incrementally.