From e1700b614c49aba3225aeb73fe708ecbcfc4a823 Mon Sep 17 00:00:00 2001 From: woksin Date: Sat, 24 Oct 2026 06:53:11 +0200 Subject: [PATCH 1/9] WIP: preserve incomplete action subject implementation before S0 repair (#1052) --- .../Screenplay/Diagnostics/DiagnosticCodes.cs | 15 +++ .../Parsing/ActionSubjectResolver.Inputs.cs | 69 ++++++++++++ .../Parsing/ActionSubjectResolver.Repairs.cs | 41 +++++++ .../Parsing/ActionSubjectResolver.cs | 106 ++++++++++++++++++ .../Parsing/GuardedActionValidator.cs | 3 + .../Parsing/ScreenParser.ActionSubjects.cs | 58 ++++++++++ .../DotNET/Screenplay/Parsing/ScreenParser.cs | 31 +++-- .../Screenplay/Parsing/ScreenplayValidator.cs | 1 + .../ScreenplayPrinter.GuardedActions.cs | 4 +- .../Printing/ScreenplayPrinter.Screens.cs | 8 +- .../DotNET/Screenplay/ScreenActionSubjects.cs | 20 ++++ .../Syntax/ScreenActionSubjectKind.cs | 16 +++ .../Syntax/ScreenGuardedActionSyntax.cs | 5 + .../DotNET/Screenplay/Syntax/ScreenSyntax.cs | 18 ++- .../Syntax/ScreenplaySyntaxWalker.Screens.cs | 1 + .../Serialization/ActionSubjectInvariants.cs | 15 +++ .../Syntax/Serialization/SyntaxJsonReader.cs | 1 + .../Syntax/Serialization/SyntaxJsonWriter.cs | 5 +- .../WorkspaceActionSubjectRepairs.cs | 82 ++++++++++++++ .../Workspaces/WorkspaceDiagnosticRepairs.cs | 5 + .../Workspaces/WorkspaceRepairVerification.cs | 6 + .../when_parsing_explicit_action_subjects.cs | 43 +++++++ .../when_resolving_action_subjects.cs | 91 +++++++++++++++ .../Compiler/Diagnostics/DiagnosticCodes.ts | 5 + .../Compiler/Parsing/ActionSubjectClause.ts | 37 ++++++ .../Compiler/Parsing/ActionSubjectInputs.ts | 64 +++++++++++ .../Parsing/GuardedActionValidator.ts | 5 + .../Compiler/Parsing/ScreenParser.ts | 26 +++-- .../Compiler/ScreenActionSubjects.ts | 60 ++++++++++ .../Compiler/Syntax/ScreenplaySyntaxWalker.ts | 1 + Source/Screenplay/Compiler/Syntax/Screens.ts | 6 + .../Compiler/Syntax/SyntaxCollections.ts | 2 +- .../Compiler/Syntax/SyntaxDefinitions.ts | 2 +- .../Compiler/Syntax/SyntaxInvariants.ts | 7 ++ .../Screenplay/Compiler/Syntax/SyntaxJson.ts | 4 + .../when_parsing_explicit_action_subjects.ts | 27 +++++ .../when_resolving_action_subjects.ts | 60 ++++++++++ Source/Screenplay/Compiler/index.ts | 1 + 38 files changed, 927 insertions(+), 24 deletions(-) create mode 100644 Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs create mode 100644 Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Repairs.cs create mode 100644 Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs create mode 100644 Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs create mode 100644 Source/DotNET/Screenplay/ScreenActionSubjects.cs create mode 100644 Source/DotNET/Screenplay/Syntax/ScreenActionSubjectKind.cs create mode 100644 Source/DotNET/Screenplay/Syntax/Serialization/ActionSubjectInvariants.cs create mode 100644 Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs create mode 100644 Source/DotNET/Screenplay/for_ScreenplayCompiler/when_parsing_explicit_action_subjects.cs create mode 100644 Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs create mode 100644 Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts create mode 100644 Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts create mode 100644 Source/Screenplay/Compiler/ScreenActionSubjects.ts create mode 100644 Source/Screenplay/Compiler/for_parse/when_parsing_explicit_action_subjects.ts create mode 100644 Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts diff --git a/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs b/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs index 727fc01c0..ad8812ff2 100644 --- a/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs +++ b/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs @@ -26,6 +26,21 @@ namespace Cratis.Screenplay.Diagnostics; /// public static class DiagnosticCodes { + /// Malformed, duplicate or inapplicable action subject clause. + public const string InvalidActionSubjectClause = "PLAY0815"; + + /// The inferred subject of an action without an authored clause. + public const string InferredActionSubject = "PLAY0816"; + + /// An inferred action subject differs from legacy row-name matching. + public const string ChangedActionSubject = "PLAY0817"; + + /// Several declared keys are eligible for an action input. + public const string AmbiguousActionInputBinding = "PLAY0818"; + + /// A guarded screen action cannot obtain an item from a collection. + public const string UnsupportedActionSubjectContext = "PLAY0819"; + // The document and its top level. /// diff --git a/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs new file mode 100644 index 000000000..927862823 --- /dev/null +++ b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs @@ -0,0 +1,69 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay.Parsing; + +internal sealed partial class ActionSubjectResolver +{ + static bool EligibleIdentifier(PropertySyntax input) => input.IsIdentifier && !input.IsGenerated && !input.Type.IsOptional && !input.Type.IsCollection; + + ScreenActionSubjectKind Subject(ScreenActionSubjectKind? authored, string commandName, IReadOnlyList subjects, DeclarationScope scope, SourceLocation location) + { + if (authored is { } explicitSubject) return explicitSubject; + var inputs = CommandInputs(commandName, scope); + var properties = Properties(subjects, scope); + var keys = properties.Where(property => property.IsKey).ToArray(); + var eligible = inputs.Where(input => EligibleIdentifier(input) && keys.Any(key => SameConcept(input, key))).ToArray(); + var inferred = subjects.Count == 1 && subjects[0].Type.IsCollection && eligible.Length == 1 && keys.Count(key => SameConcept(eligible[0], key)) == 1 + ? ScreenActionSubjectKind.Item + : ScreenActionSubjectKind.Screen; + _diagnostics.Add(new(DiagnosticSeverity.Information, DiagnosticCodes.InferredActionSubject, $"Action '{commandName}' infers 'for {inferred.ToString().ToLowerInvariant()}' from its declared data and identifier types", location)); + if (subjects.Count == 1 && subjects[0].Type.IsCollection) + { + var legacy = inputs.SelectMany(input => properties.Where(property => string.Equals(input.Name, property.Name, StringComparison.OrdinalIgnoreCase)).Select(property => (Input: input, Property: property))).ToArray(); + if ((legacy.Length > 0) != (inferred == ScreenActionSubjectKind.Item)) + { + var paths = string.Join(", ", legacy.Select(pair => $"{pair.Input.Name} from item.{pair.Property.Name}")); + _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.ChangedActionSubject, $"Action '{commandName}' now infers 'for {inferred.ToString().ToLowerInvariant()}'; legacy row-name matching would use {(paths.Length == 0 ? "no row property" : paths)}", location)); + } + } + + return inferred; + } + + InteractionArgumentSyntax[] Inputs(string commandName, IEnumerable authored, IReadOnlyList subjects, DeclarationScope scope, SourceLocation location) + { + var result = authored.ToList(); + if (subjects.Count != 1) return [.. result]; + var properties = Properties(subjects, scope); + foreach (var input in CommandInputs(commandName, scope).Where(input => !input.IsGenerated)) + { + if (result.Exists(argument => argument.Name == input.Name)) continue; + var sameName = properties.Where(property => property.Name == input.Name).ToArray(); + if (sameName.Length == 1) + { + result.Add(new(input.Name, $"item.{sameName[0].Name}", location)); + continue; + } + + if (!EligibleIdentifier(input)) continue; + var keys = properties.Where(property => property.IsKey && SameConcept(input, property)).ToArray(); + if (keys.Length == 1) result.Add(new(input.Name, $"item.{keys[0].Name}", location)); + else if (keys.Length > 1) _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.AmbiguousActionInputBinding, $"Input '{input.Name}' of action '{commandName}' matches several declared key fields - write an explicit binding", location)); + } + + return [.. result]; + } + + PropertySyntax[] Properties(IReadOnlyList subjects, DeclarationScope scope) => subjects.Count == 1 + ? _declarations.ViewProperties(subjects[0].Type.Name, scope)?.ToArray() ?? [] + : []; + + PropertySyntax[] CommandInputs(string name, DeclarationScope scope) => _declarations.Resolve(name, scope, slice => slice.Commands, command => command.Name)?.Node.Properties.ToArray() ?? []; + + bool SameConcept(PropertySyntax input, PropertySyntax key) => !key.Type.IsCollection && !key.Type.IsOptional && input.Type.Name == key.Type.Name && + application.Concepts.Count(concept => concept.Name == input.Type.Name) == 1; +} diff --git a/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Repairs.cs b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Repairs.cs new file mode 100644 index 000000000..c7bb01b87 --- /dev/null +++ b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Repairs.cs @@ -0,0 +1,41 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay.Parsing; + +internal sealed partial class ActionSubjectResolver +{ + internal Dictionary Repairs { get; } = []; + + void Remember(SyntaxNode authored, SyntaxNode effective, IReadOnlyList subjects, DeclarationScope scope) + { + var command = authored is ScreenActionSyntax action ? action.Command : ((ToolbarItemSyntax)authored).Target; + var original = authored is ScreenActionSyntax plain ? plain.Inputs.ToArray() : [.. ((ToolbarItemSyntax)authored).Parameters.Select(parameter => new InteractionArgumentSyntax(parameter.Name, parameter.Binding.Path, parameter.Location))]; + var properties = Properties(subjects, scope); + var legacy = new List(original); + var safe = subjects.Count == 1 && subjects[0].Type.IsCollection; + foreach (var input in CommandInputs(command, scope).Where(input => !input.IsGenerated && !original.Any(argument => argument.Name == input.Name))) + { + var matches = properties.Where(property => string.Equals(property.Name, input.Name, StringComparison.OrdinalIgnoreCase)).ToArray(); + if (matches.Length > 1) safe = false; + if (matches.Length == 1) legacy.Add(new(input.Name, $"item.{matches[0].Name}", authored.Location)); + + // An implicit key fallback would add a binding the legacy rule never supplied. + if (matches.Length == 0 && EligibleIdentifier(input) && properties.Any(property => property.IsKey && SameConcept(input, property))) safe = false; + } + + SyntaxNode? retained = safe ? authored switch + { + ScreenActionSyntax node => node with { Subject = ScreenActionSubjectKind.Item, Inputs = legacy }, + ToolbarItemSyntax node => node with + { + Subject = ScreenActionSubjectKind.Item, + Parameters = [.. node.Parameters, .. legacy.Skip(original.Length).Select(input => new ScreenNavigationParameterSyntax(input.Name, new(UiBindingKind.DataContext, input.Binding, input.Location), input.Location))] + }, + _ => null + } : null; + Repairs[authored] = (effective, retained); + } +} diff --git a/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs new file mode 100644 index 000000000..6dae6a62e --- /dev/null +++ b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs @@ -0,0 +1,106 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay.Parsing; + +internal sealed partial class ActionSubjectResolver(ApplicationSyntax application) +{ + readonly ConsistencyDeclarations _declarations = new(application, [.. ScreenplayValidator.ScopedSlices(application)]); + readonly List _diagnostics = []; + + internal CompilationResult Resolve() + { + var effective = application with + { + Modules = [.. application.Modules.Select(module => module with { Features = Features(module.Features) })] + }; + return new(effective, _diagnostics); + } + + FeatureSyntax[] Features(IEnumerable features) => [.. features.Select(feature => feature with + { + Features = Features(feature.Features), + Slices = [.. feature.Slices.Select(Slice)] + })]; + + SliceSyntax Slice(SliceSyntax slice) + { + var scope = _declarations.Slices.Single(entry => ReferenceEquals(entry.Slice, slice)).Scope; + return slice with + { + Screens = [.. slice.Screens.Select(screen => screen with + { + Directives = Container(screen.Directives, [], scope), + Contributions = [.. screen.Contributions.Select(contribution => contribution with { Directives = Container(contribution.Directives, [], scope) })] + })] + }; + } + + ScreenDirectiveSyntax[] Container(IEnumerable directives, IReadOnlyList inherited, DeclarationScope scope) + { + var nodes = directives.ToArray(); + var local = nodes.OfType().ToArray(); + var subjects = local.Length == 0 ? inherited : local; + return [.. nodes.Select(node => Directive(node, subjects, scope))]; + } + + ScreenDirectiveSyntax Directive(ScreenDirectiveSyntax node, IReadOnlyList subjects, DeclarationScope scope) => node switch + { + ScreenActionSyntax action => PlainAction(action, subjects, scope), + ScreenGuardedActionSyntax action => GuardedAction(action, subjects, scope), + ScreenToolbarSyntax toolbar => toolbar with { Items = [.. toolbar.Items.Select(item => ToolbarItem(item, subjects, scope))] }, + ScreenSectionSyntax section => section with { Directives = Container(section.Directives, subjects, scope) }, + ScreenSlotSyntax slot => slot with { Directives = Container(slot.Directives, subjects, scope) }, + ScreenTemplateReferenceSyntax template => template with { Slots = [.. template.Slots.Select(slot => slot with { Directives = Container(slot.Directives, subjects, scope) })] }, + ScreenComponentSyntax component => component with { Outlets = [.. component.Outlets.Select(outlet => outlet with { Directives = Container(outlet.Directives, subjects, scope) })] }, + _ => node + }; + + ScreenActionSyntax PlainAction(ScreenActionSyntax action, IReadOnlyList subjects, DeclarationScope scope) + { + var subject = Subject(action.Subject, action.Command, subjects, scope, action.Location); + var inputs = subject == ScreenActionSubjectKind.Item ? Inputs(action.Command, action.Inputs, subjects, scope, action.Location) : action.Inputs; + var effective = action with { Subject = subject, Inputs = inputs }; + Remember(action, effective, subjects, scope); + return effective; + } + + ToolbarItemSyntax ToolbarItem(ToolbarItemSyntax item, IReadOnlyList subjects, DeclarationScope scope) + { + if (item.Kind != ToolbarItemKind.Action) return item; + var subject = Subject(item.Subject, item.Target, subjects, scope, item.Location); + if (subject != ScreenActionSubjectKind.Item) + { + var effective = item with { Subject = subject }; + Remember(item, effective, subjects, scope); + return effective; + } + var authored = item.Parameters.ToArray(); + var inputs = Inputs(item.Target, authored.Select(parameter => new InteractionArgumentSyntax(parameter.Name, string.Empty, parameter.Location)), subjects, scope, item.Location); + var inferred = inputs.Skip(authored.Length).Select(input => new ScreenNavigationParameterSyntax(input.Name, new(UiBindingKind.DataContext, input.Binding, input.Location), input.Location)); + var resolved = item with { Subject = subject, Parameters = [.. authored.Concat(inferred)] }; + Remember(item, resolved, subjects, scope); + return resolved; + } + + ScreenGuardedActionSyntax GuardedAction(ScreenGuardedActionSyntax action, IReadOnlyList subjects, DeclarationScope scope) + { + if (action.Subject == ScreenActionSubjectKind.Screen && subjects.Count == 1 && subjects[0].Type.IsCollection) + { + _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.UnsupportedActionSubjectContext, "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", action.Location)); + return action; + } + + return action with + { + Subject = action.Subject ?? ScreenActionSubjectKind.Item, + Alternatives = [.. action.Alternatives.Select(alternative => alternative with { Arguments = Inputs(alternative.Command, alternative.Arguments, subjects, scope, alternative.Location) })], + Otherwise = action.Otherwise is { Command: { } command } otherwise + ? otherwise with { Arguments = Inputs(command, otherwise.Arguments, subjects, scope, otherwise.Location) } + : action.Otherwise + }; + } +} diff --git a/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs b/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs index 53be8fd23..19269943e 100644 --- a/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs +++ b/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs @@ -42,6 +42,9 @@ static void ValidateContainer( case ScreenGuardedActionSyntax action: ValidateAction(action, subjects, scope, declarations, context); break; + case ScreenActionSyntax action: + ValidateArguments(action.Command, action.Inputs, subjects.Count == 1 ? declarations.ViewProperties(subjects[0].Type.Name, scope) : null, scope, declarations, context); + break; case ScreenBehaviorSyntax attached: ValidateInteraction(attached.Behavior, subjects, scope, declarations, context); break; diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs new file mode 100644 index 000000000..8f8e607b9 --- /dev/null +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs @@ -0,0 +1,58 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Text.RegularExpressions; +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Syntax; +using Cratis.Screenplay.Text; + +namespace Cratis.Screenplay.Parsing; + +internal static partial class ScreenParser +{ + static ScreenActionSubjectKind? ParseSubjectClause(ParserContext context, SourceLine line, bool action, out string header, out string? label) + { + header = line.Content; + label = null; + var words = HeaderWordRegex().Matches(header).Cast().ToArray(); + var clauses = words.Where(word => word.Value == "for").ToArray(); + var labelWord = words.FirstOrDefault(word => word.Value == "label"); + if (labelWord is not null) + { + var match = LabelRegex().Match(header[labelWord.Index..]); + if (match.Success) + { + label = OperandText(match, 1); + header = header[..labelWord.Index].TrimEnd(); + } + } + + if (clauses.Length == 0) return null; + var clause = clauses[0]; + var suffix = SubjectClauseRegex().Match(header[clause.Index..]); + if (!action || clauses.Length != 1 || !suffix.Success || (labelWord is not null && labelWord.Index < clause.Index)) + { + context.Error(DiagnosticCodes.InvalidActionSubjectClause, "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", line.Location); + header = header[..Math.Min(clause.Index, header.Length)].TrimEnd(); + return null; + } + + header = header[..clause.Index].TrimEnd(); + return suffix.Groups[1].Value == "item" ? ScreenActionSubjectKind.Item : ScreenActionSubjectKind.Screen; + } + + static InteractionArgumentSyntax? ParsePlainActionInput(ParserContext context, SourceLine line) + { + var match = InteractionParser.WithRegex().Match(line.Content); + if (match.Success) return new(match.Groups[1].Value, match.Groups[2].Value.Trim(), line.Location); + context.Error(DiagnosticCodes.InvalidInteractionArgument, $"Invalid argument '{line.Content}' - expected 'with from '", line.Location); + context.SkipBlock(line.Indent); + return null; + } + + [GeneratedRegex("\"" + StringLiteral.BodyPattern + "\"|\\S+", RegexOptions.NonBacktracking)] + private static partial Regex HeaderWordRegex(); + + [GeneratedRegex(@"^for\s+(item|screen)$", RegexOptions.NonBacktracking)] + private static partial Regex SubjectClauseRegex(); +} diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs index 476ad05d4..7f446e371 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs @@ -158,6 +158,11 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi static ScreenDirectiveSyntax? ParseDirective(ParserContext context, SourceLine line) { + if (LineText.FirstWord(line.Content) != "action") + { + ParseSubjectClause(context, line, false, out _, out _); + } + switch (LineText.FirstWord(line.Content)) { case "data": @@ -216,13 +221,14 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi static ScreenDirectiveSyntax? ParseAction(ParserContext context, SourceLine line) { - var guarded = GuardedActionRegex().Match(line.Content); + var subject = ParseSubjectClause(context, line, true, out var header, out var inlineLabel); + var guarded = GuardedActionRegex().Match(header); if (guarded.Success) { - return ParseGuardedAction(context, line, OperandText(guarded, 1)); + return ParseGuardedAction(context, line, OperandText(guarded, 1)) with { Subject = subject }; } - var match = ActionRegex().Match(line.Content); + var match = ActionRegex().Match(header); if (!match.Success) { context.Error(DiagnosticCodes.InvalidActionDirective, $"Invalid action directive '{line.Content}' - expected 'action '", line.Location); @@ -230,9 +236,10 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi return null; } - string? label = null; - SourceLocation? labelLocation = null; + var label = inlineLabel; + SourceLocation? labelLocation = inlineLabel is null ? null : line.Location; ScreenNavigateSyntax? navigate = null; + var inputs = new List(); while (context.TryPeekChild(line.Indent, out var child)) { @@ -247,6 +254,10 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi { navigate = ParseNavigate(context, child.Content, child); } + else if (LineText.FirstWord(child.Content) == "with") + { + if (ParsePlainActionInput(context, child) is { } input) inputs.Add(input); + } else { context.Error(DiagnosticCodes.UnknownActionDirective, $"Unexpected '{child.Content}' in action - expected 'label \"...\"' or 'navigate to ...'", child.Location); @@ -255,6 +266,8 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi return new ScreenActionSyntax(match.Groups[1].Value, label, navigate, line.Location) { + Subject = subject, + Inputs = inputs, DirectiveLocations = labelLocation is null ? [] : new Dictionary { ["label"] = labelLocation } }; } @@ -530,7 +543,9 @@ static ComponentOutletSyntax ParseComponentOutlet(ParserContext context, SourceL static ToolbarItemSyntax? ParseToolbarItem(ParserContext context, SourceLine line) { - var match = ToolbarItemRegex().Match(line.Content); + var isAction = HeaderWordRegex().Matches(line.Content).Cast().Any(word => word.Value == "action"); + var subject = ParseSubjectClause(context, line, isAction, out var header, out var inlineLabel); + var match = ToolbarItemRegex().Match(header); if (!match.Success) { context.Error(DiagnosticCodes.UnknownScreenDirective, $"Invalid toolbar item '{line.Content}' - expected 'item action ', 'item navigate to ', 'item dialog ' or 'button title \"\" slice '", line.Location); @@ -544,8 +559,8 @@ static ComponentOutletSyntax ParseComponentOutlet(ParserContext context, SourceL "navigate" => ToolbarItemKind.Navigate, _ => ToolbarItemKind.Dialog }; - var item = new ToolbarItemSyntax(match.Groups[1].Value, kind, match.Groups[3].Value, line.Location); - string? label = null; + var item = new ToolbarItemSyntax(match.Groups[1].Value, kind, match.Groups[3].Value, line.Location) { Subject = subject }; + var label = inlineLabel; string? icon = null; string? confirm = null; var parameters = new List(); diff --git a/Source/DotNET/Screenplay/Parsing/ScreenplayValidator.cs b/Source/DotNET/Screenplay/Parsing/ScreenplayValidator.cs index 6e1addf80..ab79904c0 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenplayValidator.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenplayValidator.cs @@ -46,6 +46,7 @@ public static ApplicationSyntax Validate(ApplicationSyntax application, ParserCo ValidateSlices(application, slices, names, context); ValidateScopedReferences(application, expansion, names, context); ValidatePresentation(application, context); + foreach (var diagnostic in ScreenActionSubjects.Resolve(application).Diagnostics) context.Add(diagnostic); SampleDataValidator.Validate(application, slices, context); foreach (var diagnostic in expansion.Diagnostics.Where(diagnostic => diagnostic.Code != DiagnosticCodes.UnsynthesizablePersonaCaller && !context.Diagnostics.Contains(diagnostic))) context.Add(diagnostic); diff --git a/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.GuardedActions.cs b/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.GuardedActions.cs index f64a0053c..4b3d61049 100644 --- a/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.GuardedActions.cs +++ b/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.GuardedActions.cs @@ -10,9 +10,11 @@ namespace Cratis.Screenplay.Printing; /// public partial class ScreenplayPrinter { + static string WriteActionSubject(ScreenActionSubjectKind? subject) => subject is null ? string.Empty : $" for {subject.Value.ToString().ToLowerInvariant()}"; + void WriteScreenGuardedAction(ScreenplayWriter writer, ScreenGuardedActionSyntax action) { - writer.Line($"action {ScreenplaySyntaxText.LocalizableString(action.Label)}"); + writer.Line($"action {ScreenplaySyntaxText.LocalizableString(action.Label)}{WriteActionSubject(action.Subject)}"); using (writer.Indent()) { foreach (var alternative in action.Alternatives) diff --git a/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs b/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs index 6deea22d6..a5c9cfaef 100644 --- a/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs +++ b/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs @@ -156,8 +156,8 @@ string WriteUiBinding(ScreenplayWriter writer, UiBindingSyntax binding) void WriteScreenAction(ScreenplayWriter writer, ScreenActionSyntax action) { using var anchor = writer.Anchor(action); - writer.Line($"action {action.Command}"); - if (action.Label is null && action.Navigate is null) + writer.Line($"action {action.Command}{WriteActionSubject(action.Subject)}"); + if (action.Label is null && action.Navigate is null && !action.Inputs.Any()) { return; } @@ -169,6 +169,8 @@ void WriteScreenAction(ScreenplayWriter writer, ScreenActionSyntax action) writer.DirectiveLine($"label {ScreenplaySyntaxText.LocalizableString(action.Label)}", action, "label"); } + foreach (var input in action.Inputs) writer.Line($"with {input.Name} from {input.Binding}", input); + if (action.Navigate is not null) { writer.Line(WriteScreenNavigate(action.Navigate), action.Navigate); @@ -371,7 +373,7 @@ void WriteToolbarItem(ScreenplayWriter writer, ToolbarItemSyntax item) ToolbarItemKind.Dialog => $"item {item.Name} dialog {item.Target}", _ => $"item {item.Name} action {item.Target}" }; - writer.Line(head); + writer.Line(head + WriteActionSubject(item.Subject)); using (writer.Indent()) { if (item.Label is not null) diff --git a/Source/DotNET/Screenplay/ScreenActionSubjects.cs b/Source/DotNET/Screenplay/ScreenActionSubjects.cs new file mode 100644 index 000000000..347077d09 --- /dev/null +++ b/Source/DotNET/Screenplay/ScreenActionSubjects.cs @@ -0,0 +1,20 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Parsing; +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay; + +/// +/// Resolves action subjects and inputs against the complete application's declarations. +/// +public static class ScreenActionSubjects +{ + /// + /// Creates an effective application without modifying the authored syntax tree. + /// + /// The assembled application, including imported declarations. + /// The effective syntax and subject-resolution diagnostics. + public static CompilationResult Resolve(ApplicationSyntax application) => new ActionSubjectResolver(application).Resolve(); +} diff --git a/Source/DotNET/Screenplay/Syntax/ScreenActionSubjectKind.cs b/Source/DotNET/Screenplay/Syntax/ScreenActionSubjectKind.cs new file mode 100644 index 000000000..14dafe85e --- /dev/null +++ b/Source/DotNET/Screenplay/Syntax/ScreenActionSubjectKind.cs @@ -0,0 +1,16 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Cratis.Screenplay.Syntax; + +/// +/// Identifies the data subject used by a screen action. +/// +public enum ScreenActionSubjectKind +{ + /// The item supplied by a table or record context. + Item, + + /// The nearest single-record screen data context. + Screen +} diff --git a/Source/DotNET/Screenplay/Syntax/ScreenGuardedActionSyntax.cs b/Source/DotNET/Screenplay/Syntax/ScreenGuardedActionSyntax.cs index 610f2ed5f..a6c73ca79 100644 --- a/Source/DotNET/Screenplay/Syntax/ScreenGuardedActionSyntax.cs +++ b/Source/DotNET/Screenplay/Syntax/ScreenGuardedActionSyntax.cs @@ -18,6 +18,11 @@ public record ScreenGuardedActionSyntax(string Label, IEnumerable public ScreenActionOtherwiseSyntax? Otherwise { get; init; } + /// + /// Gets the explicitly authored subject, or null for the contextual default. + /// + public ScreenActionSubjectKind? Subject { get; init; } + /// /// Gets the navigation performed after successful execution of the selected command. /// diff --git a/Source/DotNET/Screenplay/Syntax/ScreenSyntax.cs b/Source/DotNET/Screenplay/Syntax/ScreenSyntax.cs index f7da953c9..c36e24e47 100644 --- a/Source/DotNET/Screenplay/Syntax/ScreenSyntax.cs +++ b/Source/DotNET/Screenplay/Syntax/ScreenSyntax.cs @@ -77,7 +77,18 @@ public record ScreenDataSyntax(TypeRefSyntax Type, string Query, string? By, Sou /// The optional display label. /// The optional performed after the action. /// The where the node starts in the source text. -public record ScreenActionSyntax(string Command, string? Label, ScreenNavigateSyntax? Navigate, SourceLocation Location) : ScreenDirectiveSyntax(Location); +public record ScreenActionSyntax(string Command, string? Label, ScreenNavigateSyntax? Navigate, SourceLocation Location) : ScreenDirectiveSyntax(Location) +{ + /// + /// Gets the explicitly authored subject, or null for the contextual default. + /// + public ScreenActionSubjectKind? Subject { get; init; } + + /// + /// Gets the explicitly authored command input bindings. + /// + public IEnumerable Inputs { get; init; } = []; +} /// /// Represents a navigate to directive. @@ -370,6 +381,11 @@ public record ToolbarButtonSyntax(string Id, string Title, SourceLocation Locati /// The where the node starts in the source text. public record ToolbarItemSyntax(string Name, ToolbarItemKind Kind, string Target, SourceLocation Location) : SyntaxNode(Location) { + /// + /// Gets the explicitly authored command subject. + /// + public ScreenActionSubjectKind? Subject { get; init; } + /// /// Gets the item label. /// diff --git a/Source/DotNET/Screenplay/Syntax/ScreenplaySyntaxWalker.Screens.cs b/Source/DotNET/Screenplay/Syntax/ScreenplaySyntaxWalker.Screens.cs index fa5cb0213..2ec9581c3 100644 --- a/Source/DotNET/Screenplay/Syntax/ScreenplaySyntaxWalker.Screens.cs +++ b/Source/DotNET/Screenplay/Syntax/ScreenplaySyntaxWalker.Screens.cs @@ -116,6 +116,7 @@ public virtual void VisitScreenData(ScreenDataSyntax syntax) public virtual void VisitScreenAction(ScreenActionSyntax syntax) { VisitNode(syntax); + foreach (var input in syntax.Inputs) VisitInteractionArgument(input); if (syntax.Navigate is not null) { diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/ActionSubjectInvariants.cs b/Source/DotNET/Screenplay/Syntax/Serialization/ActionSubjectInvariants.cs new file mode 100644 index 000000000..3e7b75ab6 --- /dev/null +++ b/Source/DotNET/Screenplay/Syntax/Serialization/ActionSubjectInvariants.cs @@ -0,0 +1,15 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Cratis.Screenplay.Syntax.Serialization; + +internal static class ActionSubjectInvariants +{ + internal static void Validate(SyntaxNode node) + { + if (node is ToolbarItemSyntax { Subject: not null, Kind: not ToolbarItemKind.Action }) + { + throw new InvalidSyntaxJson("Only an action toolbar item can have a subject."); + } + } +} diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonReader.cs b/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonReader.cs index f86b6cd02..d67bb505f 100644 --- a/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonReader.cs +++ b/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonReader.cs @@ -40,6 +40,7 @@ internal static SyntaxNode Read(JsonElement value, Type expected, string path, i var node = descriptor.Create(values); ImplementationInvariants.Validate(node); + ActionSubjectInvariants.Validate(node); return node; } diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonWriter.cs b/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonWriter.cs index 21e7ca034..6cfa530f1 100644 --- a/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonWriter.cs +++ b/Source/DotNET/Screenplay/Syntax/Serialization/SyntaxJsonWriter.cs @@ -11,6 +11,7 @@ internal static class SyntaxJsonWriter { SyntaxJson.CheckDepth(depth, path); ImplementationInvariants.Validate(node); + ActionSubjectInvariants.Validate(node); var descriptor = SyntaxKinds.For(node.GetType()); var result = new Dictionary(StringComparer.Ordinal) { ["kind"] = descriptor.Type.Name }; foreach (var member in descriptor.Members) @@ -53,7 +54,9 @@ internal static class SyntaxJsonWriter } static bool OmitDefaults(SyntaxNode node, string member, object? value) => - ClockSyntaxDefaults.Omit(node, member, value) || CompositionDefaults.Omit(node, member, value); + ClockSyntaxDefaults.Omit(node, member, value) || CompositionDefaults.Omit(node, member, value) || + (node is ScreenActionSyntax or ScreenGuardedActionSyntax or ToolbarItemSyntax && member == "subject" && value is null) || + (node is ScreenActionSyntax && member == "inputs" && value is IEnumerable inputs && !inputs.Any()); static object? WriteMember(SyntaxMember member, object? value, string path, int depth) { diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs new file mode 100644 index 000000000..bfd0dac18 --- /dev/null +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs @@ -0,0 +1,82 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Immutable; +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Files; +using Cratis.Screenplay.Parsing; +using Cratis.Screenplay.Syntax; +using Cratis.Screenplay.Syntax.Serialization; + +namespace Cratis.Screenplay.Workspaces; + +internal static class WorkspaceActionSubjectRepairs +{ + internal static ImmutableArray Find(WorkspaceSyntaxIndex index, WorkspaceRevision revision, Diagnostic diagnostic, bool verifyRepair) + { + var matches = index.Entries.Where(entry => entry.Handle.Revision == revision && entry.Location == diagnostic.Location && + entry.Node is ScreenActionSyntax { Subject: null } or ToolbarItemSyntax { Kind: ToolbarItemKind.Action, Subject: null }).ToArray(); + if (matches is not [var subject]) return []; + var roots = index.Entries.Select(entry => entry.Node).OfType().Select(application => new CompilationResult(application, [])).ToArray(); + var resolver = new ActionSubjectResolver(PlayFolderMerge.Merge(roots).Value!); + resolver.Resolve(); + if (!resolver.Repairs.TryGetValue(subject.Node, out var evidence)) return []; + var inferred = evidence.Effective is ScreenActionSyntax action ? action.Subject : ((ToolbarItemSyntax)evidence.Effective).Subject; + (SyntaxNode Node, string Title)[] candidates = diagnostic.Code == DiagnosticCodes.InferredActionSubject + ? [(Explicit(subject.Node, inferred!.Value), $"Make inferred 'for {inferred.Value.ToString().ToLowerInvariant()}' explicit")] + : + [ + (Explicit(subject.Node, ScreenActionSubjectKind.Item), "Use 'for item' (item-bound action)"), + (Explicit(subject.Node, ScreenActionSubjectKind.Screen), "Use 'for screen' (no selection binding)") + ]; + if (diagnostic.Code == DiagnosticCodes.ChangedActionSubject && evidence.Legacy is { } legacy && + !candidates.Any(candidate => SyntaxJson.StructurallyEqual(candidate.Node, legacy))) + { + candidates = [.. candidates, (legacy, "Keep legacy row bindings explicitly")]; + } + + var result = ImmutableArray.CreateBuilder(); + foreach (var (node, title) in candidates) + { + var repair = new WorkspaceDiagnosticRepair(diagnostic.Code, subject.Handle, + [new ReplaceWorkspaceNode(subject.Handle, subject.Node, node)]) + { + Title = title, + CanFixAll = false + }; + + // Each migration choice is a different recipe. Do not share the subject-only discovery cache. + if (!verifyRepair || WorkspaceRepairVerification.Verify(index, repair, new WorkspaceAuthoringRequest + { + ExpectedRevision = index.Workspace.Revision, + ExpectedCatalogRevision = index.Workspace.IdentityCatalog.Revision, + Validation = WorkspaceAuthoringValidation.Authoring, + Formatting = repair.RequiredFormatting + }).Accepted) + { + result.Add(repair); + } + } + return result.ToImmutable(); + } + + internal static bool Preserves(WorkspaceSyntaxIndex index, WorkspaceDiagnosticRepair repair, WorkspaceAuthoringResult result) + { + if (!WorkspaceRepairVerification.SameModel(index.Workspace, result.Workspace!) || !WorkspaceRepairVerification.KeepsCatalog(index.Workspace, result.Workspace!)) return false; + var subject = index.Find(repair.Subject)!; + var before = index.Workspace.Compilation.Diagnostics; + var after = result.Workspace!.Compilation.Diagnostics; + if (after.Any(diagnostic => diagnostic.Code == repair.DiagnosticCode && diagnostic.Message == before.First(original => original.Code == repair.DiagnosticCode && original.Location == subject.Location).Message)) return false; + static bool IsSubjectDiagnostic(Diagnostic diagnostic) => diagnostic.Code == DiagnosticCodes.InferredActionSubject || diagnostic.Code == DiagnosticCodes.ChangedActionSubject; + var expected = before.Where(diagnostic => diagnostic.Location != subject.Location || !IsSubjectDiagnostic(diagnostic)).Select(diagnostic => (diagnostic.Code, diagnostic.Message)).Order().ToArray(); + var actual = after.Select(diagnostic => (diagnostic.Code, diagnostic.Message)).Order().ToArray(); + return expected.SequenceEqual(actual); + } + + static SyntaxNode Explicit(SyntaxNode node, ScreenActionSubjectKind subject) => node switch + { + ScreenActionSyntax action => action with { Subject = subject }, + ToolbarItemSyntax item => item with { Subject = subject }, + _ => node + }; +} diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs index 45a9913b6..1f6f7ba45 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs @@ -195,6 +195,11 @@ static ImmutableArray Find(WorkspaceSyntaxIndex index return WorkspaceProductionRepairs.Find(index, revision, diagnostic, verifyRepair); } + if (diagnostic.Code is DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject) + { + return WorkspaceActionSubjectRepairs.Find(index, revision, diagnostic, verifyRepair); + } + if (diagnostic.Code == DiagnosticCodes.EventFromLaterSlice) { return WorkspaceTimelineRepairs.Find(index, revision, diagnostic, verifyRepair); diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs index 756218be2..bb16c63fb 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs @@ -165,6 +165,12 @@ static WorkspaceAuthoringResult VerifyTransaction(WorkspaceSyntaxIndex index, Wo return Refuse(result, WorkspaceConflictKind.InvalidOperation, "Cannot prove that the timeline repair preserves the model, catalog, readiness, placements and simulated ranks without introducing findings or problems."); } + if (result.Accepted && repair.DiagnosticCode is DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject && + !WorkspaceActionSubjectRepairs.Preserves(index, repair, result)) + { + return Refuse(result, WorkspaceConflictKind.InvalidOperation, "Cannot prove that the action subject repair preserves the model, catalog, comments and other diagnostics."); + } + return result; } diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_parsing_explicit_action_subjects.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_parsing_explicit_action_subjects.cs new file mode 100644 index 000000000..7cdb06a74 --- /dev/null +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_parsing_explicit_action_subjects.cs @@ -0,0 +1,43 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay.for_ScreenplayCompiler; + +public class when_parsing_explicit_action_subjects : given.a_compiler +{ + CompilationResult _result; + ScreenSyntax _screen; + + void Because() + { + _result = _compiler.Compile( + """ + module Work + feature Items + slice StateView Details + command Retry + itemId Uuid + query ExternalDetails => ExternalItem + screen Details + data ExternalItem via query ExternalDetails + action Retry for item + with itemId from item.itemId + action Work.Items.Details.Retry for screen + action "Again" for screen + when item.ready == true execute Retry + toolbar + item retry action Retry for item + parameter itemId from item.itemId + """); + _screen = _result.Value!.Modules.Single().Features.Single().Slices.Single().Screens.Single(); + } + + [Fact] void should_accept_the_explicit_subjects() => _result.Diagnostics.ShouldBeEmpty(); + [Fact] void should_keep_the_item_subject() => _screen.Directives.OfType().First().Subject.ShouldEqual(ScreenActionSubjectKind.Item); + [Fact] void should_keep_the_screen_subject() => _screen.Directives.OfType().Last().Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + [Fact] void should_keep_the_explicit_input() => _screen.Directives.OfType().First().Inputs.Single().Binding.ShouldEqual("item.itemId"); + [Fact] void should_keep_the_guarded_subject() => _screen.Directives.OfType().Single().Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + [Fact] void should_keep_the_toolbar_subject() => _screen.Directives.OfType().Single().Items.Single().Subject.ShouldEqual(ScreenActionSubjectKind.Item); +} diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs new file mode 100644 index 000000000..2f9c3535a --- /dev/null +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs @@ -0,0 +1,91 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Syntax; +using Cratis.Screenplay.Syntax.Serialization; + +namespace Cratis.Screenplay.for_ScreenplayCompiler; + +public class when_resolving_action_subjects : given.a_compiler +{ + const string Source = "concept ItemId : Uuid\nconcept TenantId : Uuid\nmodule Work\n feature Items\n slice StateView List\n readmodel Row\n rowId ItemId key\n itemId TenantId\n ready Boolean\n query Rows => Row[]\n command Retry\n itemId ItemId identifier\n screen List\n data Row[] via query Rows\n action Retry"; + + [Theory] + [InlineData("", ScreenActionSubjectKind.Item)] + [InlineData(" for item", ScreenActionSubjectKind.Item)] + [InlineData(" for screen", ScreenActionSubjectKind.Screen)] + void should_resolve_without_changing_authored_syntax(string clause, ScreenActionSubjectKind expected) + { + var raw = _compiler.Compile(Source + clause).Value!; + var before = SyntaxJson.Serialize(raw); + var resolved = ScreenActionSubjects.Resolve(raw); + Action(resolved.Value!).Subject.ShouldEqual(expected); + SyntaxJson.Serialize(raw).GetRawText().ShouldEqual(before.GetRawText()); + Action(raw).Inputs.ShouldBeEmpty(); + Action(resolved.Value!).Location.ShouldEqual(Action(raw).Location); + } + + [Fact] + void should_keep_same_name_precedence_over_key_type_fallback() + { + var effective = ScreenActionSubjects.Resolve(_compiler.Compile(Source).Value!).Value!; + Action(effective).Inputs.Single().Binding.ShouldEqual("item.itemId"); + } + + [Fact] + void should_bind_a_renamed_declared_key_by_nominal_concept() + { + var source = Source.Replace(" itemId TenantId\n", string.Empty, StringComparison.Ordinal); + var resolved = ScreenActionSubjects.Resolve(_compiler.Compile(source).Value!); + Action(resolved.Value!).Inputs.Single().Binding.ShouldEqual("item.rowId"); + resolved.Diagnostics.ShouldContain(diagnostic => diagnostic.Code == DiagnosticCodes.ChangedActionSubject); + } + + [Fact] + void should_keep_an_explicit_binding_before_same_name_and_key_fallback() + { + var effective = ScreenActionSubjects.Resolve(_compiler.Compile(Source + " for item\n with itemId from $context.currentItem").Value!).Value!; + Action(effective).Inputs.Single().Binding.ShouldEqual("$context.currentItem"); + } + + [Theory] + [InlineData("ItemId identifier", "ItemId optional identifier")] + [InlineData("ItemId identifier", "ItemId generated identifier")] + [InlineData("ItemId identifier", "TenantId identifier")] + void should_not_infer_item_from_ineligible_or_primitive_identifiers(string original, string replacement) + { + var raw = _compiler.Compile(Source.Replace(original, replacement, StringComparison.Ordinal)).Value!; + Action(ScreenActionSubjects.Resolve(raw).Value!).Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + } + + [Fact] + void should_not_use_primitive_equality_as_nominal_proof() + { + var source = Source.Replace("rowId ItemId key", "rowId Uuid key", StringComparison.Ordinal).Replace("itemId ItemId identifier", "itemId Uuid identifier", StringComparison.Ordinal); + Action(ScreenActionSubjects.Resolve(_compiler.Compile(source).Value!).Value!).Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + } + + [Fact] + void should_not_choose_between_multiple_eligible_keys() + { + var source = Source.Replace(" itemId TenantId\n", " otherId ItemId key\n", StringComparison.Ordinal) + " for item"; + var resolved = ScreenActionSubjects.Resolve(_compiler.Compile(source).Value!); + Action(resolved.Value!).Inputs.ShouldBeEmpty(); + resolved.Diagnostics.Single(diagnostic => diagnostic.Code == DiagnosticCodes.AmbiguousActionInputBinding).Severity.ShouldEqual(DiagnosticSeverity.Warning); + } + + [Fact] + void should_retain_a_guard_without_selecting_from_a_screen_collection() + { + var source = Source.Replace(" action Retry", " action \"Retry\" for screen\n when item.ready == true execute Retry", StringComparison.Ordinal); + var raw = _compiler.Compile(source).Value!; + var resolved = ScreenActionSubjects.Resolve(raw); + var action = Screen(resolved.Value!).Directives.OfType().Single(); + action.Alternatives.Single().Arguments.ShouldBeEmpty(); + resolved.Diagnostics.Single(diagnostic => diagnostic.Code == DiagnosticCodes.UnsupportedActionSubjectContext).Severity.ShouldEqual(DiagnosticSeverity.Warning); + } + + static ScreenSyntax Screen(ApplicationSyntax application) => application.Modules.Single().Features.Single().Slices.Single().Screens.Single(); + static ScreenActionSyntax Action(ApplicationSyntax application) => Screen(application).Directives.OfType().Single(); +} diff --git a/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts b/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts index e6f7109cd..bb0841fb0 100644 --- a/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts +++ b/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts @@ -4,6 +4,11 @@ // Shared diagnostic names, including the explicitly C#-only checks below. Catalogue membership does // not imply TypeScript validation support; see Documentation/screenplay/editor-diagnostics.md. export const DiagnosticCodes = { + InvalidActionSubjectClause: 'PLAY0815', + InferredActionSubject: 'PLAY0816', + ChangedActionSubject: 'PLAY0817', + AmbiguousActionInputBinding: 'PLAY0818', + UnsupportedActionSubjectContext: 'PLAY0819', DuplicateBehaviorAttachment: 'PLAY0340', UnknownMatchPattern: 'PLAY0366', InvalidMatchPattern: 'PLAY0367', diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts new file mode 100644 index 000000000..56a10fae6 --- /dev/null +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts @@ -0,0 +1,37 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; +import { ScreenActionSubjectKind } from '../Syntax/Screens'; +import { stringBodyPattern, unescapeString } from '../Text/StringLiteral'; +import { pattern } from '../Text/patterns'; +import { ParserContext } from './ParserContext'; +import { locationOf, SourceLine } from './SourceLine'; + +const word = new RegExp(pattern(`"${stringBodyPattern}"|\\S+`).source, 'gu'); +const label = pattern(`^label\\s+(?:"(${stringBodyPattern})"|(\\$strings\\.\\w+(?:\\.\\w+)*))$`); +const clause = pattern('^for\\s+(item|screen)$'); + +export function parseSubjectClause(context: ParserContext, line: SourceLine, action: boolean): { header: string; subject?: ScreenActionSubjectKind; label?: string } { + const words = [...line.content.matchAll(word)]; + const clauses = words.filter(part => part[0] === 'for'); + const labelWord = words.find(part => part[0] === 'label'); + let header = line.content; + let text: string | undefined; + if (labelWord !== undefined) { + const match = label.exec(header.substring(labelWord.index)); + if (match !== null) { + text = match[1] !== undefined ? unescapeString(match[1]) : match[2]; + header = header.substring(0, labelWord.index).trimEnd(); + } + } + if (clauses.length === 0) return { header, label: text }; + const start = clauses[0].index!; + const match = clause.exec(header.substring(start)); + header = header.substring(0, start).trimEnd(); + if (!action || clauses.length !== 1 || match === null || labelWord !== undefined && labelWord.index! < start) { + context.error(DiagnosticCodes.InvalidActionSubjectClause, "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", locationOf(line)); + return { header, label: text }; + } + return { header, subject: match[1] === 'item' ? 'Item' : 'Screen', label: text }; +} diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts new file mode 100644 index 000000000..7ca62eb67 --- /dev/null +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts @@ -0,0 +1,64 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { Diagnostic } from '../Diagnostics/Diagnostic'; +import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; +import { SourceLocation } from '../Diagnostics/SourceLocation'; +import { PropertySyntax } from '../Syntax/Declarations'; +import { InteractionArgumentSyntax, ScreenActionSubjectKind, ScreenDataSyntax } from '../Syntax/Screens'; +import { SliceSyntax } from '../Syntax/Structure'; +import { RefusalDeclarations } from './RefusalDeclarations'; + +export class ActionSubjectInputs { + constructor(readonly declarations: RefusalDeclarations, readonly diagnostics: Diagnostic[]) {} + + properties(subjects: readonly ScreenDataSyntax[], slice: SliceSyntax): readonly PropertySyntax[] { + return subjects.length === 1 ? this.declarations.resolve(subjects[0].type.name, slice, entry => entry.readModels)?.node.properties ?? [] : []; + } + + command(name: string, slice: SliceSyntax): readonly PropertySyntax[] { + return this.declarations.resolve(name, slice, entry => entry.commands)?.node.properties ?? []; + } + + sameConcept(input: PropertySyntax, key: PropertySyntax): boolean { + return !key.type.isCollection && !key.type.isOptional && input.type.name === key.type.name && this.declarations.application.concepts.filter(concept => concept.name === input.type.name).length === 1; + } + + eligible(input: PropertySyntax): boolean { + return input.isIdentifier && !input.isGenerated && !input.type.isOptional && !input.type.isCollection; + } + + subject(authored: ScreenActionSubjectKind | null | undefined, command: string, subjects: readonly ScreenDataSyntax[], slice: SliceSyntax, location: SourceLocation): ScreenActionSubjectKind { + if (authored != null) return authored; + const inputs = this.command(command, slice); + const properties = this.properties(subjects, slice); + const keys = properties.filter(property => property.isKey); + const eligible = inputs.filter(input => this.eligible(input) && keys.some(key => this.sameConcept(input, key))); + const inferred = subjects.length === 1 && subjects[0].type.isCollection && eligible.length === 1 && keys.filter(key => this.sameConcept(eligible[0], key)).length === 1 ? 'Item' : 'Screen'; + this.diagnostics.push({ severity: 'information', code: DiagnosticCodes.InferredActionSubject, message: `Action '${command}' infers 'for ${inferred.toLowerCase()}' from its declared data and identifier types`, location }); + if (subjects.length === 1 && subjects[0].type.isCollection) { + const legacy = inputs.flatMap(input => properties.filter(property => input.name.toLowerCase() === property.name.toLowerCase()).map(property => `${input.name} from item.${property.name}`)); + if ((legacy.length > 0) !== (inferred === 'Item')) this.diagnostics.push({ severity: 'warning', code: DiagnosticCodes.ChangedActionSubject, message: `Action '${command}' now infers 'for ${inferred.toLowerCase()}'; legacy row-name matching would use ${legacy.length === 0 ? 'no row property' : legacy.join(', ')}`, location }); + } + return inferred; + } + + inputs(command: string, authored: readonly InteractionArgumentSyntax[], subjects: readonly ScreenDataSyntax[], slice: SliceSyntax, location: SourceLocation): readonly InteractionArgumentSyntax[] { + const result = [...authored]; + if (subjects.length !== 1) return result; + const properties = this.properties(subjects, slice); + for (const input of this.command(command, slice).filter(input => !input.isGenerated)) { + if (result.some(argument => argument.name === input.name)) continue; + const named = properties.filter(property => property.name === input.name); + if (named.length === 1) { + result.push({ kind: 'InteractionArgumentSyntax', name: input.name, binding: `item.${named[0].name}`, location }); + continue; + } + if (!this.eligible(input)) continue; + const keys = properties.filter(property => property.isKey && this.sameConcept(input, property)); + if (keys.length === 1) result.push({ kind: 'InteractionArgumentSyntax', name: input.name, binding: `item.${keys[0].name}`, location }); + else if (keys.length > 1) this.diagnostics.push({ severity: 'warning', code: DiagnosticCodes.AmbiguousActionInputBinding, message: `Input '${input.name}' of action '${command}' matches several declared key fields - write an explicit binding`, location }); + } + return result; + } +} diff --git a/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts b/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts index 5955753e0..72749ee69 100644 --- a/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts +++ b/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; +import { resolveActionSubjects } from '../ScreenActionSubjects'; import { ScreenDataSyntax, ScreenDirectiveSyntax, ScreenGuardedActionSyntax, ScreenTableSyntax } from '../Syntax/Screens'; import { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure'; import { comparisons, validateArguments, validateItemPath, viewProperties } from './GuardedActionInputs'; @@ -12,6 +13,7 @@ import { RefusalDeclarations } from './RefusalDeclarations'; // Resolves known subject and input shapes without guessing imported or ambiguous declarations. export function validateGuardedActions(application: ApplicationSyntax, context: ParserContext): void { + for (const diagnostic of resolveActionSubjects(application).diagnostics) context[diagnostic.severity](diagnostic.code, diagnostic.message, diagnostic.location, diagnostic.arguments); const declarations = new RefusalDeclarations(application); const interactions = new GuardedInteractions(declarations, context); interactions.structural(application); @@ -36,6 +38,9 @@ function validateContainer(directives: readonly ScreenDirectiveSyntax[], inherit case 'ScreenGuardedActionSyntax': validateAction(directive, subjects, slice, declarations, context); break; + case 'ScreenActionSyntax': + validateArguments(directive.command, directive.inputs ?? [], subjects.length === 1 ? viewProperties(subjects[0].type.name, slice, declarations) : null, slice, declarations, context); + break; case 'ScreenBehaviorSyntax': interactions.at(directive.location, subjects, slice); break; diff --git a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts index bbc3fd9e9..2699a68d0 100644 --- a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts +++ b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts @@ -12,6 +12,8 @@ import { AuthorizeSyntax } from '../Syntax/Authorization'; import { stringBodyPattern, unescapeString } from '../Text/StringLiteral'; import { pattern } from '../Text/patterns'; import { parseAuthorize } from './AuthorizeParser'; +import { parseSubjectClause } from './ActionSubjectClause'; +import { InteractionArgumentSyntax } from '../Syntax/Screens'; import { parseFencedText } from './CodeBlockParser'; import { parseMappingSource } from './ExpressionParser'; import { parseDescription } from './DescriptionParser'; @@ -114,6 +116,7 @@ function parseDirectives(context: ParserContext, parent: SourceLine): ScreenDire } function parseDirective(context: ParserContext, line: SourceLine): ScreenDirectiveSyntax | undefined { + if (firstWord(line.content) !== 'action') parseSubjectClause(context, line, false); switch (firstWord(line.content)) { case 'data': return parseData(context, line); @@ -161,16 +164,18 @@ function parseData(context: ParserContext, line: SourceLine): ScreenDataSyntax | } function parseAction(context: ParserContext, line: SourceLine): ScreenActionSyntax | ScreenGuardedActionSyntax | undefined { - const guarded = guardedAction.exec(line.content); - if (guarded !== null) return parseGuardedAction(context, line, operandText(guarded, 1), parseNavigate); - const match = action.exec(line.content); + const parsed = parseSubjectClause(context, line, true); + const guarded = guardedAction.exec(parsed.header); + if (guarded !== null) return { ...parseGuardedAction(context, line, operandText(guarded, 1), parseNavigate), ...(parsed.subject === undefined ? {} : { subject: parsed.subject }) }; + const match = action.exec(parsed.header); if (match === null) { context.error(DiagnosticCodes.InvalidActionDirective, `Invalid action directive '${line.content}' - expected 'action '`, locationOf(line)); context.skipBlock(line.indent); return undefined; } - let text: string | null = null; + let text: string | null = parsed.label ?? null; let target: ScreenNavigateSyntax | null = null; + const inputs: InteractionArgumentSyntax[] = []; for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) { context.reader.takeSignificant(); const labelMatch = label.exec(child.content); @@ -178,11 +183,15 @@ function parseAction(context: ParserContext, line: SourceLine): ScreenActionSynt text = operandText(labelMatch, 1); } else if (firstWord(child.content) === 'navigate') { target = parseNavigate(context, child.content, child) ?? null; + } else if (firstWord(child.content) === 'with') { + const input = pattern('^with\\s+([A-Za-z_]\\w*)\\s+from\\s+(.+)$').exec(child.content); + if (input !== null) inputs.push({ kind: 'InteractionArgumentSyntax', name: input[1], binding: input[2].trim(), location: locationOf(child) }); + else context.error(DiagnosticCodes.InvalidInteractionArgument, `Invalid argument '${child.content}' - expected 'with from '`, locationOf(child)); } else { context.error(DiagnosticCodes.UnknownActionDirective, `Unexpected '${child.content}' in action - expected 'label "..."' or 'navigate to ...'`, locationOf(child)); } } - return { kind: 'ScreenActionSyntax', command: match[1], label: text, navigate: target, location: locationOf(line) }; + return { kind: 'ScreenActionSyntax', command: match[1], label: text, navigate: target, ...(parsed.subject === undefined ? {} : { subject: parsed.subject }), ...(inputs.length === 0 ? {} : { inputs }), location: locationOf(line) }; } function parseNavigate(context: ParserContext, text: string, line: SourceLine): ScreenNavigateSyntax | undefined { @@ -500,13 +509,14 @@ function parseToolbarButton(context: ParserContext, line: SourceLine): ToolbarBu } function parseToolbarItem(context: ParserContext, line: SourceLine): ToolbarItemSyntax | undefined { - const match = toolbarItem.exec(line.content); + const parsed = parseSubjectClause(context, line, /^item\s+\S+\s+action\s/u.test(line.content)); + const match = toolbarItem.exec(parsed.header); if (match === null) { context.error(DiagnosticCodes.UnknownScreenDirective, `Invalid toolbar item '${line.content}' - expected 'item action ', 'item navigate to ', 'item dialog ' or 'button title "" slice '`, locationOf(line)); context.skipBlock(line.indent); return undefined; } - let itemLabel = null; + let itemLabel: string | null = parsed.label ?? null; let icon = null; let itemConfirm: string | undefined; const parameters: ScreenNavigationParameterSyntax[] = []; @@ -535,7 +545,7 @@ function parseToolbarItem(context: ParserContext, line: SourceLine): ToolbarItem parsePresentationValue(context, child, presentationValues); } const syntaxKind: ToolbarItemKind = match[2] === 'navigate' ? 'Navigate' : match[2] === 'dialog' ? 'Dialog' : 'Action'; - return { kind: 'ToolbarItemSyntax', name: match[1], syntaxKind, target: match[3], label: itemLabel, icon, ...(itemConfirm !== undefined ? { confirm: itemConfirm } : {}), parameters, presentation: presentationValues, location: locationOf(line) }; + return { kind: 'ToolbarItemSyntax', name: match[1], syntaxKind, target: match[3], label: itemLabel, icon, ...(parsed.subject === undefined ? {} : { subject: parsed.subject }), ...(itemConfirm !== undefined ? { confirm: itemConfirm } : {}), parameters, presentation: presentationValues, location: locationOf(line) }; } function parseUiBindingValue(context: ParserContext, text: string, line: SourceLine) { diff --git a/Source/Screenplay/Compiler/ScreenActionSubjects.ts b/Source/Screenplay/Compiler/ScreenActionSubjects.ts new file mode 100644 index 000000000..67cd91d07 --- /dev/null +++ b/Source/Screenplay/Compiler/ScreenActionSubjects.ts @@ -0,0 +1,60 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { Diagnostic } from './Diagnostics/Diagnostic'; +import { DiagnosticCodes } from './Diagnostics/DiagnosticCodes'; +import { ActionSubjectInputs } from './Parsing/ActionSubjectInputs'; +import { RefusalDeclarations } from './Parsing/RefusalDeclarations'; +import type { CompilationResult } from './ScreenplayCompiler'; +import { ScreenDataSyntax, ScreenDirectiveSyntax, ScreenGuardedActionSyntax, ToolbarItemSyntax } from './Syntax/Screens'; +import { ApplicationSyntax, FeatureSyntax, SliceSyntax } from './Syntax/Structure'; + +/** Resolves effective action subjects and inputs without modifying authored syntax. */ +export function resolveActionSubjects(application: ApplicationSyntax): CompilationResult { + const diagnostics: Diagnostic[] = []; + const resolver = new ActionSubjectInputs(new RefusalDeclarations(application), diagnostics); + + function toolbar(item: ToolbarItemSyntax, subjects: readonly ScreenDataSyntax[], slice: SliceSyntax): ToolbarItemSyntax { + if (item.syntaxKind !== 'Action') return item; + const subject = resolver.subject(item.subject, item.target, subjects, slice, item.location); + if (subject !== 'Item') return { ...item, subject }; + const authored = item.parameters.map(parameter => ({ kind: 'InteractionArgumentSyntax' as const, name: parameter.name, binding: '', location: parameter.location })); + const inferred = resolver.inputs(item.target, authored, subjects, slice, item.location).slice(authored.length); + return { ...item, subject, parameters: [...item.parameters, ...inferred.map(input => ({ kind: 'ScreenNavigationParameterSyntax' as const, name: input.name, binding: { kind: 'UiBindingSyntax' as const, bindingKind: 'DataContext' as const, path: input.binding, query: null, componentId: null, componentPropertyPath: null, mode: null, nullBehavior: null, expectedValueType: null, literal: null, rawText: null, location: input.location }, location: input.location }))] }; + } + + function guarded(action: ScreenGuardedActionSyntax, subjects: readonly ScreenDataSyntax[], slice: SliceSyntax): ScreenGuardedActionSyntax { + if (action.subject === 'Screen' && subjects.length === 1 && subjects[0].type.isCollection) { + diagnostics.push({ severity: 'warning', code: DiagnosticCodes.UnsupportedActionSubjectContext, message: "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", location: action.location }); + return action; + } + return { ...action, subject: action.subject ?? 'Item', alternatives: action.alternatives.map(alternative => ({ ...alternative, arguments: resolver.inputs(alternative.command, alternative.arguments, subjects, slice, alternative.location) })), otherwise: action.otherwise?.command != null ? { ...action.otherwise, arguments: resolver.inputs(action.otherwise.command, action.otherwise.arguments, subjects, slice, action.otherwise.location) } : action.otherwise }; + } + + function container(nodes: readonly ScreenDirectiveSyntax[], inherited: readonly ScreenDataSyntax[], slice: SliceSyntax): readonly ScreenDirectiveSyntax[] { + const local = nodes.filter((node): node is ScreenDataSyntax => node.kind === 'ScreenDataSyntax'); + const subjects = local.length === 0 ? inherited : local; + return nodes.map(node => { + switch (node.kind) { + case 'ScreenActionSyntax': { + const subject = resolver.subject(node.subject, node.command, subjects, slice, node.location); + const inputs = subject === 'Item' ? resolver.inputs(node.command, node.inputs ?? [], subjects, slice, node.location) : node.inputs; + return { ...node, subject, ...(inputs === undefined ? {} : { inputs }) }; + } + case 'ScreenGuardedActionSyntax': return guarded(node, subjects, slice); + case 'ScreenToolbarSyntax': return { ...node, items: node.items.map(item => toolbar(item, subjects, slice)) }; + case 'ScreenSectionSyntax': return { ...node, directives: container(node.directives, subjects, slice) }; + case 'ScreenTemplateReferenceSyntax': return { ...node, slots: node.slots.map(slot => ({ ...slot, directives: container(slot.directives, subjects, slice) })) }; + case 'ScreenComponentSyntax': return { ...node, outlets: node.outlets.map(outlet => ({ ...outlet, directives: container(outlet.directives, subjects, slice) })) }; + default: return node; + } + }); + } + + function feature(node: FeatureSyntax): FeatureSyntax { + return { ...node, features: node.features.map(feature), slices: node.slices.map(slice => ({ ...slice, screens: slice.screens.map(screen => ({ ...screen, directives: container(screen.directives, [], slice), ...(screen.contributions === undefined ? {} : { contributions: screen.contributions.map(contribution => ({ ...contribution, directives: container(contribution.directives, [], slice) })) }) })) })) }; + } + + const value = { ...application, modules: application.modules.map(module => ({ ...module, features: module.features.map(feature) })) }; + return { value, diagnostics, success: !diagnostics.some(diagnostic => diagnostic.severity === 'error') }; +} diff --git a/Source/Screenplay/Compiler/Syntax/ScreenplaySyntaxWalker.ts b/Source/Screenplay/Compiler/Syntax/ScreenplaySyntaxWalker.ts index f26a61eb8..6b95736df 100644 --- a/Source/Screenplay/Compiler/Syntax/ScreenplaySyntaxWalker.ts +++ b/Source/Screenplay/Compiler/Syntax/ScreenplaySyntaxWalker.ts @@ -625,6 +625,7 @@ export abstract class ScreenplaySyntaxWalker { this.visitTypeRef(syntax.type); break; case 'ScreenActionSyntax': + syntax.inputs?.forEach(input => this.visitInteractionArgument(input)); if (syntax.navigate !== null) this.visitScreenDirective(syntax.navigate); break; case 'ScreenNavigateSyntax': diff --git a/Source/Screenplay/Compiler/Syntax/Screens.ts b/Source/Screenplay/Compiler/Syntax/Screens.ts index ad3025f76..4297c030f 100644 --- a/Source/Screenplay/Compiler/Syntax/Screens.ts +++ b/Source/Screenplay/Compiler/Syntax/Screens.ts @@ -45,8 +45,12 @@ export interface ScreenDataSyntax extends SyntaxNode { } // 'action ' with an optional 'label "..."' and 'navigate to ...'. +export type ScreenActionSubjectKind = 'Item' | 'Screen'; + export interface ScreenActionSyntax extends SyntaxNode { readonly kind: 'ScreenActionSyntax'; + readonly subject?: ScreenActionSubjectKind | null; + readonly inputs?: readonly InteractionArgumentSyntax[]; readonly command: string; readonly label: string | null; readonly navigate: ScreenNavigateSyntax | null; @@ -55,6 +59,7 @@ export interface ScreenActionSyntax extends SyntaxNode { // One labeled action with ordered command alternatives. export interface ScreenGuardedActionSyntax extends SyntaxNode { readonly kind: 'ScreenGuardedActionSyntax'; + readonly subject?: ScreenActionSubjectKind | null; readonly label: string; readonly alternatives: readonly ScreenActionAlternativeSyntax[]; readonly otherwise: ScreenActionOtherwiseSyntax | null; @@ -201,6 +206,7 @@ export type ToolbarItemKind = 'Unknown' | 'Action' | 'Navigate' | 'Dialog'; export interface ToolbarItemSyntax extends SyntaxNode { readonly kind: 'ToolbarItemSyntax'; + readonly subject?: ScreenActionSubjectKind | null; readonly name: string; readonly syntaxKind: ToolbarItemKind; readonly target: string; diff --git a/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts b/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts index 54447724f..9e4b4453f 100644 --- a/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts +++ b/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts @@ -2,4 +2,4 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // Generated from C# SyntaxSchema; all typed member contracts are native-owned. -export const syntaxCollections = {"kinds":["AddMappingSyntax","AllSyntax","ApplicationSyntax","ApplicationTriggerInteractionTriggerSyntax","ArrangementContainerSyntax","ArrangementOverrideSyntax","ArrangementSlotSyntax","ArrangementSyntax","AuthenticatedConditionSyntax","AuthenticationProviderSyntax","AuthenticationSyntax","AuthorizeSyntax","NavigationItemSyntax","NavigationLogoSyntax","NavigationRegionSyntax","NavigationTargetSyntax","BehaviorArgumentSyntax","BehaviorParameterSyntax","BehaviorSyntax","BuiltInInteractionTriggerSyntax","CaptureAppendSyntax","CaptureChildrenSyntax","CaptureMapEntrySyntax","CaptureNestedSyntax","CaptureSourceSettingSyntax","CaptureSourceSyntax","CaptureSplitSyntax","CaptureSyntax","CaptureTranslationSyntax","CaptureWhenSyntax","CausedByExpressionSyntax","ClockOffsetExpressionSyntax","CommandCalendarSyntax","DateOfExpressionSyntax","SpecificationTimeZoneSyntax","TimeZoneSyntax","CaseValueExpressionSyntax","ChildrenSyntax","ClaimConditionSyntax","ClaimIdentitySourceSyntax","CodeIdentitySourceSyntax","FileIdentitySourceSyntax","IdentitySyntax","IdentityDetailSyntax","QueryIdentitySourceSyntax","ClearMappingSyntax","ClearWithSyntax","CloseDialogActionSyntax","CodeBlockSyntax","ComponentExposedValueSyntax","ComponentOutletSyntax","ComponentPropertySyntax","CodeValidateSyntax","CommandSyntax","CommandStreamSyntax","ObserverFilterSyntax","ComparisonConditionSyntax","CompositeKeySyntax","ConceptAttributeSyntax","ConceptSyntax","GenerationSyntax","ConcurrencySyntax","ConfirmActionSyntax","ContextExpressionSyntax","IdentityExpressionSyntax","ContributionSyntax","ContributionDestinationSyntax","CountMappingSyntax","DeclarativeValidateSyntax","DecrementMappingSyntax","DialogTemplateSyntax","DomainSyntax","EnvironmentExpressionSyntax","EventContextExpressionSyntax","EventInteractionTriggerSyntax","EventSourceIdExpressionSyntax","EventSourceSyntax","EventStreamIdPartSyntax","EventStreamSyntax","EventSpecSyntax","EventSyntax","EverySyntax","ExecuteCommandActionSyntax","ExpressionKeySyntax","FeatureSyntax","FileConstraintSyntax","FileImportSyntax","FileReferenceSyntax","FormColumnSyntax","ExposureSyntax","ExposedPropertySyntax","InstanceContributionsSyntax","InstanceContributionSyntax","ContributedItemSyntax","ContributedItemValueSyntax","ScreenContributionSyntax","TemplateSlotContentSyntax","CommandFormLayoutSyntax","FormLayoutColumnSyntax","FormFieldPlacementSyntax","FormWidthSyntax","FormFieldSyntax","FormPopulateFromItemSyntax","FormPopulateViaQuerySyntax","FormSyntax","FromSyntax","HandlerSyntax","ImplementationSyntax","ImplementationHintSyntax","SystemSyntax","OperationSyntax","OperationPhaseSyntax","SpecificationExampleSyntax","SpecificationParameterSyntax","SpecificationCaseSyntax","SpecificationOperationFailureSyntax","SpecificationOperationSyntax","SpecificationCompensatedSyntax","ImportSyntax","IncrementMappingSyntax","InteractionAlternativeSyntax","InteractionOtherwiseSyntax","InteractionArgumentSyntax","InteractionBindingSyntax","IntervalInteractionTriggerSyntax","IntervalTriggerSourceSyntax","InvokesSyntax","InvocationRefusalSyntax","JoinEventSyntax","JoinSyntax","KeyPartSyntax","LayoutSyntax","ListExpressionSyntax","LiteralExpressionSyntax","LogicalConditionSyntax","LogicalPolicyConditionSyntax","LogicalPolicyRequirementSyntax","ModuleSyntax","NamedTriggerSourceSyntax","NavigateActionSyntax","NavigateBackActionSyntax","NestedSyntax","NotPolicyConditionSyntax","NotifyActionSyntax","OpenDialogActionSyntax","ObjectExpressionSyntax","ObjectMemberSyntax","PathExpressionSyntax","PerformerSyntax","PersonaSyntax","StickyNoteSyntax","PlaceSyntax","PolicyReferenceSyntax","PolicySyntax","PurposeSyntax","PurposeReferenceSyntax","PurposeTransferSyntax","ProducesSyntax","ProjectionEntersOnSyntax","ProjectionSyntax","ProjectionVariantSyntax","PresentationValueSyntax","PropertyMappingSyntax","PropertySyntax","PropertyResponseSourceSyntax","ResponseFieldSyntax","ScalarCommandResponseSyntax","RecordCommandResponseSyntax","ScalarSpecificationReturnSyntax","RecordSpecificationReturnSyntax","QueryParameterSyntax","QuerySyntax","RaiseTriggerActionSyntax","RawExpressionSyntax","ReactionIdentitySyntax","ReactionSyntax","ReactionTriggerSyntax","RefusalExpressionSyntax","ReadModelSyntax","ReadsSyntax","ReducerRuleSyntax","ReducerSyntax","RefreshQueryActionSyntax","RemoveViaJoinSyntax","RemoveWithSyntax","RequirementSyntax","RoleConditionSyntax","ScheduleTriggerSourceSyntax","ScreenActionSyntax","ScreenNavigationParameterSyntax","ScreenGuardedActionSyntax","ScreenActionAlternativeSyntax","ScreenActionOtherwiseSyntax","ScreenBehaviorSyntax","ScreenCodeSyntax","ScreenComponentSyntax","ScreenColumnSyntax","ScreenDataSyntax","ScreenFieldSyntax","ScreenNavigateSyntax","ScreenSectionSyntax","ScreenSlotSyntax","ScreenSummarySyntax","ScreenSyntax","ScreenTableSyntax","ScreenTemplateReferenceSyntax","ScreenTemplateSyntax","ScreenTitleSyntax","ScreenToolbarSyntax","ScreenUsesBehaviorSyntax","SeedEventSyntax","SeedGroupSyntax","SeedSyntax","SetMappingSyntax","TemplateAssignmentSyntax","TemplateExposedValueSyntax","TemplateOutletSyntax","SetStateActionSyntax","SliceSyntax","SlotSyntax","SourceItemExpressionSyntax","SpecificationAbsentReadModelSyntax","SpecificationCallerClaimSyntax","SpecificationCallerPersonaSyntax","SpecificationCallerSyntax","SpecificationCaptureSyntax","SpecificationClockSyntax","SpecificationGeneratedValueSyntax","SpecificationCommandSyntax","SpecificationDeniedSyntax","SpecificationErrorSyntax","SpecificationEventSyntax","NewScreenTemplateSyntax","ProfileAppearanceSyntax","ProfileIdentitySyntax","RootTemplateSyntax","SampleDataBindingSyntax","ShellOptionSyntax","SampleDataFieldSyntax","SampleDataMappingSyntax","SampleDataPackReferenceSyntax","SampleDataPackSyntax","SampleDataRowSyntax","SampleDataSelectionSyntax","SampleDataSetSyntax","SpecificationNoResultSyntax","SpecificationStreamSyntax","SpecificationNoStreamSyntax","SpecificationQueryResultSyntax","SpecificationQuerySyntax","SpecificationReadModelSyntax","SpecificationRedeliverySyntax","SpecificationSyntax","SpecificationTriggerSyntax","SpecificationWhenQuerySyntax","StringsExpressionSyntax","SubtractMappingSyntax","TagSyntax","ToolbarButtonSyntax","ToolbarItemSyntax","TemplateExpressionSyntax","TemplateInterpolationSyntax","TemplateTextSyntax","ThemeSyntax","TriggerDataSyntax","TriggerSyntax","TypeRefSyntax","TypeSyntax","UiBindingSyntax","UiProfileSyntax","UniqueEventConstraintSyntax","UniquePropertyConstraintSyntax","DependsOnSyntax","UsesBehaviorSyntax","ValidationRuleSyntax","VariantSyntax","AnonymousConditionSyntax"],"names":["factor","property","value","autoMap","mappings","authentication","behaviors","commandReadMode","concepts","domain","eventSources","examples","exposures","fileImports","identity","imports","instanceContributions","layouts","modules","personas","policies","purposes","reactionProductionMode","sampleDataPacks","seeds","sourceOptions","numericMode","stickyNotes","systems","templates","themes","timeZone","triggers","types","uiProfiles","triggerName","children","columns","gap","grow","rows","span","syntaxKind","height","root","width","growFactor","name","mode","overrides","variants","alias","providers","requirement","icon","id","slot","target","title","image","buttons","items","logo","region","feature","module","type","bindings","description","file","order","parameters","event","tags","when","appends","identifiedBy","map","source","translations","settings","separator","targets","key","keyIsEventSource","nested","from","to","expression","fromValue","properties","toValue","amount","clock","unit","contextMember","operand","configurable","parameter","blocks","claim","matches","matchesSubject","code","details","by","query","arguments","onFailure","onResult","onSuccess","language","binding","directives","authorize","calendar","concurrency","documentation","handler","produces","reads","response","stream","streamCandidates","validations","eventSource","propertyCandidate","streamId","streamIdParts","left","leftExpression","operator","right","parts","criminal","reason","scope","specialCategory","attributes","generation","valueNumbers","values","alphabet","case","checksum","count","encoding","pattern","prefix","range","rule","size","strategy","eventSourceType","eventStreamId","eventStreamType","eventTypes","message","messageIsLiteral","path","contributionPoint","destination","group","label","navigate","presentation","requirements","rules","arrangement","category","content","displayName","exposes","outlets","restrictsScopes","scopes","sliceKinds","slots","templateType","usedBehaviors","eventName","identifier","streams","x","y","hasGenerationMarker","origin","visibility","includeChildren","command","contributions","dependsOn","features","isPlacement","slices","toolbars","additionalRules","ignoreCasing","releasedBy","owner","component","editableFields","isCollection","operations","reExposes","restrictsFields","instance","field","columnGap","placements","rowGap","index","maxWidth","minWidth","column","columnSpan","row","rowSpan","composeUsing","columnMode","fields","for","generationMode","layout","onSubmit","populate","events","parentKey","implementation","hints","text","compensate","execute","inputs","uses","generatedValues","noStream","operation","qualifiedName","actions","condition","alternatives","otherwise","trigger","onRefused","acknowledge","constraint","selector","on","navigation","literalType","dialogTemplates","forms","screenTemplates","screen","level","dialogTemplate","members","goals","canvas","colour","hidden","sizeHeight","sizeWidth","slotName","authorization","basis","basisReference","conditionReference","erasureException","interest","recipients","retention","subjects","transfers","safeguard","inlineEvent","inlineOperation","readModel","sequence","entersOn","isGenerated","isIdentifier","isKey","isSubject","byParts","filters","isObservable","performer","returnType","roles","runsAs","where","data","invokes","member","partsKey","severity","role","dayOfMonth","dayOfWeek","time","outcome","behavior","context","stableId","outlet","route","rowClick","blueprint","version","fitsSlot","eventSourceId","groups","captures","commands","constraints","direction","projections","queries","reactions","readModels","reducers","screens","specifications","contributes","authenticated","claims","capture","record","instant","commandType","inlineProperty","caseValue","eventType","accent","colorScheme","corners","font","logoKind","logoValue","showName","options","pack","shape","isBlueprint","locale","sets","active","exactly","results","reaction","cases","given","givenCaller","givenCallerPersona","givenCaptures","givenClock","givenGenerated","givenOperationFailures","givenReadModels","givenTimeZone","thenAbsentReadModels","thenCompensated","thenDenied","thenErrors","thenEvents","thenEventsInAnyOrder","thenNoEvents","thenNoResult","thenOperations","thenQueries","thenReadModels","thenResults","thenReturns","whenAppended","whenCapture","whenClock","whenQuery","whenRedelivered","whenTrigger","confirm","emphasis","slice","compatibleWith","isOptional","bindingKind","componentId","componentPropertyPath","expectedValueType","literal","nullBehavior","rawText","appearance","defaultSizeClass","icons","newScreenTemplate","packages","platforms","sampleData","theme","additionalProperties","places"],"rules":[["ref",30,31,33,36,63,64,72,73,75,132,133,145,147,173,177,220,255,260],["null"],["union",0,1],["string"],["object",[[0,2,false],[1,3,true],[2,0,true]]],["enum","Inherit","Disabled","Enabled"],["ref",0,45,67,69,119,213,256],["array",6],["object",[[3,5,true],[4,7,false]]],["ref",10],["union",9,1],["ref",18],["array",11],["enum","Protected"],["union",13,1],["ref",59],["array",15],["ref",71],["union",17,1],["ref",76],["array",19],["ref",112],["array",21],["ref",89],["array",23],["ref",86],["array",25],["ref",42],["union",27,1],["ref",118],["array",29],["ref",91],["array",31],["ref",131],["array",33],["union",34,1],["ref",137],["array",36],["ref",149],["array",38],["union",39,1],["ref",153],["array",41],["ref",154],["array",43],["enum","Atomic"],["union",45,1],["ref",241],["array",47],["ref",212],["array",49],["union",50,1],["enum","legacy","exact"],["object",[[26,52,true]]],["ref",150],["array",54],["ref",109],["array",56],["ref",214],["array",58],["ref",263],["array",60],["union",61,1],["ref",35],["union",63,1],["ref",265],["array",65],["union",66,1],["ref",267],["array",68],["union",69,1],["ref",269],["array",71],["union",72,1],["object",[[5,10,false],[6,12,false],[7,14,false],[8,16,false],[9,18,false],[10,20,false],[11,22,false],[12,24,false],[13,26,false],[14,28,false],[15,30,false],[16,32,false],[17,35,false],[18,37,false],[19,40,false],[20,42,false],[21,44,false],[22,46,false],[23,48,false],[24,51,false],[25,53,false],[27,55,false],[28,57,false],[29,59,false],[30,62,false],[31,64,false],[32,67,false],[33,70,false],[34,73,false]]],["object",[[35,3,true]]],["ref",4,6],["array",76],["integer",-2147483648,2147483647],["union",78,1],["number"],["union",80,1],["enum","Flat","Row","Column","Grid"],["object",[[36,77,false],[37,79,false],[38,79,false],[39,81,false],[40,79,false],[41,79,false],[42,82,true]]],["union",3,1],["object",[[43,84,false],[44,76,true],[45,84,false]]],["boolean"],["object",[[39,86,false],[46,81,false],[43,79,false],[47,3,true],[41,79,false],[45,79,false]]],["enum","Flow","Freeform"],["ref",5],["array",89],["union",90,1],["union",76,1],["ref",275],["array",93],["union",94,1],["object",[[48,88,true],[49,91,false],[44,92,false],[50,95,false]]],["object",[]],["object",[[51,84,false],[47,3,true]]],["ref",9],["array",99],["object",[[52,100,false]]],["ref",136,152],["object",[[53,102,true]]],["ref",12],["array",104],["ref",15],["union",106,1],["object",[[36,105,false],[54,84,false],[55,3,true],[56,84,false],[57,107,false],[58,3,true]]],["object",[[59,3,true],[58,3,true]]],["ref",258],["array",110],["ref",13],["union",112,1],["enum","Unspecified","Inherit","Extend","Override"],["enum","Topbar","Sidebar"],["object",[[60,111,false],[61,105,false],[62,113,false],[48,114,true],[63,115,true]]],["object",[[64,84,false],[65,3,true]]],["object",[[47,3,true],[2,3,true]]],["ref",266],["union",119,1],["object",[[47,3,true],[66,120,false]]],["ref",123],["array",122],["ref",87],["union",124,1],["ref",17],["array",126],["object",[[67,123,false],[68,84,false],[69,125,false],[47,84,false],[70,79,false],[71,127,false]]],["enum","Click","DoubleClick","Select","Submit","Change","Load","Unload","Enter","Leave","Unknown"],["object",[[42,129,true]]],["ref",162],["array",131],["ref",257],["array",133],["union",134,1],["ref",29],["union",136,1],["object",[[72,3,true],[4,132,false],[73,135,false],[74,137,false]]],["ref",20],["array",139],["ref",22,26],["array",141],["object",[[75,140,false],[76,3,true],[77,142,false],[1,3,true]]],["ref",28],["array",144],["object",[[1,3,true],[78,0,true],[79,145,false]]],["object",[[75,140,false],[77,142,false],[1,3,true]]],["ref",24],["array",148],["object",[[80,149,false],[42,3,true]]],["array",3],["object",[[81,3,true],[78,0,true],[82,151,false]]],["ref",21],["array",153],["ref",23],["array",155],["ref",25],["union",157,1],["object",[[75,140,false],[36,154,false],[83,84,false],[84,86,false],[77,142,false],[47,3,true],[85,156,false],[78,158,false],[25,53,false]]],["object",[[86,3,true],[87,3,true]]],["enum","PropertyChanged","Added","Removed","Changed","LogicalOr","LogicalAnd","ValueTransition","Expression"],["object",[[88,84,false],[89,84,false],[90,151,false],[42,161,true],[91,84,false]]],["object",[[1,84,false]]],["object",[[92,78,true],[93,3,true],[94,3,true]]],["object",[[95,84,false],[55,84,false]]],["object",[[96,0,true]]],["object",[[55,3,true]]],["object",[[97,86,true],[55,3,true]]],["object",[[98,3,true]]],["ref",1,37,46,81,105,129,141,160,183,184],["array",170],["object",[[3,5,true],[99,171,false],[76,0,true],[1,3,true]]],["object",[[100,3,true],[101,2,false],[102,86,true]]],["object",[[100,3,true]]],["ref",48],["object",[[103,175,true]]],["object",[[69,124,true]]],["ref",43],["array",178],["object",[[68,84,false],[104,179,false]]],["ref",39,40,41,44],["object",[[47,3,true],[78,181,true],[66,119,true]]],["object",[[105,0,true],[106,3,true]]],["object",[[1,3,true]]],["object",[[72,3,true]]],["ref",122],["array",186],["ref",47,62,82,139,140,143,144,172,182,217],["array",188],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false]]],["object",[[103,3,true],[111,3,true]]],["ref",268],["object",[[112,192,true],[47,3,true]]],["ref",188,190,193,194,195,197,199,200,201,202,204,205,207,208,209],["array",194],["object",[[113,195,false],[47,3,true]]],["union",192,1],["object",[[112,197,false],[1,3,true],[2,2,false]]],["ref",11],["union",199,1],["ref",32],["union",201,1],["ref",61],["union",203,1],["ref",106],["union",205,1],["ref",157],["array",207],["ref",163],["array",209],["ref",179],["array",211],["union",212,1],["ref",166,167],["union",214,1],["ref",54],["union",216,1],["array",216],["ref",52,68],["array",219],["object",[[114,200,false],[115,202,false],[116,204,false],[68,84,false],[117,84,false],[118,206,false],[47,3,true],[119,208,false],[90,210,false],[120,213,false],[121,215,false],[122,217,false],[123,218,false],[124,220,false]]],["union",209,1],["union",131,1],["object",[[125,3,true],[126,222,false],[122,3,true],[127,223,false],[128,132,false]]],["object",[[125,3,true],[122,84,false]]],["enum","Equal","NotEqual","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Contains","StartsWith"],["object",[[129,3,true],[130,2,false],[131,226,true],[132,0,true]]],["ref",130],["array",228],["object",[[133,229,false],[66,3,true]]],["object",[[134,86,false],[47,3,true],[135,84,false],[136,84,false],[137,84,false]]],["ref",58],["array",232],["ref",60],["union",234,1],["union",220,1],["array",78],["union",237,1],["object",[[138,233,false],[68,84,false],[69,125,false],[139,235,false],[47,3,true],[66,3,true],[124,236,false],[140,238,false],[141,151,false]]],["union",175,1],["object",[[142,84,false],[143,84,false],[144,84,false],[103,240,false],[145,79,false],[146,84,false],[69,125,false],[147,84,false],[148,84,false],[149,84,false],[150,84,false],[151,79,false],[152,3,true]]],["object",[[125,86,true],[153,84,false],[154,84,false],[155,84,false],[156,151,false]]],["object",[[107,187,false],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[159,3,true]]],["ref",66],["union",245,1],["ref",199],["union",247,1],["object",[[160,3,true],[161,246,false],[162,84,false],[54,84,false],[55,84,false],[163,84,false],[164,248,false],[70,79,false],[165,84,false]]],["enum","Outlet","Dialog","External"],["object",[[42,250,true],[57,3,true]]],["ref",185],["array",252],["union",253,1],["ref",274],["array",255],["object",[[166,254,false],[167,256,false]]],["ref",7],["union",258,1],["ref",96],["array",260],["ref",215],["array",262],["ref",216],["array",264],["ref",219],["array",266],["ref",273],["array",268],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["object",[[47,3,true]]],["object",[[180,3,true]]],["ref",78],["array",273],["object",[[68,84,false],[55,84,false],[181,120,false],[47,3,true],[182,274,false],[183,79,false],[184,79,false]]],["object",[[47,3,true],[66,119,true]]],["ref",77],["array",277],["object",[[68,84,false],[55,84,false],[47,3,true],[127,120,false],[128,278,false]]],["object",[[72,3,true],[83,2,false]]],["integer",0,4294967295],["enum","Private","Public"],["object",[[68,84,false],[117,84,false],[69,125,false],[139,281,false],[185,86,false],[55,84,false],[47,3,true],[186,84,false],[90,210,false],[73,135,false],[187,282,false]]],["object",[[3,5,true],[188,86,true],[4,7,false]]],["object",[[107,187,false],[189,3,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[88,0,true]]],["ref",65],["array",287],["union",288,1],["ref",272],["array",290],["ref",84],["array",292],["ref",155],["array",294],["ref",218],["array",296],["ref",208],["array",298],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[193,86,true],[47,3,true],[21,295,false],[194,297,false],[29,59,false],[195,299,false],[179,269,false]]],["ref",85,270,271],["array",301],["object",[[196,302,false],[68,84,false],[69,124,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[147,3,true]]],["object",[[163,84,false],[1,3,true]]],["ref",90],["array",306],["object",[[199,3,true],[90,307,false]]],["object",[[200,3,true],[201,151,false],[202,86,true],[163,84,false],[203,151,false],[159,3,true],[204,84,false],[205,86,true]]],["ref",92],["array",310],["object",[[190,311,false],[206,3,true]]],["ref",93],["array",313],["object",[[200,3,true],[61,314,false],[159,3,true],[2,2,false]]],["ref",94],["array",316],["object",[[55,3,true],[141,317,false]]],["object",[[207,3,true],[2,0,true]]],["object",[[160,3,true],[113,195,false],[70,79,false]]],["object",[[113,195,false],[56,3,true]]],["ref",100],["union",322,1],["ref",98],["array",324],["ref",99],["array",326],["object",[[208,323,false],[37,325,false],[209,327,false],[210,323,false]]],["object",[[211,78,true],[212,323,false],[213,323,false],[45,323,false]]],["object",[[214,78,true],[215,79,false],[207,3,true],[216,78,true],[217,79,false],[45,323,false]]],["enum","Fraction","Pixels","Percent","Auto"],["object",[[94,331,true],[2,81,false]]],["object",[[218,84,false],[86,84,false],[163,84,false],[1,3,true]]],["object",[[105,84,false],[106,3,true]]],["enum","Unspecified","Auto","Manual"],["ref",88],["array",336],["ref",101],["array",338],["ref",97],["union",340,1],["ref",102,103],["union",342,1],["object",[[6,12,false],[219,335,true],[37,337,false],[68,84,false],[220,339,false],[221,3,true],[222,335,true],[223,341,false],[47,3,true],[224,248,false],[225,343,false],[179,269,false]]],["ref",79],["array",345],["ref",57,83],["union",347,1],["object",[[226,346,false],[83,348,false],[4,7,false],[227,2,false]]],["ref",107],["union",350,1],["object",[[103,240,false],[69,125,false],[228,351,false]]],["ref",108],["array",353],["object",[[229,354,false]]],["object",[[230,3,true]]],["object",[[68,84,false],[47,3,true]]],["ref",111],["union",358,1],["object",[[231,359,false],[68,84,false],[232,359,false],[233,210,false],[47,3,true],[234,3,true]]],["object",[[103,240,false],[68,84,false],[69,125,false],[228,351,false]]],["ref",247],["union",362,1],["ref",246],["union",364,1],["object",[[68,84,false],[221,2,false],[235,132,false],[47,3,true],[236,363,false],[122,365,false],[66,3,true],[141,132,false]]],["object",[[47,3,true],[141,132,false]]],["object",[[237,3,true]]],["object",[[237,3,true],[141,132,false]]],["object",[[186,84,false],[238,3,true],[187,282,false]]],["ref",56,134],["object",[[239,189,false],[240,371,true]]],["object",[[239,189,false]]],["object",[[112,3,true],[47,3,true]]],["ref",120],["array",375],["ref",121],["union",377,1],["ref",3,19,74,124],["object",[[239,189,false],[241,376,false],[240,84,false],[242,378,false],[243,379,true]]],["enum","Seconds","Minutes","Hours","Days"],["object",[[92,78,true],[94,381,true]]],["ref",127],["array",383],["object",[[189,3,true],[4,132,false],[244,384,false]]],["object",[[245,86,true],[246,84,false],[119,208,false],[247,3,true]]],["object",[[3,5,true],[72,3,true],[4,7,false]]],["ref",128],["array",388],["object",[[226,389,false],[248,3,true],[1,3,true]]],["object",[[88,0,true],[1,3,true]]],["ref",14],["array",392],["object",[[168,259,false],[6,12,false],[169,84,false],[172,263,false],[47,3,true],[249,393,false],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["array",0],["object",[[61,395,false]]],["union",3,86,1],["number",-1.7976931348623157E+308,1.7976931348623157E+308],["enum","Int32","Int64","Decimal","Single"],["string","^-?[0-9]\u002B(\\.[0-9]\u002B)?([Ee][\u002B-]?[0-9]\u002B)?$"],["object",[[250,399,true],[2,400,true]]],["const","ExactNumber"],["string","^(?:0|-?(?:[1-9][0-9]{0,28}|(?:0|[1-9][0-9]{0,28})\\.[0-9]{0,27}[1-9]))$"],["object",[[250,402,true],[2,403,true]]],["union",397,398,401,404],["object",[[2,405,false]]],["enum","And","Or"],["object",[[129,371,true],[131,407,true],[132,371,true]]],["ref",8,38,135,142,186,276],["object",[[129,409,true],[131,407,true],[132,409,true]]],["object",[[129,102,true],[131,407,true],[132,102,true]]],["ref",70],["array",412],["union",413,1],["ref",104],["array",415],["union",416,1],["ref",206],["array",418],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[251,414,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[252,417,false],[193,86,true],[47,3,true],[249,393,false],[21,295,false],[253,419,false],[29,59,false],[195,299,false],[179,269,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[254,3,true]]],["object",[[3,5,true],[99,171,false],[1,3,true]]],["object",[[96,409,true]]],["enum","Info","Warning","Error","Unknown"],["object",[[107,187,false],[255,424,true],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[107,187,false],[256,3,true],[108,189,false],[109,189,false],[110,189,false]]],["ref",146],["array",427],["object",[[257,428,false]]],["object",[[47,3,true],[2,0,true]]],["object",[[103,240,false],[69,125,false]]],["object",[[68,84,false],[258,151,false],[43,79,false],[47,3,true],[20,151,false],[45,79,false],[183,79,false],[184,79,false]]],["object",[[259,3,true],[260,84,false],[43,79,false],[230,3,true],[45,79,false],[183,78,true],[184,78,true]]],["object",[[261,86,false],[262,84,false],[263,84,false],[264,3,true],[183,79,false],[184,79,false]]],["union",409,1],["object",[[103,240,false],[240,435,false],[68,84,false],[69,125,false],[47,3,true]]],["ref",156],["array",437],["object",[[265,84,false],[266,84,false],[267,84,false],[240,84,false],[268,84,false],[68,84,false],[269,84,false],[270,84,false],[47,3,true],[271,151,false],[272,84,false],[273,151,false],[274,438,false]]],["object",[[161,3,true],[275,3,true]]],["ref",80],["union",441,1],["ref",110],["union",443,1],["union",371,1],["object",[[72,3,true],[221,2,false],[276,442,false],[277,444,false],[4,132,false],[122,217,false],[73,135,false],[74,445,false]]],["object",[[3,5,true],[99,171,false],[68,84,false],[69,125,false],[83,348,false],[47,3,true],[278,84,false],[279,84,false],[25,53,false]]],["ref",158],["array",448],["object",[[99,171,false],[280,449,false],[47,3,true]]],["object",[[1,3,true],[78,0,true]]],["object",[[281,86,false],[282,86,false],[283,86,false],[284,86,false],[47,3,true],[66,119,true]]],["ref",164],["object",[[47,3,true],[78,453,true],[66,120,false]]],["object",[[78,453,true]]],["ref",165],["array",456],["object",[[220,457,false]]],["object",[[2,0,true]]],["object",[[220,132,false]]],["object",[[47,3,true],[78,2,false],[66,119,true]]],["ref",170],["union",462,1],["array",462],["ref",148],["union",465,1],["object",[[114,200,false],[105,463,false],[285,464,false],[68,84,false],[286,464,false],[287,86,false],[47,3,true],[288,466,false],[289,119,true],[136,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[243,3,true]]],["object",[[290,151,false],[42,3,true]]],["ref",55],["union",470,1],["ref",174],["union",472,1],["ref",176],["array",474],["object",[[68,84,false],[117,84,false],[86,471,false],[47,3,true],[291,473,false],[32,475,false],[292,445,false]]],["ref",264],["array",477],["ref",126],["array",479],["union",480,1],["union",208,1],["ref",125,138,187],["object",[[103,240,false],[293,478,false],[68,84,false],[69,125,false],[294,481,false],[119,482,false],[120,213,false],[78,483,true]]],["object",[[295,3,true]]],["object",[[68,84,false],[117,84,false],[69,125,false],[47,3,true],[90,210,false]]],["object",[[51,84,false],[105,84,false],[285,132,false],[278,3,true]]],["object",[[103,240,false],[68,84,false],[72,3,true],[69,125,false]]],["ref",180],["array",489],["object",[[68,84,false],[86,471,false],[47,3,true],[278,3,true],[167,490,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[106,3,true]]],["ref",57],["union",493,1],["object",[[72,3,true],[83,2,false],[227,2,false],[296,494,false]]],["enum","Error","Information","Warning"],["object",[[240,371,true],[157,84,false],[297,496,true]]],["object",[[298,3,true]]],["enum","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["union",499,1],["string","^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,7})?$"],["object",[[299,79,false],[300,500,false],[301,501,true]]],["object",[[189,3,true],[163,84,false],[164,248,false]]],["ref",191],["array",504],["ref",192],["union",506,1],["object",[[241,505,false],[163,3,true],[164,248,false],[242,507,false]]],["object",[[107,187,false],[189,3,true],[240,371,true]]],["enum","Hidden","Execute","Unknown"],["object",[[107,187,false],[189,84,false],[302,510,true]]],["object",[[303,11,true]]],["ref",49],["array",513],["ref",50],["array",515],["ref",161],["array",517],["ref",51],["array",519],["object",[[6,12,false],[200,3,true],[304,197,false],[172,514,false],[54,84,false],[47,3,true],[173,516,false],[165,518,false],[90,520,false],[305,84,false],[179,269,false]]],["object",[[105,84,false],[106,3,true],[66,119,true]]],["object",[[163,3,true],[1,3,true]]],["ref",189],["array",524],["object",[[105,84,false],[306,84,false],[71,525,false],[307,84,false],[254,3,true]]],["ref",198],["array",527],["object",[[220,528,false],[57,3,true]]],["ref",95],["array",530],["object",[[190,531,false],[68,84,false],[113,195,false],[69,125,false],[47,3,true]]],["ref",196],["array",533],["object",[[6,12,false],[37,534,false],[308,248,false],[57,3,true],[179,269,false]]],["ref",201],["array",536],["object",[[309,84,false],[47,3,true],[177,537,false],[310,84,false]]],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[311,84,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["ref",259],["array",540],["object",[[60,111,false],[61,541,false],[47,3,true]]],["object",[[234,268,true]]],["object",[[72,3,true],[90,132,false]]],["ref",210],["array",545],["object",[[312,3,true],[226,546,false]]],["ref",211],["array",548],["object",[[313,549,false],[47,84,false],[183,79,false],[184,79,false]]],["object",[[309,84,false],[47,3,true],[310,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[57,3,true],[2,3,true]]],["ref",27],["array",553],["ref",53],["array",555],["enum","Inbound","Outbound"],["union",557,1],["array",441],["array",443],["ref",159],["array",561],["ref",171],["array",563],["ref",175],["array",565],["ref",178],["array",567],["union",568,1],["ref",181],["array",570],["union",571,1],["ref",203],["array",573],["ref",252],["array",575],["enum","StateChange","StateView","Automation","Translate"],["object",[[314,554,false],[315,556,false],[316,302,false],[68,84,false],[317,558,false],[117,84,false],[226,559,false],[11,22,false],[69,125,false],[47,3,true],[203,560,false],[318,562,false],[21,295,false],[319,564,false],[320,566,false],[321,569,false],[322,572,false],[323,574,false],[324,576,false],[29,59,false],[66,577,true]]],["object",[[325,84,false],[47,3,true]]],["object",[[83,0,true],[47,3,true]]],["object",[[66,3,true],[2,3,true]]],["ref",222],["array",582],["object",[[326,86,true],[327,583,false],[290,151,false]]],["object",[[328,3,true],[329,132,false]]],["object",[[330,3,true]]],["object",[[189,3,true],[1,3,true],[78,0,true]]],["object",[[331,3,true],[221,2,false],[235,132,false],[332,84,false],[141,132,false]]],["ref",36],["union",589,1],["object",[[333,590,false],[47,84,false]]],["object",[[334,3,true],[221,2,false],[332,84,false],[236,363,false],[122,365,false],[141,132,false]]],["object",[[335,84,false],[336,84,false],[337,84,false],[338,84,false]]],["union",86,1],["object",[[339,84,false],[340,84,false],[47,84,false],[341,594,false]]],["ref",237],["array",596],["object",[[309,84,false],[47,3,true],[342,597,false],[310,84,false]]],["ref",240],["object",[[343,599,true],[278,3,true]]],["enum","Word","Text","Number","Flag"],["object",[[47,3,true],[42,601,true],[2,3,true]]],["enum","Text","Number","Flag","Null"],["object",[[47,3,true],[42,603,true],[2,84,false]]],["object",[[278,3,true],[344,3,true]]],["object",[[345,86,true],[47,3,true]]],["ref",244],["array",607],["object",[[346,84,false],[47,3,true],[347,608,false],[58,84,false]]],["ref",238],["array",610],["object",[[220,611,false]]],["union",599,1],["ref",236],["array",614],["ref",239],["array",616],["object",[[348,613,false],[67,615,false],[4,617,false]]],["ref",242],["array",619],["object",[[40,620,false],[344,3,true]]],["object",[[125,3,true],[122,3,true],[127,223,false],[128,132,false]]],["object",[[349,86,true],[90,132,false]]],["ref",248],["array",624],["object",[[107,132,false],[349,86,true],[106,3,true],[350,625,false]]],["object",[[349,86,true],[332,84,false],[47,3,true],[90,132,false]]],["object",[[334,3,true],[221,2,false],[236,363,false],[351,3,true],[122,365,false],[141,132,false]]],["ref",114],["array",629],["ref",231],["array",631],["ref",224],["union",633,1],["ref",223],["union",635,1],["ref",225],["array",637],["ref",226],["union",639,1],["ref",227],["array",641],["ref",115],["array",643],["ref",250],["array",645],["union",646,1],["ref",34],["union",648,1],["ref",113],["array",650],["ref",221],["array",652],["ref",117],["array",654],["ref",229],["union",656,1],["ref",230],["array",658],["ref",245],["union",660,1],["ref",116],["array",662],["ref",249],["array",664],["ref",168,169],["union",666,1],["ref",228],["union",668,1],["union",631,1],["union",637,1],["ref",254],["union",672,1],["ref",251],["union",674,1],["ref",253],["union",676,1],["object",[[352,630,false],[68,84,false],[11,22,false],[69,125,false],[353,632,false],[354,634,false],[355,636,false],[356,638,false],[357,640,false],[358,642,false],[359,644,false],[360,647,false],[361,649,false],[47,3,true],[71,651,false],[25,53,false],[362,653,false],[363,655,false],[364,657,false],[365,659,false],[366,632,false],[367,86,true],[368,86,false],[369,661,false],[370,663,false],[371,665,false],[372,647,false],[373,625,false],[374,667,false],[74,669,false],[375,670,false],[376,671,false],[377,640,false],[378,673,false],[379,675,false],[380,677,false]]],["object",[[243,3,true],[141,132,false]]],["object",[[107,132,false],[106,3,true]]],["object",[[83,3,true]]],["enum","Primary","Secondary","Quiet"],["union",682,1],["object",[[114,200,false],[381,84,false],[382,683,false],[54,84,false],[55,3,true],[383,84,false],[58,3,true]]],["enum","Unknown","Action","Navigate","Dialog"],["object",[[381,84,false],[54,84,false],[163,84,false],[47,3,true],[71,525,false],[165,518,false],[42,685,true],[57,3,true]]],["ref",261,262],["array",687],["object",[[133,688,false]]],["object",[[384,151,false],[47,3,true]]],["object",[[293,478,false],[68,84,false],[69,125,false],[47,3,true]]],["object",[[202,86,true],[385,86,true],[47,3,true]]],["object",[[68,84,false],[69,125,false],[47,3,true],[90,210,false]]],["enum","Invalid","DataContext","QueryResult","ComponentProperty","Literal"],["enum","OneWay","TwoWay"],["union",695,1],["enum","Propagate","Clear","Preserve"],["union",697,1],["object",[[386,694,true],[387,84,false],[388,84,false],[389,84,false],[390,2,false],[48,696,false],[391,698,false],[159,3,true],[106,84,false],[392,84,false]]],["ref",233],["union",700,1],["ref",234],["union",702,1],["ref",232],["union",704,1],["ref",235],["union",706,1],["ref",243],["union",708,1],["object",[[393,701,false],[394,84,false],[395,151,false],[14,703,false],[223,84,false],[47,3,true],[396,705,false],[397,151,false],[398,151,false],[44,707,false],[399,709,false],[400,84,false]]],["object",[[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[401,151,false],[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[1,3,true],[198,151,false]]],["object",[[57,3,true]]],["ref",16],["array",714],["object",[[107,715,false],[303,3,true]]],["enum","NotEmpty","Max","Min","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Equal","Length","Matches","AllGreaterThan","AllGreaterThanOrEqual","Rule","NotEqual","Checksum","Contains","NotContains","StartsWith","EndsWith","DecimalPlaces"],["object",[[103,240,false],[69,125,false],[228,351,false],[157,84,false],[1,3,true],[150,717,true],[297,496,true],[2,2,false]]],["ref",151],["array",719],["object",[[43,3,true],[402,720,false],[45,3,true]]]],"contracts":[4,8,74,75,83,85,87,96,97,98,101,103,108,109,116,117,118,121,128,130,138,143,146,147,118,150,152,159,160,162,163,164,165,166,167,168,169,172,173,174,176,177,180,182,183,184,185,190,191,193,196,198,176,221,224,225,227,230,231,239,241,242,243,244,244,249,251,184,257,184,270,271,271,244,272,97,275,276,279,280,283,284,285,286,300,303,304,244,305,308,309,312,315,318,319,320,321,328,329,330,332,333,97,334,344,349,352,355,356,357,360,361,366,276,367,368,369,368,370,184,372,373,374,380,382,382,385,386,387,390,391,394,396,406,408,410,411,420,271,421,190,422,423,425,426,429,430,244,431,432,433,434,271,436,439,271,440,446,280,447,450,118,451,452,184,454,455,458,459,460,461,467,468,356,469,476,484,485,486,487,488,491,492,280,495,497,498,502,503,193,508,509,511,512,176,521,305,522,523,526,196,196,529,532,535,538,539,356,542,543,544,547,550,451,551,121,271,552,578,579,244,580,581,271,584,585,586,587,588,97,591,592,551,593,595,598,600,602,604,605,606,609,612,618,621,97,622,97,623,626,627,628,678,679,680,681,4,459,684,686,689,286,356,690,121,691,692,693,699,710,711,712,713,716,718,721,97]} as const; +export const syntaxCollections = {"kinds":["AddMappingSyntax","AllSyntax","ApplicationSyntax","ApplicationTriggerInteractionTriggerSyntax","ArrangementContainerSyntax","ArrangementOverrideSyntax","ArrangementSlotSyntax","ArrangementSyntax","AuthenticatedConditionSyntax","AuthenticationProviderSyntax","AuthenticationSyntax","AuthorizeSyntax","NavigationItemSyntax","NavigationLogoSyntax","NavigationRegionSyntax","NavigationTargetSyntax","BehaviorArgumentSyntax","BehaviorParameterSyntax","BehaviorSyntax","BuiltInInteractionTriggerSyntax","CaptureAppendSyntax","CaptureChildrenSyntax","CaptureMapEntrySyntax","CaptureNestedSyntax","CaptureSourceSettingSyntax","CaptureSourceSyntax","CaptureSplitSyntax","CaptureSyntax","CaptureTranslationSyntax","CaptureWhenSyntax","CausedByExpressionSyntax","ClockOffsetExpressionSyntax","CommandCalendarSyntax","DateOfExpressionSyntax","SpecificationTimeZoneSyntax","TimeZoneSyntax","CaseValueExpressionSyntax","ChildrenSyntax","ClaimConditionSyntax","ClaimIdentitySourceSyntax","CodeIdentitySourceSyntax","FileIdentitySourceSyntax","IdentitySyntax","IdentityDetailSyntax","QueryIdentitySourceSyntax","ClearMappingSyntax","ClearWithSyntax","CloseDialogActionSyntax","CodeBlockSyntax","ComponentExposedValueSyntax","ComponentOutletSyntax","ComponentPropertySyntax","CodeValidateSyntax","CommandSyntax","CommandStreamSyntax","ObserverFilterSyntax","ComparisonConditionSyntax","CompositeKeySyntax","ConceptAttributeSyntax","ConceptSyntax","GenerationSyntax","ConcurrencySyntax","ConfirmActionSyntax","ContextExpressionSyntax","IdentityExpressionSyntax","ContributionSyntax","ContributionDestinationSyntax","CountMappingSyntax","DeclarativeValidateSyntax","DecrementMappingSyntax","DialogTemplateSyntax","DomainSyntax","EnvironmentExpressionSyntax","EventContextExpressionSyntax","EventInteractionTriggerSyntax","EventSourceIdExpressionSyntax","EventSourceSyntax","EventStreamIdPartSyntax","EventStreamSyntax","EventSpecSyntax","EventSyntax","EverySyntax","ExecuteCommandActionSyntax","ExpressionKeySyntax","FeatureSyntax","FileConstraintSyntax","FileImportSyntax","FileReferenceSyntax","FormColumnSyntax","ExposureSyntax","ExposedPropertySyntax","InstanceContributionsSyntax","InstanceContributionSyntax","ContributedItemSyntax","ContributedItemValueSyntax","ScreenContributionSyntax","TemplateSlotContentSyntax","CommandFormLayoutSyntax","FormLayoutColumnSyntax","FormFieldPlacementSyntax","FormWidthSyntax","FormFieldSyntax","FormPopulateFromItemSyntax","FormPopulateViaQuerySyntax","FormSyntax","FromSyntax","HandlerSyntax","ImplementationSyntax","ImplementationHintSyntax","SystemSyntax","OperationSyntax","OperationPhaseSyntax","SpecificationExampleSyntax","SpecificationParameterSyntax","SpecificationCaseSyntax","SpecificationOperationFailureSyntax","SpecificationOperationSyntax","SpecificationCompensatedSyntax","ImportSyntax","IncrementMappingSyntax","InteractionAlternativeSyntax","InteractionOtherwiseSyntax","InteractionArgumentSyntax","InteractionBindingSyntax","IntervalInteractionTriggerSyntax","IntervalTriggerSourceSyntax","InvokesSyntax","InvocationRefusalSyntax","JoinEventSyntax","JoinSyntax","KeyPartSyntax","LayoutSyntax","ListExpressionSyntax","LiteralExpressionSyntax","LogicalConditionSyntax","LogicalPolicyConditionSyntax","LogicalPolicyRequirementSyntax","ModuleSyntax","NamedTriggerSourceSyntax","NavigateActionSyntax","NavigateBackActionSyntax","NestedSyntax","NotPolicyConditionSyntax","NotifyActionSyntax","OpenDialogActionSyntax","ObjectExpressionSyntax","ObjectMemberSyntax","PathExpressionSyntax","PerformerSyntax","PersonaSyntax","StickyNoteSyntax","PlaceSyntax","PolicyReferenceSyntax","PolicySyntax","PurposeSyntax","PurposeReferenceSyntax","PurposeTransferSyntax","ProducesSyntax","ProjectionEntersOnSyntax","ProjectionSyntax","ProjectionVariantSyntax","PresentationValueSyntax","PropertyMappingSyntax","PropertySyntax","PropertyResponseSourceSyntax","ResponseFieldSyntax","ScalarCommandResponseSyntax","RecordCommandResponseSyntax","ScalarSpecificationReturnSyntax","RecordSpecificationReturnSyntax","QueryParameterSyntax","QuerySyntax","RaiseTriggerActionSyntax","RawExpressionSyntax","ReactionIdentitySyntax","ReactionSyntax","ReactionTriggerSyntax","RefusalExpressionSyntax","ReadModelSyntax","ReadsSyntax","ReducerRuleSyntax","ReducerSyntax","RefreshQueryActionSyntax","RemoveViaJoinSyntax","RemoveWithSyntax","RequirementSyntax","RoleConditionSyntax","ScheduleTriggerSourceSyntax","ScreenActionSyntax","ScreenNavigationParameterSyntax","ScreenGuardedActionSyntax","ScreenActionAlternativeSyntax","ScreenActionOtherwiseSyntax","ScreenBehaviorSyntax","ScreenCodeSyntax","ScreenComponentSyntax","ScreenColumnSyntax","ScreenDataSyntax","ScreenFieldSyntax","ScreenNavigateSyntax","ScreenSectionSyntax","ScreenSlotSyntax","ScreenSummarySyntax","ScreenSyntax","ScreenTableSyntax","ScreenTemplateReferenceSyntax","ScreenTemplateSyntax","ScreenTitleSyntax","ScreenToolbarSyntax","ScreenUsesBehaviorSyntax","SeedEventSyntax","SeedGroupSyntax","SeedSyntax","SetMappingSyntax","TemplateAssignmentSyntax","TemplateExposedValueSyntax","TemplateOutletSyntax","SetStateActionSyntax","SliceSyntax","SlotSyntax","SourceItemExpressionSyntax","SpecificationAbsentReadModelSyntax","SpecificationCallerClaimSyntax","SpecificationCallerPersonaSyntax","SpecificationCallerSyntax","SpecificationCaptureSyntax","SpecificationClockSyntax","SpecificationGeneratedValueSyntax","SpecificationCommandSyntax","SpecificationDeniedSyntax","SpecificationErrorSyntax","SpecificationEventSyntax","NewScreenTemplateSyntax","ProfileAppearanceSyntax","ProfileIdentitySyntax","RootTemplateSyntax","SampleDataBindingSyntax","ShellOptionSyntax","SampleDataFieldSyntax","SampleDataMappingSyntax","SampleDataPackReferenceSyntax","SampleDataPackSyntax","SampleDataRowSyntax","SampleDataSelectionSyntax","SampleDataSetSyntax","SpecificationNoResultSyntax","SpecificationStreamSyntax","SpecificationNoStreamSyntax","SpecificationQueryResultSyntax","SpecificationQuerySyntax","SpecificationReadModelSyntax","SpecificationRedeliverySyntax","SpecificationSyntax","SpecificationTriggerSyntax","SpecificationWhenQuerySyntax","StringsExpressionSyntax","SubtractMappingSyntax","TagSyntax","ToolbarButtonSyntax","ToolbarItemSyntax","TemplateExpressionSyntax","TemplateInterpolationSyntax","TemplateTextSyntax","ThemeSyntax","TriggerDataSyntax","TriggerSyntax","TypeRefSyntax","TypeSyntax","UiBindingSyntax","UiProfileSyntax","UniqueEventConstraintSyntax","UniquePropertyConstraintSyntax","DependsOnSyntax","UsesBehaviorSyntax","ValidationRuleSyntax","VariantSyntax","AnonymousConditionSyntax"],"names":["factor","property","value","autoMap","mappings","authentication","behaviors","commandReadMode","concepts","domain","eventSources","examples","exposures","fileImports","identity","imports","instanceContributions","layouts","modules","personas","policies","purposes","reactionProductionMode","sampleDataPacks","seeds","sourceOptions","numericMode","stickyNotes","systems","templates","themes","timeZone","triggers","types","uiProfiles","triggerName","children","columns","gap","grow","rows","span","syntaxKind","height","root","width","growFactor","name","mode","overrides","variants","alias","providers","requirement","icon","id","slot","target","title","image","buttons","items","logo","region","feature","module","type","bindings","description","file","order","parameters","event","tags","when","appends","identifiedBy","map","source","translations","settings","separator","targets","key","keyIsEventSource","nested","from","to","expression","fromValue","properties","toValue","amount","clock","unit","contextMember","operand","configurable","parameter","blocks","claim","matches","matchesSubject","code","details","by","query","arguments","onFailure","onResult","onSuccess","language","binding","directives","authorize","calendar","concurrency","documentation","handler","produces","reads","response","stream","streamCandidates","validations","eventSource","propertyCandidate","streamId","streamIdParts","left","leftExpression","operator","right","parts","criminal","reason","scope","specialCategory","attributes","generation","valueNumbers","values","alphabet","case","checksum","count","encoding","pattern","prefix","range","rule","size","strategy","eventSourceType","eventStreamId","eventStreamType","eventTypes","message","messageIsLiteral","path","contributionPoint","destination","group","label","navigate","presentation","requirements","rules","arrangement","category","content","displayName","exposes","outlets","restrictsScopes","scopes","sliceKinds","slots","templateType","usedBehaviors","eventName","identifier","streams","x","y","hasGenerationMarker","origin","visibility","includeChildren","command","contributions","dependsOn","features","isPlacement","slices","toolbars","additionalRules","ignoreCasing","releasedBy","owner","component","editableFields","isCollection","operations","reExposes","restrictsFields","instance","field","columnGap","placements","rowGap","index","maxWidth","minWidth","column","columnSpan","row","rowSpan","composeUsing","columnMode","fields","for","generationMode","layout","onSubmit","populate","events","parentKey","implementation","hints","text","compensate","execute","inputs","uses","generatedValues","noStream","operation","qualifiedName","actions","condition","alternatives","otherwise","trigger","onRefused","acknowledge","constraint","selector","on","navigation","literalType","dialogTemplates","forms","screenTemplates","screen","level","dialogTemplate","members","goals","canvas","colour","hidden","sizeHeight","sizeWidth","slotName","authorization","basis","basisReference","conditionReference","erasureException","interest","recipients","retention","subjects","transfers","safeguard","inlineEvent","inlineOperation","readModel","sequence","entersOn","isGenerated","isIdentifier","isKey","isSubject","byParts","filters","isObservable","performer","returnType","roles","runsAs","where","data","invokes","member","partsKey","severity","role","dayOfMonth","dayOfWeek","time","subject","outcome","behavior","context","stableId","outlet","route","rowClick","blueprint","version","fitsSlot","eventSourceId","groups","captures","commands","constraints","direction","projections","queries","reactions","readModels","reducers","screens","specifications","contributes","authenticated","claims","capture","record","instant","commandType","inlineProperty","caseValue","eventType","accent","colorScheme","corners","font","logoKind","logoValue","showName","options","pack","shape","isBlueprint","locale","sets","active","exactly","results","reaction","cases","given","givenCaller","givenCallerPersona","givenCaptures","givenClock","givenGenerated","givenOperationFailures","givenReadModels","givenTimeZone","thenAbsentReadModels","thenCompensated","thenDenied","thenErrors","thenEvents","thenEventsInAnyOrder","thenNoEvents","thenNoResult","thenOperations","thenQueries","thenReadModels","thenResults","thenReturns","whenAppended","whenCapture","whenClock","whenQuery","whenRedelivered","whenTrigger","confirm","emphasis","slice","compatibleWith","isOptional","bindingKind","componentId","componentPropertyPath","expectedValueType","literal","nullBehavior","rawText","appearance","defaultSizeClass","icons","newScreenTemplate","packages","platforms","sampleData","theme","additionalProperties","places"],"rules":[["ref",30,31,33,36,63,64,72,73,75,132,133,145,147,173,177,220,255,260],["null"],["union",0,1],["string"],["object",[[0,2,false],[1,3,true],[2,0,true]]],["enum","Inherit","Disabled","Enabled"],["ref",0,45,67,69,119,213,256],["array",6],["object",[[3,5,true],[4,7,false]]],["ref",10],["union",9,1],["ref",18],["array",11],["enum","Protected"],["union",13,1],["ref",59],["array",15],["ref",71],["union",17,1],["ref",76],["array",19],["ref",112],["array",21],["ref",89],["array",23],["ref",86],["array",25],["ref",42],["union",27,1],["ref",118],["array",29],["ref",91],["array",31],["ref",131],["array",33],["union",34,1],["ref",137],["array",36],["ref",149],["array",38],["union",39,1],["ref",153],["array",41],["ref",154],["array",43],["enum","Atomic"],["union",45,1],["ref",241],["array",47],["ref",212],["array",49],["union",50,1],["enum","legacy","exact"],["object",[[26,52,true]]],["ref",150],["array",54],["ref",109],["array",56],["ref",214],["array",58],["ref",263],["array",60],["union",61,1],["ref",35],["union",63,1],["ref",265],["array",65],["union",66,1],["ref",267],["array",68],["union",69,1],["ref",269],["array",71],["union",72,1],["object",[[5,10,false],[6,12,false],[7,14,false],[8,16,false],[9,18,false],[10,20,false],[11,22,false],[12,24,false],[13,26,false],[14,28,false],[15,30,false],[16,32,false],[17,35,false],[18,37,false],[19,40,false],[20,42,false],[21,44,false],[22,46,false],[23,48,false],[24,51,false],[25,53,false],[27,55,false],[28,57,false],[29,59,false],[30,62,false],[31,64,false],[32,67,false],[33,70,false],[34,73,false]]],["object",[[35,3,true]]],["ref",4,6],["array",76],["integer",-2147483648,2147483647],["union",78,1],["number"],["union",80,1],["enum","Flat","Row","Column","Grid"],["object",[[36,77,false],[37,79,false],[38,79,false],[39,81,false],[40,79,false],[41,79,false],[42,82,true]]],["union",3,1],["object",[[43,84,false],[44,76,true],[45,84,false]]],["boolean"],["object",[[39,86,false],[46,81,false],[43,79,false],[47,3,true],[41,79,false],[45,79,false]]],["enum","Flow","Freeform"],["ref",5],["array",89],["union",90,1],["union",76,1],["ref",275],["array",93],["union",94,1],["object",[[48,88,true],[49,91,false],[44,92,false],[50,95,false]]],["object",[]],["object",[[51,84,false],[47,3,true]]],["ref",9],["array",99],["object",[[52,100,false]]],["ref",136,152],["object",[[53,102,true]]],["ref",12],["array",104],["ref",15],["union",106,1],["object",[[36,105,false],[54,84,false],[55,3,true],[56,84,false],[57,107,false],[58,3,true]]],["object",[[59,3,true],[58,3,true]]],["ref",258],["array",110],["ref",13],["union",112,1],["enum","Unspecified","Inherit","Extend","Override"],["enum","Topbar","Sidebar"],["object",[[60,111,false],[61,105,false],[62,113,false],[48,114,true],[63,115,true]]],["object",[[64,84,false],[65,3,true]]],["object",[[47,3,true],[2,3,true]]],["ref",266],["union",119,1],["object",[[47,3,true],[66,120,false]]],["ref",123],["array",122],["ref",87],["union",124,1],["ref",17],["array",126],["object",[[67,123,false],[68,84,false],[69,125,false],[47,84,false],[70,79,false],[71,127,false]]],["enum","Click","DoubleClick","Select","Submit","Change","Load","Unload","Enter","Leave","Unknown"],["object",[[42,129,true]]],["ref",162],["array",131],["ref",257],["array",133],["union",134,1],["ref",29],["union",136,1],["object",[[72,3,true],[4,132,false],[73,135,false],[74,137,false]]],["ref",20],["array",139],["ref",22,26],["array",141],["object",[[75,140,false],[76,3,true],[77,142,false],[1,3,true]]],["ref",28],["array",144],["object",[[1,3,true],[78,0,true],[79,145,false]]],["object",[[75,140,false],[77,142,false],[1,3,true]]],["ref",24],["array",148],["object",[[80,149,false],[42,3,true]]],["array",3],["object",[[81,3,true],[78,0,true],[82,151,false]]],["ref",21],["array",153],["ref",23],["array",155],["ref",25],["union",157,1],["object",[[75,140,false],[36,154,false],[83,84,false],[84,86,false],[77,142,false],[47,3,true],[85,156,false],[78,158,false],[25,53,false]]],["object",[[86,3,true],[87,3,true]]],["enum","PropertyChanged","Added","Removed","Changed","LogicalOr","LogicalAnd","ValueTransition","Expression"],["object",[[88,84,false],[89,84,false],[90,151,false],[42,161,true],[91,84,false]]],["object",[[1,84,false]]],["object",[[92,78,true],[93,3,true],[94,3,true]]],["object",[[95,84,false],[55,84,false]]],["object",[[96,0,true]]],["object",[[55,3,true]]],["object",[[97,86,true],[55,3,true]]],["object",[[98,3,true]]],["ref",1,37,46,81,105,129,141,160,183,184],["array",170],["object",[[3,5,true],[99,171,false],[76,0,true],[1,3,true]]],["object",[[100,3,true],[101,2,false],[102,86,true]]],["object",[[100,3,true]]],["ref",48],["object",[[103,175,true]]],["object",[[69,124,true]]],["ref",43],["array",178],["object",[[68,84,false],[104,179,false]]],["ref",39,40,41,44],["object",[[47,3,true],[78,181,true],[66,119,true]]],["object",[[105,0,true],[106,3,true]]],["object",[[1,3,true]]],["object",[[72,3,true]]],["ref",122],["array",186],["ref",47,62,82,139,140,143,144,172,182,217],["array",188],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false]]],["object",[[103,3,true],[111,3,true]]],["ref",268],["object",[[112,192,true],[47,3,true]]],["ref",188,190,193,194,195,197,199,200,201,202,204,205,207,208,209],["array",194],["object",[[113,195,false],[47,3,true]]],["union",192,1],["object",[[112,197,false],[1,3,true],[2,2,false]]],["ref",11],["union",199,1],["ref",32],["union",201,1],["ref",61],["union",203,1],["ref",106],["union",205,1],["ref",157],["array",207],["ref",163],["array",209],["ref",179],["array",211],["union",212,1],["ref",166,167],["union",214,1],["ref",54],["union",216,1],["array",216],["ref",52,68],["array",219],["object",[[114,200,false],[115,202,false],[116,204,false],[68,84,false],[117,84,false],[118,206,false],[47,3,true],[119,208,false],[90,210,false],[120,213,false],[121,215,false],[122,217,false],[123,218,false],[124,220,false]]],["union",209,1],["union",131,1],["object",[[125,3,true],[126,222,false],[122,3,true],[127,223,false],[128,132,false]]],["object",[[125,3,true],[122,84,false]]],["enum","Equal","NotEqual","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Contains","StartsWith"],["object",[[129,3,true],[130,2,false],[131,226,true],[132,0,true]]],["ref",130],["array",228],["object",[[133,229,false],[66,3,true]]],["object",[[134,86,false],[47,3,true],[135,84,false],[136,84,false],[137,84,false]]],["ref",58],["array",232],["ref",60],["union",234,1],["union",220,1],["array",78],["union",237,1],["object",[[138,233,false],[68,84,false],[69,125,false],[139,235,false],[47,3,true],[66,3,true],[124,236,false],[140,238,false],[141,151,false]]],["union",175,1],["object",[[142,84,false],[143,84,false],[144,84,false],[103,240,false],[145,79,false],[146,84,false],[69,125,false],[147,84,false],[148,84,false],[149,84,false],[150,84,false],[151,79,false],[152,3,true]]],["object",[[125,86,true],[153,84,false],[154,84,false],[155,84,false],[156,151,false]]],["object",[[107,187,false],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[159,3,true]]],["ref",66],["union",245,1],["ref",199],["union",247,1],["object",[[160,3,true],[161,246,false],[162,84,false],[54,84,false],[55,84,false],[163,84,false],[164,248,false],[70,79,false],[165,84,false]]],["enum","Outlet","Dialog","External"],["object",[[42,250,true],[57,3,true]]],["ref",185],["array",252],["union",253,1],["ref",274],["array",255],["object",[[166,254,false],[167,256,false]]],["ref",7],["union",258,1],["ref",96],["array",260],["ref",215],["array",262],["ref",216],["array",264],["ref",219],["array",266],["ref",273],["array",268],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["object",[[47,3,true]]],["object",[[180,3,true]]],["ref",78],["array",273],["object",[[68,84,false],[55,84,false],[181,120,false],[47,3,true],[182,274,false],[183,79,false],[184,79,false]]],["object",[[47,3,true],[66,119,true]]],["ref",77],["array",277],["object",[[68,84,false],[55,84,false],[47,3,true],[127,120,false],[128,278,false]]],["object",[[72,3,true],[83,2,false]]],["integer",0,4294967295],["enum","Private","Public"],["object",[[68,84,false],[117,84,false],[69,125,false],[139,281,false],[185,86,false],[55,84,false],[47,3,true],[186,84,false],[90,210,false],[73,135,false],[187,282,false]]],["object",[[3,5,true],[188,86,true],[4,7,false]]],["object",[[107,187,false],[189,3,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[88,0,true]]],["ref",65],["array",287],["union",288,1],["ref",272],["array",290],["ref",84],["array",292],["ref",155],["array",294],["ref",218],["array",296],["ref",208],["array",298],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[193,86,true],[47,3,true],[21,295,false],[194,297,false],[29,59,false],[195,299,false],[179,269,false]]],["ref",85,270,271],["array",301],["object",[[196,302,false],[68,84,false],[69,124,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[147,3,true]]],["object",[[163,84,false],[1,3,true]]],["ref",90],["array",306],["object",[[199,3,true],[90,307,false]]],["object",[[200,3,true],[201,151,false],[202,86,true],[163,84,false],[203,151,false],[159,3,true],[204,84,false],[205,86,true]]],["ref",92],["array",310],["object",[[190,311,false],[206,3,true]]],["ref",93],["array",313],["object",[[200,3,true],[61,314,false],[159,3,true],[2,2,false]]],["ref",94],["array",316],["object",[[55,3,true],[141,317,false]]],["object",[[207,3,true],[2,0,true]]],["object",[[160,3,true],[113,195,false],[70,79,false]]],["object",[[113,195,false],[56,3,true]]],["ref",100],["union",322,1],["ref",98],["array",324],["ref",99],["array",326],["object",[[208,323,false],[37,325,false],[209,327,false],[210,323,false]]],["object",[[211,78,true],[212,323,false],[213,323,false],[45,323,false]]],["object",[[214,78,true],[215,79,false],[207,3,true],[216,78,true],[217,79,false],[45,323,false]]],["enum","Fraction","Pixels","Percent","Auto"],["object",[[94,331,true],[2,81,false]]],["object",[[218,84,false],[86,84,false],[163,84,false],[1,3,true]]],["object",[[105,84,false],[106,3,true]]],["enum","Unspecified","Auto","Manual"],["ref",88],["array",336],["ref",101],["array",338],["ref",97],["union",340,1],["ref",102,103],["union",342,1],["object",[[6,12,false],[219,335,true],[37,337,false],[68,84,false],[220,339,false],[221,3,true],[222,335,true],[223,341,false],[47,3,true],[224,248,false],[225,343,false],[179,269,false]]],["ref",79],["array",345],["ref",57,83],["union",347,1],["object",[[226,346,false],[83,348,false],[4,7,false],[227,2,false]]],["ref",107],["union",350,1],["object",[[103,240,false],[69,125,false],[228,351,false]]],["ref",108],["array",353],["object",[[229,354,false]]],["object",[[230,3,true]]],["object",[[68,84,false],[47,3,true]]],["ref",111],["union",358,1],["object",[[231,359,false],[68,84,false],[232,359,false],[233,210,false],[47,3,true],[234,3,true]]],["object",[[103,240,false],[68,84,false],[69,125,false],[228,351,false]]],["ref",247],["union",362,1],["ref",246],["union",364,1],["object",[[68,84,false],[221,2,false],[235,132,false],[47,3,true],[236,363,false],[122,365,false],[66,3,true],[141,132,false]]],["object",[[47,3,true],[141,132,false]]],["object",[[237,3,true]]],["object",[[237,3,true],[141,132,false]]],["object",[[186,84,false],[238,3,true],[187,282,false]]],["ref",56,134],["object",[[239,189,false],[240,371,true]]],["object",[[239,189,false]]],["object",[[112,3,true],[47,3,true]]],["ref",120],["array",375],["ref",121],["union",377,1],["ref",3,19,74,124],["object",[[239,189,false],[241,376,false],[240,84,false],[242,378,false],[243,379,true]]],["enum","Seconds","Minutes","Hours","Days"],["object",[[92,78,true],[94,381,true]]],["ref",127],["array",383],["object",[[189,3,true],[4,132,false],[244,384,false]]],["object",[[245,86,true],[246,84,false],[119,208,false],[247,3,true]]],["object",[[3,5,true],[72,3,true],[4,7,false]]],["ref",128],["array",388],["object",[[226,389,false],[248,3,true],[1,3,true]]],["object",[[88,0,true],[1,3,true]]],["ref",14],["array",392],["object",[[168,259,false],[6,12,false],[169,84,false],[172,263,false],[47,3,true],[249,393,false],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["array",0],["object",[[61,395,false]]],["union",3,86,1],["number",-1.7976931348623157E+308,1.7976931348623157E+308],["enum","Int32","Int64","Decimal","Single"],["string","^-?[0-9]\u002B(\\.[0-9]\u002B)?([Ee][\u002B-]?[0-9]\u002B)?$"],["object",[[250,399,true],[2,400,true]]],["const","ExactNumber"],["string","^(?:0|-?(?:[1-9][0-9]{0,28}|(?:0|[1-9][0-9]{0,28})\\.[0-9]{0,27}[1-9]))$"],["object",[[250,402,true],[2,403,true]]],["union",397,398,401,404],["object",[[2,405,false]]],["enum","And","Or"],["object",[[129,371,true],[131,407,true],[132,371,true]]],["ref",8,38,135,142,186,276],["object",[[129,409,true],[131,407,true],[132,409,true]]],["object",[[129,102,true],[131,407,true],[132,102,true]]],["ref",70],["array",412],["union",413,1],["ref",104],["array",415],["union",416,1],["ref",206],["array",418],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[251,414,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[252,417,false],[193,86,true],[47,3,true],[249,393,false],[21,295,false],[253,419,false],[29,59,false],[195,299,false],[179,269,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[254,3,true]]],["object",[[3,5,true],[99,171,false],[1,3,true]]],["object",[[96,409,true]]],["enum","Info","Warning","Error","Unknown"],["object",[[107,187,false],[255,424,true],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[107,187,false],[256,3,true],[108,189,false],[109,189,false],[110,189,false]]],["ref",146],["array",427],["object",[[257,428,false]]],["object",[[47,3,true],[2,0,true]]],["object",[[103,240,false],[69,125,false]]],["object",[[68,84,false],[258,151,false],[43,79,false],[47,3,true],[20,151,false],[45,79,false],[183,79,false],[184,79,false]]],["object",[[259,3,true],[260,84,false],[43,79,false],[230,3,true],[45,79,false],[183,78,true],[184,78,true]]],["object",[[261,86,false],[262,84,false],[263,84,false],[264,3,true],[183,79,false],[184,79,false]]],["union",409,1],["object",[[103,240,false],[240,435,false],[68,84,false],[69,125,false],[47,3,true]]],["ref",156],["array",437],["object",[[265,84,false],[266,84,false],[267,84,false],[240,84,false],[268,84,false],[68,84,false],[269,84,false],[270,84,false],[47,3,true],[271,151,false],[272,84,false],[273,151,false],[274,438,false]]],["object",[[161,3,true],[275,3,true]]],["ref",80],["union",441,1],["ref",110],["union",443,1],["union",371,1],["object",[[72,3,true],[221,2,false],[276,442,false],[277,444,false],[4,132,false],[122,217,false],[73,135,false],[74,445,false]]],["object",[[3,5,true],[99,171,false],[68,84,false],[69,125,false],[83,348,false],[47,3,true],[278,84,false],[279,84,false],[25,53,false]]],["ref",158],["array",448],["object",[[99,171,false],[280,449,false],[47,3,true]]],["object",[[1,3,true],[78,0,true]]],["object",[[281,86,false],[282,86,false],[283,86,false],[284,86,false],[47,3,true],[66,119,true]]],["ref",164],["object",[[47,3,true],[78,453,true],[66,120,false]]],["object",[[78,453,true]]],["ref",165],["array",456],["object",[[220,457,false]]],["object",[[2,0,true]]],["object",[[220,132,false]]],["object",[[47,3,true],[78,2,false],[66,119,true]]],["ref",170],["union",462,1],["array",462],["ref",148],["union",465,1],["object",[[114,200,false],[105,463,false],[285,464,false],[68,84,false],[286,464,false],[287,86,false],[47,3,true],[288,466,false],[289,119,true],[136,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[243,3,true]]],["object",[[290,151,false],[42,3,true]]],["ref",55],["union",470,1],["ref",174],["union",472,1],["ref",176],["array",474],["object",[[68,84,false],[117,84,false],[86,471,false],[47,3,true],[291,473,false],[32,475,false],[292,445,false]]],["ref",264],["array",477],["ref",126],["array",479],["union",480,1],["union",208,1],["ref",125,138,187],["object",[[103,240,false],[293,478,false],[68,84,false],[69,125,false],[294,481,false],[119,482,false],[120,213,false],[78,483,true]]],["object",[[295,3,true]]],["object",[[68,84,false],[117,84,false],[69,125,false],[47,3,true],[90,210,false]]],["object",[[51,84,false],[105,84,false],[285,132,false],[278,3,true]]],["object",[[103,240,false],[68,84,false],[72,3,true],[69,125,false]]],["ref",180],["array",489],["object",[[68,84,false],[86,471,false],[47,3,true],[278,3,true],[167,490,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[106,3,true]]],["ref",57],["union",493,1],["object",[[72,3,true],[83,2,false],[227,2,false],[296,494,false]]],["enum","Error","Information","Warning"],["object",[[240,371,true],[157,84,false],[297,496,true]]],["object",[[298,3,true]]],["enum","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["union",499,1],["string","^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,7})?$"],["object",[[299,79,false],[300,500,false],[301,501,true]]],["enum","Item","Screen"],["union",503,1],["object",[[189,3,true],[233,187,false],[163,84,false],[164,248,false],[302,504,false]]],["ref",191],["array",506],["ref",192],["union",508,1],["object",[[241,507,false],[163,3,true],[164,248,false],[242,509,false],[302,504,false]]],["object",[[107,187,false],[189,3,true],[240,371,true]]],["enum","Hidden","Execute","Unknown"],["object",[[107,187,false],[189,84,false],[303,512,true]]],["object",[[304,11,true]]],["ref",49],["array",515],["ref",50],["array",517],["ref",161],["array",519],["ref",51],["array",521],["object",[[6,12,false],[200,3,true],[305,197,false],[172,516,false],[54,84,false],[47,3,true],[173,518,false],[165,520,false],[90,522,false],[306,84,false],[179,269,false]]],["object",[[105,84,false],[106,3,true],[66,119,true]]],["object",[[163,3,true],[1,3,true]]],["ref",189],["array",526],["object",[[105,84,false],[307,84,false],[71,527,false],[308,84,false],[254,3,true]]],["ref",198],["array",529],["object",[[220,530,false],[57,3,true]]],["ref",95],["array",532],["object",[[190,533,false],[68,84,false],[113,195,false],[69,125,false],[47,3,true]]],["ref",196],["array",535],["object",[[6,12,false],[37,536,false],[309,248,false],[57,3,true],[179,269,false]]],["ref",201],["array",538],["object",[[310,84,false],[47,3,true],[177,539,false],[311,84,false]]],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[312,84,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["ref",259],["array",542],["object",[[60,111,false],[61,543,false],[47,3,true]]],["object",[[234,268,true]]],["object",[[72,3,true],[90,132,false]]],["ref",210],["array",547],["object",[[313,3,true],[226,548,false]]],["ref",211],["array",550],["object",[[314,551,false],[47,84,false],[183,79,false],[184,79,false]]],["object",[[310,84,false],[47,3,true],[311,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[57,3,true],[2,3,true]]],["ref",27],["array",555],["ref",53],["array",557],["enum","Inbound","Outbound"],["union",559,1],["array",441],["array",443],["ref",159],["array",563],["ref",171],["array",565],["ref",175],["array",567],["ref",178],["array",569],["union",570,1],["ref",181],["array",572],["union",573,1],["ref",203],["array",575],["ref",252],["array",577],["enum","StateChange","StateView","Automation","Translate"],["object",[[315,556,false],[316,558,false],[317,302,false],[68,84,false],[318,560,false],[117,84,false],[226,561,false],[11,22,false],[69,125,false],[47,3,true],[203,562,false],[319,564,false],[21,295,false],[320,566,false],[321,568,false],[322,571,false],[323,574,false],[324,576,false],[325,578,false],[29,59,false],[66,579,true]]],["object",[[326,84,false],[47,3,true]]],["object",[[83,0,true],[47,3,true]]],["object",[[66,3,true],[2,3,true]]],["ref",222],["array",584],["object",[[327,86,true],[328,585,false],[290,151,false]]],["object",[[329,3,true],[330,132,false]]],["object",[[331,3,true]]],["object",[[189,3,true],[1,3,true],[78,0,true]]],["object",[[332,3,true],[221,2,false],[235,132,false],[333,84,false],[141,132,false]]],["ref",36],["union",591,1],["object",[[334,592,false],[47,84,false]]],["object",[[335,3,true],[221,2,false],[333,84,false],[236,363,false],[122,365,false],[141,132,false]]],["object",[[336,84,false],[337,84,false],[338,84,false],[339,84,false]]],["union",86,1],["object",[[340,84,false],[341,84,false],[47,84,false],[342,596,false]]],["ref",237],["array",598],["object",[[310,84,false],[47,3,true],[343,599,false],[311,84,false]]],["ref",240],["object",[[344,601,true],[278,3,true]]],["enum","Word","Text","Number","Flag"],["object",[[47,3,true],[42,603,true],[2,3,true]]],["enum","Text","Number","Flag","Null"],["object",[[47,3,true],[42,605,true],[2,84,false]]],["object",[[278,3,true],[345,3,true]]],["object",[[346,86,true],[47,3,true]]],["ref",244],["array",609],["object",[[347,84,false],[47,3,true],[348,610,false],[58,84,false]]],["ref",238],["array",612],["object",[[220,613,false]]],["union",601,1],["ref",236],["array",616],["ref",239],["array",618],["object",[[349,615,false],[67,617,false],[4,619,false]]],["ref",242],["array",621],["object",[[40,622,false],[345,3,true]]],["object",[[125,3,true],[122,3,true],[127,223,false],[128,132,false]]],["object",[[350,86,true],[90,132,false]]],["ref",248],["array",626],["object",[[107,132,false],[350,86,true],[106,3,true],[351,627,false]]],["object",[[350,86,true],[333,84,false],[47,3,true],[90,132,false]]],["object",[[335,3,true],[221,2,false],[236,363,false],[352,3,true],[122,365,false],[141,132,false]]],["ref",114],["array",631],["ref",231],["array",633],["ref",224],["union",635,1],["ref",223],["union",637,1],["ref",225],["array",639],["ref",226],["union",641,1],["ref",227],["array",643],["ref",115],["array",645],["ref",250],["array",647],["union",648,1],["ref",34],["union",650,1],["ref",113],["array",652],["ref",221],["array",654],["ref",117],["array",656],["ref",229],["union",658,1],["ref",230],["array",660],["ref",245],["union",662,1],["ref",116],["array",664],["ref",249],["array",666],["ref",168,169],["union",668,1],["ref",228],["union",670,1],["union",633,1],["union",639,1],["ref",254],["union",674,1],["ref",251],["union",676,1],["ref",253],["union",678,1],["object",[[353,632,false],[68,84,false],[11,22,false],[69,125,false],[354,634,false],[355,636,false],[356,638,false],[357,640,false],[358,642,false],[359,644,false],[360,646,false],[361,649,false],[362,651,false],[47,3,true],[71,653,false],[25,53,false],[363,655,false],[364,657,false],[365,659,false],[366,661,false],[367,634,false],[368,86,true],[369,86,false],[370,663,false],[371,665,false],[372,667,false],[373,649,false],[374,627,false],[375,669,false],[74,671,false],[376,672,false],[377,673,false],[378,642,false],[379,675,false],[380,677,false],[381,679,false]]],["object",[[243,3,true],[141,132,false]]],["object",[[107,132,false],[106,3,true]]],["object",[[83,3,true]]],["enum","Primary","Secondary","Quiet"],["union",684,1],["object",[[114,200,false],[382,84,false],[383,685,false],[54,84,false],[55,3,true],[384,84,false],[58,3,true]]],["enum","Unknown","Action","Navigate","Dialog"],["object",[[382,84,false],[54,84,false],[163,84,false],[47,3,true],[71,527,false],[165,520,false],[302,504,false],[42,687,true],[57,3,true]]],["ref",261,262],["array",689],["object",[[133,690,false]]],["object",[[385,151,false],[47,3,true]]],["object",[[293,478,false],[68,84,false],[69,125,false],[47,3,true]]],["object",[[202,86,true],[386,86,true],[47,3,true]]],["object",[[68,84,false],[69,125,false],[47,3,true],[90,210,false]]],["enum","Invalid","DataContext","QueryResult","ComponentProperty","Literal"],["enum","OneWay","TwoWay"],["union",697,1],["enum","Propagate","Clear","Preserve"],["union",699,1],["object",[[387,696,true],[388,84,false],[389,84,false],[390,84,false],[391,2,false],[48,698,false],[392,700,false],[159,3,true],[106,84,false],[393,84,false]]],["ref",233],["union",702,1],["ref",234],["union",704,1],["ref",232],["union",706,1],["ref",235],["union",708,1],["ref",243],["union",710,1],["object",[[394,703,false],[395,84,false],[396,151,false],[14,705,false],[223,84,false],[47,3,true],[397,707,false],[398,151,false],[399,151,false],[44,709,false],[400,711,false],[401,84,false]]],["object",[[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[402,151,false],[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[1,3,true],[198,151,false]]],["object",[[57,3,true]]],["ref",16],["array",716],["object",[[107,717,false],[304,3,true]]],["enum","NotEmpty","Max","Min","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Equal","Length","Matches","AllGreaterThan","AllGreaterThanOrEqual","Rule","NotEqual","Checksum","Contains","NotContains","StartsWith","EndsWith","DecimalPlaces"],["object",[[103,240,false],[69,125,false],[228,351,false],[157,84,false],[1,3,true],[150,719,true],[297,496,true],[2,2,false]]],["ref",151],["array",721],["object",[[43,3,true],[403,722,false],[45,3,true]]]],"contracts":[4,8,74,75,83,85,87,96,97,98,101,103,108,109,116,117,118,121,128,130,138,143,146,147,118,150,152,159,160,162,163,164,165,166,167,168,169,172,173,174,176,177,180,182,183,184,185,190,191,193,196,198,176,221,224,225,227,230,231,239,241,242,243,244,244,249,251,184,257,184,270,271,271,244,272,97,275,276,279,280,283,284,285,286,300,303,304,244,305,308,309,312,315,318,319,320,321,328,329,330,332,333,97,334,344,349,352,355,356,357,360,361,366,276,367,368,369,368,370,184,372,373,374,380,382,382,385,386,387,390,391,394,396,406,408,410,411,420,271,421,190,422,423,425,426,429,430,244,431,432,433,434,271,436,439,271,440,446,280,447,450,118,451,452,184,454,455,458,459,460,461,467,468,356,469,476,484,485,486,487,488,491,492,280,495,497,498,502,505,193,510,511,513,514,176,523,305,524,525,528,196,196,531,534,537,540,541,356,544,545,546,549,552,451,553,121,271,554,580,581,244,582,583,271,586,587,588,589,590,97,593,594,553,595,597,600,602,604,606,607,608,611,614,620,623,97,624,97,625,628,629,630,680,681,682,683,4,459,686,688,691,286,356,692,121,693,694,695,701,712,713,714,715,718,720,723,97]} as const; diff --git a/Source/Screenplay/Compiler/Syntax/SyntaxDefinitions.ts b/Source/Screenplay/Compiler/Syntax/SyntaxDefinitions.ts index a9d3a0374..00c693cd1 100644 --- a/Source/Screenplay/Compiler/Syntax/SyntaxDefinitions.ts +++ b/Source/Screenplay/Compiler/Syntax/SyntaxDefinitions.ts @@ -2,4 +2,4 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // Generated from C# SyntaxSchema; the native specification holds every kind and member to it. -export const syntaxDefinitions = {"AddMappingSyntax":{"title":"AddMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AddMappingSyntax"},"factor":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"property":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","value"]},"AllSyntax":{"title":"AllSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AllSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]}},"required":["kind","autoMap"]},"ApplicationSyntax":{"title":"ApplicationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ApplicationSyntax"},"authentication":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthenticationSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"commandReadMode":{"anyOf":[{"type":"string","enum":["Protected"]},{"type":"null"}],"default":null},"concepts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ConceptSyntax"}]},"default":[]},"domain":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/DomainSyntax"}]},{"type":"null"}],"default":null},"eventSources":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventSourceSyntax"}]},"default":[]},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"exposures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ExposureSyntax"}]},"default":[]},"fileImports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileImportSyntax"}]},"default":[]},"identity":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/IdentitySyntax"}]},{"type":"null"}],"default":null},"imports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ImportSyntax"}]},"default":[]},"instanceContributions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InstanceContributionsSyntax"}]},"default":[]},"layouts":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/LayoutSyntax"}]}},{"type":"null"}],"default":[]},"modules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ModuleSyntax"}]},"default":[]},"personas":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PersonaSyntax"}]}},{"type":"null"}],"default":[]},"policies":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PolicySyntax"}]},"default":[]},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeSyntax"}]},"default":[]},"reactionProductionMode":{"anyOf":[{"type":"string","enum":["Atomic"]},{"type":"null"}],"default":null},"sampleDataPacks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataPackSyntax"}]},"default":[]},"seeds":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SeedSyntax"}]}},{"type":"null"}],"default":[]},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}},"stickyNotes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/StickyNoteSyntax"}]},"default":[]},"systems":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SystemSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"themes":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ThemeSyntax"}]}},{"type":"null"}],"default":[]},"timeZone":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TimeZoneSyntax"}]},{"type":"null"}],"default":null},"triggers":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TriggerSyntax"}]}},{"type":"null"}],"default":[]},"types":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TypeSyntax"}]}},{"type":"null"}],"default":[]},"uiProfiles":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UiProfileSyntax"}]}},{"type":"null"}],"default":[]}},"required":["kind"]},"ApplicationTriggerInteractionTriggerSyntax":{"title":"ApplicationTriggerInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ApplicationTriggerInteractionTriggerSyntax"},"triggerName":{"type":"string"}},"required":["kind","triggerName"]},"ArrangementContainerSyntax":{"title":"ArrangementContainerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementContainerSyntax"},"children":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ArrangementContainerSyntax"},{"$ref":"#/$defs/ArrangementSlotSyntax"}]},"default":[]},"columns":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"gap":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"grow":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null},"rows":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"span":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"syntaxKind":{"type":"string","enum":["Flat","Row","Column","Grid"]}},"required":["kind","syntaxKind"]},"ArrangementOverrideSyntax":{"title":"ArrangementOverrideSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementOverrideSyntax"},"height":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"root":{"oneOf":[{"$ref":"#/$defs/ArrangementContainerSyntax"},{"$ref":"#/$defs/ArrangementSlotSyntax"}]},"width":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","root"]},"ArrangementSlotSyntax":{"title":"ArrangementSlotSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementSlotSyntax"},"grow":{"type":"boolean","default":false},"growFactor":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null},"height":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"name":{"type":"string"},"span":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"width":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","name"]},"ArrangementSyntax":{"title":"ArrangementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementSyntax"},"mode":{"type":"string","enum":["Flow","Freeform"]},"overrides":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ArrangementOverrideSyntax"}]}},{"type":"null"}],"default":[]},"root":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementContainerSyntax"},{"$ref":"#/$defs/ArrangementSlotSyntax"}]},{"type":"null"}],"default":null},"variants":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/VariantSyntax"}]}},{"type":"null"}],"default":[]}},"required":["kind","mode"]},"AuthenticatedConditionSyntax":{"title":"AuthenticatedConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthenticatedConditionSyntax"}},"required":["kind"]},"AuthenticationProviderSyntax":{"title":"AuthenticationProviderSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthenticationProviderSyntax"},"alias":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"AuthenticationSyntax":{"title":"AuthenticationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthenticationSyntax"},"providers":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AuthenticationProviderSyntax"}]},"default":[]}},"required":["kind"]},"AuthorizeSyntax":{"title":"AuthorizeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthorizeSyntax"},"requirement":{"oneOf":[{"$ref":"#/$defs/LogicalPolicyRequirementSyntax"},{"$ref":"#/$defs/PolicyReferenceSyntax"}]}},"required":["kind","requirement"]},"NavigationItemSyntax":{"title":"NavigationItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationItemSyntax"},"children":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationItemSyntax"}]},"default":[]},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"type":"string"},"slot":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"target":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/NavigationTargetSyntax"}]},{"type":"null"}],"default":null},"title":{"type":"string"}},"required":["kind","id","title"]},"NavigationLogoSyntax":{"title":"NavigationLogoSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationLogoSyntax"},"image":{"type":"string"},"title":{"type":"string"}},"required":["kind","image","title"]},"NavigationRegionSyntax":{"title":"NavigationRegionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationRegionSyntax"},"buttons":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ToolbarButtonSyntax"}]},"default":[]},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationItemSyntax"}]},"default":[]},"logo":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/NavigationLogoSyntax"}]},{"type":"null"}],"default":null},"mode":{"type":"string","enum":["Unspecified","Inherit","Extend","Override"]},"region":{"type":"string","enum":["Topbar","Sidebar"]}},"required":["kind","mode","region"]},"NavigationTargetSyntax":{"title":"NavigationTargetSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationTargetSyntax"},"feature":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"module":{"type":"string"}},"required":["kind","module"]},"BehaviorArgumentSyntax":{"title":"BehaviorArgumentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BehaviorArgumentSyntax"},"name":{"type":"string"},"value":{"type":"string"}},"required":["kind","name","value"]},"BehaviorParameterSyntax":{"title":"BehaviorParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BehaviorParameterSyntax"},"name":{"type":"string"},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"BehaviorSyntax":{"title":"BehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BehaviorSyntax"},"bindings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionBindingSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"order":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorParameterSyntax"}]},"default":[]}},"required":["kind"]},"BuiltInInteractionTriggerSyntax":{"title":"BuiltInInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BuiltInInteractionTriggerSyntax"},"syntaxKind":{"type":"string","enum":["Click","DoubleClick","Select","Submit","Change","Load","Unload","Enter","Leave","Unknown"]}},"required":["kind","syntaxKind"]},"CaptureAppendSyntax":{"title":"CaptureAppendSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureAppendSyntax"},"event":{"type":"string"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"tags":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TagSyntax"}]}},{"type":"null"}],"default":[]},"when":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CaptureWhenSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"CaptureChildrenSyntax":{"title":"CaptureChildrenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureChildrenSyntax"},"appends":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureAppendSyntax"}]},"default":[]},"identifiedBy":{"type":"string"},"map":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureMapEntrySyntax"},{"$ref":"#/$defs/CaptureSplitSyntax"}]},"default":[]},"property":{"type":"string"}},"required":["kind","identifiedBy","property"]},"CaptureMapEntrySyntax":{"title":"CaptureMapEntrySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureMapEntrySyntax"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"translations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureTranslationSyntax"}]},"default":[]}},"required":["kind","property","source"]},"CaptureNestedSyntax":{"title":"CaptureNestedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureNestedSyntax"},"appends":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureAppendSyntax"}]},"default":[]},"map":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureMapEntrySyntax"},{"$ref":"#/$defs/CaptureSplitSyntax"}]},"default":[]},"property":{"type":"string"}},"required":["kind","property"]},"CaptureSourceSettingSyntax":{"title":"CaptureSourceSettingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSourceSettingSyntax"},"name":{"type":"string"},"value":{"type":"string"}},"required":["kind","name","value"]},"CaptureSourceSyntax":{"title":"CaptureSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSourceSyntax"},"settings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureSourceSettingSyntax"}]},"default":[]},"syntaxKind":{"type":"string"}},"required":["kind","syntaxKind"]},"CaptureSplitSyntax":{"title":"CaptureSplitSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSplitSyntax"},"separator":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"targets":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","separator","source"]},"CaptureSyntax":{"title":"CaptureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSyntax"},"appends":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureAppendSyntax"}]},"default":[]},"children":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureChildrenSyntax"}]},"default":[]},"key":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"keyIsEventSource":{"type":"boolean","default":false},"map":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureMapEntrySyntax"},{"$ref":"#/$defs/CaptureSplitSyntax"}]},"default":[]},"name":{"type":"string"},"nested":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureNestedSyntax"}]},"default":[]},"source":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CaptureSourceSyntax"}]},{"type":"null"}],"default":null},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}}},"required":["kind","name"]},"CaptureTranslationSyntax":{"title":"CaptureTranslationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureTranslationSyntax"},"from":{"type":"string"},"to":{"type":"string"}},"required":["kind","from","to"]},"CaptureWhenSyntax":{"title":"CaptureWhenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureWhenSyntax"},"expression":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"fromValue":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"properties":{"type":"array","items":{"type":"string"},"default":[]},"syntaxKind":{"type":"string","enum":["PropertyChanged","Added","Removed","Changed","LogicalOr","LogicalAnd","ValueTransition","Expression"]},"toValue":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","syntaxKind"]},"CausedByExpressionSyntax":{"title":"CausedByExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CausedByExpressionSyntax"},"property":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"ClockOffsetExpressionSyntax":{"title":"ClockOffsetExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClockOffsetExpressionSyntax"},"amount":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"clock":{"type":"string"},"unit":{"type":"string"}},"required":["kind","amount","clock","unit"]},"CommandCalendarSyntax":{"title":"CommandCalendarSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandCalendarSyntax"},"contextMember":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"DateOfExpressionSyntax":{"title":"DateOfExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DateOfExpressionSyntax"},"operand":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","operand"]},"SpecificationTimeZoneSyntax":{"title":"SpecificationTimeZoneSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationTimeZoneSyntax"},"id":{"type":"string"}},"required":["kind","id"]},"TimeZoneSyntax":{"title":"TimeZoneSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TimeZoneSyntax"},"configurable":{"type":"boolean"},"id":{"type":"string"}},"required":["kind","configurable","id"]},"CaseValueExpressionSyntax":{"title":"CaseValueExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaseValueExpressionSyntax"},"parameter":{"type":"string"}},"required":["kind","parameter"]},"ChildrenSyntax":{"title":"ChildrenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ChildrenSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"identifiedBy":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"property":{"type":"string"}},"required":["kind","autoMap","identifiedBy","property"]},"ClaimConditionSyntax":{"title":"ClaimConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClaimConditionSyntax"},"claim":{"type":"string"},"matches":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"matchesSubject":{"type":"boolean"}},"required":["kind","claim","matchesSubject"]},"ClaimIdentitySourceSyntax":{"title":"ClaimIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClaimIdentitySourceSyntax"},"claim":{"type":"string"}},"required":["kind","claim"]},"CodeIdentitySourceSyntax":{"title":"CodeIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CodeIdentitySourceSyntax"},"code":{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]}},"required":["kind","code"]},"FileIdentitySourceSyntax":{"title":"FileIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileIdentitySourceSyntax"},"file":{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]}},"required":["kind","file"]},"IdentitySyntax":{"title":"IdentitySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IdentitySyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"details":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/IdentityDetailSyntax"}]},"default":[]}},"required":["kind"]},"IdentityDetailSyntax":{"title":"IdentityDetailSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IdentityDetailSyntax"},"name":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/ClaimIdentitySourceSyntax"},{"$ref":"#/$defs/CodeIdentitySourceSyntax"},{"$ref":"#/$defs/FileIdentitySourceSyntax"},{"$ref":"#/$defs/QueryIdentitySourceSyntax"}]},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","source","type"]},"QueryIdentitySourceSyntax":{"title":"QueryIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"QueryIdentitySourceSyntax"},"by":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"query":{"type":"string"}},"required":["kind","by","query"]},"ClearMappingSyntax":{"title":"ClearMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClearMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"ClearWithSyntax":{"title":"ClearWithSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClearWithSyntax"},"event":{"type":"string"}},"required":["kind","event"]},"CloseDialogActionSyntax":{"title":"CloseDialogActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CloseDialogActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind"]},"CodeBlockSyntax":{"title":"CodeBlockSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CodeBlockSyntax"},"code":{"type":"string"},"language":{"type":"string"}},"required":["kind","code","language"]},"ComponentExposedValueSyntax":{"title":"ComponentExposedValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComponentExposedValueSyntax"},"binding":{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},"name":{"type":"string"}},"required":["kind","binding","name"]},"ComponentOutletSyntax":{"title":"ComponentOutletSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComponentOutletSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ComponentPropertySyntax":{"title":"ComponentPropertySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComponentPropertySyntax"},"binding":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},{"type":"null"}],"default":null},"property":{"type":"string"},"value":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","property"]},"CodeValidateSyntax":{"title":"CodeValidateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CodeValidateSyntax"},"code":{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]}},"required":["kind","code"]},"CommandSyntax":{"title":"CommandSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"calendar":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandCalendarSyntax"}]},{"type":"null"}],"default":null},"concurrency":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ConcurrencySyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"handler":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/HandlerSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"produces":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProducesSyntax"}]},"default":[]},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]},"reads":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReadsSyntax"}]}},{"type":"null"}],"default":[]},"response":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScalarCommandResponseSyntax"},{"$ref":"#/$defs/RecordCommandResponseSyntax"}]},{"type":"null"}],"default":null},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandStreamSyntax"}]},{"type":"null"}],"default":null},"streamCandidates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CommandStreamSyntax"}]},"default":[]},"validations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CodeValidateSyntax"},{"$ref":"#/$defs/DeclarativeValidateSyntax"}]},"default":[]}},"required":["kind","name"]},"CommandStreamSyntax":{"title":"CommandStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandStreamSyntax"},"eventSource":{"type":"string"},"propertyCandidate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},{"type":"null"}],"default":null},"stream":{"type":"string"},"streamId":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},{"type":"null"}],"default":null},"streamIdParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventSource","stream"]},"ObserverFilterSyntax":{"title":"ObserverFilterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ObserverFilterSyntax"},"eventSource":{"type":"string"},"stream":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","eventSource"]},"ComparisonConditionSyntax":{"title":"ComparisonConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComparisonConditionSyntax"},"left":{"type":"string"},"leftExpression":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"operator":{"type":"string","enum":["Equal","NotEqual","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Contains","StartsWith"]},"right":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","left","operator","right"]},"CompositeKeySyntax":{"title":"CompositeKeySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CompositeKeySyntax"},"parts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/KeyPartSyntax"}]},"default":[]},"type":{"type":"string"}},"required":["kind","type"]},"ConceptAttributeSyntax":{"title":"ConceptAttributeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConceptAttributeSyntax"},"criminal":{"type":"boolean","default":false},"name":{"type":"string"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"specialCategory":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"ConceptSyntax":{"title":"ConceptSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConceptSyntax"},"attributes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ConceptAttributeSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"generation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/GenerationSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"type":{"type":"string"},"validations":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CodeValidateSyntax"},{"$ref":"#/$defs/DeclarativeValidateSyntax"}]}},{"type":"null"}],"default":[]},"valueNumbers":{"anyOf":[{"type":"array","items":{"type":"integer","minimum":-2147483648,"maximum":2147483647}},{"type":"null"}],"default":null},"values":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","name","type"]},"GenerationSyntax":{"title":"GenerationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"GenerationSyntax"},"alphabet":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"case":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"checksum":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"count":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"encoding":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"pattern":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"range":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"rule":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"size":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"strategy":{"type":"string"}},"required":["kind","strategy"]},"ConcurrencySyntax":{"title":"ConcurrencySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConcurrencySyntax"},"eventSource":{"type":"boolean"},"eventSourceType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"eventStreamId":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"eventStreamType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"eventTypes":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","eventSource"]},"ConfirmActionSyntax":{"title":"ConfirmActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConfirmActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"message":{"type":"string"},"messageIsLiteral":{"type":"boolean"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","message","messageIsLiteral"]},"ContextExpressionSyntax":{"title":"ContextExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContextExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"IdentityExpressionSyntax":{"title":"IdentityExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IdentityExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"ContributionSyntax":{"title":"ContributionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributionSyntax"},"contributionPoint":{"type":"string"},"destination":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ContributionDestinationSyntax"}]},{"type":"null"}],"default":null},"group":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"navigate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"order":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"presentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","contributionPoint"]},"ContributionDestinationSyntax":{"title":"ContributionDestinationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributionDestinationSyntax"},"syntaxKind":{"type":"string","enum":["Outlet","Dialog","External"]},"target":{"type":"string"}},"required":["kind","syntaxKind","target"]},"CountMappingSyntax":{"title":"CountMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CountMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"DeclarativeValidateSyntax":{"title":"DeclarativeValidateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DeclarativeValidateSyntax"},"requirements":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/RequirementSyntax"}]}},{"type":"null"}],"default":[]},"rules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ValidationRuleSyntax"}]},"default":[]}},"required":["kind"]},"DecrementMappingSyntax":{"title":"DecrementMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DecrementMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"DialogTemplateSyntax":{"title":"DialogTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DialogTemplateSyntax"},"arrangement":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"content":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateSlotContentSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"displayName":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateExposedValueSyntax"}]},"default":[]},"name":{"type":"string"},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateOutletSyntax"}]},"default":[]},"restrictsScopes":{"type":"boolean","default":false},"scopes":{"type":"array","items":{"type":"string"},"default":[]},"sliceKinds":{"type":"array","items":{"type":"string"},"default":[]},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SlotSyntax"}]},"default":[]},"templateType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","name"]},"DomainSyntax":{"title":"DomainSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DomainSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"EnvironmentExpressionSyntax":{"title":"EnvironmentExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EnvironmentExpressionSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"EventContextExpressionSyntax":{"title":"EventContextExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventContextExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"EventInteractionTriggerSyntax":{"title":"EventInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventInteractionTriggerSyntax"},"eventName":{"type":"string"}},"required":["kind","eventName"]},"EventSourceIdExpressionSyntax":{"title":"EventSourceIdExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSourceIdExpressionSyntax"}},"required":["kind"]},"EventSourceSyntax":{"title":"EventSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSourceSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"identifier":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"streams":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventStreamSyntax"}]},"default":[]},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","name"]},"EventStreamIdPartSyntax":{"title":"EventStreamIdPartSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventStreamIdPartSyntax"},"name":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"EventStreamSyntax":{"title":"EventStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventStreamSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"streamId":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null},"streamIdParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventStreamIdPartSyntax"}]},"default":[]}},"required":["kind","name"]},"EventSpecSyntax":{"title":"EventSpecSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSpecSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"EventSyntax":{"title":"EventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"generation":{"type":"integer","minimum":0,"maximum":4294967295,"default":1},"hasGenerationMarker":{"type":"boolean","default":false},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]},"tags":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TagSyntax"}]}},{"type":"null"}],"default":[]},"visibility":{"type":"string","enum":["Private","Public"],"default":"Private"}},"required":["kind","name"]},"EverySyntax":{"title":"EverySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EverySyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"includeChildren":{"type":"boolean"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]}},"required":["kind","autoMap","includeChildren"]},"ExecuteCommandActionSyntax":{"title":"ExecuteCommandActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExecuteCommandActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"command":{"type":"string"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","command"]},"ExpressionKeySyntax":{"title":"ExpressionKeySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExpressionKeySyntax"},"expression":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","expression"]},"FeatureSyntax":{"title":"FeatureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FeatureSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"contributions":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributionSyntax"}]}},{"type":"null"}],"default":[]},"dependsOn":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/DependsOnSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"features":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FeatureSyntax"}]},"default":[]},"fileImports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileImportSyntax"}]},"default":[]},"isPlacement":{"type":"boolean"},"name":{"type":"string"},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeReferenceSyntax"}]},"default":[]},"slices":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SliceSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"toolbars":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenToolbarSyntax"}]},"default":[]},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","isPlacement","name"]},"FileConstraintSyntax":{"title":"FileConstraintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileConstraintSyntax"},"additionalRules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},"ignoreCasing":{"type":"boolean"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"releasedBy":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","file","ignoreCasing","name"]},"FileImportSyntax":{"title":"FileImportSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileImportSyntax"},"pattern":{"type":"string"}},"required":["kind","pattern"]},"FileReferenceSyntax":{"title":"FileReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileReferenceSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"FormColumnSyntax":{"title":"FormColumnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormColumnSyntax"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"}},"required":["kind","property"]},"ExposureSyntax":{"title":"ExposureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExposureSyntax"},"owner":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ExposedPropertySyntax"}]},"default":[]}},"required":["kind","owner"]},"ExposedPropertySyntax":{"title":"ExposedPropertySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExposedPropertySyntax"},"component":{"type":"string"},"editableFields":{"type":"array","items":{"type":"string"},"default":[]},"isCollection":{"type":"boolean"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"operations":{"type":"array","items":{"type":"string"},"default":[]},"path":{"type":"string"},"reExposes":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"restrictsFields":{"type":"boolean"}},"required":["kind","component","isCollection","path","restrictsFields"]},"InstanceContributionsSyntax":{"title":"InstanceContributionsSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InstanceContributionsSyntax"},"contributions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InstanceContributionSyntax"}]},"default":[]},"instance":{"type":"string"}},"required":["kind","instance"]},"InstanceContributionSyntax":{"title":"InstanceContributionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InstanceContributionSyntax"},"component":{"type":"string"},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributedItemSyntax"}]},"default":[]},"path":{"type":"string"},"value":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","component","path"]},"ContributedItemSyntax":{"title":"ContributedItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributedItemSyntax"},"id":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributedItemValueSyntax"}]},"default":[]}},"required":["kind","id"]},"ContributedItemValueSyntax":{"title":"ContributedItemValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributedItemValueSyntax"},"field":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","field","value"]},"ScreenContributionSyntax":{"title":"ScreenContributionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenContributionSyntax"},"contributionPoint":{"type":"string"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"order":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","contributionPoint"]},"TemplateSlotContentSyntax":{"title":"TemplateSlotContentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateSlotContentSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"slot":{"type":"string"}},"required":["kind","slot"]},"CommandFormLayoutSyntax":{"title":"CommandFormLayoutSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandFormLayoutSyntax"},"columnGap":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null},"columns":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormLayoutColumnSyntax"}]},"default":[]},"placements":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormFieldPlacementSyntax"}]},"default":[]},"rowGap":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"FormLayoutColumnSyntax":{"title":"FormLayoutColumnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormLayoutColumnSyntax"},"index":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"maxWidth":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null},"minWidth":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null},"width":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","index"]},"FormFieldPlacementSyntax":{"title":"FormFieldPlacementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormFieldPlacementSyntax"},"column":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"columnSpan":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"field":{"type":"string"},"row":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"rowSpan":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"width":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","column","field","row"]},"FormWidthSyntax":{"title":"FormWidthSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormWidthSyntax"},"unit":{"type":"string","enum":["Fraction","Pixels","Percent","Auto"]},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null}},"required":["kind","unit"]},"FormFieldSyntax":{"title":"FormFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormFieldSyntax"},"composeUsing":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"from":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"}},"required":["kind","property"]},"FormPopulateFromItemSyntax":{"title":"FormPopulateFromItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormPopulateFromItemSyntax"}},"required":["kind"]},"FormPopulateViaQuerySyntax":{"title":"FormPopulateViaQuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormPopulateViaQuerySyntax"},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"query":{"type":"string"}},"required":["kind","query"]},"FormSyntax":{"title":"FormSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormSyntax"},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"columnMode":{"type":"string","enum":["Unspecified","Auto","Manual"]},"columns":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormColumnSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormFieldSyntax"}]},"default":[]},"for":{"type":"string"},"generationMode":{"type":"string","enum":["Unspecified","Auto","Manual"]},"layout":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandFormLayoutSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"onSubmit":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"populate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormPopulateFromItemSyntax"},{"$ref":"#/$defs/FormPopulateViaQuerySyntax"}]},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","columnMode","for","generationMode","name"]},"FromSyntax":{"title":"FromSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FromSyntax"},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventSpecSyntax"}]},"default":[]},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CompositeKeySyntax"},{"$ref":"#/$defs/ExpressionKeySyntax"}]},{"type":"null"}],"default":null},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]},"parentKey":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"HandlerSyntax":{"title":"HandlerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"HandlerSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"implementation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ImplementationSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"ImplementationSyntax":{"title":"ImplementationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ImplementationSyntax"},"hints":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ImplementationHintSyntax"}]},"default":[]}},"required":["kind"]},"ImplementationHintSyntax":{"title":"ImplementationHintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ImplementationHintSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"SystemSyntax":{"title":"SystemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SystemSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"OperationSyntax":{"title":"OperationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"OperationSyntax"},"compensate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/OperationPhaseSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"execute":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/OperationPhaseSyntax"}]},{"type":"null"}],"default":null},"inputs":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]},"name":{"type":"string"},"uses":{"type":"string"}},"required":["kind","name","uses"]},"OperationPhaseSyntax":{"title":"OperationPhaseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"OperationPhaseSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"implementation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ImplementationSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"SpecificationExampleSyntax":{"title":"SpecificationExampleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationExampleSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"generatedValues":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"name":{"type":"string"},"noStream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoStreamSyntax"}]},{"type":"null"}],"default":null},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationStreamSyntax"}]},{"type":"null"}],"default":null},"type":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","name","type"]},"SpecificationParameterSyntax":{"title":"SpecificationParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationParameterSyntax"},"name":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"SpecificationCaseSyntax":{"title":"SpecificationCaseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCaseSyntax"},"name":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","name"]},"SpecificationOperationFailureSyntax":{"title":"SpecificationOperationFailureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationOperationFailureSyntax"},"operation":{"type":"string"}},"required":["kind","operation"]},"SpecificationOperationSyntax":{"title":"SpecificationOperationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationOperationSyntax"},"operation":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","operation"]},"SpecificationCompensatedSyntax":{"title":"SpecificationCompensatedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCompensatedSyntax"},"operation":{"type":"string"}},"required":["kind","operation"]},"ImportSyntax":{"title":"ImportSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ImportSyntax"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"qualifiedName":{"type":"string"},"visibility":{"type":"string","enum":["Private","Public"],"default":"Private"}},"required":["kind","qualifiedName"]},"IncrementMappingSyntax":{"title":"IncrementMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IncrementMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"InteractionAlternativeSyntax":{"title":"InteractionAlternativeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionAlternativeSyntax"},"actions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"condition":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]}},"required":["kind","condition"]},"InteractionOtherwiseSyntax":{"title":"InteractionOtherwiseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionOtherwiseSyntax"},"actions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind"]},"InteractionArgumentSyntax":{"title":"InteractionArgumentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionArgumentSyntax"},"binding":{"type":"string"},"name":{"type":"string"}},"required":["kind","binding","name"]},"InteractionBindingSyntax":{"title":"InteractionBindingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionBindingSyntax"},"actions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"alternatives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionAlternativeSyntax"}]},"default":[]},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"otherwise":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/InteractionOtherwiseSyntax"}]},{"type":"null"}],"default":null},"trigger":{"oneOf":[{"$ref":"#/$defs/ApplicationTriggerInteractionTriggerSyntax"},{"$ref":"#/$defs/BuiltInInteractionTriggerSyntax"},{"$ref":"#/$defs/EventInteractionTriggerSyntax"},{"$ref":"#/$defs/IntervalInteractionTriggerSyntax"}]}},"required":["kind","trigger"]},"IntervalInteractionTriggerSyntax":{"title":"IntervalInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IntervalInteractionTriggerSyntax"},"amount":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"unit":{"type":"string","enum":["Seconds","Minutes","Hours","Days"]}},"required":["kind","amount","unit"]},"IntervalTriggerSourceSyntax":{"title":"IntervalTriggerSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IntervalTriggerSourceSyntax"},"amount":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"unit":{"type":"string","enum":["Seconds","Minutes","Hours","Days"]}},"required":["kind","amount","unit"]},"InvokesSyntax":{"title":"InvokesSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InvokesSyntax"},"command":{"type":"string"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"onRefused":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InvocationRefusalSyntax"}]},"default":[]}},"required":["kind","command"]},"InvocationRefusalSyntax":{"title":"InvocationRefusalSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InvocationRefusalSyntax"},"acknowledge":{"type":"boolean"},"constraint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"produces":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProducesSyntax"}]},"default":[]},"selector":{"type":"string"}},"required":["kind","acknowledge","selector"]},"JoinEventSyntax":{"title":"JoinEventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"JoinEventSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"event":{"type":"string"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]}},"required":["kind","autoMap","event"]},"JoinSyntax":{"title":"JoinSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"JoinSyntax"},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/JoinEventSyntax"}]},"default":[]},"on":{"type":"string"},"property":{"type":"string"}},"required":["kind","on","property"]},"KeyPartSyntax":{"title":"KeyPartSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"KeyPartSyntax"},"expression":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"property":{"type":"string"}},"required":["kind","expression","property"]},"LayoutSyntax":{"title":"LayoutSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LayoutSyntax"},"arrangement":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateExposedValueSyntax"}]},"default":[]},"name":{"type":"string"},"navigation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationRegionSyntax"}]},"default":[]},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateOutletSyntax"}]},"default":[]},"restrictsScopes":{"type":"boolean","default":false},"scopes":{"type":"array","items":{"type":"string"},"default":[]},"sliceKinds":{"type":"array","items":{"type":"string"},"default":[]},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SlotSyntax"}]},"default":[]},"templateType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","name"]},"ListExpressionSyntax":{"title":"ListExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ListExpressionSyntax"},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"default":[]}},"required":["kind"]},"LiteralExpressionSyntax":{"title":"LiteralExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LiteralExpressionSyntax"},"value":{"anyOf":[{"type":["string","boolean","null"]},{"type":"number","minimum":-1.7976931348623157E+308,"maximum":1.7976931348623157E+308},{"type":"object","description":"A non-Double numeric literal. The value is an invariant canonical CLR numeric string (G29 for Decimal, R for Single).","additionalProperties":false,"required":["literalType","value"],"properties":{"literalType":{"enum":["Int32","Int64","Decimal","Single"]},"value":{"type":"string","pattern":"^-?[0-9]\u002B(\\.[0-9]\u002B)?([Ee][\u002B-]?[0-9]\u002B)?$"}}},{"type":"object","description":"An explicit ExactNumber in canonical fixed-point text. The codec additionally enforces the normalized Decimal coefficient bound.","additionalProperties":false,"required":["literalType","value"],"properties":{"literalType":{"const":"ExactNumber"},"value":{"type":"string","pattern":"^(?:0|-?(?:[1-9][0-9]{0,28}|(?:0|[1-9][0-9]{0,28})\\.[0-9]{0,27}[1-9]))$"}}}],"default":null}},"required":["kind"]},"LogicalConditionSyntax":{"title":"LogicalConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LogicalConditionSyntax"},"left":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},"operator":{"type":"string","enum":["And","Or"]},"right":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]}},"required":["kind","left","operator","right"]},"LogicalPolicyConditionSyntax":{"title":"LogicalPolicyConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LogicalPolicyConditionSyntax"},"left":{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]},"operator":{"type":"string","enum":["And","Or"]},"right":{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]}},"required":["kind","left","operator","right"]},"LogicalPolicyRequirementSyntax":{"title":"LogicalPolicyRequirementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LogicalPolicyRequirementSyntax"},"left":{"oneOf":[{"$ref":"#/$defs/LogicalPolicyRequirementSyntax"},{"$ref":"#/$defs/PolicyReferenceSyntax"}]},"operator":{"type":"string","enum":["And","Or"]},"right":{"oneOf":[{"$ref":"#/$defs/LogicalPolicyRequirementSyntax"},{"$ref":"#/$defs/PolicyReferenceSyntax"}]}},"required":["kind","left","operator","right"]},"ModuleSyntax":{"title":"ModuleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ModuleSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"contributions":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributionSyntax"}]}},{"type":"null"}],"default":[]},"dependsOn":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/DependsOnSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"dialogTemplates":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/DialogTemplateSyntax"}]}},{"type":"null"}],"default":[]},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"features":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FeatureSyntax"}]},"default":[]},"fileImports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileImportSyntax"}]},"default":[]},"forms":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormSyntax"}]}},{"type":"null"}],"default":[]},"isPlacement":{"type":"boolean"},"name":{"type":"string"},"navigation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationRegionSyntax"}]},"default":[]},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeReferenceSyntax"}]},"default":[]},"screenTemplates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenTemplateSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"toolbars":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenToolbarSyntax"}]},"default":[]},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","isPlacement","name"]},"NamedTriggerSourceSyntax":{"title":"NamedTriggerSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NamedTriggerSourceSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"NavigateActionSyntax":{"title":"NavigateActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigateActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"screen":{"type":"string"}},"required":["kind","screen"]},"NavigateBackActionSyntax":{"title":"NavigateBackActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigateBackActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind"]},"NestedSyntax":{"title":"NestedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NestedSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"property":{"type":"string"}},"required":["kind","autoMap","property"]},"NotPolicyConditionSyntax":{"title":"NotPolicyConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NotPolicyConditionSyntax"},"operand":{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]}},"required":["kind","operand"]},"NotifyActionSyntax":{"title":"NotifyActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NotifyActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"level":{"type":"string","enum":["Info","Warning","Error","Unknown"]},"message":{"type":"string"},"messageIsLiteral":{"type":"boolean"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","level","message","messageIsLiteral"]},"OpenDialogActionSyntax":{"title":"OpenDialogActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"OpenDialogActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"dialogTemplate":{"type":"string"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","dialogTemplate"]},"ObjectExpressionSyntax":{"title":"ObjectExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ObjectExpressionSyntax"},"members":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ObjectMemberSyntax"}]},"default":[]}},"required":["kind"]},"ObjectMemberSyntax":{"title":"ObjectMemberSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ObjectMemberSyntax"},"name":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","name","value"]},"PathExpressionSyntax":{"title":"PathExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PathExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"PerformerSyntax":{"title":"PerformerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PerformerSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"PersonaSyntax":{"title":"PersonaSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PersonaSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"goals":{"type":"array","items":{"type":"string"},"default":[]},"height":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"name":{"type":"string"},"policies":{"type":"array","items":{"type":"string"},"default":[]},"width":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","name"]},"StickyNoteSyntax":{"title":"StickyNoteSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"StickyNoteSyntax"},"canvas":{"type":"string"},"colour":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"height":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"text":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"x":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"y":{"type":"integer","minimum":-2147483648,"maximum":2147483647}},"required":["kind","canvas","text","x","y"]},"PlaceSyntax":{"title":"PlaceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PlaceSyntax"},"hidden":{"type":"boolean","default":false},"sizeHeight":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"sizeWidth":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"slotName":{"type":"string"},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","slotName"]},"PolicyReferenceSyntax":{"title":"PolicyReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PolicyReferenceSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"PolicySyntax":{"title":"PolicySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PolicySyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"condition":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"PurposeSyntax":{"title":"PurposeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PurposeSyntax"},"authorization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"basisReference":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"conditionReference":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"erasureException":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"interest":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"recipients":{"type":"array","items":{"type":"string"},"default":[]},"retention":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"subjects":{"type":"array","items":{"type":"string"},"default":[]},"transfers":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeTransferSyntax"}]},"default":[]}},"required":["kind","name"]},"PurposeReferenceSyntax":{"title":"PurposeReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PurposeReferenceSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"PurposeTransferSyntax":{"title":"PurposeTransferSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PurposeTransferSyntax"},"destination":{"type":"string"},"safeguard":{"type":"string"}},"required":["kind","destination","safeguard"]},"ProducesSyntax":{"title":"ProducesSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProducesSyntax"},"event":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"inlineEvent":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/EventSyntax"}]},{"type":"null"}],"default":null},"inlineOperation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/OperationSyntax"}]},{"type":"null"}],"default":null},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandStreamSyntax"}]},{"type":"null"}],"default":null},"tags":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TagSyntax"}]}},{"type":"null"}],"default":[]},"when":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"ProjectionEntersOnSyntax":{"title":"ProjectionEntersOnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProjectionEntersOnSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"ProjectionSyntax":{"title":"ProjectionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProjectionSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CompositeKeySyntax"},{"$ref":"#/$defs/ExpressionKeySyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"readModel":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}}},"required":["kind","autoMap","name"]},"ProjectionVariantSyntax":{"title":"ProjectionVariantSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProjectionVariantSyntax"},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"entersOn":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProjectionEntersOnSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"PresentationValueSyntax":{"title":"PresentationValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PresentationValueSyntax"},"name":{"type":"string"},"value":{"type":"string"}},"required":["kind","name","value"]},"PropertyMappingSyntax":{"title":"PropertyMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PropertyMappingSyntax"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","source"]},"PropertySyntax":{"title":"PropertySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PropertySyntax"},"isGenerated":{"type":"boolean","default":false},"isIdentifier":{"type":"boolean","default":false},"isKey":{"type":"boolean","default":false},"isSubject":{"type":"boolean","default":false},"name":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"PropertyResponseSourceSyntax":{"title":"PropertyResponseSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PropertyResponseSourceSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"ResponseFieldSyntax":{"title":"ResponseFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ResponseFieldSyntax"},"name":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/PropertyResponseSourceSyntax"}]},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name","source"]},"ScalarCommandResponseSyntax":{"title":"ScalarCommandResponseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScalarCommandResponseSyntax"},"source":{"oneOf":[{"$ref":"#/$defs/PropertyResponseSourceSyntax"}]}},"required":["kind","source"]},"RecordCommandResponseSyntax":{"title":"RecordCommandResponseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RecordCommandResponseSyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ResponseFieldSyntax"}]},"default":[]}},"required":["kind"]},"ScalarSpecificationReturnSyntax":{"title":"ScalarSpecificationReturnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScalarSpecificationReturnSyntax"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","value"]},"RecordSpecificationReturnSyntax":{"title":"RecordSpecificationReturnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RecordSpecificationReturnSyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind"]},"QueryParameterSyntax":{"title":"QueryParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"QueryParameterSyntax"},"name":{"type":"string"},"source":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"QuerySyntax":{"title":"QuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"QuerySyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"by":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/QueryParameterSyntax"}]},{"type":"null"}],"default":null},"byParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/QueryParameterSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"filters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/QueryParameterSyntax"}]},"default":[]},"isObservable":{"type":"boolean","default":false},"name":{"type":"string"},"performer":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PerformerSyntax"}]},{"type":"null"}],"default":null},"returnType":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name","returnType"]},"RaiseTriggerActionSyntax":{"title":"RaiseTriggerActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RaiseTriggerActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"trigger":{"type":"string"}},"required":["kind","trigger"]},"RawExpressionSyntax":{"title":"RawExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RawExpressionSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"ReactionIdentitySyntax":{"title":"ReactionIdentitySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReactionIdentitySyntax"},"roles":{"type":"array","items":{"type":"string"},"default":[]},"syntaxKind":{"type":"string"}},"required":["kind","syntaxKind"]},"ReactionSyntax":{"title":"ReactionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReactionSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"from":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ObserverFilterSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"runsAs":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ReactionIdentitySyntax"}]},{"type":"null"}],"default":null},"triggers":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReactionTriggerSyntax"}]},"default":[]},"where":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"ReactionTriggerSyntax":{"title":"ReactionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReactionTriggerSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"data":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TriggerDataSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"invokes":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InvokesSyntax"}]}},{"type":"null"}],"default":[]},"produces":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProducesSyntax"}]}},{"type":"null"}],"default":[]},"reads":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReadsSyntax"}]}},{"type":"null"}],"default":[]},"source":{"oneOf":[{"$ref":"#/$defs/IntervalTriggerSourceSyntax"},{"$ref":"#/$defs/NamedTriggerSourceSyntax"},{"$ref":"#/$defs/ScheduleTriggerSourceSyntax"}]}},"required":["kind","source"]},"RefusalExpressionSyntax":{"title":"RefusalExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RefusalExpressionSyntax"},"member":{"type":"string"}},"required":["kind","member"]},"ReadModelSyntax":{"title":"ReadModelSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReadModelSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]}},"required":["kind","name"]},"ReadsSyntax":{"title":"ReadsSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReadsSyntax"},"alias":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"byParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"readModel":{"type":"string"}},"required":["kind","readModel"]},"ReducerRuleSyntax":{"title":"ReducerRuleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReducerRuleSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"event":{"type":"string"},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"ReducerSyntax":{"title":"ReducerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReducerSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"from":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ObserverFilterSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"readModel":{"type":"string"},"rules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReducerRuleSyntax"}]},"default":[]}},"required":["kind","name","readModel"]},"RefreshQueryActionSyntax":{"title":"RefreshQueryActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RefreshQueryActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"query":{"type":"string"}},"required":["kind","query"]},"RemoveViaJoinSyntax":{"title":"RemoveViaJoinSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RemoveViaJoinSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"RemoveWithSyntax":{"title":"RemoveWithSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RemoveWithSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"parentKey":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"partsKey":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CompositeKeySyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"RequirementSyntax":{"title":"RequirementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RequirementSyntax"},"condition":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"severity":{"type":"string","enum":["Error","Information","Warning"]}},"required":["kind","condition","severity"]},"RoleConditionSyntax":{"title":"RoleConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RoleConditionSyntax"},"role":{"type":"string"}},"required":["kind","role"]},"ScheduleTriggerSourceSyntax":{"title":"ScheduleTriggerSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScheduleTriggerSourceSyntax"},"dayOfMonth":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"dayOfWeek":{"anyOf":[{"type":"string","enum":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},{"type":"null"}],"default":null},"time":{"type":"string","pattern":"^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,7})?$"}},"required":["kind","time"]},"ScreenActionSyntax":{"title":"ScreenActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenActionSyntax"},"command":{"type":"string"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"navigate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","command"]},"ScreenNavigationParameterSyntax":{"title":"ScreenNavigationParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenNavigationParameterSyntax"},"binding":{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},"name":{"type":"string"}},"required":["kind","binding","name"]},"ScreenGuardedActionSyntax":{"title":"ScreenGuardedActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenGuardedActionSyntax"},"alternatives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionAlternativeSyntax"}]},"default":[]},"label":{"type":"string"},"navigate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"otherwise":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenActionOtherwiseSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","label"]},"ScreenActionAlternativeSyntax":{"title":"ScreenActionAlternativeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenActionAlternativeSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"command":{"type":"string"},"condition":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]}},"required":["kind","command","condition"]},"ScreenActionOtherwiseSyntax":{"title":"ScreenActionOtherwiseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenActionOtherwiseSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"command":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"outcome":{"type":"string","enum":["Hidden","Execute","Unknown"]}},"required":["kind","outcome"]},"ScreenBehaviorSyntax":{"title":"ScreenBehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenBehaviorSyntax"},"behavior":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]}},"required":["kind","behavior"]},"ScreenCodeSyntax":{"title":"ScreenCodeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenCodeSyntax"},"code":{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]}},"required":["kind","code"]},"ScreenComponentSyntax":{"title":"ScreenComponentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenComponentSyntax"},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"component":{"type":"string"},"context":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ComponentExposedValueSyntax"}]},"default":[]},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ComponentOutletSyntax"}]},"default":[]},"presentation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PresentationValueSyntax"}]},"default":[]},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ComponentPropertySyntax"}]},"default":[]},"stableId":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","component","name"]},"ScreenColumnSyntax":{"title":"ScreenColumnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenColumnSyntax"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"}},"required":["kind","property"]},"ScreenDataSyntax":{"title":"ScreenDataSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenDataSyntax"},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"query":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","query","type"]},"ScreenFieldSyntax":{"title":"ScreenFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenFieldSyntax"},"label":{"type":"string"},"property":{"type":"string"}},"required":["kind","label","property"]},"ScreenNavigateSyntax":{"title":"ScreenNavigateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenNavigateSyntax"},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"outlet":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenNavigationParameterSyntax"}]},"default":[]},"route":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"screen":{"type":"string"}},"required":["kind","screen"]},"ScreenSectionSyntax":{"title":"ScreenSectionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSectionSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ScreenSlotSyntax":{"title":"ScreenSlotSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSlotSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ScreenSummarySyntax":{"title":"ScreenSummarySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSummarySyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenFieldSyntax"}]},"default":[]},"target":{"type":"string"}},"required":["kind","target"]},"ScreenSyntax":{"title":"ScreenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSyntax"},"contributions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenContributionSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"ScreenTableSyntax":{"title":"ScreenTableSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTableSyntax"},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"columns":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenColumnSyntax"}]},"default":[]},"rowClick":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"target":{"type":"string"},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","target"]},"ScreenTemplateReferenceSyntax":{"title":"ScreenTemplateReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTemplateReferenceSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenSlotSyntax"}]},"default":[]},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"ScreenTemplateSyntax":{"title":"ScreenTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTemplateSyntax"},"arrangement":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"content":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateSlotContentSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"displayName":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateExposedValueSyntax"}]},"default":[]},"fitsSlot":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateOutletSyntax"}]},"default":[]},"restrictsScopes":{"type":"boolean","default":false},"scopes":{"type":"array","items":{"type":"string"},"default":[]},"sliceKinds":{"type":"array","items":{"type":"string"},"default":[]},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SlotSyntax"}]},"default":[]},"templateType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","name"]},"ScreenTitleSyntax":{"title":"ScreenTitleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTitleSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"ScreenToolbarSyntax":{"title":"ScreenToolbarSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenToolbarSyntax"},"buttons":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ToolbarButtonSyntax"}]},"default":[]},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ToolbarItemSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ScreenUsesBehaviorSyntax":{"title":"ScreenUsesBehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenUsesBehaviorSyntax"},"uses":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]}},"required":["kind","uses"]},"SeedEventSyntax":{"title":"SeedEventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SeedEventSyntax"},"event":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","event"]},"SeedGroupSyntax":{"title":"SeedGroupSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SeedGroupSyntax"},"eventSourceId":{"type":"string"},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SeedEventSyntax"}]},"default":[]}},"required":["kind","eventSourceId"]},"SeedSyntax":{"title":"SeedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SeedSyntax"},"groups":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SeedGroupSyntax"}]},"default":[]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind"]},"SetMappingSyntax":{"title":"SetMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SetMappingSyntax"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","source"]},"TemplateAssignmentSyntax":{"title":"TemplateAssignmentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateAssignmentSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"TemplateExposedValueSyntax":{"title":"TemplateExposedValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateExposedValueSyntax"},"name":{"type":"string"},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"TemplateOutletSyntax":{"title":"TemplateOutletSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateOutletSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"SetStateActionSyntax":{"title":"SetStateActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SetStateActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"target":{"type":"string"},"value":{"type":"string"}},"required":["kind","target","value"]},"SliceSyntax":{"title":"SliceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SliceSyntax"},"captures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureSyntax"}]},"default":[]},"commands":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CommandSyntax"}]},"default":[]},"constraints":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"direction":{"anyOf":[{"type":"string","enum":["Inbound","Outbound"]},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventSyntax"}]},"default":[]},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"operations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/OperationSyntax"}]},"default":[]},"projections":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProjectionSyntax"}]},"default":[]},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeReferenceSyntax"}]},"default":[]},"queries":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/QuerySyntax"}]},"default":[]},"reactions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReactionSyntax"}]},"default":[]},"readModels":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReadModelSyntax"}]}},{"type":"null"}],"default":[]},"reducers":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReducerSyntax"}]}},{"type":"null"}],"default":[]},"screens":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenSyntax"}]},"default":[]},"specifications":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"type":{"type":"string","enum":["StateChange","StateView","Automation","Translate"]}},"required":["kind","name","type"]},"SlotSyntax":{"title":"SlotSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SlotSyntax"},"contributes":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"SourceItemExpressionSyntax":{"title":"SourceItemExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SourceItemExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"SpecificationAbsentReadModelSyntax":{"title":"SpecificationAbsentReadModelSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationAbsentReadModelSyntax"},"key":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"name":{"type":"string"}},"required":["kind","key","name"]},"SpecificationCallerClaimSyntax":{"title":"SpecificationCallerClaimSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCallerClaimSyntax"},"type":{"type":"string"},"value":{"type":"string"}},"required":["kind","type","value"]},"SpecificationCallerPersonaSyntax":{"title":"SpecificationCallerPersonaSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCallerPersonaSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"SpecificationCallerSyntax":{"title":"SpecificationCallerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCallerSyntax"},"authenticated":{"type":"boolean"},"claims":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCallerClaimSyntax"}]},"default":[]},"roles":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","authenticated"]},"SpecificationCaptureSyntax":{"title":"SpecificationCaptureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCaptureSyntax"},"capture":{"type":"string"},"record":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","capture"]},"SpecificationClockSyntax":{"title":"SpecificationClockSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationClockSyntax"},"instant":{"type":"string"}},"required":["kind","instant"]},"SpecificationGeneratedValueSyntax":{"title":"SpecificationGeneratedValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationGeneratedValueSyntax"},"command":{"type":"string"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","command","property","source"]},"SpecificationCommandSyntax":{"title":"SpecificationCommandSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCommandSyntax"},"commandType":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"generatedValues":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"inlineProperty":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","commandType"]},"SpecificationDeniedSyntax":{"title":"SpecificationDeniedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationDeniedSyntax"}},"required":["kind"]},"SpecificationErrorSyntax":{"title":"SpecificationErrorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationErrorSyntax"},"caseValue":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CaseValueExpressionSyntax"}]},{"type":"null"}],"default":null},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"SpecificationEventSyntax":{"title":"SpecificationEventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationEventSyntax"},"eventType":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"inlineProperty":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"noStream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoStreamSyntax"}]},{"type":"null"}],"default":null},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationStreamSyntax"}]},{"type":"null"}],"default":null},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventType"]},"NewScreenTemplateSyntax":{"title":"NewScreenTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NewScreenTemplateSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"ProfileAppearanceSyntax":{"title":"ProfileAppearanceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProfileAppearanceSyntax"},"accent":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"colorScheme":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"corners":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"font":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"ProfileIdentitySyntax":{"title":"ProfileIdentitySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProfileIdentitySyntax"},"logoKind":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"logoValue":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"showName":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null}},"required":["kind"]},"RootTemplateSyntax":{"title":"RootTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RootTemplateSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"options":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ShellOptionSyntax"}]},"default":[]},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"SampleDataBindingSyntax":{"title":"SampleDataBindingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataBindingSyntax"},"pack":{"oneOf":[{"$ref":"#/$defs/SampleDataPackReferenceSyntax"}]},"readModel":{"type":"string"}},"required":["kind","pack","readModel"]},"ShellOptionSyntax":{"title":"ShellOptionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ShellOptionSyntax"},"name":{"type":"string"},"syntaxKind":{"type":"string","enum":["Word","Text","Number","Flag"]},"value":{"type":"string"}},"required":["kind","name","syntaxKind","value"]},"SampleDataFieldSyntax":{"title":"SampleDataFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataFieldSyntax"},"name":{"type":"string"},"syntaxKind":{"type":"string","enum":["Text","Number","Flag","Null"]},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name","syntaxKind"]},"SampleDataMappingSyntax":{"title":"SampleDataMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataMappingSyntax"},"readModel":{"type":"string"},"shape":{"type":"string"}},"required":["kind","readModel","shape"]},"SampleDataPackReferenceSyntax":{"title":"SampleDataPackReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataPackReferenceSyntax"},"isBlueprint":{"type":"boolean"},"name":{"type":"string"}},"required":["kind","isBlueprint","name"]},"SampleDataPackSyntax":{"title":"SampleDataPackSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataPackSyntax"},"locale":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"sets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataSetSyntax"}]},"default":[]},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"SampleDataRowSyntax":{"title":"SampleDataRowSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataRowSyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataFieldSyntax"}]},"default":[]}},"required":["kind"]},"SampleDataSelectionSyntax":{"title":"SampleDataSelectionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataSelectionSyntax"},"active":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SampleDataPackReferenceSyntax"}]},{"type":"null"}],"default":null},"bindings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataBindingSyntax"}]},"default":[]},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataMappingSyntax"}]},"default":[]}},"required":["kind"]},"SampleDataSetSyntax":{"title":"SampleDataSetSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataSetSyntax"},"rows":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataRowSyntax"}]},"default":[]},"shape":{"type":"string"}},"required":["kind","shape"]},"SpecificationNoResultSyntax":{"title":"SpecificationNoResultSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationNoResultSyntax"}},"required":["kind"]},"SpecificationStreamSyntax":{"title":"SpecificationStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationStreamSyntax"},"eventSource":{"type":"string"},"stream":{"type":"string"},"streamId":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},{"type":"null"}],"default":null},"streamIdParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventSource","stream"]},"SpecificationNoStreamSyntax":{"title":"SpecificationNoStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationNoStreamSyntax"}},"required":["kind"]},"SpecificationQueryResultSyntax":{"title":"SpecificationQueryResultSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationQueryResultSyntax"},"exactly":{"type":"boolean"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","exactly"]},"SpecificationQuerySyntax":{"title":"SpecificationQuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationQuerySyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"exactly":{"type":"boolean"},"query":{"type":"string"},"results":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationQueryResultSyntax"}]},"default":[]}},"required":["kind","exactly","query"]},"SpecificationReadModelSyntax":{"title":"SpecificationReadModelSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationReadModelSyntax"},"exactly":{"type":"boolean"},"inlineProperty":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","exactly","name"]},"SpecificationRedeliverySyntax":{"title":"SpecificationRedeliverySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationRedeliverySyntax"},"eventType":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"noStream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoStreamSyntax"}]},{"type":"null"}],"default":null},"reaction":{"type":"string"},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationStreamSyntax"}]},{"type":"null"}],"default":null},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventType","reaction"]},"SpecificationSyntax":{"title":"SpecificationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationSyntax"},"cases":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCaseSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"given":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationEventSyntax"}]},"default":[]},"givenCaller":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCallerSyntax"}]},{"type":"null"}],"default":null},"givenCallerPersona":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCallerPersonaSyntax"}]},{"type":"null"}],"default":null},"givenCaptures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCaptureSyntax"}]},"default":[]},"givenClock":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationClockSyntax"}]},{"type":"null"}],"default":null},"givenGenerated":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationGeneratedValueSyntax"}]},"default":[]},"givenOperationFailures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationOperationFailureSyntax"}]},"default":[]},"givenReadModels":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationReadModelSyntax"}]}},{"type":"null"}],"default":[]},"givenTimeZone":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationTimeZoneSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationParameterSyntax"}]},"default":[]},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}},"thenAbsentReadModels":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationAbsentReadModelSyntax"}]},"default":[]},"thenCompensated":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCompensatedSyntax"}]},"default":[]},"thenDenied":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationDeniedSyntax"}]},{"type":"null"}],"default":null},"thenErrors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationErrorSyntax"}]},"default":[]},"thenEvents":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationEventSyntax"}]},"default":[]},"thenEventsInAnyOrder":{"type":"boolean"},"thenNoEvents":{"type":"boolean","default":false},"thenNoResult":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoResultSyntax"}]},{"type":"null"}],"default":null},"thenOperations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationOperationSyntax"}]},"default":[]},"thenQueries":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationQuerySyntax"}]},"default":[]},"thenReadModels":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationReadModelSyntax"}]}},{"type":"null"}],"default":[]},"thenResults":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationQueryResultSyntax"}]},"default":[]},"thenReturns":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScalarSpecificationReturnSyntax"},{"$ref":"#/$defs/RecordSpecificationReturnSyntax"}]},{"type":"null"}],"default":null},"when":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCommandSyntax"}]},{"type":"null"}],"default":null},"whenAppended":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationEventSyntax"}]},{"type":"null"}],"default":null},"whenCapture":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCaptureSyntax"}]},{"type":"null"}],"default":null},"whenClock":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationClockSyntax"}]},{"type":"null"}],"default":null},"whenQuery":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationWhenQuerySyntax"}]},{"type":"null"}],"default":null},"whenRedelivered":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationRedeliverySyntax"}]},{"type":"null"}],"default":null},"whenTrigger":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationTriggerSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name","thenEventsInAnyOrder"]},"SpecificationTriggerSyntax":{"title":"SpecificationTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationTriggerSyntax"},"trigger":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","trigger"]},"SpecificationWhenQuerySyntax":{"title":"SpecificationWhenQuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationWhenQuerySyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"query":{"type":"string"}},"required":["kind","query"]},"StringsExpressionSyntax":{"title":"StringsExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"StringsExpressionSyntax"},"key":{"type":"string"}},"required":["kind","key"]},"SubtractMappingSyntax":{"title":"SubtractMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SubtractMappingSyntax"},"factor":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"property":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","value"]},"TagSyntax":{"title":"TagSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TagSyntax"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","value"]},"ToolbarButtonSyntax":{"title":"ToolbarButtonSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ToolbarButtonSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"confirm":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"emphasis":{"anyOf":[{"type":"string","enum":["Primary","Secondary","Quiet"]},{"type":"null"}],"default":null},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"type":"string"},"slice":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"title":{"type":"string"}},"required":["kind","id","title"]},"ToolbarItemSyntax":{"title":"ToolbarItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ToolbarItemSyntax"},"confirm":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenNavigationParameterSyntax"}]},"default":[]},"presentation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PresentationValueSyntax"}]},"default":[]},"syntaxKind":{"type":"string","enum":["Unknown","Action","Navigate","Dialog"]},"target":{"type":"string"}},"required":["kind","name","syntaxKind","target"]},"TemplateExpressionSyntax":{"title":"TemplateExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateExpressionSyntax"},"parts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateInterpolationSyntax"},{"$ref":"#/$defs/TemplateTextSyntax"}]},"default":[]}},"required":["kind"]},"TemplateInterpolationSyntax":{"title":"TemplateInterpolationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateInterpolationSyntax"},"expression":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","expression"]},"TemplateTextSyntax":{"title":"TemplateTextSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateTextSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"ThemeSyntax":{"title":"ThemeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ThemeSyntax"},"compatibleWith":{"type":"array","items":{"type":"string"},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"TriggerDataSyntax":{"title":"TriggerDataSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TriggerDataSyntax"},"name":{"type":"string"},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"TriggerSyntax":{"title":"TriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TriggerSyntax"},"data":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TriggerDataSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"TypeRefSyntax":{"title":"TypeRefSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TypeRefSyntax"},"isCollection":{"type":"boolean"},"isOptional":{"type":"boolean"},"name":{"type":"string"}},"required":["kind","isCollection","isOptional","name"]},"TypeSyntax":{"title":"TypeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TypeSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]}},"required":["kind","name"]},"UiBindingSyntax":{"title":"UiBindingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UiBindingSyntax"},"bindingKind":{"type":"string","enum":["Invalid","DataContext","QueryResult","ComponentProperty","Literal"]},"componentId":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"componentPropertyPath":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"expectedValueType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"literal":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"mode":{"anyOf":[{"type":"string","enum":["OneWay","TwoWay"]},{"type":"null"}],"default":null},"nullBehavior":{"anyOf":[{"type":"string","enum":["Propagate","Clear","Preserve"]},{"type":"null"}],"default":null},"path":{"type":"string"},"query":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"rawText":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","bindingKind","path"]},"UiProfileSyntax":{"title":"UiProfileSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UiProfileSyntax"},"appearance":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ProfileAppearanceSyntax"}]},{"type":"null"}],"default":null},"defaultSizeClass":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"icons":{"type":"array","items":{"type":"string"},"default":[]},"identity":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ProfileIdentitySyntax"}]},{"type":"null"}],"default":null},"layout":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"newScreenTemplate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/NewScreenTemplateSyntax"}]},{"type":"null"}],"default":null},"packages":{"type":"array","items":{"type":"string"},"default":[]},"platforms":{"type":"array","items":{"type":"string"},"default":[]},"root":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/RootTemplateSyntax"}]},{"type":"null"}],"default":null},"sampleData":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SampleDataSelectionSyntax"}]},{"type":"null"}],"default":null},"theme":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"UniqueEventConstraintSyntax":{"title":"UniqueEventConstraintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UniqueEventConstraintSyntax"},"additionalRules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"event":{"type":"string"},"ignoreCasing":{"type":"boolean"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"releasedBy":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","event","ignoreCasing","name"]},"UniquePropertyConstraintSyntax":{"title":"UniquePropertyConstraintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UniquePropertyConstraintSyntax"},"additionalProperties":{"type":"array","items":{"type":"string"},"default":[]},"additionalRules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"event":{"type":"string"},"ignoreCasing":{"type":"boolean"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"property":{"type":"string"},"releasedBy":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","event","ignoreCasing","name","property"]},"DependsOnSyntax":{"title":"DependsOnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DependsOnSyntax"},"target":{"type":"string"}},"required":["kind","target"]},"UsesBehaviorSyntax":{"title":"UsesBehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UsesBehaviorSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorArgumentSyntax"}]},"default":[]},"behavior":{"type":"string"}},"required":["kind","behavior"]},"ValidationRuleSyntax":{"title":"ValidationRuleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ValidationRuleSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"implementation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ImplementationSyntax"}]},{"type":"null"}],"default":null},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"},"rule":{"type":"string","enum":["NotEmpty","Max","Min","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Equal","Length","Matches","AllGreaterThan","AllGreaterThanOrEqual","Rule","NotEqual","Checksum","Contains","NotContains","StartsWith","EndsWith","DecimalPlaces"]},"severity":{"type":"string","enum":["Error","Information","Warning"]},"value":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","property","rule","severity"]},"VariantSyntax":{"title":"VariantSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"VariantSyntax"},"height":{"type":"string"},"places":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PlaceSyntax"}]},"default":[]},"width":{"type":"string"}},"required":["kind","height","width"]},"AnonymousConditionSyntax":{"title":"AnonymousConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AnonymousConditionSyntax"}},"required":["kind"]}} as const; +export const syntaxDefinitions = {"AddMappingSyntax":{"title":"AddMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AddMappingSyntax"},"factor":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"property":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","value"]},"AllSyntax":{"title":"AllSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AllSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]}},"required":["kind","autoMap"]},"ApplicationSyntax":{"title":"ApplicationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ApplicationSyntax"},"authentication":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthenticationSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"commandReadMode":{"anyOf":[{"type":"string","enum":["Protected"]},{"type":"null"}],"default":null},"concepts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ConceptSyntax"}]},"default":[]},"domain":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/DomainSyntax"}]},{"type":"null"}],"default":null},"eventSources":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventSourceSyntax"}]},"default":[]},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"exposures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ExposureSyntax"}]},"default":[]},"fileImports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileImportSyntax"}]},"default":[]},"identity":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/IdentitySyntax"}]},{"type":"null"}],"default":null},"imports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ImportSyntax"}]},"default":[]},"instanceContributions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InstanceContributionsSyntax"}]},"default":[]},"layouts":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/LayoutSyntax"}]}},{"type":"null"}],"default":[]},"modules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ModuleSyntax"}]},"default":[]},"personas":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PersonaSyntax"}]}},{"type":"null"}],"default":[]},"policies":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PolicySyntax"}]},"default":[]},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeSyntax"}]},"default":[]},"reactionProductionMode":{"anyOf":[{"type":"string","enum":["Atomic"]},{"type":"null"}],"default":null},"sampleDataPacks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataPackSyntax"}]},"default":[]},"seeds":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SeedSyntax"}]}},{"type":"null"}],"default":[]},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}},"stickyNotes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/StickyNoteSyntax"}]},"default":[]},"systems":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SystemSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"themes":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ThemeSyntax"}]}},{"type":"null"}],"default":[]},"timeZone":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TimeZoneSyntax"}]},{"type":"null"}],"default":null},"triggers":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TriggerSyntax"}]}},{"type":"null"}],"default":[]},"types":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TypeSyntax"}]}},{"type":"null"}],"default":[]},"uiProfiles":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UiProfileSyntax"}]}},{"type":"null"}],"default":[]}},"required":["kind"]},"ApplicationTriggerInteractionTriggerSyntax":{"title":"ApplicationTriggerInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ApplicationTriggerInteractionTriggerSyntax"},"triggerName":{"type":"string"}},"required":["kind","triggerName"]},"ArrangementContainerSyntax":{"title":"ArrangementContainerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementContainerSyntax"},"children":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ArrangementContainerSyntax"},{"$ref":"#/$defs/ArrangementSlotSyntax"}]},"default":[]},"columns":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"gap":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"grow":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null},"rows":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"span":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"syntaxKind":{"type":"string","enum":["Flat","Row","Column","Grid"]}},"required":["kind","syntaxKind"]},"ArrangementOverrideSyntax":{"title":"ArrangementOverrideSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementOverrideSyntax"},"height":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"root":{"oneOf":[{"$ref":"#/$defs/ArrangementContainerSyntax"},{"$ref":"#/$defs/ArrangementSlotSyntax"}]},"width":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","root"]},"ArrangementSlotSyntax":{"title":"ArrangementSlotSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementSlotSyntax"},"grow":{"type":"boolean","default":false},"growFactor":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null},"height":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"name":{"type":"string"},"span":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"width":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","name"]},"ArrangementSyntax":{"title":"ArrangementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ArrangementSyntax"},"mode":{"type":"string","enum":["Flow","Freeform"]},"overrides":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ArrangementOverrideSyntax"}]}},{"type":"null"}],"default":[]},"root":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementContainerSyntax"},{"$ref":"#/$defs/ArrangementSlotSyntax"}]},{"type":"null"}],"default":null},"variants":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/VariantSyntax"}]}},{"type":"null"}],"default":[]}},"required":["kind","mode"]},"AuthenticatedConditionSyntax":{"title":"AuthenticatedConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthenticatedConditionSyntax"}},"required":["kind"]},"AuthenticationProviderSyntax":{"title":"AuthenticationProviderSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthenticationProviderSyntax"},"alias":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"AuthenticationSyntax":{"title":"AuthenticationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthenticationSyntax"},"providers":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AuthenticationProviderSyntax"}]},"default":[]}},"required":["kind"]},"AuthorizeSyntax":{"title":"AuthorizeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AuthorizeSyntax"},"requirement":{"oneOf":[{"$ref":"#/$defs/LogicalPolicyRequirementSyntax"},{"$ref":"#/$defs/PolicyReferenceSyntax"}]}},"required":["kind","requirement"]},"NavigationItemSyntax":{"title":"NavigationItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationItemSyntax"},"children":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationItemSyntax"}]},"default":[]},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"type":"string"},"slot":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"target":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/NavigationTargetSyntax"}]},{"type":"null"}],"default":null},"title":{"type":"string"}},"required":["kind","id","title"]},"NavigationLogoSyntax":{"title":"NavigationLogoSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationLogoSyntax"},"image":{"type":"string"},"title":{"type":"string"}},"required":["kind","image","title"]},"NavigationRegionSyntax":{"title":"NavigationRegionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationRegionSyntax"},"buttons":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ToolbarButtonSyntax"}]},"default":[]},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationItemSyntax"}]},"default":[]},"logo":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/NavigationLogoSyntax"}]},{"type":"null"}],"default":null},"mode":{"type":"string","enum":["Unspecified","Inherit","Extend","Override"]},"region":{"type":"string","enum":["Topbar","Sidebar"]}},"required":["kind","mode","region"]},"NavigationTargetSyntax":{"title":"NavigationTargetSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigationTargetSyntax"},"feature":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"module":{"type":"string"}},"required":["kind","module"]},"BehaviorArgumentSyntax":{"title":"BehaviorArgumentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BehaviorArgumentSyntax"},"name":{"type":"string"},"value":{"type":"string"}},"required":["kind","name","value"]},"BehaviorParameterSyntax":{"title":"BehaviorParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BehaviorParameterSyntax"},"name":{"type":"string"},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"BehaviorSyntax":{"title":"BehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BehaviorSyntax"},"bindings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionBindingSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"order":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorParameterSyntax"}]},"default":[]}},"required":["kind"]},"BuiltInInteractionTriggerSyntax":{"title":"BuiltInInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"BuiltInInteractionTriggerSyntax"},"syntaxKind":{"type":"string","enum":["Click","DoubleClick","Select","Submit","Change","Load","Unload","Enter","Leave","Unknown"]}},"required":["kind","syntaxKind"]},"CaptureAppendSyntax":{"title":"CaptureAppendSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureAppendSyntax"},"event":{"type":"string"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"tags":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TagSyntax"}]}},{"type":"null"}],"default":[]},"when":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CaptureWhenSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"CaptureChildrenSyntax":{"title":"CaptureChildrenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureChildrenSyntax"},"appends":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureAppendSyntax"}]},"default":[]},"identifiedBy":{"type":"string"},"map":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureMapEntrySyntax"},{"$ref":"#/$defs/CaptureSplitSyntax"}]},"default":[]},"property":{"type":"string"}},"required":["kind","identifiedBy","property"]},"CaptureMapEntrySyntax":{"title":"CaptureMapEntrySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureMapEntrySyntax"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"translations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureTranslationSyntax"}]},"default":[]}},"required":["kind","property","source"]},"CaptureNestedSyntax":{"title":"CaptureNestedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureNestedSyntax"},"appends":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureAppendSyntax"}]},"default":[]},"map":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureMapEntrySyntax"},{"$ref":"#/$defs/CaptureSplitSyntax"}]},"default":[]},"property":{"type":"string"}},"required":["kind","property"]},"CaptureSourceSettingSyntax":{"title":"CaptureSourceSettingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSourceSettingSyntax"},"name":{"type":"string"},"value":{"type":"string"}},"required":["kind","name","value"]},"CaptureSourceSyntax":{"title":"CaptureSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSourceSyntax"},"settings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureSourceSettingSyntax"}]},"default":[]},"syntaxKind":{"type":"string"}},"required":["kind","syntaxKind"]},"CaptureSplitSyntax":{"title":"CaptureSplitSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSplitSyntax"},"separator":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"targets":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","separator","source"]},"CaptureSyntax":{"title":"CaptureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureSyntax"},"appends":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureAppendSyntax"}]},"default":[]},"children":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureChildrenSyntax"}]},"default":[]},"key":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"keyIsEventSource":{"type":"boolean","default":false},"map":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureMapEntrySyntax"},{"$ref":"#/$defs/CaptureSplitSyntax"}]},"default":[]},"name":{"type":"string"},"nested":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureNestedSyntax"}]},"default":[]},"source":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CaptureSourceSyntax"}]},{"type":"null"}],"default":null},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}}},"required":["kind","name"]},"CaptureTranslationSyntax":{"title":"CaptureTranslationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureTranslationSyntax"},"from":{"type":"string"},"to":{"type":"string"}},"required":["kind","from","to"]},"CaptureWhenSyntax":{"title":"CaptureWhenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaptureWhenSyntax"},"expression":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"fromValue":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"properties":{"type":"array","items":{"type":"string"},"default":[]},"syntaxKind":{"type":"string","enum":["PropertyChanged","Added","Removed","Changed","LogicalOr","LogicalAnd","ValueTransition","Expression"]},"toValue":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","syntaxKind"]},"CausedByExpressionSyntax":{"title":"CausedByExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CausedByExpressionSyntax"},"property":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"ClockOffsetExpressionSyntax":{"title":"ClockOffsetExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClockOffsetExpressionSyntax"},"amount":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"clock":{"type":"string"},"unit":{"type":"string"}},"required":["kind","amount","clock","unit"]},"CommandCalendarSyntax":{"title":"CommandCalendarSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandCalendarSyntax"},"contextMember":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"DateOfExpressionSyntax":{"title":"DateOfExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DateOfExpressionSyntax"},"operand":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","operand"]},"SpecificationTimeZoneSyntax":{"title":"SpecificationTimeZoneSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationTimeZoneSyntax"},"id":{"type":"string"}},"required":["kind","id"]},"TimeZoneSyntax":{"title":"TimeZoneSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TimeZoneSyntax"},"configurable":{"type":"boolean"},"id":{"type":"string"}},"required":["kind","configurable","id"]},"CaseValueExpressionSyntax":{"title":"CaseValueExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CaseValueExpressionSyntax"},"parameter":{"type":"string"}},"required":["kind","parameter"]},"ChildrenSyntax":{"title":"ChildrenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ChildrenSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"identifiedBy":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"property":{"type":"string"}},"required":["kind","autoMap","identifiedBy","property"]},"ClaimConditionSyntax":{"title":"ClaimConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClaimConditionSyntax"},"claim":{"type":"string"},"matches":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"matchesSubject":{"type":"boolean"}},"required":["kind","claim","matchesSubject"]},"ClaimIdentitySourceSyntax":{"title":"ClaimIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClaimIdentitySourceSyntax"},"claim":{"type":"string"}},"required":["kind","claim"]},"CodeIdentitySourceSyntax":{"title":"CodeIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CodeIdentitySourceSyntax"},"code":{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]}},"required":["kind","code"]},"FileIdentitySourceSyntax":{"title":"FileIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileIdentitySourceSyntax"},"file":{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]}},"required":["kind","file"]},"IdentitySyntax":{"title":"IdentitySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IdentitySyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"details":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/IdentityDetailSyntax"}]},"default":[]}},"required":["kind"]},"IdentityDetailSyntax":{"title":"IdentityDetailSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IdentityDetailSyntax"},"name":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/ClaimIdentitySourceSyntax"},{"$ref":"#/$defs/CodeIdentitySourceSyntax"},{"$ref":"#/$defs/FileIdentitySourceSyntax"},{"$ref":"#/$defs/QueryIdentitySourceSyntax"}]},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","source","type"]},"QueryIdentitySourceSyntax":{"title":"QueryIdentitySourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"QueryIdentitySourceSyntax"},"by":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"query":{"type":"string"}},"required":["kind","by","query"]},"ClearMappingSyntax":{"title":"ClearMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClearMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"ClearWithSyntax":{"title":"ClearWithSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ClearWithSyntax"},"event":{"type":"string"}},"required":["kind","event"]},"CloseDialogActionSyntax":{"title":"CloseDialogActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CloseDialogActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind"]},"CodeBlockSyntax":{"title":"CodeBlockSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CodeBlockSyntax"},"code":{"type":"string"},"language":{"type":"string"}},"required":["kind","code","language"]},"ComponentExposedValueSyntax":{"title":"ComponentExposedValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComponentExposedValueSyntax"},"binding":{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},"name":{"type":"string"}},"required":["kind","binding","name"]},"ComponentOutletSyntax":{"title":"ComponentOutletSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComponentOutletSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ComponentPropertySyntax":{"title":"ComponentPropertySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComponentPropertySyntax"},"binding":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},{"type":"null"}],"default":null},"property":{"type":"string"},"value":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","property"]},"CodeValidateSyntax":{"title":"CodeValidateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CodeValidateSyntax"},"code":{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]}},"required":["kind","code"]},"CommandSyntax":{"title":"CommandSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"calendar":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandCalendarSyntax"}]},{"type":"null"}],"default":null},"concurrency":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ConcurrencySyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"handler":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/HandlerSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"produces":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProducesSyntax"}]},"default":[]},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]},"reads":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReadsSyntax"}]}},{"type":"null"}],"default":[]},"response":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScalarCommandResponseSyntax"},{"$ref":"#/$defs/RecordCommandResponseSyntax"}]},{"type":"null"}],"default":null},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandStreamSyntax"}]},{"type":"null"}],"default":null},"streamCandidates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CommandStreamSyntax"}]},"default":[]},"validations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CodeValidateSyntax"},{"$ref":"#/$defs/DeclarativeValidateSyntax"}]},"default":[]}},"required":["kind","name"]},"CommandStreamSyntax":{"title":"CommandStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandStreamSyntax"},"eventSource":{"type":"string"},"propertyCandidate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},{"type":"null"}],"default":null},"stream":{"type":"string"},"streamId":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},{"type":"null"}],"default":null},"streamIdParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventSource","stream"]},"ObserverFilterSyntax":{"title":"ObserverFilterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ObserverFilterSyntax"},"eventSource":{"type":"string"},"stream":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","eventSource"]},"ComparisonConditionSyntax":{"title":"ComparisonConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ComparisonConditionSyntax"},"left":{"type":"string"},"leftExpression":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"operator":{"type":"string","enum":["Equal","NotEqual","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Contains","StartsWith"]},"right":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","left","operator","right"]},"CompositeKeySyntax":{"title":"CompositeKeySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CompositeKeySyntax"},"parts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/KeyPartSyntax"}]},"default":[]},"type":{"type":"string"}},"required":["kind","type"]},"ConceptAttributeSyntax":{"title":"ConceptAttributeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConceptAttributeSyntax"},"criminal":{"type":"boolean","default":false},"name":{"type":"string"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"specialCategory":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"ConceptSyntax":{"title":"ConceptSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConceptSyntax"},"attributes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ConceptAttributeSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"generation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/GenerationSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"type":{"type":"string"},"validations":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CodeValidateSyntax"},{"$ref":"#/$defs/DeclarativeValidateSyntax"}]}},{"type":"null"}],"default":[]},"valueNumbers":{"anyOf":[{"type":"array","items":{"type":"integer","minimum":-2147483648,"maximum":2147483647}},{"type":"null"}],"default":null},"values":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","name","type"]},"GenerationSyntax":{"title":"GenerationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"GenerationSyntax"},"alphabet":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"case":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"checksum":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"count":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"encoding":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"pattern":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"prefix":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"range":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"rule":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"size":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"strategy":{"type":"string"}},"required":["kind","strategy"]},"ConcurrencySyntax":{"title":"ConcurrencySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConcurrencySyntax"},"eventSource":{"type":"boolean"},"eventSourceType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"eventStreamId":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"eventStreamType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"eventTypes":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","eventSource"]},"ConfirmActionSyntax":{"title":"ConfirmActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ConfirmActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"message":{"type":"string"},"messageIsLiteral":{"type":"boolean"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","message","messageIsLiteral"]},"ContextExpressionSyntax":{"title":"ContextExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContextExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"IdentityExpressionSyntax":{"title":"IdentityExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IdentityExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"ContributionSyntax":{"title":"ContributionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributionSyntax"},"contributionPoint":{"type":"string"},"destination":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ContributionDestinationSyntax"}]},{"type":"null"}],"default":null},"group":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"navigate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"order":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"presentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","contributionPoint"]},"ContributionDestinationSyntax":{"title":"ContributionDestinationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributionDestinationSyntax"},"syntaxKind":{"type":"string","enum":["Outlet","Dialog","External"]},"target":{"type":"string"}},"required":["kind","syntaxKind","target"]},"CountMappingSyntax":{"title":"CountMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CountMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"DeclarativeValidateSyntax":{"title":"DeclarativeValidateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DeclarativeValidateSyntax"},"requirements":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/RequirementSyntax"}]}},{"type":"null"}],"default":[]},"rules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ValidationRuleSyntax"}]},"default":[]}},"required":["kind"]},"DecrementMappingSyntax":{"title":"DecrementMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DecrementMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"DialogTemplateSyntax":{"title":"DialogTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DialogTemplateSyntax"},"arrangement":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"content":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateSlotContentSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"displayName":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateExposedValueSyntax"}]},"default":[]},"name":{"type":"string"},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateOutletSyntax"}]},"default":[]},"restrictsScopes":{"type":"boolean","default":false},"scopes":{"type":"array","items":{"type":"string"},"default":[]},"sliceKinds":{"type":"array","items":{"type":"string"},"default":[]},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SlotSyntax"}]},"default":[]},"templateType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","name"]},"DomainSyntax":{"title":"DomainSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DomainSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"EnvironmentExpressionSyntax":{"title":"EnvironmentExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EnvironmentExpressionSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"EventContextExpressionSyntax":{"title":"EventContextExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventContextExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"EventInteractionTriggerSyntax":{"title":"EventInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventInteractionTriggerSyntax"},"eventName":{"type":"string"}},"required":["kind","eventName"]},"EventSourceIdExpressionSyntax":{"title":"EventSourceIdExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSourceIdExpressionSyntax"}},"required":["kind"]},"EventSourceSyntax":{"title":"EventSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSourceSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"identifier":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"streams":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventStreamSyntax"}]},"default":[]},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","name"]},"EventStreamIdPartSyntax":{"title":"EventStreamIdPartSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventStreamIdPartSyntax"},"name":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"EventStreamSyntax":{"title":"EventStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventStreamSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"streamId":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null},"streamIdParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventStreamIdPartSyntax"}]},"default":[]}},"required":["kind","name"]},"EventSpecSyntax":{"title":"EventSpecSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSpecSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"EventSyntax":{"title":"EventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EventSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"generation":{"type":"integer","minimum":0,"maximum":4294967295,"default":1},"hasGenerationMarker":{"type":"boolean","default":false},"id":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]},"tags":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TagSyntax"}]}},{"type":"null"}],"default":[]},"visibility":{"type":"string","enum":["Private","Public"],"default":"Private"}},"required":["kind","name"]},"EverySyntax":{"title":"EverySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"EverySyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"includeChildren":{"type":"boolean"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]}},"required":["kind","autoMap","includeChildren"]},"ExecuteCommandActionSyntax":{"title":"ExecuteCommandActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExecuteCommandActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"command":{"type":"string"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","command"]},"ExpressionKeySyntax":{"title":"ExpressionKeySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExpressionKeySyntax"},"expression":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","expression"]},"FeatureSyntax":{"title":"FeatureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FeatureSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"contributions":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributionSyntax"}]}},{"type":"null"}],"default":[]},"dependsOn":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/DependsOnSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"features":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FeatureSyntax"}]},"default":[]},"fileImports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileImportSyntax"}]},"default":[]},"isPlacement":{"type":"boolean"},"name":{"type":"string"},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeReferenceSyntax"}]},"default":[]},"slices":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SliceSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"toolbars":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenToolbarSyntax"}]},"default":[]},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","isPlacement","name"]},"FileConstraintSyntax":{"title":"FileConstraintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileConstraintSyntax"},"additionalRules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},"ignoreCasing":{"type":"boolean"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"releasedBy":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","file","ignoreCasing","name"]},"FileImportSyntax":{"title":"FileImportSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileImportSyntax"},"pattern":{"type":"string"}},"required":["kind","pattern"]},"FileReferenceSyntax":{"title":"FileReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FileReferenceSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"FormColumnSyntax":{"title":"FormColumnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormColumnSyntax"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"}},"required":["kind","property"]},"ExposureSyntax":{"title":"ExposureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExposureSyntax"},"owner":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ExposedPropertySyntax"}]},"default":[]}},"required":["kind","owner"]},"ExposedPropertySyntax":{"title":"ExposedPropertySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ExposedPropertySyntax"},"component":{"type":"string"},"editableFields":{"type":"array","items":{"type":"string"},"default":[]},"isCollection":{"type":"boolean"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"operations":{"type":"array","items":{"type":"string"},"default":[]},"path":{"type":"string"},"reExposes":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"restrictsFields":{"type":"boolean"}},"required":["kind","component","isCollection","path","restrictsFields"]},"InstanceContributionsSyntax":{"title":"InstanceContributionsSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InstanceContributionsSyntax"},"contributions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InstanceContributionSyntax"}]},"default":[]},"instance":{"type":"string"}},"required":["kind","instance"]},"InstanceContributionSyntax":{"title":"InstanceContributionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InstanceContributionSyntax"},"component":{"type":"string"},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributedItemSyntax"}]},"default":[]},"path":{"type":"string"},"value":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","component","path"]},"ContributedItemSyntax":{"title":"ContributedItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributedItemSyntax"},"id":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributedItemValueSyntax"}]},"default":[]}},"required":["kind","id"]},"ContributedItemValueSyntax":{"title":"ContributedItemValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ContributedItemValueSyntax"},"field":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","field","value"]},"ScreenContributionSyntax":{"title":"ScreenContributionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenContributionSyntax"},"contributionPoint":{"type":"string"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"order":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","contributionPoint"]},"TemplateSlotContentSyntax":{"title":"TemplateSlotContentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateSlotContentSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"slot":{"type":"string"}},"required":["kind","slot"]},"CommandFormLayoutSyntax":{"title":"CommandFormLayoutSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"CommandFormLayoutSyntax"},"columnGap":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null},"columns":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormLayoutColumnSyntax"}]},"default":[]},"placements":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormFieldPlacementSyntax"}]},"default":[]},"rowGap":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"FormLayoutColumnSyntax":{"title":"FormLayoutColumnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormLayoutColumnSyntax"},"index":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"maxWidth":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null},"minWidth":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null},"width":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","index"]},"FormFieldPlacementSyntax":{"title":"FormFieldPlacementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormFieldPlacementSyntax"},"column":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"columnSpan":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"field":{"type":"string"},"row":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"rowSpan":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"width":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormWidthSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","column","field","row"]},"FormWidthSyntax":{"title":"FormWidthSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormWidthSyntax"},"unit":{"type":"string","enum":["Fraction","Pixels","Percent","Auto"]},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"default":null}},"required":["kind","unit"]},"FormFieldSyntax":{"title":"FormFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormFieldSyntax"},"composeUsing":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"from":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"}},"required":["kind","property"]},"FormPopulateFromItemSyntax":{"title":"FormPopulateFromItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormPopulateFromItemSyntax"}},"required":["kind"]},"FormPopulateViaQuerySyntax":{"title":"FormPopulateViaQuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormPopulateViaQuerySyntax"},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"query":{"type":"string"}},"required":["kind","query"]},"FormSyntax":{"title":"FormSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FormSyntax"},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"columnMode":{"type":"string","enum":["Unspecified","Auto","Manual"]},"columns":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormColumnSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormFieldSyntax"}]},"default":[]},"for":{"type":"string"},"generationMode":{"type":"string","enum":["Unspecified","Auto","Manual"]},"layout":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandFormLayoutSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"onSubmit":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"populate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FormPopulateFromItemSyntax"},{"$ref":"#/$defs/FormPopulateViaQuerySyntax"}]},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","columnMode","for","generationMode","name"]},"FromSyntax":{"title":"FromSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"FromSyntax"},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventSpecSyntax"}]},"default":[]},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CompositeKeySyntax"},{"$ref":"#/$defs/ExpressionKeySyntax"}]},{"type":"null"}],"default":null},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]},"parentKey":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"HandlerSyntax":{"title":"HandlerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"HandlerSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"implementation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ImplementationSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"ImplementationSyntax":{"title":"ImplementationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ImplementationSyntax"},"hints":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ImplementationHintSyntax"}]},"default":[]}},"required":["kind"]},"ImplementationHintSyntax":{"title":"ImplementationHintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ImplementationHintSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"SystemSyntax":{"title":"SystemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SystemSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"OperationSyntax":{"title":"OperationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"OperationSyntax"},"compensate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/OperationPhaseSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"execute":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/OperationPhaseSyntax"}]},{"type":"null"}],"default":null},"inputs":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]},"name":{"type":"string"},"uses":{"type":"string"}},"required":["kind","name","uses"]},"OperationPhaseSyntax":{"title":"OperationPhaseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"OperationPhaseSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"implementation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ImplementationSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"SpecificationExampleSyntax":{"title":"SpecificationExampleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationExampleSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"generatedValues":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"name":{"type":"string"},"noStream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoStreamSyntax"}]},{"type":"null"}],"default":null},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationStreamSyntax"}]},{"type":"null"}],"default":null},"type":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","name","type"]},"SpecificationParameterSyntax":{"title":"SpecificationParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationParameterSyntax"},"name":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"SpecificationCaseSyntax":{"title":"SpecificationCaseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCaseSyntax"},"name":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","name"]},"SpecificationOperationFailureSyntax":{"title":"SpecificationOperationFailureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationOperationFailureSyntax"},"operation":{"type":"string"}},"required":["kind","operation"]},"SpecificationOperationSyntax":{"title":"SpecificationOperationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationOperationSyntax"},"operation":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","operation"]},"SpecificationCompensatedSyntax":{"title":"SpecificationCompensatedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCompensatedSyntax"},"operation":{"type":"string"}},"required":["kind","operation"]},"ImportSyntax":{"title":"ImportSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ImportSyntax"},"origin":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"qualifiedName":{"type":"string"},"visibility":{"type":"string","enum":["Private","Public"],"default":"Private"}},"required":["kind","qualifiedName"]},"IncrementMappingSyntax":{"title":"IncrementMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IncrementMappingSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"InteractionAlternativeSyntax":{"title":"InteractionAlternativeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionAlternativeSyntax"},"actions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"condition":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]}},"required":["kind","condition"]},"InteractionOtherwiseSyntax":{"title":"InteractionOtherwiseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionOtherwiseSyntax"},"actions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind"]},"InteractionArgumentSyntax":{"title":"InteractionArgumentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionArgumentSyntax"},"binding":{"type":"string"},"name":{"type":"string"}},"required":["kind","binding","name"]},"InteractionBindingSyntax":{"title":"InteractionBindingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InteractionBindingSyntax"},"actions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"alternatives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionAlternativeSyntax"}]},"default":[]},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"otherwise":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/InteractionOtherwiseSyntax"}]},{"type":"null"}],"default":null},"trigger":{"oneOf":[{"$ref":"#/$defs/ApplicationTriggerInteractionTriggerSyntax"},{"$ref":"#/$defs/BuiltInInteractionTriggerSyntax"},{"$ref":"#/$defs/EventInteractionTriggerSyntax"},{"$ref":"#/$defs/IntervalInteractionTriggerSyntax"}]}},"required":["kind","trigger"]},"IntervalInteractionTriggerSyntax":{"title":"IntervalInteractionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IntervalInteractionTriggerSyntax"},"amount":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"unit":{"type":"string","enum":["Seconds","Minutes","Hours","Days"]}},"required":["kind","amount","unit"]},"IntervalTriggerSourceSyntax":{"title":"IntervalTriggerSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"IntervalTriggerSourceSyntax"},"amount":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"unit":{"type":"string","enum":["Seconds","Minutes","Hours","Days"]}},"required":["kind","amount","unit"]},"InvokesSyntax":{"title":"InvokesSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InvokesSyntax"},"command":{"type":"string"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"onRefused":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InvocationRefusalSyntax"}]},"default":[]}},"required":["kind","command"]},"InvocationRefusalSyntax":{"title":"InvocationRefusalSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"InvocationRefusalSyntax"},"acknowledge":{"type":"boolean"},"constraint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"produces":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProducesSyntax"}]},"default":[]},"selector":{"type":"string"}},"required":["kind","acknowledge","selector"]},"JoinEventSyntax":{"title":"JoinEventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"JoinEventSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"event":{"type":"string"},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AddMappingSyntax"},{"$ref":"#/$defs/ClearMappingSyntax"},{"$ref":"#/$defs/CountMappingSyntax"},{"$ref":"#/$defs/DecrementMappingSyntax"},{"$ref":"#/$defs/IncrementMappingSyntax"},{"$ref":"#/$defs/SetMappingSyntax"},{"$ref":"#/$defs/SubtractMappingSyntax"}]},"default":[]}},"required":["kind","autoMap","event"]},"JoinSyntax":{"title":"JoinSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"JoinSyntax"},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/JoinEventSyntax"}]},"default":[]},"on":{"type":"string"},"property":{"type":"string"}},"required":["kind","on","property"]},"KeyPartSyntax":{"title":"KeyPartSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"KeyPartSyntax"},"expression":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"property":{"type":"string"}},"required":["kind","expression","property"]},"LayoutSyntax":{"title":"LayoutSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LayoutSyntax"},"arrangement":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateExposedValueSyntax"}]},"default":[]},"name":{"type":"string"},"navigation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationRegionSyntax"}]},"default":[]},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateOutletSyntax"}]},"default":[]},"restrictsScopes":{"type":"boolean","default":false},"scopes":{"type":"array","items":{"type":"string"},"default":[]},"sliceKinds":{"type":"array","items":{"type":"string"},"default":[]},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SlotSyntax"}]},"default":[]},"templateType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","name"]},"ListExpressionSyntax":{"title":"ListExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ListExpressionSyntax"},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"default":[]}},"required":["kind"]},"LiteralExpressionSyntax":{"title":"LiteralExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LiteralExpressionSyntax"},"value":{"anyOf":[{"type":["string","boolean","null"]},{"type":"number","minimum":-1.7976931348623157E+308,"maximum":1.7976931348623157E+308},{"type":"object","description":"A non-Double numeric literal. The value is an invariant canonical CLR numeric string (G29 for Decimal, R for Single).","additionalProperties":false,"required":["literalType","value"],"properties":{"literalType":{"enum":["Int32","Int64","Decimal","Single"]},"value":{"type":"string","pattern":"^-?[0-9]\u002B(\\.[0-9]\u002B)?([Ee][\u002B-]?[0-9]\u002B)?$"}}},{"type":"object","description":"An explicit ExactNumber in canonical fixed-point text. The codec additionally enforces the normalized Decimal coefficient bound.","additionalProperties":false,"required":["literalType","value"],"properties":{"literalType":{"const":"ExactNumber"},"value":{"type":"string","pattern":"^(?:0|-?(?:[1-9][0-9]{0,28}|(?:0|[1-9][0-9]{0,28})\\.[0-9]{0,27}[1-9]))$"}}}],"default":null}},"required":["kind"]},"LogicalConditionSyntax":{"title":"LogicalConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LogicalConditionSyntax"},"left":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},"operator":{"type":"string","enum":["And","Or"]},"right":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]}},"required":["kind","left","operator","right"]},"LogicalPolicyConditionSyntax":{"title":"LogicalPolicyConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LogicalPolicyConditionSyntax"},"left":{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]},"operator":{"type":"string","enum":["And","Or"]},"right":{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]}},"required":["kind","left","operator","right"]},"LogicalPolicyRequirementSyntax":{"title":"LogicalPolicyRequirementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"LogicalPolicyRequirementSyntax"},"left":{"oneOf":[{"$ref":"#/$defs/LogicalPolicyRequirementSyntax"},{"$ref":"#/$defs/PolicyReferenceSyntax"}]},"operator":{"type":"string","enum":["And","Or"]},"right":{"oneOf":[{"$ref":"#/$defs/LogicalPolicyRequirementSyntax"},{"$ref":"#/$defs/PolicyReferenceSyntax"}]}},"required":["kind","left","operator","right"]},"ModuleSyntax":{"title":"ModuleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ModuleSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"contributions":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ContributionSyntax"}]}},{"type":"null"}],"default":[]},"dependsOn":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/DependsOnSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"dialogTemplates":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/DialogTemplateSyntax"}]}},{"type":"null"}],"default":[]},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"features":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FeatureSyntax"}]},"default":[]},"fileImports":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileImportSyntax"}]},"default":[]},"forms":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FormSyntax"}]}},{"type":"null"}],"default":[]},"isPlacement":{"type":"boolean"},"name":{"type":"string"},"navigation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/NavigationRegionSyntax"}]},"default":[]},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeReferenceSyntax"}]},"default":[]},"screenTemplates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenTemplateSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"toolbars":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenToolbarSyntax"}]},"default":[]},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","isPlacement","name"]},"NamedTriggerSourceSyntax":{"title":"NamedTriggerSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NamedTriggerSourceSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"NavigateActionSyntax":{"title":"NavigateActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigateActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"screen":{"type":"string"}},"required":["kind","screen"]},"NavigateBackActionSyntax":{"title":"NavigateBackActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NavigateBackActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind"]},"NestedSyntax":{"title":"NestedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NestedSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"property":{"type":"string"}},"required":["kind","autoMap","property"]},"NotPolicyConditionSyntax":{"title":"NotPolicyConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NotPolicyConditionSyntax"},"operand":{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]}},"required":["kind","operand"]},"NotifyActionSyntax":{"title":"NotifyActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NotifyActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"level":{"type":"string","enum":["Info","Warning","Error","Unknown"]},"message":{"type":"string"},"messageIsLiteral":{"type":"boolean"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","level","message","messageIsLiteral"]},"OpenDialogActionSyntax":{"title":"OpenDialogActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"OpenDialogActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"dialogTemplate":{"type":"string"},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]}},"required":["kind","dialogTemplate"]},"ObjectExpressionSyntax":{"title":"ObjectExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ObjectExpressionSyntax"},"members":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ObjectMemberSyntax"}]},"default":[]}},"required":["kind"]},"ObjectMemberSyntax":{"title":"ObjectMemberSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ObjectMemberSyntax"},"name":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","name","value"]},"PathExpressionSyntax":{"title":"PathExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PathExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"PerformerSyntax":{"title":"PerformerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PerformerSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null}},"required":["kind"]},"PersonaSyntax":{"title":"PersonaSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PersonaSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"goals":{"type":"array","items":{"type":"string"},"default":[]},"height":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"name":{"type":"string"},"policies":{"type":"array","items":{"type":"string"},"default":[]},"width":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","name"]},"StickyNoteSyntax":{"title":"StickyNoteSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"StickyNoteSyntax"},"canvas":{"type":"string"},"colour":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"height":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"text":{"type":"string"},"width":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"x":{"type":"integer","minimum":-2147483648,"maximum":2147483647},"y":{"type":"integer","minimum":-2147483648,"maximum":2147483647}},"required":["kind","canvas","text","x","y"]},"PlaceSyntax":{"title":"PlaceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PlaceSyntax"},"hidden":{"type":"boolean","default":false},"sizeHeight":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"sizeWidth":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"slotName":{"type":"string"},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind","slotName"]},"PolicyReferenceSyntax":{"title":"PolicyReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PolicyReferenceSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"PolicySyntax":{"title":"PolicySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PolicySyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"condition":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthenticatedConditionSyntax"},{"$ref":"#/$defs/ClaimConditionSyntax"},{"$ref":"#/$defs/LogicalPolicyConditionSyntax"},{"$ref":"#/$defs/NotPolicyConditionSyntax"},{"$ref":"#/$defs/RoleConditionSyntax"},{"$ref":"#/$defs/AnonymousConditionSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"PurposeSyntax":{"title":"PurposeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PurposeSyntax"},"authorization":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"basis":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"basisReference":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"conditionReference":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"erasureException":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"interest":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"recipients":{"type":"array","items":{"type":"string"},"default":[]},"retention":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"subjects":{"type":"array","items":{"type":"string"},"default":[]},"transfers":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeTransferSyntax"}]},"default":[]}},"required":["kind","name"]},"PurposeReferenceSyntax":{"title":"PurposeReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PurposeReferenceSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"PurposeTransferSyntax":{"title":"PurposeTransferSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PurposeTransferSyntax"},"destination":{"type":"string"},"safeguard":{"type":"string"}},"required":["kind","destination","safeguard"]},"ProducesSyntax":{"title":"ProducesSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProducesSyntax"},"event":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"inlineEvent":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/EventSyntax"}]},{"type":"null"}],"default":null},"inlineOperation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/OperationSyntax"}]},{"type":"null"}],"default":null},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CommandStreamSyntax"}]},{"type":"null"}],"default":null},"tags":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TagSyntax"}]}},{"type":"null"}],"default":[]},"when":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"ProjectionEntersOnSyntax":{"title":"ProjectionEntersOnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProjectionEntersOnSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"ProjectionSyntax":{"title":"ProjectionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProjectionSyntax"},"autoMap":{"type":"string","enum":["Inherit","Disabled","Enabled"]},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CompositeKeySyntax"},{"$ref":"#/$defs/ExpressionKeySyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"readModel":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"sequence":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}}},"required":["kind","autoMap","name"]},"ProjectionVariantSyntax":{"title":"ProjectionVariantSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProjectionVariantSyntax"},"blocks":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/AllSyntax"},{"$ref":"#/$defs/ChildrenSyntax"},{"$ref":"#/$defs/ClearWithSyntax"},{"$ref":"#/$defs/EverySyntax"},{"$ref":"#/$defs/FromSyntax"},{"$ref":"#/$defs/JoinSyntax"},{"$ref":"#/$defs/NestedSyntax"},{"$ref":"#/$defs/ProjectionVariantSyntax"},{"$ref":"#/$defs/RemoveViaJoinSyntax"},{"$ref":"#/$defs/RemoveWithSyntax"}]},"default":[]},"entersOn":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProjectionEntersOnSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"PresentationValueSyntax":{"title":"PresentationValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PresentationValueSyntax"},"name":{"type":"string"},"value":{"type":"string"}},"required":["kind","name","value"]},"PropertyMappingSyntax":{"title":"PropertyMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PropertyMappingSyntax"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","source"]},"PropertySyntax":{"title":"PropertySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PropertySyntax"},"isGenerated":{"type":"boolean","default":false},"isIdentifier":{"type":"boolean","default":false},"isKey":{"type":"boolean","default":false},"isSubject":{"type":"boolean","default":false},"name":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"PropertyResponseSourceSyntax":{"title":"PropertyResponseSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"PropertyResponseSourceSyntax"},"property":{"type":"string"}},"required":["kind","property"]},"ResponseFieldSyntax":{"title":"ResponseFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ResponseFieldSyntax"},"name":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/PropertyResponseSourceSyntax"}]},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name","source"]},"ScalarCommandResponseSyntax":{"title":"ScalarCommandResponseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScalarCommandResponseSyntax"},"source":{"oneOf":[{"$ref":"#/$defs/PropertyResponseSourceSyntax"}]}},"required":["kind","source"]},"RecordCommandResponseSyntax":{"title":"RecordCommandResponseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RecordCommandResponseSyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ResponseFieldSyntax"}]},"default":[]}},"required":["kind"]},"ScalarSpecificationReturnSyntax":{"title":"ScalarSpecificationReturnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScalarSpecificationReturnSyntax"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","value"]},"RecordSpecificationReturnSyntax":{"title":"RecordSpecificationReturnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RecordSpecificationReturnSyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind"]},"QueryParameterSyntax":{"title":"QueryParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"QueryParameterSyntax"},"name":{"type":"string"},"source":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","name","type"]},"QuerySyntax":{"title":"QuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"QuerySyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"by":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/QueryParameterSyntax"}]},{"type":"null"}],"default":null},"byParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/QueryParameterSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"filters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/QueryParameterSyntax"}]},"default":[]},"isObservable":{"type":"boolean","default":false},"name":{"type":"string"},"performer":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PerformerSyntax"}]},{"type":"null"}],"default":null},"returnType":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name","returnType"]},"RaiseTriggerActionSyntax":{"title":"RaiseTriggerActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RaiseTriggerActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"trigger":{"type":"string"}},"required":["kind","trigger"]},"RawExpressionSyntax":{"title":"RawExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RawExpressionSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"ReactionIdentitySyntax":{"title":"ReactionIdentitySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReactionIdentitySyntax"},"roles":{"type":"array","items":{"type":"string"},"default":[]},"syntaxKind":{"type":"string"}},"required":["kind","syntaxKind"]},"ReactionSyntax":{"title":"ReactionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReactionSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"from":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ObserverFilterSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"runsAs":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ReactionIdentitySyntax"}]},{"type":"null"}],"default":null},"triggers":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReactionTriggerSyntax"}]},"default":[]},"where":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"ReactionTriggerSyntax":{"title":"ReactionTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReactionTriggerSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"data":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TriggerDataSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"invokes":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InvokesSyntax"}]}},{"type":"null"}],"default":[]},"produces":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProducesSyntax"}]}},{"type":"null"}],"default":[]},"reads":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReadsSyntax"}]}},{"type":"null"}],"default":[]},"source":{"oneOf":[{"$ref":"#/$defs/IntervalTriggerSourceSyntax"},{"$ref":"#/$defs/NamedTriggerSourceSyntax"},{"$ref":"#/$defs/ScheduleTriggerSourceSyntax"}]}},"required":["kind","source"]},"RefusalExpressionSyntax":{"title":"RefusalExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RefusalExpressionSyntax"},"member":{"type":"string"}},"required":["kind","member"]},"ReadModelSyntax":{"title":"ReadModelSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReadModelSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]}},"required":["kind","name"]},"ReadsSyntax":{"title":"ReadsSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReadsSyntax"},"alias":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"byParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"readModel":{"type":"string"}},"required":["kind","readModel"]},"ReducerRuleSyntax":{"title":"ReducerRuleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReducerRuleSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"event":{"type":"string"},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"ReducerSyntax":{"title":"ReducerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ReducerSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"from":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ObserverFilterSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"readModel":{"type":"string"},"rules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReducerRuleSyntax"}]},"default":[]}},"required":["kind","name","readModel"]},"RefreshQueryActionSyntax":{"title":"RefreshQueryActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RefreshQueryActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"query":{"type":"string"}},"required":["kind","query"]},"RemoveViaJoinSyntax":{"title":"RemoveViaJoinSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RemoveViaJoinSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"RemoveWithSyntax":{"title":"RemoveWithSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RemoveWithSyntax"},"event":{"type":"string"},"key":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"parentKey":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"partsKey":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CompositeKeySyntax"}]},{"type":"null"}],"default":null}},"required":["kind","event"]},"RequirementSyntax":{"title":"RequirementSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RequirementSyntax"},"condition":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"severity":{"type":"string","enum":["Error","Information","Warning"]}},"required":["kind","condition","severity"]},"RoleConditionSyntax":{"title":"RoleConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RoleConditionSyntax"},"role":{"type":"string"}},"required":["kind","role"]},"ScheduleTriggerSourceSyntax":{"title":"ScheduleTriggerSourceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScheduleTriggerSourceSyntax"},"dayOfMonth":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"dayOfWeek":{"anyOf":[{"type":"string","enum":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},{"type":"null"}],"default":null},"time":{"type":"string","pattern":"^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,7})?$"}},"required":["kind","time"]},"ScreenActionSyntax":{"title":"ScreenActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenActionSyntax"},"command":{"type":"string"},"inputs":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"navigate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"subject":{"anyOf":[{"type":"string","enum":["Item","Screen"]},{"type":"null"}],"default":null}},"required":["kind","command"]},"ScreenNavigationParameterSyntax":{"title":"ScreenNavigationParameterSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenNavigationParameterSyntax"},"binding":{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},"name":{"type":"string"}},"required":["kind","binding","name"]},"ScreenGuardedActionSyntax":{"title":"ScreenGuardedActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenGuardedActionSyntax"},"alternatives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionAlternativeSyntax"}]},"default":[]},"label":{"type":"string"},"navigate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"otherwise":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenActionOtherwiseSyntax"}]},{"type":"null"}],"default":null},"subject":{"anyOf":[{"type":"string","enum":["Item","Screen"]},{"type":"null"}],"default":null}},"required":["kind","label"]},"ScreenActionAlternativeSyntax":{"title":"ScreenActionAlternativeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenActionAlternativeSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"command":{"type":"string"},"condition":{"oneOf":[{"$ref":"#/$defs/ComparisonConditionSyntax"},{"$ref":"#/$defs/LogicalConditionSyntax"}]}},"required":["kind","command","condition"]},"ScreenActionOtherwiseSyntax":{"title":"ScreenActionOtherwiseSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenActionOtherwiseSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"command":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"outcome":{"type":"string","enum":["Hidden","Execute","Unknown"]}},"required":["kind","outcome"]},"ScreenBehaviorSyntax":{"title":"ScreenBehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenBehaviorSyntax"},"behavior":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]}},"required":["kind","behavior"]},"ScreenCodeSyntax":{"title":"ScreenCodeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenCodeSyntax"},"code":{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]}},"required":["kind","code"]},"ScreenComponentSyntax":{"title":"ScreenComponentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenComponentSyntax"},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"component":{"type":"string"},"context":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/UiBindingSyntax"}]},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ComponentExposedValueSyntax"}]},"default":[]},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ComponentOutletSyntax"}]},"default":[]},"presentation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PresentationValueSyntax"}]},"default":[]},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ComponentPropertySyntax"}]},"default":[]},"stableId":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","component","name"]},"ScreenColumnSyntax":{"title":"ScreenColumnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenColumnSyntax"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"}},"required":["kind","property"]},"ScreenDataSyntax":{"title":"ScreenDataSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenDataSyntax"},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"query":{"type":"string"},"type":{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]}},"required":["kind","query","type"]},"ScreenFieldSyntax":{"title":"ScreenFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenFieldSyntax"},"label":{"type":"string"},"property":{"type":"string"}},"required":["kind","label","property"]},"ScreenNavigateSyntax":{"title":"ScreenNavigateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenNavigateSyntax"},"by":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"outlet":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenNavigationParameterSyntax"}]},"default":[]},"route":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"screen":{"type":"string"}},"required":["kind","screen"]},"ScreenSectionSyntax":{"title":"ScreenSectionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSectionSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ScreenSlotSyntax":{"title":"ScreenSlotSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSlotSyntax"},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ScreenSummarySyntax":{"title":"ScreenSummarySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSummarySyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenFieldSyntax"}]},"default":[]},"target":{"type":"string"}},"required":["kind","target"]},"ScreenSyntax":{"title":"ScreenSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenSyntax"},"contributions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenContributionSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"directives":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenActionSyntax"},{"$ref":"#/$defs/ScreenGuardedActionSyntax"},{"$ref":"#/$defs/ScreenBehaviorSyntax"},{"$ref":"#/$defs/ScreenCodeSyntax"},{"$ref":"#/$defs/ScreenComponentSyntax"},{"$ref":"#/$defs/ScreenDataSyntax"},{"$ref":"#/$defs/ScreenNavigateSyntax"},{"$ref":"#/$defs/ScreenSectionSyntax"},{"$ref":"#/$defs/ScreenSlotSyntax"},{"$ref":"#/$defs/ScreenSummarySyntax"},{"$ref":"#/$defs/ScreenTableSyntax"},{"$ref":"#/$defs/ScreenTemplateReferenceSyntax"},{"$ref":"#/$defs/ScreenTitleSyntax"},{"$ref":"#/$defs/ScreenToolbarSyntax"},{"$ref":"#/$defs/ScreenUsesBehaviorSyntax"}]},"default":[]},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"ScreenTableSyntax":{"title":"ScreenTableSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTableSyntax"},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"columns":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenColumnSyntax"}]},"default":[]},"rowClick":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScreenNavigateSyntax"}]},{"type":"null"}],"default":null},"target":{"type":"string"},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","target"]},"ScreenTemplateReferenceSyntax":{"title":"ScreenTemplateReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTemplateReferenceSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenSlotSyntax"}]},"default":[]},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"ScreenTemplateSyntax":{"title":"ScreenTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTemplateSyntax"},"arrangement":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ArrangementSyntax"}]},{"type":"null"}],"default":null},"behaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorSyntax"}]},"default":[]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"content":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateSlotContentSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"displayName":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"exposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateExposedValueSyntax"}]},"default":[]},"fitsSlot":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"outlets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateOutletSyntax"}]},"default":[]},"restrictsScopes":{"type":"boolean","default":false},"scopes":{"type":"array","items":{"type":"string"},"default":[]},"sliceKinds":{"type":"array","items":{"type":"string"},"default":[]},"slots":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SlotSyntax"}]},"default":[]},"templateType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"usedBehaviors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]},"default":[]}},"required":["kind","name"]},"ScreenTitleSyntax":{"title":"ScreenTitleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenTitleSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"ScreenToolbarSyntax":{"title":"ScreenToolbarSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenToolbarSyntax"},"buttons":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ToolbarButtonSyntax"}]},"default":[]},"items":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ToolbarItemSyntax"}]},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"ScreenUsesBehaviorSyntax":{"title":"ScreenUsesBehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ScreenUsesBehaviorSyntax"},"uses":{"oneOf":[{"$ref":"#/$defs/UsesBehaviorSyntax"}]}},"required":["kind","uses"]},"SeedEventSyntax":{"title":"SeedEventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SeedEventSyntax"},"event":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","event"]},"SeedGroupSyntax":{"title":"SeedGroupSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SeedGroupSyntax"},"eventSourceId":{"type":"string"},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SeedEventSyntax"}]},"default":[]}},"required":["kind","eventSourceId"]},"SeedSyntax":{"title":"SeedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SeedSyntax"},"groups":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SeedGroupSyntax"}]},"default":[]},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"x":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null},"y":{"anyOf":[{"type":"integer","minimum":-2147483648,"maximum":2147483647},{"type":"null"}],"default":null}},"required":["kind"]},"SetMappingSyntax":{"title":"SetMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SetMappingSyntax"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","source"]},"TemplateAssignmentSyntax":{"title":"TemplateAssignmentSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateAssignmentSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"TemplateExposedValueSyntax":{"title":"TemplateExposedValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateExposedValueSyntax"},"name":{"type":"string"},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"TemplateOutletSyntax":{"title":"TemplateOutletSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateOutletSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"SetStateActionSyntax":{"title":"SetStateActionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SetStateActionSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/InteractionArgumentSyntax"}]},"default":[]},"onFailure":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onResult":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"onSuccess":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CloseDialogActionSyntax"},{"$ref":"#/$defs/ConfirmActionSyntax"},{"$ref":"#/$defs/ExecuteCommandActionSyntax"},{"$ref":"#/$defs/NavigateActionSyntax"},{"$ref":"#/$defs/NavigateBackActionSyntax"},{"$ref":"#/$defs/NotifyActionSyntax"},{"$ref":"#/$defs/OpenDialogActionSyntax"},{"$ref":"#/$defs/RaiseTriggerActionSyntax"},{"$ref":"#/$defs/RefreshQueryActionSyntax"},{"$ref":"#/$defs/SetStateActionSyntax"}]},"default":[]},"target":{"type":"string"},"value":{"type":"string"}},"required":["kind","target","value"]},"SliceSyntax":{"title":"SliceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SliceSyntax"},"captures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CaptureSyntax"}]},"default":[]},"commands":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/CommandSyntax"}]},"default":[]},"constraints":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"direction":{"anyOf":[{"type":"string","enum":["Inbound","Outbound"]},{"type":"null"}],"default":null},"documentation":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"events":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/EventSyntax"}]},"default":[]},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"operations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/OperationSyntax"}]},"default":[]},"projections":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ProjectionSyntax"}]},"default":[]},"purposes":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PurposeReferenceSyntax"}]},"default":[]},"queries":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/QuerySyntax"}]},"default":[]},"reactions":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReactionSyntax"}]},"default":[]},"readModels":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReadModelSyntax"}]}},{"type":"null"}],"default":[]},"reducers":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ReducerSyntax"}]}},{"type":"null"}],"default":[]},"screens":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenSyntax"}]},"default":[]},"specifications":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationSyntax"}]},"default":[]},"templates":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateAssignmentSyntax"}]},"default":[]},"type":{"type":"string","enum":["StateChange","StateView","Automation","Translate"]}},"required":["kind","name","type"]},"SlotSyntax":{"title":"SlotSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SlotSyntax"},"contributes":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"SourceItemExpressionSyntax":{"title":"SourceItemExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SourceItemExpressionSyntax"},"path":{"type":"string"}},"required":["kind","path"]},"SpecificationAbsentReadModelSyntax":{"title":"SpecificationAbsentReadModelSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationAbsentReadModelSyntax"},"key":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},"name":{"type":"string"}},"required":["kind","key","name"]},"SpecificationCallerClaimSyntax":{"title":"SpecificationCallerClaimSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCallerClaimSyntax"},"type":{"type":"string"},"value":{"type":"string"}},"required":["kind","type","value"]},"SpecificationCallerPersonaSyntax":{"title":"SpecificationCallerPersonaSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCallerPersonaSyntax"},"name":{"type":"string"}},"required":["kind","name"]},"SpecificationCallerSyntax":{"title":"SpecificationCallerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCallerSyntax"},"authenticated":{"type":"boolean"},"claims":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCallerClaimSyntax"}]},"default":[]},"roles":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","authenticated"]},"SpecificationCaptureSyntax":{"title":"SpecificationCaptureSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCaptureSyntax"},"capture":{"type":"string"},"record":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","capture"]},"SpecificationClockSyntax":{"title":"SpecificationClockSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationClockSyntax"},"instant":{"type":"string"}},"required":["kind","instant"]},"SpecificationGeneratedValueSyntax":{"title":"SpecificationGeneratedValueSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationGeneratedValueSyntax"},"command":{"type":"string"},"property":{"type":"string"},"source":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","command","property","source"]},"SpecificationCommandSyntax":{"title":"SpecificationCommandSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationCommandSyntax"},"commandType":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"generatedValues":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"inlineProperty":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","commandType"]},"SpecificationDeniedSyntax":{"title":"SpecificationDeniedSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationDeniedSyntax"}},"required":["kind"]},"SpecificationErrorSyntax":{"title":"SpecificationErrorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationErrorSyntax"},"caseValue":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CaseValueExpressionSyntax"}]},{"type":"null"}],"default":null},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"SpecificationEventSyntax":{"title":"SpecificationEventSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationEventSyntax"},"eventType":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"inlineProperty":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"noStream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoStreamSyntax"}]},{"type":"null"}],"default":null},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationStreamSyntax"}]},{"type":"null"}],"default":null},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventType"]},"NewScreenTemplateSyntax":{"title":"NewScreenTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"NewScreenTemplateSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"ProfileAppearanceSyntax":{"title":"ProfileAppearanceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProfileAppearanceSyntax"},"accent":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"colorScheme":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"corners":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"font":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind"]},"ProfileIdentitySyntax":{"title":"ProfileIdentitySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ProfileIdentitySyntax"},"logoKind":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"logoValue":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"showName":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null}},"required":["kind"]},"RootTemplateSyntax":{"title":"RootTemplateSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"RootTemplateSyntax"},"blueprint":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"options":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ShellOptionSyntax"}]},"default":[]},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"SampleDataBindingSyntax":{"title":"SampleDataBindingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataBindingSyntax"},"pack":{"oneOf":[{"$ref":"#/$defs/SampleDataPackReferenceSyntax"}]},"readModel":{"type":"string"}},"required":["kind","pack","readModel"]},"ShellOptionSyntax":{"title":"ShellOptionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ShellOptionSyntax"},"name":{"type":"string"},"syntaxKind":{"type":"string","enum":["Word","Text","Number","Flag"]},"value":{"type":"string"}},"required":["kind","name","syntaxKind","value"]},"SampleDataFieldSyntax":{"title":"SampleDataFieldSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataFieldSyntax"},"name":{"type":"string"},"syntaxKind":{"type":"string","enum":["Text","Number","Flag","Null"]},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name","syntaxKind"]},"SampleDataMappingSyntax":{"title":"SampleDataMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataMappingSyntax"},"readModel":{"type":"string"},"shape":{"type":"string"}},"required":["kind","readModel","shape"]},"SampleDataPackReferenceSyntax":{"title":"SampleDataPackReferenceSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataPackReferenceSyntax"},"isBlueprint":{"type":"boolean"},"name":{"type":"string"}},"required":["kind","isBlueprint","name"]},"SampleDataPackSyntax":{"title":"SampleDataPackSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataPackSyntax"},"locale":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"sets":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataSetSyntax"}]},"default":[]},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"SampleDataRowSyntax":{"title":"SampleDataRowSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataRowSyntax"},"fields":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataFieldSyntax"}]},"default":[]}},"required":["kind"]},"SampleDataSelectionSyntax":{"title":"SampleDataSelectionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataSelectionSyntax"},"active":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SampleDataPackReferenceSyntax"}]},{"type":"null"}],"default":null},"bindings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataBindingSyntax"}]},"default":[]},"mappings":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataMappingSyntax"}]},"default":[]}},"required":["kind"]},"SampleDataSetSyntax":{"title":"SampleDataSetSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SampleDataSetSyntax"},"rows":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SampleDataRowSyntax"}]},"default":[]},"shape":{"type":"string"}},"required":["kind","shape"]},"SpecificationNoResultSyntax":{"title":"SpecificationNoResultSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationNoResultSyntax"}},"required":["kind"]},"SpecificationStreamSyntax":{"title":"SpecificationStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationStreamSyntax"},"eventSource":{"type":"string"},"stream":{"type":"string"},"streamId":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},{"type":"null"}],"default":null},"streamIdParts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventSource","stream"]},"SpecificationNoStreamSyntax":{"title":"SpecificationNoStreamSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationNoStreamSyntax"}},"required":["kind"]},"SpecificationQueryResultSyntax":{"title":"SpecificationQueryResultSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationQueryResultSyntax"},"exactly":{"type":"boolean"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","exactly"]},"SpecificationQuerySyntax":{"title":"SpecificationQuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationQuerySyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"exactly":{"type":"boolean"},"query":{"type":"string"},"results":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationQueryResultSyntax"}]},"default":[]}},"required":["kind","exactly","query"]},"SpecificationReadModelSyntax":{"title":"SpecificationReadModelSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationReadModelSyntax"},"exactly":{"type":"boolean"},"inlineProperty":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","exactly","name"]},"SpecificationRedeliverySyntax":{"title":"SpecificationRedeliverySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationRedeliverySyntax"},"eventType":{"type":"string"},"for":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"noStream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoStreamSyntax"}]},{"type":"null"}],"default":null},"reaction":{"type":"string"},"stream":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationStreamSyntax"}]},{"type":"null"}],"default":null},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","eventType","reaction"]},"SpecificationSyntax":{"title":"SpecificationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationSyntax"},"cases":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCaseSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"examples":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationExampleSyntax"}]},"default":[]},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"given":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationEventSyntax"}]},"default":[]},"givenCaller":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCallerSyntax"}]},{"type":"null"}],"default":null},"givenCallerPersona":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCallerPersonaSyntax"}]},{"type":"null"}],"default":null},"givenCaptures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCaptureSyntax"}]},"default":[]},"givenClock":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationClockSyntax"}]},{"type":"null"}],"default":null},"givenGenerated":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationGeneratedValueSyntax"}]},"default":[]},"givenOperationFailures":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationOperationFailureSyntax"}]},"default":[]},"givenReadModels":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationReadModelSyntax"}]}},{"type":"null"}],"default":[]},"givenTimeZone":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationTimeZoneSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationParameterSyntax"}]},"default":[]},"sourceOptions":{"type":"object","additionalProperties":false,"required":["numericMode"],"properties":{"numericMode":{"type":"string","enum":["legacy","exact"]}},"default":{"numericMode":"legacy"}},"thenAbsentReadModels":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationAbsentReadModelSyntax"}]},"default":[]},"thenCompensated":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationCompensatedSyntax"}]},"default":[]},"thenDenied":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationDeniedSyntax"}]},{"type":"null"}],"default":null},"thenErrors":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationErrorSyntax"}]},"default":[]},"thenEvents":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationEventSyntax"}]},"default":[]},"thenEventsInAnyOrder":{"type":"boolean"},"thenNoEvents":{"type":"boolean","default":false},"thenNoResult":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationNoResultSyntax"}]},{"type":"null"}],"default":null},"thenOperations":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationOperationSyntax"}]},"default":[]},"thenQueries":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationQuerySyntax"}]},"default":[]},"thenReadModels":{"anyOf":[{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationReadModelSyntax"}]}},{"type":"null"}],"default":[]},"thenResults":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/SpecificationQueryResultSyntax"}]},"default":[]},"thenReturns":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ScalarSpecificationReturnSyntax"},{"$ref":"#/$defs/RecordSpecificationReturnSyntax"}]},{"type":"null"}],"default":null},"when":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCommandSyntax"}]},{"type":"null"}],"default":null},"whenAppended":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationEventSyntax"}]},{"type":"null"}],"default":null},"whenCapture":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationCaptureSyntax"}]},{"type":"null"}],"default":null},"whenClock":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationClockSyntax"}]},{"type":"null"}],"default":null},"whenQuery":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationWhenQuerySyntax"}]},{"type":"null"}],"default":null},"whenRedelivered":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationRedeliverySyntax"}]},{"type":"null"}],"default":null},"whenTrigger":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SpecificationTriggerSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name","thenEventsInAnyOrder"]},"SpecificationTriggerSyntax":{"title":"SpecificationTriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationTriggerSyntax"},"trigger":{"type":"string"},"values":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]}},"required":["kind","trigger"]},"SpecificationWhenQuerySyntax":{"title":"SpecificationWhenQuerySyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SpecificationWhenQuerySyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertyMappingSyntax"}]},"default":[]},"query":{"type":"string"}},"required":["kind","query"]},"StringsExpressionSyntax":{"title":"StringsExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"StringsExpressionSyntax"},"key":{"type":"string"}},"required":["kind","key"]},"SubtractMappingSyntax":{"title":"SubtractMappingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"SubtractMappingSyntax"},"factor":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"property":{"type":"string"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","property","value"]},"TagSyntax":{"title":"TagSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TagSyntax"},"value":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","value"]},"ToolbarButtonSyntax":{"title":"ToolbarButtonSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ToolbarButtonSyntax"},"authorize":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/AuthorizeSyntax"}]},{"type":"null"}],"default":null},"confirm":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"emphasis":{"anyOf":[{"type":"string","enum":["Primary","Secondary","Quiet"]},{"type":"null"}],"default":null},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"id":{"type":"string"},"slice":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"title":{"type":"string"}},"required":["kind","id","title"]},"ToolbarItemSyntax":{"title":"ToolbarItemSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ToolbarItemSyntax"},"confirm":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"parameters":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/ScreenNavigationParameterSyntax"}]},"default":[]},"presentation":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PresentationValueSyntax"}]},"default":[]},"subject":{"anyOf":[{"type":"string","enum":["Item","Screen"]},{"type":"null"}],"default":null},"syntaxKind":{"type":"string","enum":["Unknown","Action","Navigate","Dialog"]},"target":{"type":"string"}},"required":["kind","name","syntaxKind","target"]},"TemplateExpressionSyntax":{"title":"TemplateExpressionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateExpressionSyntax"},"parts":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TemplateInterpolationSyntax"},{"$ref":"#/$defs/TemplateTextSyntax"}]},"default":[]}},"required":["kind"]},"TemplateInterpolationSyntax":{"title":"TemplateInterpolationSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateInterpolationSyntax"},"expression":{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]}},"required":["kind","expression"]},"TemplateTextSyntax":{"title":"TemplateTextSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TemplateTextSyntax"},"text":{"type":"string"}},"required":["kind","text"]},"ThemeSyntax":{"title":"ThemeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ThemeSyntax"},"compatibleWith":{"type":"array","items":{"type":"string"},"default":[]},"name":{"type":"string"}},"required":["kind","name"]},"TriggerDataSyntax":{"title":"TriggerDataSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TriggerDataSyntax"},"name":{"type":"string"},"type":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/TypeRefSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","name"]},"TriggerSyntax":{"title":"TriggerSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TriggerSyntax"},"data":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/TriggerDataSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"}},"required":["kind","name"]},"TypeRefSyntax":{"title":"TypeRefSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TypeRefSyntax"},"isCollection":{"type":"boolean"},"isOptional":{"type":"boolean"},"name":{"type":"string"}},"required":["kind","isCollection","isOptional","name"]},"TypeSyntax":{"title":"TypeSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"TypeSyntax"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"name":{"type":"string"},"properties":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PropertySyntax"}]},"default":[]}},"required":["kind","name"]},"UiBindingSyntax":{"title":"UiBindingSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UiBindingSyntax"},"bindingKind":{"type":"string","enum":["Invalid","DataContext","QueryResult","ComponentProperty","Literal"]},"componentId":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"componentPropertyPath":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"expectedValueType":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"literal":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null},"mode":{"anyOf":[{"type":"string","enum":["OneWay","TwoWay"]},{"type":"null"}],"default":null},"nullBehavior":{"anyOf":[{"type":"string","enum":["Propagate","Clear","Preserve"]},{"type":"null"}],"default":null},"path":{"type":"string"},"query":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"rawText":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","bindingKind","path"]},"UiProfileSyntax":{"title":"UiProfileSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UiProfileSyntax"},"appearance":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ProfileAppearanceSyntax"}]},{"type":"null"}],"default":null},"defaultSizeClass":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"icons":{"type":"array","items":{"type":"string"},"default":[]},"identity":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ProfileIdentitySyntax"}]},{"type":"null"}],"default":null},"layout":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"newScreenTemplate":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/NewScreenTemplateSyntax"}]},{"type":"null"}],"default":null},"packages":{"type":"array","items":{"type":"string"},"default":[]},"platforms":{"type":"array","items":{"type":"string"},"default":[]},"root":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/RootTemplateSyntax"}]},{"type":"null"}],"default":null},"sampleData":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/SampleDataSelectionSyntax"}]},{"type":"null"}],"default":null},"theme":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null}},"required":["kind","name"]},"UniqueEventConstraintSyntax":{"title":"UniqueEventConstraintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UniqueEventConstraintSyntax"},"additionalRules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"event":{"type":"string"},"ignoreCasing":{"type":"boolean"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"releasedBy":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","event","ignoreCasing","name"]},"UniquePropertyConstraintSyntax":{"title":"UniquePropertyConstraintSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UniquePropertyConstraintSyntax"},"additionalProperties":{"type":"array","items":{"type":"string"},"default":[]},"additionalRules":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/FileConstraintSyntax"},{"$ref":"#/$defs/UniqueEventConstraintSyntax"},{"$ref":"#/$defs/UniquePropertyConstraintSyntax"}]},"default":[]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"event":{"type":"string"},"ignoreCasing":{"type":"boolean"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"name":{"type":"string"},"property":{"type":"string"},"releasedBy":{"type":"array","items":{"type":"string"},"default":[]}},"required":["kind","event","ignoreCasing","name","property"]},"DependsOnSyntax":{"title":"DependsOnSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"DependsOnSyntax"},"target":{"type":"string"}},"required":["kind","target"]},"UsesBehaviorSyntax":{"title":"UsesBehaviorSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"UsesBehaviorSyntax"},"arguments":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/BehaviorArgumentSyntax"}]},"default":[]},"behavior":{"type":"string"}},"required":["kind","behavior"]},"ValidationRuleSyntax":{"title":"ValidationRuleSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"ValidationRuleSyntax"},"code":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CodeBlockSyntax"}]},{"type":"null"}],"default":null},"file":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/FileReferenceSyntax"}]},{"type":"null"}],"default":null},"implementation":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/ImplementationSyntax"}]},{"type":"null"}],"default":null},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null},"property":{"type":"string"},"rule":{"type":"string","enum":["NotEmpty","Max","Min","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Equal","Length","Matches","AllGreaterThan","AllGreaterThanOrEqual","Rule","NotEqual","Checksum","Contains","NotContains","StartsWith","EndsWith","DecimalPlaces"]},"severity":{"type":"string","enum":["Error","Information","Warning"]},"value":{"anyOf":[{"oneOf":[{"$ref":"#/$defs/CausedByExpressionSyntax"},{"$ref":"#/$defs/ClockOffsetExpressionSyntax"},{"$ref":"#/$defs/DateOfExpressionSyntax"},{"$ref":"#/$defs/CaseValueExpressionSyntax"},{"$ref":"#/$defs/ContextExpressionSyntax"},{"$ref":"#/$defs/IdentityExpressionSyntax"},{"$ref":"#/$defs/EnvironmentExpressionSyntax"},{"$ref":"#/$defs/EventContextExpressionSyntax"},{"$ref":"#/$defs/EventSourceIdExpressionSyntax"},{"$ref":"#/$defs/ListExpressionSyntax"},{"$ref":"#/$defs/LiteralExpressionSyntax"},{"$ref":"#/$defs/ObjectExpressionSyntax"},{"$ref":"#/$defs/PathExpressionSyntax"},{"$ref":"#/$defs/RawExpressionSyntax"},{"$ref":"#/$defs/RefusalExpressionSyntax"},{"$ref":"#/$defs/SourceItemExpressionSyntax"},{"$ref":"#/$defs/StringsExpressionSyntax"},{"$ref":"#/$defs/TemplateExpressionSyntax"}]},{"type":"null"}],"default":null}},"required":["kind","property","rule","severity"]},"VariantSyntax":{"title":"VariantSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"VariantSyntax"},"height":{"type":"string"},"places":{"type":"array","items":{"oneOf":[{"$ref":"#/$defs/PlaceSyntax"}]},"default":[]},"width":{"type":"string"}},"required":["kind","height","width"]},"AnonymousConditionSyntax":{"title":"AnonymousConditionSyntax","type":"object","additionalProperties":false,"properties":{"kind":{"type":"string","const":"AnonymousConditionSyntax"}},"required":["kind"]}} as const; diff --git a/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts b/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts index 107f991bf..94ea45d95 100644 --- a/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts +++ b/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts @@ -13,6 +13,7 @@ import { OperationPhaseSyntax } from './Operations'; import { ProducesSyntax } from './Reactions'; import { ObserverFilterSyntax } from './ObserverFilterSyntax'; import { SyntaxNode } from './SyntaxNode'; +import { ScreenActionSyntax, ScreenGuardedActionSyntax, ToolbarItemSyntax } from './Screens'; import { SpecificationEventSyntax, SpecificationStreamSyntax } from './Specifications'; import { isBlankImplementationHint } from '../Text/ImplementationHintText'; import { isSourceStreamName, isSourceStreamTypeName, sourceStreamPattern } from '../Text/SourceStreamNames'; @@ -31,6 +32,12 @@ const collection = (value: unknown, kind: string, message: string): void => { // The native ImplementationInvariants / OperationInvariants / EventSourceInvariants contracts. // Shared by the isolated strict reader and the writer, without pulling the transport schema into Monaco. export function validateSyntaxInvariants(node: SyntaxNode): void { + if (['ScreenActionSyntax', 'ScreenGuardedActionSyntax', 'ToolbarItemSyntax'].includes(node.kind)) { + const action = node as ScreenActionSyntax | ScreenGuardedActionSyntax | ToolbarItemSyntax; + if (action.subject != null && action.subject !== 'Item' && action.subject !== 'Screen') refuse('An action subject must be Item or Screen.'); + if (action.kind === 'ToolbarItemSyntax' && action.subject != null && action.syntaxKind !== 'Action') refuse('Only an action toolbar item can have a subject.'); + if (action.kind === 'ScreenActionSyntax' && action.inputs !== undefined) collection(action.inputs, 'InteractionArgumentSyntax', 'Action inputs must be a collection of arguments.'); + } const metadataError = publicEventMetadataError(node); if (metadataError !== undefined) refuse(metadataError); if (node.kind === 'ConceptSyntax') { diff --git a/Source/Screenplay/Compiler/Syntax/SyntaxJson.ts b/Source/Screenplay/Compiler/Syntax/SyntaxJson.ts index b2e65fbf9..4d219911f 100644 --- a/Source/Screenplay/Compiler/Syntax/SyntaxJson.ts +++ b/Source/Screenplay/Compiler/Syntax/SyntaxJson.ts @@ -117,6 +117,9 @@ const omittedWhenNull: Record = { UniquePropertyConstraintSyntax: ['description'], ProjectionSyntax: ['description'], ScreenSyntax: ['description'], + ScreenActionSyntax: ['subject'], + ScreenGuardedActionSyntax: ['subject'], + ToolbarItemSyntax: ['subject'], FormSyntax: ['description'], SpecificationSyntax: ['description', 'whenRedelivered', 'givenTimeZone'], SpecificationErrorSyntax: ['caseValue'], @@ -126,6 +129,7 @@ const omittedWhenNull: Record = { // Members omitted from the wire form when empty arrays, by node kind. const omittedWhenEmpty: Record = { + ScreenActionSyntax: ['inputs'], ModuleSyntax: ['dependsOn'], FeatureSyntax: ['dependsOn'], SpecificationSyntax: ['parameters', 'cases'], diff --git a/Source/Screenplay/Compiler/for_parse/when_parsing_explicit_action_subjects.ts b/Source/Screenplay/Compiler/for_parse/when_parsing_explicit_action_subjects.ts new file mode 100644 index 000000000..7c7156a9a --- /dev/null +++ b/Source/Screenplay/Compiler/for_parse/when_parsing_explicit_action_subjects.ts @@ -0,0 +1,27 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { describe, it } from 'vitest'; +import { ScreenActionSyntax, ScreenGuardedActionSyntax, ScreenToolbarSyntax } from '../Syntax/Screens'; +import { a_parsed_document } from './given/a_parsed_document'; + +const parse = () => a_parsed_document('module Work', ' feature Items', ' slice StateView Details', + ' command Retry', ' itemId Uuid', ' query ExternalDetails => ExternalItem', ' screen Details', ' data ExternalItem via query ExternalDetails', + ' action Retry for item', ' with itemId from item.itemId', ' action Work.Items.Details.Retry for screen', + ' action "Again" for screen', ' when item.ready == true execute Retry', + ' toolbar', ' item retry action Retry for item', ' parameter itemId from item.itemId'); + +describe('when parsing explicit action subjects', () => { + it('should accept the explicit subjects', () => parse().diagnostics.should.deep.equal([])); + it('should retain authored subjects and inputs', () => { + const directives = parse().value.modules[0].features[0].slices[0].screens[0].directives; + const action = directives[1] as ScreenActionSyntax; + action.subject!.should.equal('Item'); + action.inputs![0].binding.should.equal('item.itemId'); + (directives[2] as ScreenActionSyntax).subject!.should.equal('Screen'); + (directives[3] as ScreenGuardedActionSyntax).subject!.should.equal('Screen'); + const item = (directives[4] as ScreenToolbarSyntax).items[0]; + item.subject!.should.equal('Item'); + item.parameters[0].name.should.equal('itemId'); + }); +}); diff --git a/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts new file mode 100644 index 000000000..8c6cc3a97 --- /dev/null +++ b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts @@ -0,0 +1,60 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { describe, it } from 'vitest'; +import { parse } from '../ScreenplayCompiler'; +import { resolveActionSubjects } from '../ScreenActionSubjects'; +import { ScreenActionSyntax, ScreenGuardedActionSyntax } from '../Syntax/Screens'; +import { ApplicationSyntax } from '../Syntax/Structure'; +import { toSyntaxJson } from '../Syntax/SyntaxJson'; + +const source = 'concept ItemId : Uuid\nconcept TenantId : Uuid\nmodule Work\n feature Items\n slice StateView List\n readmodel Row\n rowId ItemId key\n itemId TenantId\n ready Boolean\n query Rows => Row[]\n command Retry\n itemId ItemId identifier\n screen List\n data Row[] via query Rows\n action Retry'; +const screen = (application: ApplicationSyntax) => application.modules[0].features[0].slices[0].screens[0]; +const action = (application: ApplicationSyntax) => screen(application).directives[1] as ScreenActionSyntax; + +describe('when resolving action subjects', () => { + for (const [clause, expected] of [['', 'Item'], [' for item', 'Item'], [' for screen', 'Screen']]) { + it(`should resolve '${clause}' without modifying the authored tree`, () => { + const raw = parse(source + clause).value; + const before = JSON.stringify(toSyntaxJson(raw)); + const effective = resolveActionSubjects(raw).value; + action(effective).subject!.should.equal(expected); + JSON.stringify(toSyntaxJson(raw)).should.equal(before); + (action(raw).inputs ?? []).should.deep.equal([]); + action(effective).location.should.deep.equal(action(raw).location); + }); + } + it('should keep same-name precedence before key fallback', () => { + action(resolveActionSubjects(parse(source).value).value).inputs![0].binding.should.equal('item.itemId'); + }); + it('should bind a renamed key by nominal concept', () => { + const resolved = resolveActionSubjects(parse(source.replace(' itemId TenantId\n', '')).value); + action(resolved.value).inputs![0].binding.should.equal('item.rowId'); + resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0817').should.equal(true); + }); + it('should retain an explicit mapping', () => { + const effective = resolveActionSubjects(parse(source + ' for item\n with itemId from $context.currentItem').value).value; + action(effective).inputs![0].binding.should.equal('$context.currentItem'); + }); + for (const replacement of ['ItemId optional identifier', 'ItemId generated identifier', 'TenantId identifier']) { + it(`should not infer an item from ${replacement}`, () => { + action(resolveActionSubjects(parse(source.replace('ItemId identifier', replacement)).value).value).subject!.should.equal('Screen'); + }); + } + it('should not use primitive equality as nominal proof', () => { + const primitive = source.replace('rowId ItemId key', 'rowId Uuid key').replace('itemId ItemId identifier', 'itemId Uuid identifier'); + action(resolveActionSubjects(parse(primitive).value).value).subject!.should.equal('Screen'); + }); + it('should leave ambiguous key input unresolved', () => { + const ambiguous = source.replace(' itemId TenantId\n', ' otherId ItemId key\n') + ' for item'; + const resolved = resolveActionSubjects(parse(ambiguous).value); + action(resolved.value).inputs!.should.deep.equal([]); + resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0818' && diagnostic.severity === 'warning').should.equal(true); + }); + it('should retain a guarded screen collection without selecting an item', () => { + const guarded = source.replace(' action Retry', ' action "Retry" for screen\n when item.ready == true execute Retry'); + const resolved = resolveActionSubjects(parse(guarded).value); + (screen(resolved.value).directives[1] as ScreenGuardedActionSyntax).alternatives[0].arguments.should.deep.equal([]); + resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0819' && diagnostic.severity === 'warning').should.equal(true); + }); +}); diff --git a/Source/Screenplay/Compiler/index.ts b/Source/Screenplay/Compiler/index.ts index 013223ff7..206ed11e8 100644 --- a/Source/Screenplay/Compiler/index.ts +++ b/Source/Screenplay/Compiler/index.ts @@ -7,6 +7,7 @@ export * from './Diagnostics'; export * from './Dependencies'; export * from './Syntax'; export * from './ScreenplayCompiler'; +export { resolveActionSubjects } from './ScreenActionSubjects'; export { checkPortableMatchPattern } from './Parsing/checkPortableMatchPattern'; export { PortableMatchStatus } from './Parsing/PortableMatchStatus'; export type { PortableMatchCheck } from './Parsing/PortableMatchCheck'; From 389a7f52ec7457d53cc6dac0477d5befb28ea771 Mon Sep 17 00:00:00 2001 From: woksin Date: Sat, 24 Oct 2026 12:45:43 +0200 Subject: [PATCH 2/9] WIP: continue action subject inference, fixtures and authoring (#1052) --- Documentation/screenplay/action-subjects.md | 57 + Documentation/screenplay/ast-compatibility.md | 12 + Documentation/screenplay/diagnostics.md | 8 + Documentation/screenplay/grammar.md | 14 +- Documentation/screenplay/screens.md | 13 +- Documentation/screenplay/toc.yml | 2 + Samples/Library/library.play | 5 +- .../Parsing/ActionSubjectContext.cs | 9 + .../Parsing/ActionSubjectResolver.Inputs.cs | 76 +- .../Parsing/ActionSubjectResolver.cs | 29 +- .../Parsing/GuardedActionValidator.cs | 7 +- ..._exporting_action_subject_fixture_packs.cs | 130 + .../WorkspaceActionSubjectRepairs.cs | 4 +- .../when_resolving_action_subjects.cs | 7 +- .../Authoring/ActionSubjectQuickFixes.ts | 70 + .../Compiler/Authoring/QuickFixes.ts | 9 +- .../when_repairing_action_subjects.ts | 54 + .../action-subjects/native.context.json | 2530 +++++++++++++++++ .../action-subjects/native.diagnostics.json | 245 ++ .../native.effective.syntax.json | 1315 +++++++++ .../action-subjects/native.raw.syntax.json | 1181 ++++++++ .../Conformance/action-subjects/source.play | 117 + .../action-subjects/typescript.context.json | 2463 ++++++++++++++++ .../typescript.diagnostics.json | 245 ++ .../typescript.effective.syntax.json | 1248 ++++++++ .../typescript.raw.syntax.json | 1114 ++++++++ ..._exporting_action_subject_fixture_packs.ts | 58 + .../Compiler/Parsing/ActionSubjectInputs.ts | 87 +- .../Parsing/ActionSubjectResolution.ts | 79 + .../Compiler/Parsing/GuardedActionInputs.ts | 3 + .../Parsing/GuardedActionValidator.ts | 4 - .../Compiler/ScreenActionSubjects.ts | 57 +- .../when_resolving_action_subjects.ts | 6 +- .../action-subject-authoring.ts | 12 + .../screenplay-language/completion-items.ts | 16 +- .../screenplay-language/completion-planner.ts | 6 + .../screenplay-language/diagnostic-codes.ts | 5 + .../screenplay-language/hover-content.ts | 3 + .../Monaco/screenplay-language/tokens.ts | 7 + .../syntaxes/screenplay.tmLanguage.json | 17 + 40 files changed, 11170 insertions(+), 154 deletions(-) create mode 100644 Documentation/screenplay/action-subjects.md create mode 100644 Source/DotNET/Screenplay/Parsing/ActionSubjectContext.cs create mode 100644 Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs create mode 100644 Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts create mode 100644 Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/source.play create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json create mode 100644 Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts create mode 100644 Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts create mode 100644 Source/Screenplay/Monaco/screenplay-language/action-subject-authoring.ts diff --git a/Documentation/screenplay/action-subjects.md b/Documentation/screenplay/action-subjects.md new file mode 100644 index 000000000..645162916 --- /dev/null +++ b/Documentation/screenplay/action-subjects.md @@ -0,0 +1,57 @@ +--- +title: "Action subjects" +description: "Explicit action scope, identifier-aware inputs, and the authored/effective syntax boundary." +--- + +# Action subjects + +State intent explicitly (decision 0110): + +```play +action RetryItem for item label "Retry" + with itemId from item.rowId + with note from $context.note + +action AddItem for screen + +toolbar actions + item retry action RetryItem for item + item add action AddItem for screen +``` + +The clause follows the command or guarded label, before an inline `label`. Only action toolbar items accept it; navigation and dialog items do not. These are contextual words, not new reserved declaration or property names. Plain-action `with from ` entries remain ordered authored syntax. Guarded alternatives retain their arguments; toolbar items retain their UI-binding parameters. + +## Inference and inputs + +`for item` needs one nearest `data` declaration: a record, or a selected collection item. Local sibling data takes precedence over inherited data regardless of source order, including sections, filled slots and outlets. Missing or equally near data is not guessed. + +1. Explicit input bindings win. +2. Remaining non-generated inputs use compatible, case-sensitive same-name fields. +3. A required, non-generated, non-collection identifier can use one key field with the same declared nominal concept. +4. Remaining inputs can use an existing command form or renderer input. + +Primitive equality, coincidentally similar names, optional identifiers and unmarked foreign keys are not identity proof. Multiple matching keys warn and need an explicit binding. There is no first-row or first-key fallback. + +`for screen` keeps plain and toolbar actions independent of selection and does not fill inputs from a row. A guarded action can inspect a single record even with `for screen`; collection-valued data warns, stays unresolved, and never chooses the first row. + +Without a clause, a plain or toolbar action infers Item only for exactly one collection data context, exactly one required non-generated identifier, and one matching declared key. Otherwise Screen remains the omitted legacy default. Guarded actions retain their existing single-subject behavior. + +## Diagnostics and migration + +| Code | Severity | Meaning | +|---|---|---| +| PLAY0815 | Error | Malformed, duplicate or misplaced subject clause. | +| PLAY0816 | Information | Explains an omitted plain/toolbar subject's inference. | +| PLAY0817 | Warning | Effective row binding differs from legacy case-insensitive name matching. | +| PLAY0818 | Warning | Multiple nominal keys could bind an input; write an explicit binding. | +| PLAY0819 | Warning | Guarded `for screen` has collection-valued data and cannot choose one item. | + +PLAY0319 still covers malformed/duplicate input syntax, PLAY0345 still covers unknown subject fields, and PLAY0346 still covers a missing or ambiguous guarded subject. Fixes can make inference explicit or retain legacy row behavior using explicit bindings when declaration proof is unambiguous. No fix silently rewrites source or guesses an imported declaration. + +## Authored and effective syntax + +Native `ScreenActionSubjects.Resolve(application)` and TypeScript `resolveActionSubjects(application)` return a separate effective application and diagnostics without mutating authored syntax. Resolution is idempotent. Consumers needing subject behavior opt in; raw compilation, canonical JSON and printing preserve the source form. Empty inputs and omitted subjects remain absent in legacy raw JSON. The additive native properties do not alter positional record constructors or deconstruction arity. + +The paired native/TypeScript fixture packs are under `Source/Screenplay/Compiler/Conformance/action-subjects`: authored source, raw syntax, effective syntax, diagnostics, and context/location sidecars. Each context includes the complete authored declaration tree and canonical-path source locations, so consumers can verify nominal identity without inventing it. Native/TS packs preserve their existing modeled syntax surfaces and assert common-member parity separately. + +Runtime execution and rendering proof are Scene-owned. Compiler fixtures and editor assistance do not claim renderer support or change the executable semantic model. diff --git a/Documentation/screenplay/ast-compatibility.md b/Documentation/screenplay/ast-compatibility.md index de5b8c8c1..38b3855ef 100644 --- a/Documentation/screenplay/ast-compatibility.md +++ b/Documentation/screenplay/ast-compatibility.md @@ -9,6 +9,18 @@ The syntax tree is a public API. Every consumer that compiles Screenplay to some This page states those promises. It is deliberately narrow: a guarantee you cannot rely on is worse than one that was never made. +## Action subject additions + +Decision 0110 adds nullable init-only `Subject` properties to `ScreenActionSyntax`, +`ScreenGuardedActionSyntax` and `ToolbarItemSyntax`, plus ordered init-only `Inputs` +on plain actions. Positional constructors and deconstruction arities are unchanged. +TypeScript adds optional equivalents. JSON omits absent subjects and empty inputs; +unknown subject enum values and subjects on non-action toolbar items are rejected. +Raw compile/parse and printing preserve authored syntax. Effective semantics require +native `ScreenActionSubjects.Resolve(application)` or TypeScript +`resolveActionSubjects(application)`; neither mutates its input. See +[action subjects](action-subjects.md) for the paired fixture/context boundary. + ## Clock operand authoring additions Decisions 0106/0107 add optional `ApplicationSyntax.TimeZone`, `CommandSyntax.Calendar`, diff --git a/Documentation/screenplay/diagnostics.md b/Documentation/screenplay/diagnostics.md index 3ec3ded37..060732293 100644 --- a/Documentation/screenplay/diagnostics.md +++ b/Documentation/screenplay/diagnostics.md @@ -9,6 +9,14 @@ Every problem the compiler finds is reported as a **diagnostic**: a severity, a A message is written for a person and gets reworded whenever a clearer wording is found. A **code never changes**. So a code is what you match on, suppress on, and group by - anything reading the message text breaks the next time the message is improved. +## Action subject diagnostics + +Decision 0110 reserves PLAY0815–PLAY0819: malformed/duplicate/misplaced clauses +(Error), inference (Information), changed legacy row behavior (Warning), ambiguous +input keys (Warning), and unsupported guarded screen/collection context (Warning), +respectively. See [action subjects](action-subjects.md#diagnostics-and-migration) +for triggers and safe fixes. PLAY0319, PLAY0345 and PLAY0346 keep their existing meanings. + ## Reading a diagnostic The CLI prints a diagnostic in the format editors and build servers already parse - the file, the position, the severity, the code, and the message - followed by the offending line and a caret: diff --git a/Documentation/screenplay/grammar.md b/Documentation/screenplay/grammar.md index e98e1a734..9c0396bce 100644 --- a/Documentation/screenplay/grammar.md +++ b/Documentation/screenplay/grammar.md @@ -1548,7 +1548,12 @@ ScreenDirective = DataDecl ToolbarDecl = "toolbar", Ident, NL, [ INDENT, { ToolbarItem | ToolbarButton }, DEDENT ] ; -ToolbarItem = "item", Ident, ( "action" | "dialog" ), QualifiedName, NL, +ToolbarItem = "item", Ident, "action", QualifiedName, [ ActionSubject ], [ "label", LocalizableString ], NL, + [ INDENT, { "parameter", Ident, "from", (* UI binding *) NL + | "label", LocalizableString, NL + | "icon", ( Ident | String ), NL + | ToolbarConfirm }, DEDENT ] + | "item", Ident, "dialog", QualifiedName, NL, [ INDENT, { "label", LocalizableString, NL | "icon", ( Ident | String ), NL | ToolbarConfirm }, DEDENT ] @@ -1565,9 +1570,11 @@ ToolbarConfirm = "confirm", LocalizableString, NL ; (* asked before the comman DataDecl = "data", RequiredTypeRef, "via", "query", QualifiedName, [ "by", Ident ], NL ; -ActionDecl = "action", QualifiedName, NL, +ActionSubject = "for", ( "item" | "screen" ) ; + +ActionDecl = "action", QualifiedName, [ ActionSubject ], [ "label", LocalizableString ], NL, [ INDENT, { ActionOption }, DEDENT ] - | "action", LocalizableString, NL, + | "action", LocalizableString, [ ActionSubject ], NL, INDENT, { ActionAlternative | ActionOtherwise | NavigateDecl }, DEDENT ; ActionAlternative = "when", Condition, "execute", QualifiedName, NL, @@ -1581,6 +1588,7 @@ ActionOtherwise = "otherwise", "hidden", NL ordering requires numbers, contains / starts with require strings. *) ActionOption = NavigateDecl + | InteractionArgument | "label", LocalizableString, NL ; NavigateDecl = "navigate", "to", QualifiedName, [ "by", Ident ], NL, diff --git a/Documentation/screenplay/screens.md b/Documentation/screenplay/screens.md index a26133cb9..0bdf4a614 100644 --- a/Documentation/screenplay/screens.md +++ b/Documentation/screenplay/screens.md @@ -56,6 +56,10 @@ issues the command and discovers its command-bound form. An action's `navigate t Screen `data ... via query ... by value` and `navigate ... by value` remain scalar lookups. They cannot supply a composite read-model key to a single-instance query. The compiler reports `PLAY0661`; no automatic screen repair is offered. Collection queries may filter by a subset. See [Read-model keys](readmodels.md#keys). +## Action subjects + +Plain actions, guarded actions and action toolbar items accept `for item` or `for screen` after the command or label, before an inline `label`. Plain actions also accept ordered `with from ` children. Prefer explicit scope in new documents. See [action subjects](action-subjects.md) for inference, nominal identifier/key binding, migration diagnostics and the separate authored/effective compiler boundary. + ## One action, several commands Use a label-headed **guarded action** when one user decision can run different commands as the displayed item's state changes. The label is a quoted string or a `$strings.` reference; it replaces the plain action's `label` child. @@ -77,7 +81,7 @@ screen PlanDetails ### Subject and conditions -`item` is the nearest container's `data` item, or the selected element when that data is a collection. Sibling data in the action's section, filled slot or screen body takes precedence over outer data, regardless of source order. Without an item (loading or no selection), the action is always hidden, even with an execute fallback. Missing or equally near data declarations produce a warning rather than guessing a subject. +For a guarded action (omitted subject or `for item`), `item` is the nearest container's `data` item, or the selected element when that data is a collection. Sibling data in the action's section, filled slot or screen body takes precedence over outer data, regardless of source order. Without an item (loading or no selection), the action is always hidden, even with an execute fallback. Missing or equally near data declarations produce a warning rather than guessing a subject. Conditions compare `item.[.…]` with a literal: a string, number, Boolean or `null`. They do not read route parameters, screen state, `$context` or `$env`, and cannot compare two item paths. Use `==`, `!=`, numeric `>`, `>=`, `<`, `<=`, or string `contains` and `starts with`. Combine comparisons with `and`, `or` and parentheses; `and` binds more tightly. Collection-valued fields are not supported in conditions. Unsupported punctuation, such as brackets around a literal, is rejected with `PLAY0344` rather than discarded. @@ -92,9 +96,10 @@ Alternatives are checked in authored order whenever query data changes. The firs Each alternative and execute fallback may bind inputs with `with from `. A binding may pass a terminal collection field, such as `with ids from item.ids`, to a matching collection input; it cannot traverse through a collection. Inputs resolve in this order: 1. Explicit `with` bindings. -2. Subject fields with the same name as the command input. -3. The command's declared [form](forms.md). -4. Renderer input. +2. Compatible subject fields with the same case-sensitive name as the command input. +3. A unique declared nominal identifier/key match for required, non-generated identifier inputs. +4. The command's declared [form](forms.md). +5. Renderer input. The guard controls what the user is offered, not what the system accepts. The selected command still enforces its authorization, validation and constraints. If the selected command is unavailable to the caller, present the action as unavailable, as [#335](https://github.com/Cratis/Screenplay/issues/335) defines once admitted. Authorization denial never falls through to another command. A click runs the choice shown to the user; if a click-time check changes that choice, the renderer must refresh instead of executing the new one. A single optional `navigate to` runs after whichever command succeeds, never to open that command's own input screen. If input needs a separate screen or dialog, open it first with a click or row-click carrying the item's identity; place the guarded action on that input screen. diff --git a/Documentation/screenplay/toc.yml b/Documentation/screenplay/toc.yml index d5fc759da..04871314c 100644 --- a/Documentation/screenplay/toc.yml +++ b/Documentation/screenplay/toc.yml @@ -77,6 +77,8 @@ href: triggers.md - name: Screens href: screens.md +- name: Action subjects + href: action-subjects.md - name: Interactions href: interactions.md - name: Layouts and templates diff --git a/Samples/Library/library.play b/Samples/Library/library.play index acd893165..8e118f544 100644 --- a/Samples/Library/library.play +++ b/Samples/Library/library.play @@ -174,8 +174,9 @@ module Lending column title label "Title" column author label "Author" column available label "On the shelf" - action AddBook - action BorrowBook + action AddBook for screen + action BorrowBook for item + with bookId from item.bookId specification BorrowingTakesABookOffTheShelf given caller diff --git a/Source/DotNET/Screenplay/Parsing/ActionSubjectContext.cs b/Source/DotNET/Screenplay/Parsing/ActionSubjectContext.cs new file mode 100644 index 000000000..85fc191ea --- /dev/null +++ b/Source/DotNET/Screenplay/Parsing/ActionSubjectContext.cs @@ -0,0 +1,9 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay.Parsing; + +internal sealed record ActionSubjectContext(IReadOnlyList Data, DeclarationScope Scope, SourceLocation Location); diff --git a/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs index 927862823..d578e49e6 100644 --- a/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs +++ b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.Inputs.cs @@ -10,54 +10,66 @@ internal sealed partial class ActionSubjectResolver { static bool EligibleIdentifier(PropertySyntax input) => input.IsIdentifier && !input.IsGenerated && !input.Type.IsOptional && !input.Type.IsCollection; - ScreenActionSubjectKind Subject(ScreenActionSubjectKind? authored, string commandName, IReadOnlyList subjects, DeclarationScope scope, SourceLocation location) + ScreenActionSubjectKind? Subject(ScreenActionSubjectKind? authored, string command, IEnumerable bound, ActionSubjectContext context) { - if (authored is { } explicitSubject) return explicitSubject; - var inputs = CommandInputs(commandName, scope); - var properties = Properties(subjects, scope); - var keys = properties.Where(property => property.IsKey).ToArray(); - var eligible = inputs.Where(input => EligibleIdentifier(input) && keys.Any(key => SameConcept(input, key))).ToArray(); - var inferred = subjects.Count == 1 && subjects[0].Type.IsCollection && eligible.Length == 1 && keys.Count(key => SameConcept(eligible[0], key)) == 1 - ? ScreenActionSubjectKind.Item - : ScreenActionSubjectKind.Screen; - _diagnostics.Add(new(DiagnosticSeverity.Information, DiagnosticCodes.InferredActionSubject, $"Action '{commandName}' infers 'for {inferred.ToString().ToLowerInvariant()}' from its declared data and identifier types", location)); - if (subjects.Count == 1 && subjects[0].Type.IsCollection) + if (authored is not null) return authored; + var inputs = CommandInputs(command, context.Scope); + var properties = Properties(context.Data, context.Scope); + var identifiers = inputs.Where(EligibleIdentifier).ToArray(); + var item = context.Data is [{ Type.IsCollection: true }] && identifiers is [var identifier] && Keys(identifier, properties).Length == 1; + var inferred = item ? ScreenActionSubjectKind.Item : ScreenActionSubjectKind.Screen; + _diagnostics.Add(new(DiagnosticSeverity.Information, DiagnosticCodes.InferredActionSubject, $"Action '{command}' infers 'for {inferred.ToString().ToLowerInvariant()}' from its declared data and identifier types", context.Location)); + ReportMigration(command, bound, context, item); + + // Screen is the legacy omitted default; inference must not manufacture authored metadata. + return item ? ScreenActionSubjectKind.Item : null; + } + + void ReportMigration(string command, IEnumerable bound, ActionSubjectContext context, bool item) + { + if (context.Data is not [{ Type.IsCollection: true }]) return; + var properties = Properties(context.Data, context.Scope); + var inputs = CommandInputs(command, context.Scope).Where(input => !input.IsGenerated && !bound.Contains(input.Name)).ToArray(); + var legacy = inputs.SelectMany(input => properties.Where(property => string.Equals(input.Name, property.Name, StringComparison.OrdinalIgnoreCase)).Select(property => $"{input.Name} from item.{property.Name}")).ToArray(); + var current = item ? inputs.Select(input => (Input: input, Property: Binding(input, properties))).Where(pair => pair.Property is not null).Select(pair => $"{pair.Input.Name} from item.{pair.Property!.Name}").ToArray() : []; + if (!legacy.SequenceEqual(current)) { - var legacy = inputs.SelectMany(input => properties.Where(property => string.Equals(input.Name, property.Name, StringComparison.OrdinalIgnoreCase)).Select(property => (Input: input, Property: property))).ToArray(); - if ((legacy.Length > 0) != (inferred == ScreenActionSubjectKind.Item)) - { - var paths = string.Join(", ", legacy.Select(pair => $"{pair.Input.Name} from item.{pair.Property.Name}")); - _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.ChangedActionSubject, $"Action '{commandName}' now infers 'for {inferred.ToString().ToLowerInvariant()}'; legacy row-name matching would use {(paths.Length == 0 ? "no row property" : paths)}", location)); - } + _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.ChangedActionSubject, $"Action '{command}' now infers 'for {(item ? "item" : "screen")}'; legacy row-name matching would use {(legacy.Length == 0 ? "no row property" : string.Join(", ", legacy))}", context.Location)); } - - return inferred; } - InteractionArgumentSyntax[] Inputs(string commandName, IEnumerable authored, IReadOnlyList subjects, DeclarationScope scope, SourceLocation location) + InteractionArgumentSyntax[] Inputs(string command, IEnumerable authored, ActionSubjectContext context) { var result = authored.ToList(); - if (subjects.Count != 1) return [.. result]; - var properties = Properties(subjects, scope); - foreach (var input in CommandInputs(commandName, scope).Where(input => !input.IsGenerated)) + if (context.Data.Count != 1) return [.. result]; + var properties = Properties(context.Data, context.Scope); + foreach (var input in CommandInputs(command, context.Scope).Where(input => !input.IsGenerated)) { if (result.Exists(argument => argument.Name == input.Name)) continue; - var sameName = properties.Where(property => property.Name == input.Name).ToArray(); - if (sameName.Length == 1) + if (Binding(input, properties) is { } property) { - result.Add(new(input.Name, $"item.{sameName[0].Name}", location)); - continue; + result.Add(new(input.Name, $"item.{property.Name}", context.Location)); + } + else if (Keys(input, properties).Length > 1) + { + _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.AmbiguousActionInputBinding, $"Input '{input.Name}' of action '{command}' matches several declared key fields - write an explicit binding", context.Location)); } - - if (!EligibleIdentifier(input)) continue; - var keys = properties.Where(property => property.IsKey && SameConcept(input, property)).ToArray(); - if (keys.Length == 1) result.Add(new(input.Name, $"item.{keys[0].Name}", location)); - else if (keys.Length > 1) _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.AmbiguousActionInputBinding, $"Input '{input.Name}' of action '{commandName}' matches several declared key fields - write an explicit binding", location)); } return [.. result]; } + PropertySyntax? Binding(PropertySyntax input, PropertySyntax[] properties) + { + var named = properties.Where(property => property.Name == input.Name && _declarations.Compatible(property.Type, input.Type) == true).ToArray(); + if (named is [var property]) return property; + return Keys(input, properties) is [var key] ? key : null; + } + + PropertySyntax[] Keys(PropertySyntax input, PropertySyntax[] properties) => EligibleIdentifier(input) + ? [.. properties.Where(property => property.IsKey && SameConcept(input, property))] + : []; + PropertySyntax[] Properties(IReadOnlyList subjects, DeclarationScope scope) => subjects.Count == 1 ? _declarations.ViewProperties(subjects[0].Type.Name, scope)?.ToArray() ?? [] : []; diff --git a/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs index 6dae6a62e..1c22dd44b 100644 --- a/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs +++ b/Source/DotNET/Screenplay/Parsing/ActionSubjectResolver.cs @@ -61,8 +61,9 @@ ScreenDirectiveSyntax[] Container(IEnumerable directives, ScreenActionSyntax PlainAction(ScreenActionSyntax action, IReadOnlyList subjects, DeclarationScope scope) { - var subject = Subject(action.Subject, action.Command, subjects, scope, action.Location); - var inputs = subject == ScreenActionSubjectKind.Item ? Inputs(action.Command, action.Inputs, subjects, scope, action.Location) : action.Inputs; + var context = new ActionSubjectContext(subjects, scope, action.Location); + var subject = Subject(action.Subject, action.Command, action.Inputs.Select(input => input.Name), context); + var inputs = subject == ScreenActionSubjectKind.Item && HasSubject(subjects, action.Location, false) ? Inputs(action.Command, action.Inputs, context) : action.Inputs; var effective = action with { Subject = subject, Inputs = inputs }; Remember(action, effective, subjects, scope); return effective; @@ -71,24 +72,34 @@ ScreenActionSyntax PlainAction(ScreenActionSyntax action, IReadOnlyList subjects, DeclarationScope scope) { if (item.Kind != ToolbarItemKind.Action) return item; - var subject = Subject(item.Subject, item.Target, subjects, scope, item.Location); - if (subject != ScreenActionSubjectKind.Item) + var context = new ActionSubjectContext(subjects, scope, item.Location); + var subject = Subject(item.Subject, item.Target, item.Parameters.Select(parameter => parameter.Name), context); + if (subject != ScreenActionSubjectKind.Item || !HasSubject(subjects, item.Location, false)) { var effective = item with { Subject = subject }; Remember(item, effective, subjects, scope); return effective; } var authored = item.Parameters.ToArray(); - var inputs = Inputs(item.Target, authored.Select(parameter => new InteractionArgumentSyntax(parameter.Name, string.Empty, parameter.Location)), subjects, scope, item.Location); + var inputs = Inputs(item.Target, authored.Select(parameter => new InteractionArgumentSyntax(parameter.Name, string.Empty, parameter.Location)), context); var inferred = inputs.Skip(authored.Length).Select(input => new ScreenNavigationParameterSyntax(input.Name, new(UiBindingKind.DataContext, input.Binding, input.Location), input.Location)); var resolved = item with { Subject = subject, Parameters = [.. authored.Concat(inferred)] }; Remember(item, resolved, subjects, scope); return resolved; } + bool HasSubject(IReadOnlyList subjects, Cratis.Screenplay.Diagnostics.SourceLocation location, bool guarded) + { + if (subjects.Count == 1) return true; + var message = guarded ? "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved" : "Action 'for item' requires one resolvable data subject - no item binding is inferred"; + _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.UnresolvedActionSubject, message, location)); + return false; + } + ScreenGuardedActionSyntax GuardedAction(ScreenGuardedActionSyntax action, IReadOnlyList subjects, DeclarationScope scope) { - if (action.Subject == ScreenActionSubjectKind.Screen && subjects.Count == 1 && subjects[0].Type.IsCollection) + if (!HasSubject(subjects, action.Location, true)) return action; + if (action.Subject == ScreenActionSubjectKind.Screen && subjects[0].Type.IsCollection) { _diagnostics.Add(new(DiagnosticSeverity.Warning, DiagnosticCodes.UnsupportedActionSubjectContext, "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", action.Location)); return action; @@ -96,10 +107,10 @@ ScreenGuardedActionSyntax GuardedAction(ScreenGuardedActionSyntax action, IReadO return action with { - Subject = action.Subject ?? ScreenActionSubjectKind.Item, - Alternatives = [.. action.Alternatives.Select(alternative => alternative with { Arguments = Inputs(alternative.Command, alternative.Arguments, subjects, scope, alternative.Location) })], + Subject = action.Subject, + Alternatives = [.. action.Alternatives.Select(alternative => alternative with { Arguments = Inputs(alternative.Command, alternative.Arguments, new(subjects, scope, alternative.Location)) })], Otherwise = action.Otherwise is { Command: { } command } otherwise - ? otherwise with { Arguments = Inputs(command, otherwise.Arguments, subjects, scope, otherwise.Location) } + ? otherwise with { Arguments = Inputs(command, otherwise.Arguments, new(subjects, scope, otherwise.Location)) } : action.Otherwise }; } diff --git a/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs b/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs index 19269943e..833bb8d47 100644 --- a/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs +++ b/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs @@ -82,11 +82,6 @@ static void ValidateAction( ParserContext context) { var properties = subjects.Count == 1 ? declarations.ViewProperties(subjects[0].Type.Name, scope) : null; - if (subjects.Count != 1) - { - context.Warning(DiagnosticCodes.UnresolvedActionSubject, "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved", action.Location); - } - foreach (var alternative in action.Alternatives) { foreach (var comparison in Comparisons(alternative.Condition)) @@ -114,8 +109,10 @@ static void ValidateArguments( ParserContext context) { var command = declarations.Resolve(commandName, scope, slice => slice.Commands, command => command.Name)?.Node; + var names = new HashSet(StringComparer.Ordinal); foreach (var argument in arguments) { + if (!names.Add(argument.Name)) context.Error(DiagnosticCodes.InvalidInteractionArgument, $"Duplicate argument '{argument.Name}' - supply each input only once", argument.Location); var inputs = command?.Properties.Where(property => property.Name == argument.Name).ToArray(); if (inputs is { Length: 0 }) { diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs new file mode 100644 index 000000000..9fe32e864 --- /dev/null +++ b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs @@ -0,0 +1,130 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections; +using System.Runtime.CompilerServices; +using System.Text.Json; +using Cratis.Screenplay.Diagnostics; + +namespace Cratis.Screenplay.Syntax.Serialization.for_SyntaxJson; + +public class when_exporting_action_subject_fixture_packs : Specification +{ + readonly Dictionary _exports = []; + ApplicationSyntax _raw; + ApplicationSyntax _effective; + JsonElement _before; + string _directory; + + void Establish() + { + _directory = Fixtures(); + var compiled = new ScreenplayCompiler().Compile(File.ReadAllText(Path.Combine(_directory, "source.play"))); + _raw = compiled.Value!; + _before = SyntaxJson.Serialize(_raw); + _exports["diagnostics"] = JsonSerializer.SerializeToElement(compiled.Diagnostics.Where(Relevant).Select(diagnostic => new + { + code = diagnostic.Code, + severity = diagnostic.Severity.ToString().ToLowerInvariant(), + message = diagnostic.Message, + location = new { line = diagnostic.Location.Line, column = diagnostic.Location.Column } + })); + } + + void Because() + { + _effective = ScreenActionSubjects.Resolve(_raw).Value!; + _exports["raw.syntax"] = SyntaxJson.Serialize(_raw); + _exports["effective.syntax"] = SyntaxJson.Serialize(_effective); + _exports["context"] = JsonSerializer.SerializeToElement(new + { + source = "source.play", + application = _before, + locations = Locations(_raw, "$").OrderBy(entry => entry.Path, StringComparer.Ordinal).Select(entry => new + { + path = entry.Path, + kind = entry.Node.GetType().Name, + location = new { line = entry.Node.Location.Line, column = entry.Node.Location.Column } + }) + }); + } + + [Fact] void should_leave_authored_syntax_unchanged() => SyntaxJson.StructurallyEqual(_raw, SyntaxJson.Deserialize(_before)).ShouldBeTrue(); + [Fact] void should_be_idempotent() => SyntaxJson.StructurallyEqual(_effective, ScreenActionSubjects.Resolve(_effective).Value!).ShouldBeTrue(); + + [Fact] + void should_match_the_native_fixture_pack() + { + var regenerate = Environment.GetEnvironmentVariable("SCREENPLAY_REGENERATE_ACTION_SUBJECT_FIXTURES") == "1"; + foreach (var (name, value) in _exports) + { + var path = Path.Combine(_directory, $"native.{name}.json"); + if (regenerate) File.WriteAllText(path, JsonSerializer.Serialize(value, new JsonSerializerOptions { WriteIndented = true }) + "\n"); + else Assert.True(JsonElement.DeepEquals(value, JsonDocument.Parse(File.ReadAllText(path)).RootElement), path); + } + Assert.False(regenerate, "Fixture pack regenerated; review and rerun without SCREENPLAY_REGENERATE_ACTION_SUBJECT_FIXTURES"); + } + + [Fact] + void should_agree_with_typescript_on_authored_and_effective_members() + { + foreach (var name in new[] { "raw.syntax", "effective.syntax" }) + { + var expected = JsonDocument.Parse(File.ReadAllText(Path.Combine(_directory, $"typescript.{name}.json"))).RootElement; + Compare(expected, _exports[name], "$"); + } + } + + static bool Relevant(Diagnostic diagnostic) => diagnostic.Code is DiagnosticCodes.InvalidInteractionArgument or DiagnosticCodes.UnknownActionSubjectField or DiagnosticCodes.UnresolvedActionSubject or DiagnosticCodes.InvalidActionSubjectClause or DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject or DiagnosticCodes.AmbiguousActionInputBinding or DiagnosticCodes.UnsupportedActionSubjectContext; + + static IEnumerable<(string Path, SyntaxNode Node)> Locations(SyntaxNode node, string path) + { + yield return (path, node); + foreach (var member in SyntaxKinds.For(node.GetType()).Members) + { + var value = member.Property.GetValue(node); + if (value is SyntaxNode child) + { + foreach (var entry in Locations(child, $"{path}.{member.Name}")) yield return entry; + } + else if (value is IEnumerable items and not string) + { + var index = 0; + foreach (var item in items) + { + if (item is SyntaxNode element) + { + foreach (var entry in Locations(element, $"{path}.{member.Name}[{index}]")) yield return entry; + } + index++; + } + } + } + } + + static void Compare(JsonElement expected, JsonElement actual, string path) + { + Assert.True(actual.ValueKind == expected.ValueKind, path); + if (expected.ValueKind == JsonValueKind.Object) + { + foreach (var property in expected.EnumerateObject()) + { + Assert.True(actual.TryGetProperty(property.Name, out var value), $"{path}.{property.Name}"); + Compare(property.Value, value, $"{path}.{property.Name}"); + } + } + else if (expected.ValueKind == JsonValueKind.Array) + { + Assert.True(actual.GetArrayLength() == expected.GetArrayLength(), path); + for (var index = 0; index < expected.GetArrayLength(); index++) Compare(expected[index], actual[index], $"{path}[{index}]"); + } + else Assert.True(JsonElement.DeepEquals(expected, actual), path); + } + + static string Fixtures([CallerFilePath] string path = "") + { + var directory = Directory.GetParent(path); + while (directory is not null && !Directory.Exists(Path.Combine(directory.FullName, "Documentation"))) directory = directory.Parent; + return Path.Combine(directory!.FullName, "Source", "Screenplay", "Compiler", "Conformance", "action-subjects"); + } +} diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs index bfd0dac18..6f47b08e1 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs @@ -21,9 +21,9 @@ internal static ImmutableArray Find(WorkspaceSyntaxIn var resolver = new ActionSubjectResolver(PlayFolderMerge.Merge(roots).Value!); resolver.Resolve(); if (!resolver.Repairs.TryGetValue(subject.Node, out var evidence)) return []; - var inferred = evidence.Effective is ScreenActionSyntax action ? action.Subject : ((ToolbarItemSyntax)evidence.Effective).Subject; + var inferred = (evidence.Effective is ScreenActionSyntax action ? action.Subject : ((ToolbarItemSyntax)evidence.Effective).Subject) ?? ScreenActionSubjectKind.Screen; (SyntaxNode Node, string Title)[] candidates = diagnostic.Code == DiagnosticCodes.InferredActionSubject - ? [(Explicit(subject.Node, inferred!.Value), $"Make inferred 'for {inferred.Value.ToString().ToLowerInvariant()}' explicit")] + ? [(Explicit(subject.Node, inferred), $"Make inferred 'for {inferred.ToString().ToLowerInvariant()}' explicit")] : [ (Explicit(subject.Node, ScreenActionSubjectKind.Item), "Use 'for item' (item-bound action)"), diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs index 2f9c3535a..3d8ac60df 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs @@ -29,7 +29,8 @@ void should_resolve_without_changing_authored_syntax(string clause, ScreenAction [Fact] void should_keep_same_name_precedence_over_key_type_fallback() { - var effective = ScreenActionSubjects.Resolve(_compiler.Compile(Source).Value!).Value!; + var source = Source.Replace("itemId TenantId", "itemId ItemId", StringComparison.Ordinal); + var effective = ScreenActionSubjects.Resolve(_compiler.Compile(source).Value!).Value!; Action(effective).Inputs.Single().Binding.ShouldEqual("item.itemId"); } @@ -56,14 +57,14 @@ void should_keep_an_explicit_binding_before_same_name_and_key_fallback() void should_not_infer_item_from_ineligible_or_primitive_identifiers(string original, string replacement) { var raw = _compiler.Compile(Source.Replace(original, replacement, StringComparison.Ordinal)).Value!; - Action(ScreenActionSubjects.Resolve(raw).Value!).Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + Action(ScreenActionSubjects.Resolve(raw).Value!).Subject.ShouldBeNull(); } [Fact] void should_not_use_primitive_equality_as_nominal_proof() { var source = Source.Replace("rowId ItemId key", "rowId Uuid key", StringComparison.Ordinal).Replace("itemId ItemId identifier", "itemId Uuid identifier", StringComparison.Ordinal); - Action(ScreenActionSubjects.Resolve(_compiler.Compile(source).Value!).Value!).Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + Action(ScreenActionSubjects.Resolve(_compiler.Compile(source).Value!).Value!).Subject.ShouldBeNull(); } [Fact] diff --git a/Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts b/Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts new file mode 100644 index 000000000..16654923c --- /dev/null +++ b/Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts @@ -0,0 +1,70 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; +import { ActionSubjectEvidence, resolveActionSubjectApplication } from '../Parsing/ActionSubjectResolution'; +import { ActionSubjectInputs } from '../Parsing/ActionSubjectInputs'; +import { RefusalDeclarations } from '../Parsing/RefusalDeclarations'; +import { splitLines } from '../Parsing/SourceLineSplitter'; +import { parseForAuthoring } from '../ScreenplayCompiler'; +import { InteractionArgumentSyntax, ScreenActionSubjectKind } from '../Syntax/Screens'; +import { ApplicationSyntax } from '../Syntax/Structure'; +import { toSyntaxJson } from '../Syntax/SyntaxJson'; +import { pattern } from '../Text/patterns'; +import { applyQuickFixEdits, QuickFix, QuickFixEdit, QuickFixOptions } from './QuickFixes'; + +export function prepareActionSubjectQuickFixes(source: string, options: Pick): (line?: number, code?: string) => QuickFix[] { + // Imported application snapshots belong to the native workspace; never guess missing declarations in a buffer. + if (options.documents !== undefined && options.documents.size > 1) return () => []; + const original = parseForAuthoring(source, undefined, options.placement); + if (!original.success) return () => []; + const declarations = new RefusalDeclarations(original.value); + const resolver = new ActionSubjectInputs(declarations, []); + const evidence: ActionSubjectEvidence[] = []; + resolveActionSubjectApplication(original.value, entry => evidence.push(entry)); + const lines = splitLines(source); + const ending = source.includes('\r\n') ? '\r\n' : '\n'; + const fixes: QuickFix[] = []; + for (const entry of evidence) { + if (entry.authored.subject != null || declarations.resolve(entry.command, entry.context.slice, slice => slice.commands) === null) continue; + const diagnostic = original.diagnostics.find(diagnostic => diagnostic.location.line === entry.authored.location.line && diagnostic.code === DiagnosticCodes.InferredActionSubject); + if (diagnostic === undefined) continue; + const subject = entry.effective.subject ?? 'Screen'; + const explicit = candidate(entry, subject, `Make inferred 'for ${subject.toLowerCase()}' explicit`); + if (explicit !== undefined) fixes.push(explicit); + if (original.diagnostics.some(diagnostic => diagnostic.location.line === entry.authored.location.line && diagnostic.code === DiagnosticCodes.ChangedActionSubject)) { + const authored = entry.authored.kind === 'ScreenActionSyntax' ? entry.authored.inputs ?? [] : entry.authored.parameters.map(parameter => ({ kind: 'InteractionArgumentSyntax' as const, name: parameter.name, binding: parameter.binding.path, location: parameter.location })); + const retained = resolver.legacyInputs(entry.command, authored, entry.context); + if (retained !== null) { + const legacy = candidate(entry, 'Item', 'Retain legacy row behavior explicitly', retained.slice(authored.length)); + if (legacy !== undefined) fixes.push({ ...legacy, diagnosticCode: DiagnosticCodes.ChangedActionSubject }); + } + if (explicit !== undefined) fixes.push({ ...explicit, diagnosticCode: DiagnosticCodes.ChangedActionSubject }); + } + } + return (line, code) => fixes.filter(fix => (line === undefined || fix.line === line) && (code === undefined || fix.diagnosticCode === code)); + + function candidate(entry: ActionSubjectEvidence, subject: ScreenActionSubjectKind, title: string, additions: readonly InteractionArgumentSyntax[] = []): QuickFix | undefined { + const line = lines[entry.authored.location.line - 1]; + const header = pattern(entry.authored.kind === 'ScreenActionSyntax' ? '^(\\s*action\\s+[\\w.]+)' : '^(\\s*item\\s+\\w+\\s+action\\s+[\\w.]+)').exec(line.raw); + if (header === null) return undefined; + const edits: QuickFixEdit[] = [{ path: options.path, start: line.startOffset + header[0].length, length: 0, text: ` for ${subject.toLowerCase()}` }]; + const prefix = /^\s*/.exec(line.raw)![0]; + const end = lines.find(child => child.number > line.number && child.raw.trim().length > 0 && /^\s*/.exec(child.raw)![0].length <= prefix.length)?.startOffset ?? source.length; + if (additions.length > 0) { + const indent = lines.find(child => child.number > line.number && child.startOffset < end && child.raw.trim().length > 0)?.raw.match(/^\s*/)![0] ?? `${prefix} `; + const text = additions.map(input => `${indent}${entry.authored.kind === 'ScreenActionSyntax' ? 'with' : 'parameter'} ${input.name} from ${entry.authored.kind === 'ScreenActionSyntax' ? '' : 'data '}${input.binding}`).join(ending) + ending; + edits.push({ path: options.path, start: end, length: 0, text: (end > 0 && source[end - 1] !== '\n' ? ending : '') + text }); + } + const replacement = entry.authored.kind === 'ScreenActionSyntax' + ? { ...entry.authored, subject, inputs: [...(entry.authored.inputs ?? []), ...additions] } + : { ...entry.authored, subject, parameters: [...entry.authored.parameters, ...additions.map(input => ({ kind: 'ScreenNavigationParameterSyntax', name: input.name, binding: { kind: 'UiBindingSyntax', bindingKind: 'DataContext', path: input.binding, query: null, componentId: null, componentPropertyPath: null, mode: null, nullBehavior: null, expectedValueType: null, literal: null, rawText: null, location: input.location }, location: input.location }))] }; + const expected = JSON.parse(JSON.stringify(original.value, (_key, value: unknown) => value === entry.authored ? replacement : value)) as ApplicationSyntax; + const edited = applyQuickFixEdits(source, edits); + if (edited === undefined) return undefined; + const parsed = parseForAuthoring(edited, undefined, options.placement); + if (!parsed.success || JSON.stringify(toSyntaxJson(parsed.value)) !== JSON.stringify(toSyntaxJson(expected))) return undefined; + if (parsed.diagnostics.some(diagnostic => diagnostic.location.line === line.number && (diagnostic.code === DiagnosticCodes.InferredActionSubject || diagnostic.code === DiagnosticCodes.ChangedActionSubject))) return undefined; + return { line: line.number, diagnosticCode: DiagnosticCodes.InferredActionSubject, title, scope: 'occurrence', edits }; + } +} diff --git a/Source/Screenplay/Compiler/Authoring/QuickFixes.ts b/Source/Screenplay/Compiler/Authoring/QuickFixes.ts index 32adcfecf..d2f76d31b 100644 --- a/Source/Screenplay/Compiler/Authoring/QuickFixes.ts +++ b/Source/Screenplay/Compiler/Authoring/QuickFixes.ts @@ -17,6 +17,7 @@ import { ScreenplaySyntaxWalker } from '../Syntax/ScreenplaySyntaxWalker'; import { pattern } from '../Text/patterns'; import { QuickFixCandidate } from './QuickFixCandidate'; import { prepareTimelineQuickFixes } from './TimelineQuickFixes'; +import { prepareActionSubjectQuickFixes } from './ActionSubjectQuickFixes'; export interface QuickFixEdit { /** Destination document for an application-snapshot repair; absent for a buffer-local edit. */ @@ -44,7 +45,7 @@ export interface QuickFixOptions { } export function isQuickFixDiagnostic(code: unknown): code is string { - return code === DiagnosticCodes.EventFromLaterSlice || code === DiagnosticCodes.DeprecatedStudioTextRulePattern || code === DiagnosticCodes.DuplicateComplianceMarker || code === DiagnosticCodes.LegacyOptionalSuffix || code === DiagnosticCodes.LegacyComplianceMarker || code === DiagnosticCodes.RedundantEventId || code === DiagnosticCodes.PublicTranslationRequiresDirection || code === DiagnosticCodes.LegacyProfileLayout; + return code === DiagnosticCodes.InferredActionSubject || code === DiagnosticCodes.ChangedActionSubject || code === DiagnosticCodes.EventFromLaterSlice || code === DiagnosticCodes.DeprecatedStudioTextRulePattern || code === DiagnosticCodes.DuplicateComplianceMarker || code === DiagnosticCodes.LegacyOptionalSuffix || code === DiagnosticCodes.LegacyComplianceMarker || code === DiagnosticCodes.RedundantEventId || code === DiagnosticCodes.PublicTranslationRequiresDirection || code === DiagnosticCodes.LegacyProfileLayout; } // Diagnostics point at the complete type, not at the suffix. Never derive edits from message text. @@ -63,12 +64,16 @@ export function findQuickFixes(source: string, options: QuickFixOptions = {}): Q export function prepareQuickFixes(source: string, options: Pick = {}): (line?: number | readonly { line: number; diagnosticCode: string }[], diagnosticCode?: string) => QuickFix[] { const local = prepareLocalQuickFixes(source, options); let timeline: ReturnType | undefined; + let subjects: ReturnType | undefined; + const subjectFixes = (line?: number, code?: string) => (subjects ??= prepareActionSubjectQuickFixes(source, options))(line, code); return (line, diagnosticCode) => { const requests = typeof line === 'number' ? [{ line, diagnosticCode }] : line ?? []; const localFixes = local(line, diagnosticCode); const selected = requests.filter(request => request.diagnosticCode === DiagnosticCodes.EventFromLaterSlice || (request.diagnosticCode === undefined && localFixes.length === 0)); const fixes = selected.length === 0 ? [] : [...new Set(selected.map(request => request.line))].flatMap(line => (timeline ??= prepareTimelineQuickFixes(source, options))(line)); - return [...localFixes, ...fixes]; + const subjectRequests = requests.filter(request => request.diagnosticCode === undefined || request.diagnosticCode === DiagnosticCodes.InferredActionSubject || request.diagnosticCode === DiagnosticCodes.ChangedActionSubject); + const actions = requests.length === 0 ? subjectFixes(undefined, diagnosticCode) : subjectRequests.flatMap(request => subjectFixes(request.line, request.diagnosticCode)); + return [...localFixes, ...fixes, ...actions]; }; } diff --git a/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts new file mode 100644 index 000000000..26aaf2bba --- /dev/null +++ b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts @@ -0,0 +1,54 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { describe, expect, it } from 'vitest'; +import { parse } from '../../ScreenplayCompiler'; +import { applyQuickFixEdits, findQuickFixes, isQuickFixDiagnostic } from '../QuickFixes'; + +const source = `concept ItemId : Uuid +module Work + feature Items + slice StateView List + readmodel Row + rowId ItemId key + name String + command Retry + itemId ItemId identifier + query Rows => Row[] + screen List + data Row[] via query Rows + action Retry // preserve this comment +`; + +const fixes = (text: string, code = 'PLAY0817') => findQuickFixes(text, { diagnosticCode: code }); + +describe('when repairing action subjects', () => { + it('should advertise both inference diagnostics', () => { + expect(isQuickFixDiagnostic('PLAY0816')).toBe(true); + expect(isQuickFixDiagnostic('PLAY0817')).toBe(true); + }); + it('should make the inferred item subject explicit without rewriting comments', () => { + const fix = fixes(source, 'PLAY0816'); + expect(fix).toHaveLength(1); + const edited = applyQuickFixEdits(source, fix[0].edits)!; + expect(edited).toContain('action Retry for item // preserve this comment'); + expect(parse(edited).diagnostics.some(diagnostic => ['PLAY0816', 'PLAY0817'].includes(diagnostic.code))).toBe(false); + expect(fixes(edited, 'PLAY0816')).toEqual([]); + }); + it('should suppress legacy intent that the effective key fallback cannot represent', () => { + expect(fixes(source).map(fix => fix.title)).toEqual(["Make inferred 'for item' explicit"]); + }); + it('should offer explicit legacy row inputs when name matching is provable', () => { + const legacy = source.replace('rowId ItemId key', 'itemId ItemId key').replace('itemId ItemId identifier', 'itemId ItemId'); + const proposals = fixes(legacy); + expect(proposals).toHaveLength(2); + const retained = proposals.find(fix => fix.title === 'Retain legacy row behavior explicitly')!; + const edited = applyQuickFixEdits(legacy, retained.edits)!; + expect(edited).toContain('action Retry for item'); + expect(edited).toContain('with itemId from item.itemId'); + expect(fixes(edited)).toEqual([]); + }); + it('should not guess declarations in imported buffer snapshots', () => { + expect(findQuickFixes(source, { documents: new Map([['a.play', source], ['b.play', '']]), path: 'a.play', diagnosticCode: 'PLAY0816' })).toEqual([]); + }); +}); diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json new file mode 100644 index 000000000..d0ad78be3 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json @@ -0,0 +1,2530 @@ +{ + "source": "source.play", + "application": { + "kind": "ApplicationSyntax", + "authentication": null, + "behaviors": [], + "concepts": [ + { + "kind": "ConceptSyntax", + "attributes": [], + "file": null, + "name": "ItemId", + "type": "Uuid", + "validations": [], + "values": [] + }, + { + "kind": "ConceptSyntax", + "attributes": [], + "file": null, + "name": "TenantId", + "type": "Uuid", + "validations": [], + "values": [] + } + ], + "domain": null, + "eventSources": [], + "fileImports": [], + "imports": [], + "layouts": [], + "modules": [ + { + "kind": "ModuleSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "dialogTemplates": [], + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Items", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Foreign", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Optional", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": true, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Generated", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": true, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Primitive", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Uuid" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "TwoIdentifiers", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "List", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NamedRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "AmbiguousRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "One", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "ready", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Bool" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "NamedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "AmbiguousRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "otherId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + } + ], + "reducers": [], + "screens": [ + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "InferredItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": "Retry", + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "ExplicitItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Screen" + } + ], + "file": null, + "name": "ScreenScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "SameName" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Foreign", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "ForeignKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Optional", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "OptionalIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Generated", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "GeneratedIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Primitive", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "PrimitiveIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "TwoIdentifiers", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "MultipleIdentifiers" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "AmbiguousKeys" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "file": null, + "name": "GuardedCollection" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "file": null, + "name": "GuardedRecord" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": null, + "outcome": "Hidden" + } + } + ], + "file": null, + "name": "LegacyGuarded" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + } + ], + "file": null, + "name": "MissingSubject" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "EquallyNear" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenSectionSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "\u0022Details\u0022" + }, + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "retry", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "$context.name", + "query": null, + "rawText": null + }, + "name": "name" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "global", + "parameters": [], + "presentation": [], + "subject": "Screen", + "syntaxKind": "Action", + "target": "Foreign" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "inferred", + "parameters": [], + "presentation": [], + "syntaxKind": "Action", + "target": "Retry" + } + ], + "name": "" + } + ], + "file": null, + "name": "Nested" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "InvalidClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "DuplicateClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "go", + "parameters": [], + "presentation": [], + "syntaxKind": "Navigate", + "target": "InferredItem" + } + ], + "name": "" + } + ], + "file": null, + "name": "InapplicableClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "InvalidInput" + } + ], + "specifications": [], + "templates": [], + "type": "StateView" + } + ], + "templates": [], + "usedBehaviors": [] + } + ], + "fileImports": [], + "forms": [], + "isPlacement": false, + "name": "Work", + "screenTemplates": [], + "templates": [], + "usedBehaviors": [] + } + ], + "personas": [], + "policies": [], + "sampleDataPacks": [], + "seeds": [], + "systems": [], + "templates": [], + "themes": [], + "triggers": [], + "types": [], + "uiProfiles": [] + }, + "locations": [ + { + "path": "$", + "kind": "ApplicationSyntax", + "location": { + "line": 1, + "column": 1 + } + }, + { + "path": "$.concepts[0]", + "kind": "ConceptSyntax", + "location": { + "line": 1, + "column": 1 + } + }, + { + "path": "$.concepts[1]", + "kind": "ConceptSyntax", + "location": { + "line": 2, + "column": 1 + } + }, + { + "path": "$.modules[0]", + "kind": "ModuleSyntax", + "location": { + "line": 3, + "column": 1 + } + }, + { + "path": "$.modules[0].features[0]", + "kind": "FeatureSyntax", + "location": { + "line": 4, + "column": 3 + } + }, + { + "path": "$.modules[0].features[0].slices[0]", + "kind": "SliceSyntax", + "location": { + "line": 5, + "column": 5 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0]", + "kind": "CommandSyntax", + "location": { + "line": 20, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 21, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 21, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 22, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 22, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1]", + "kind": "CommandSyntax", + "location": { + "line": 23, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 24, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 24, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2]", + "kind": "CommandSyntax", + "location": { + "line": 25, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 26, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 26, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3]", + "kind": "CommandSyntax", + "location": { + "line": 27, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 28, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 28, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4]", + "kind": "CommandSyntax", + "location": { + "line": 29, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 30, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 30, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5]", + "kind": "CommandSyntax", + "location": { + "line": 31, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 32, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 32, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 33, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 33, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0]", + "kind": "QuerySyntax", + "location": { + "line": 34, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 34, + "column": 21 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1]", + "kind": "QuerySyntax", + "location": { + "line": 35, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 35, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2]", + "kind": "QuerySyntax", + "location": { + "line": 36, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 36, + "column": 30 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3]", + "kind": "QuerySyntax", + "location": { + "line": 37, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 37, + "column": 20 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0]", + "kind": "ReadModelSyntax", + "location": { + "line": 6, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 7, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 7, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 8, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 8, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2]", + "kind": "PropertySyntax", + "location": { + "line": 9, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2].type", + "kind": "TypeRefSyntax", + "location": { + "line": 9, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3]", + "kind": "PropertySyntax", + "location": { + "line": 10, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3].type", + "kind": "TypeRefSyntax", + "location": { + "line": 10, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4]", + "kind": "PropertySyntax", + "location": { + "line": 11, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4].type", + "kind": "TypeRefSyntax", + "location": { + "line": 11, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1]", + "kind": "ReadModelSyntax", + "location": { + "line": 12, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 13, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 13, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 14, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 14, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2]", + "kind": "PropertySyntax", + "location": { + "line": 15, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2].type", + "kind": "TypeRefSyntax", + "location": { + "line": 15, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2]", + "kind": "ReadModelSyntax", + "location": { + "line": 16, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 17, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 17, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 18, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 18, + "column": 17 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2]", + "kind": "PropertySyntax", + "location": { + "line": 19, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2].type", + "kind": "TypeRefSyntax", + "location": { + "line": 19, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0]", + "kind": "ScreenSyntax", + "location": { + "line": 38, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 39, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 39, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 40, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10]", + "kind": "ScreenSyntax", + "location": { + "line": 70, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 71, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 71, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 72, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 73, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 73, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 73, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].otherwise", + "kind": "ScreenActionOtherwiseSyntax", + "location": { + "line": 74, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11]", + "kind": "ScreenSyntax", + "location": { + "line": 75, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 76, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 76, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 77, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 78, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 78, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 78, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].otherwise", + "kind": "ScreenActionOtherwiseSyntax", + "location": { + "line": 79, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12]", + "kind": "ScreenSyntax", + "location": { + "line": 80, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 81, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 81, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 82, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 83, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[0]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 84, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[1]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 85, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 83, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 83, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].otherwise", + "kind": "ScreenActionOtherwiseSyntax", + "location": { + "line": 86, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13]", + "kind": "ScreenSyntax", + "location": { + "line": 87, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 88, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 89, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 89, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 89, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14]", + "kind": "ScreenSyntax", + "location": { + "line": 90, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 91, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 91, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "kind": "ScreenDataSyntax", + "location": { + "line": 92, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 92, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 93, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 94, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 94, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 94, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[3]", + "kind": "ScreenActionSyntax", + "location": { + "line": 95, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15]", + "kind": "ScreenSyntax", + "location": { + "line": 96, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 97, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 97, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1]", + "kind": "ScreenSectionSyntax", + "location": { + "line": 98, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 99, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1]", + "kind": "ScreenDataSyntax", + "location": { + "line": 100, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 100, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2]", + "kind": "ScreenToolbarSyntax", + "location": { + "line": 101, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 102, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0]", + "kind": "ScreenNavigationParameterSyntax", + "location": { + "line": 103, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0].binding", + "kind": "UiBindingSyntax", + "location": { + "line": 103, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[1]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 104, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[2]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 105, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[16]", + "kind": "ScreenSyntax", + "location": { + "line": 106, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[16].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 107, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[17]", + "kind": "ScreenSyntax", + "location": { + "line": 108, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[17].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 109, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18]", + "kind": "ScreenSyntax", + "location": { + "line": 110, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0]", + "kind": "ScreenToolbarSyntax", + "location": { + "line": 111, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0].items[0]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 112, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19]", + "kind": "ScreenSyntax", + "location": { + "line": 113, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 114, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[0]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 116, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[1]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 117, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1]", + "kind": "ScreenSyntax", + "location": { + "line": 41, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 42, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 42, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 43, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[0]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 44, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[1]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 45, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2]", + "kind": "ScreenSyntax", + "location": { + "line": 46, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 47, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 47, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 48, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3]", + "kind": "ScreenSyntax", + "location": { + "line": 49, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 50, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 50, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 51, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4]", + "kind": "ScreenSyntax", + "location": { + "line": 52, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 53, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 53, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 54, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5]", + "kind": "ScreenSyntax", + "location": { + "line": 55, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 56, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 56, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 57, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6]", + "kind": "ScreenSyntax", + "location": { + "line": 58, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 59, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 59, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 60, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7]", + "kind": "ScreenSyntax", + "location": { + "line": 61, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 62, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 62, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 63, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8]", + "kind": "ScreenSyntax", + "location": { + "line": 64, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 65, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 65, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 66, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9]", + "kind": "ScreenSyntax", + "location": { + "line": 67, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 68, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 68, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 69, + "column": 9 + } + } + ] +} diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json new file mode 100644 index 000000000..640d35bbc --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json @@ -0,0 +1,245 @@ +[ + { + "code": "PLAY0815", + "severity": "error", + "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", + "location": { + "line": 107, + "column": 9 + } + }, + { + "code": "PLAY0815", + "severity": "error", + "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", + "location": { + "line": 109, + "column": 9 + } + }, + { + "code": "PLAY0815", + "severity": "error", + "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", + "location": { + "line": 112, + "column": 11 + } + }, + { + "code": "PLAY0319", + "severity": "error", + "message": "Invalid argument \u0027with itemId\u0027 - expected \u0027with \u003Cname\u003E from \u003Cbinding\u003E\u0027", + "location": { + "line": 115, + "column": 11 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "A guarded action requires exactly one nearest \u0027data\u0027 subject; no data or equally near data bindings leave \u0027item\u0027 unresolved", + "location": { + "line": 88, + "column": 9 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "A guarded action requires exactly one nearest \u0027data\u0027 subject; no data or equally near data bindings leave \u0027item\u0027 unresolved", + "location": { + "line": 93, + "column": 9 + } + }, + { + "code": "PLAY0319", + "severity": "error", + "message": "Duplicate argument \u0027name\u0027 - supply each input only once", + "location": { + "line": 117, + "column": 11 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 40, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", + "location": { + "line": 40, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 51, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Foreign\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 54, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Foreign\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use tenantId from item.tenantId", + "location": { + "line": 54, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Optional\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 57, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Optional\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", + "location": { + "line": 57, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Generated\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 60, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Primitive\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 63, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Primitive\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", + "location": { + "line": 63, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027TwoIdentifiers\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 66, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027TwoIdentifiers\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, tenantId from item.tenantId", + "location": { + "line": 66, + "column": 9 + } + }, + { + "code": "PLAY0818", + "severity": "warning", + "message": "Input \u0027itemId\u0027 of action \u0027Retry\u0027 matches several declared key fields - write an explicit binding", + "location": { + "line": 69, + "column": 9 + } + }, + { + "code": "PLAY0819", + "severity": "warning", + "message": "A guarded action \u0027for screen\u0027 cannot use a collection as \u0027item\u0027 - use a single-record data context or \u0027for item\u0027", + "location": { + "line": 72, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 95, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 99, + "column": 11 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 105, + "column": 11 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", + "location": { + "line": 105, + "column": 11 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 107, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 109, + "column": 9 + } + } +] diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json new file mode 100644 index 000000000..a61186d3f --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json @@ -0,0 +1,1315 @@ +{ + "kind": "ApplicationSyntax", + "authentication": null, + "behaviors": [], + "concepts": [ + { + "kind": "ConceptSyntax", + "attributes": [], + "file": null, + "name": "ItemId", + "type": "Uuid", + "validations": [], + "values": [] + }, + { + "kind": "ConceptSyntax", + "attributes": [], + "file": null, + "name": "TenantId", + "type": "Uuid", + "validations": [], + "values": [] + } + ], + "domain": null, + "eventSources": [], + "fileImports": [], + "imports": [], + "layouts": [], + "modules": [ + { + "kind": "ModuleSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "dialogTemplates": [], + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Items", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Foreign", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Optional", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": true, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Generated", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": true, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Primitive", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Uuid" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "TwoIdentifiers", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "List", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NamedRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "AmbiguousRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "One", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "ready", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Bool" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "NamedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "AmbiguousRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "otherId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + } + ], + "reducers": [], + "screens": [ + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "InferredItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": "Retry", + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "ExplicitItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Screen" + } + ], + "file": null, + "name": "ScreenScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.itemId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "SameName" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Foreign", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "ForeignKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Optional", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "OptionalIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Generated", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "GeneratedIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Primitive", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "PrimitiveIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "TwoIdentifiers", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "tenantId" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "MultipleIdentifiers" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "AmbiguousKeys" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "file": null, + "name": "GuardedCollection" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "file": null, + "name": "GuardedRecord" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": null, + "outcome": "Hidden" + } + } + ], + "file": null, + "name": "LegacyGuarded" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + } + ], + "file": null, + "name": "MissingSubject" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "EquallyNear" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenSectionSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.itemId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "\u0022Details\u0022" + }, + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "retry", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "$context.name", + "query": null, + "rawText": null + }, + "name": "name" + }, + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "item.rowId", + "query": null, + "rawText": null + }, + "name": "itemId" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "global", + "parameters": [], + "presentation": [], + "subject": "Screen", + "syntaxKind": "Action", + "target": "Foreign" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "inferred", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "item.rowId", + "query": null, + "rawText": null + }, + "name": "itemId" + }, + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "item.name", + "query": null, + "rawText": null + }, + "name": "name" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + } + ], + "name": "" + } + ], + "file": null, + "name": "Nested" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "InvalidClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "DuplicateClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "go", + "parameters": [], + "presentation": [], + "syntaxKind": "Navigate", + "target": "InferredItem" + } + ], + "name": "" + } + ], + "file": null, + "name": "InapplicableClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "InvalidInput" + } + ], + "specifications": [], + "templates": [], + "type": "StateView" + } + ], + "templates": [], + "usedBehaviors": [] + } + ], + "fileImports": [], + "forms": [], + "isPlacement": false, + "name": "Work", + "screenTemplates": [], + "templates": [], + "usedBehaviors": [] + } + ], + "personas": [], + "policies": [], + "sampleDataPacks": [], + "seeds": [], + "systems": [], + "templates": [], + "themes": [], + "triggers": [], + "types": [], + "uiProfiles": [] +} diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json new file mode 100644 index 000000000..844837db1 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json @@ -0,0 +1,1181 @@ +{ + "kind": "ApplicationSyntax", + "authentication": null, + "behaviors": [], + "concepts": [ + { + "kind": "ConceptSyntax", + "attributes": [], + "file": null, + "name": "ItemId", + "type": "Uuid", + "validations": [], + "values": [] + }, + { + "kind": "ConceptSyntax", + "attributes": [], + "file": null, + "name": "TenantId", + "type": "Uuid", + "validations": [], + "values": [] + } + ], + "domain": null, + "eventSources": [], + "fileImports": [], + "imports": [], + "layouts": [], + "modules": [ + { + "kind": "ModuleSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "dialogTemplates": [], + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Items", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Foreign", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Optional", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": true, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Generated", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": true, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Primitive", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Uuid" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "TwoIdentifiers", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "List", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NamedRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "AmbiguousRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "One", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "ready", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Bool" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "NamedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "AmbiguousRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "otherId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + } + ], + "reducers": [], + "screens": [ + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "InferredItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": "Retry", + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "ExplicitItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Screen" + } + ], + "file": null, + "name": "ScreenScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "SameName" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Foreign", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "ForeignKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Optional", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "OptionalIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Generated", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "GeneratedIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Primitive", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "PrimitiveIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "TwoIdentifiers", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "MultipleIdentifiers" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "AmbiguousKeys" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "file": null, + "name": "GuardedCollection" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "file": null, + "name": "GuardedRecord" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": null, + "outcome": "Hidden" + } + } + ], + "file": null, + "name": "LegacyGuarded" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + } + ], + "file": null, + "name": "MissingSubject" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "EquallyNear" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenSectionSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "\u0022Details\u0022" + }, + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "retry", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "$context.name", + "query": null, + "rawText": null + }, + "name": "name" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "global", + "parameters": [], + "presentation": [], + "subject": "Screen", + "syntaxKind": "Action", + "target": "Foreign" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "inferred", + "parameters": [], + "presentation": [], + "syntaxKind": "Action", + "target": "Retry" + } + ], + "name": "" + } + ], + "file": null, + "name": "Nested" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "InvalidClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "DuplicateClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "go", + "parameters": [], + "presentation": [], + "syntaxKind": "Navigate", + "target": "InferredItem" + } + ], + "name": "" + } + ], + "file": null, + "name": "InapplicableClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "InvalidInput" + } + ], + "specifications": [], + "templates": [], + "type": "StateView" + } + ], + "templates": [], + "usedBehaviors": [] + } + ], + "fileImports": [], + "forms": [], + "isPlacement": false, + "name": "Work", + "screenTemplates": [], + "templates": [], + "usedBehaviors": [] + } + ], + "personas": [], + "policies": [], + "sampleDataPacks": [], + "seeds": [], + "systems": [], + "templates": [], + "themes": [], + "triggers": [], + "types": [], + "uiProfiles": [] +} diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/source.play b/Source/Screenplay/Compiler/Conformance/action-subjects/source.play new file mode 100644 index 000000000..1d8aded8a --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/source.play @@ -0,0 +1,117 @@ +concept ItemId : Uuid +concept TenantId : Uuid +module Work + feature Items + slice StateView List + readmodel Row + rowId ItemId key + itemId TenantId + tenantId TenantId + name String + ready Bool + readmodel NamedRow + rowId ItemId key + itemId ItemId + name String + readmodel AmbiguousRow + rowId ItemId key + otherId ItemId key + name String + command Retry + itemId ItemId identifier + name String + command Foreign + tenantId TenantId + command Optional + itemId ItemId optional identifier + command Generated + itemId ItemId generated identifier + command Primitive + itemId Uuid identifier + command TwoIdentifiers + itemId ItemId identifier + tenantId TenantId identifier + query Rows => Row[] + query NamedRows => NamedRow[] + query AmbiguousRows => AmbiguousRow[] + query One => Row + screen InferredItem + data Row[] via query Rows + action Retry + screen ExplicitItem + data Row[] via query Rows + action Retry for item label "Retry" + with itemId from item.tenantId + with name from $context.name + screen ScreenScope + data Row[] via query Rows + action Retry for screen + screen SameName + data NamedRow[] via query NamedRows + action Retry + screen ForeignKey + data Row[] via query Rows + action Foreign + screen OptionalIdentifier + data Row[] via query Rows + action Optional + screen GeneratedIdentifier + data Row[] via query Rows + action Generated + screen PrimitiveIdentifier + data Row[] via query Rows + action Primitive + screen MultipleIdentifiers + data Row[] via query Rows + action TwoIdentifiers + screen AmbiguousKeys + data AmbiguousRow[] via query AmbiguousRows + action Retry for item + screen GuardedCollection + data Row[] via query Rows + action "Retry" for screen + when item.ready == true execute Retry + otherwise execute Retry + screen GuardedRecord + data Row via query One + action "Retry" for screen + when item.ready == true execute Retry + otherwise execute Retry + screen LegacyGuarded + data Row via query One + action "Retry" + when item.ready == true execute Retry + with itemId from item.rowId + with name from item.name + otherwise hidden + screen MissingSubject + action "Retry" for item + when item.ready == true execute Retry + screen EquallyNear + data Row[] via query Rows + data NamedRow[] via query NamedRows + action "Retry" for item + when item.ready == true execute Retry + action Retry + screen Nested + data Row[] via query Rows + section "Details" + action Retry + data NamedRow[] via query NamedRows + toolbar + item retry action Retry for item + parameter name from $context.name + item global action Foreign for screen + item inferred action Retry + screen InvalidClause + action Retry for planet + screen DuplicateClause + action Retry for item for screen + screen InapplicableClause + toolbar + item go navigate to InferredItem for item + screen InvalidInput + action Retry for item + with itemId + with name from item.name + with name from $context.name diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json new file mode 100644 index 000000000..f24e48faf --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json @@ -0,0 +1,2463 @@ +{ + "source": "source.play", + "application": { + "kind": "ApplicationSyntax", + "concepts": [ + { + "kind": "ConceptSyntax", + "attributes": [], + "name": "ItemId", + "type": "Uuid", + "values": [] + }, + { + "kind": "ConceptSyntax", + "attributes": [], + "name": "TenantId", + "type": "Uuid", + "values": [] + } + ], + "domain": null, + "eventSources": [], + "fileImports": [], + "imports": [], + "modules": [ + { + "kind": "ModuleSyntax", + "authorize": null, + "description": null, + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Items", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Foreign", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Optional", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": true, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Generated", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": true, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Primitive", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Uuid" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "TwoIdentifiers", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "name": "List", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NamedRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "AmbiguousRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "One", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "ready", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Bool" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "NamedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "AmbiguousRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "otherId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + } + ], + "screens": [ + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "InferredItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": "Retry", + "navigate": null, + "subject": "Item" + } + ], + "name": "ExplicitItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Screen" + } + ], + "name": "ScreenScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "SameName" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Foreign", + "label": null, + "navigate": null + } + ], + "name": "ForeignKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Optional", + "label": null, + "navigate": null + } + ], + "name": "OptionalIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Generated", + "label": null, + "navigate": null + } + ], + "name": "GeneratedIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Primitive", + "label": null, + "navigate": null + } + ], + "name": "PrimitiveIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "TwoIdentifiers", + "label": null, + "navigate": null + } + ], + "name": "MultipleIdentifiers" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "AmbiguousKeys" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "name": "GuardedCollection" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "name": "GuardedRecord" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": null, + "outcome": "Hidden" + } + } + ], + "name": "LegacyGuarded" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + } + ], + "name": "MissingSubject" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "EquallyNear" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenSectionSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "\"Details\"" + }, + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "retry", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "$context.name", + "query": null, + "rawText": null + }, + "name": "name" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "global", + "parameters": [], + "presentation": [], + "subject": "Screen", + "syntaxKind": "Action", + "target": "Foreign" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "inferred", + "parameters": [], + "presentation": [], + "syntaxKind": "Action", + "target": "Retry" + } + ], + "name": "" + } + ], + "name": "Nested" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "InvalidClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "DuplicateClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "go", + "parameters": [], + "presentation": [], + "syntaxKind": "Navigate", + "target": "InferredItem" + } + ], + "name": "" + } + ], + "name": "InapplicableClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "InvalidInput" + } + ], + "specifications": [], + "type": "StateView" + } + ] + } + ], + "fileImports": [], + "isPlacement": false, + "name": "Work" + } + ], + "personas": [], + "systems": [], + "types": [] + }, + "locations": [ + { + "path": "$", + "kind": "ApplicationSyntax", + "location": { + "line": 1, + "column": 1 + } + }, + { + "path": "$.concepts[0]", + "kind": "ConceptSyntax", + "location": { + "line": 1, + "column": 1 + } + }, + { + "path": "$.concepts[1]", + "kind": "ConceptSyntax", + "location": { + "line": 2, + "column": 1 + } + }, + { + "path": "$.modules[0]", + "kind": "ModuleSyntax", + "location": { + "line": 3, + "column": 1 + } + }, + { + "path": "$.modules[0].features[0]", + "kind": "FeatureSyntax", + "location": { + "line": 4, + "column": 3 + } + }, + { + "path": "$.modules[0].features[0].slices[0]", + "kind": "SliceSyntax", + "location": { + "line": 5, + "column": 5 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0]", + "kind": "CommandSyntax", + "location": { + "line": 20, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 21, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 21, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 22, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 22, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1]", + "kind": "CommandSyntax", + "location": { + "line": 23, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 24, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 24, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2]", + "kind": "CommandSyntax", + "location": { + "line": 25, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 26, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 26, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3]", + "kind": "CommandSyntax", + "location": { + "line": 27, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 28, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 28, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4]", + "kind": "CommandSyntax", + "location": { + "line": 29, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 30, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 30, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5]", + "kind": "CommandSyntax", + "location": { + "line": 31, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 32, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 32, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 33, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 33, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0]", + "kind": "QuerySyntax", + "location": { + "line": 34, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 34, + "column": 21 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1]", + "kind": "QuerySyntax", + "location": { + "line": 35, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 35, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2]", + "kind": "QuerySyntax", + "location": { + "line": 36, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 36, + "column": 30 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3]", + "kind": "QuerySyntax", + "location": { + "line": 37, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 37, + "column": 20 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0]", + "kind": "ReadModelSyntax", + "location": { + "line": 6, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 7, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 7, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 8, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 8, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2]", + "kind": "PropertySyntax", + "location": { + "line": 9, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2].type", + "kind": "TypeRefSyntax", + "location": { + "line": 9, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3]", + "kind": "PropertySyntax", + "location": { + "line": 10, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3].type", + "kind": "TypeRefSyntax", + "location": { + "line": 10, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4]", + "kind": "PropertySyntax", + "location": { + "line": 11, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4].type", + "kind": "TypeRefSyntax", + "location": { + "line": 11, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1]", + "kind": "ReadModelSyntax", + "location": { + "line": 12, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 13, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 13, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 14, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 14, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2]", + "kind": "PropertySyntax", + "location": { + "line": 15, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2].type", + "kind": "TypeRefSyntax", + "location": { + "line": 15, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2]", + "kind": "ReadModelSyntax", + "location": { + "line": 16, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 17, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 17, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 18, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 18, + "column": 17 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2]", + "kind": "PropertySyntax", + "location": { + "line": 19, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2].type", + "kind": "TypeRefSyntax", + "location": { + "line": 19, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0]", + "kind": "ScreenSyntax", + "location": { + "line": 38, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 39, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 39, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 40, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10]", + "kind": "ScreenSyntax", + "location": { + "line": 70, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 71, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 71, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 72, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 73, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 73, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 73, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].otherwise", + "kind": "ScreenActionOtherwiseSyntax", + "location": { + "line": 74, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11]", + "kind": "ScreenSyntax", + "location": { + "line": 75, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 76, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 76, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 77, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 78, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 78, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 78, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].otherwise", + "kind": "ScreenActionOtherwiseSyntax", + "location": { + "line": 79, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12]", + "kind": "ScreenSyntax", + "location": { + "line": 80, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 81, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 81, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 82, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 83, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[0]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 84, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[1]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 85, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 83, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 83, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].otherwise", + "kind": "ScreenActionOtherwiseSyntax", + "location": { + "line": 86, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13]", + "kind": "ScreenSyntax", + "location": { + "line": 87, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 88, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 89, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 89, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 89, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14]", + "kind": "ScreenSyntax", + "location": { + "line": 90, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 91, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 91, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "kind": "ScreenDataSyntax", + "location": { + "line": 92, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 92, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2]", + "kind": "ScreenGuardedActionSyntax", + "location": { + "line": 93, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0]", + "kind": "ScreenActionAlternativeSyntax", + "location": { + "line": 94, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition", + "kind": "ComparisonConditionSyntax", + "location": { + "line": 94, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 94, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[3]", + "kind": "ScreenActionSyntax", + "location": { + "line": 95, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15]", + "kind": "ScreenSyntax", + "location": { + "line": 96, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 97, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 97, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1]", + "kind": "ScreenSectionSyntax", + "location": { + "line": 98, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 99, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1]", + "kind": "ScreenDataSyntax", + "location": { + "line": 100, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 100, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2]", + "kind": "ScreenToolbarSyntax", + "location": { + "line": 101, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 102, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0]", + "kind": "ScreenNavigationParameterSyntax", + "location": { + "line": 103, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0].binding", + "kind": "UiBindingSyntax", + "location": { + "line": 103, + "column": 13 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[1]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 104, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[2]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 105, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[16]", + "kind": "ScreenSyntax", + "location": { + "line": 106, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[16].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 107, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[17]", + "kind": "ScreenSyntax", + "location": { + "line": 108, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[17].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 109, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18]", + "kind": "ScreenSyntax", + "location": { + "line": 110, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0]", + "kind": "ScreenToolbarSyntax", + "location": { + "line": 111, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0].items[0]", + "kind": "ToolbarItemSyntax", + "location": { + "line": 112, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19]", + "kind": "ScreenSyntax", + "location": { + "line": 113, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0]", + "kind": "ScreenActionSyntax", + "location": { + "line": 114, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[0]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 116, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[1]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 117, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1]", + "kind": "ScreenSyntax", + "location": { + "line": 41, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 42, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 42, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 43, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[0]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 44, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[1]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 45, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2]", + "kind": "ScreenSyntax", + "location": { + "line": 46, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 47, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 47, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 48, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3]", + "kind": "ScreenSyntax", + "location": { + "line": 49, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 50, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 50, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 51, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4]", + "kind": "ScreenSyntax", + "location": { + "line": 52, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 53, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 53, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 54, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5]", + "kind": "ScreenSyntax", + "location": { + "line": 55, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 56, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 56, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 57, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6]", + "kind": "ScreenSyntax", + "location": { + "line": 58, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 59, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 59, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 60, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7]", + "kind": "ScreenSyntax", + "location": { + "line": 61, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 62, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 62, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 63, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8]", + "kind": "ScreenSyntax", + "location": { + "line": 64, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 65, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 65, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 66, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9]", + "kind": "ScreenSyntax", + "location": { + "line": 67, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 68, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 68, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 69, + "column": 9 + } + } + ] +} diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json new file mode 100644 index 000000000..c997a4e36 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json @@ -0,0 +1,245 @@ +[ + { + "code": "PLAY0815", + "severity": "error", + "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", + "location": { + "line": 107, + "column": 9 + } + }, + { + "code": "PLAY0815", + "severity": "error", + "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", + "location": { + "line": 109, + "column": 9 + } + }, + { + "code": "PLAY0815", + "severity": "error", + "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", + "location": { + "line": 112, + "column": 11 + } + }, + { + "code": "PLAY0319", + "severity": "error", + "message": "Invalid argument 'with itemId' - expected 'with from '", + "location": { + "line": 115, + "column": 11 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "location": { + "line": 40, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", + "location": { + "line": 40, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "location": { + "line": 51, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Foreign' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 54, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Foreign' now infers 'for screen'; legacy row-name matching would use tenantId from item.tenantId", + "location": { + "line": 54, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Optional' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 57, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Optional' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", + "location": { + "line": 57, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Generated' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 60, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Primitive' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 63, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Primitive' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", + "location": { + "line": 63, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'TwoIdentifiers' infers 'for item' from its declared data and identifier types", + "location": { + "line": 66, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'TwoIdentifiers' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, tenantId from item.tenantId", + "location": { + "line": 66, + "column": 9 + } + }, + { + "code": "PLAY0818", + "severity": "warning", + "message": "Input 'itemId' of action 'Retry' matches several declared key fields - write an explicit binding", + "location": { + "line": 69, + "column": 9 + } + }, + { + "code": "PLAY0819", + "severity": "warning", + "message": "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", + "location": { + "line": 72, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 95, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "location": { + "line": 99, + "column": 11 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "location": { + "line": 105, + "column": 11 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", + "location": { + "line": 105, + "column": 11 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 107, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 109, + "column": 9 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved", + "location": { + "line": 88, + "column": 9 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved", + "location": { + "line": 93, + "column": 9 + } + }, + { + "code": "PLAY0319", + "severity": "error", + "message": "Duplicate argument 'name' - supply each input only once", + "location": { + "line": 117, + "column": 11 + } + } +] diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json new file mode 100644 index 000000000..3edcbf406 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json @@ -0,0 +1,1248 @@ +{ + "kind": "ApplicationSyntax", + "concepts": [ + { + "kind": "ConceptSyntax", + "attributes": [], + "name": "ItemId", + "type": "Uuid", + "values": [] + }, + { + "kind": "ConceptSyntax", + "attributes": [], + "name": "TenantId", + "type": "Uuid", + "values": [] + } + ], + "domain": null, + "eventSources": [], + "fileImports": [], + "imports": [], + "modules": [ + { + "kind": "ModuleSyntax", + "authorize": null, + "description": null, + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Items", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Foreign", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Optional", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": true, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Generated", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": true, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Primitive", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Uuid" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "TwoIdentifiers", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "name": "List", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NamedRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "AmbiguousRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "One", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "ready", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Bool" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "NamedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "AmbiguousRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "otherId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + } + ], + "screens": [ + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "InferredItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": "Retry", + "navigate": null, + "subject": "Item" + } + ], + "name": "ExplicitItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Screen" + } + ], + "name": "ScreenScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.itemId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "SameName" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Foreign", + "label": null, + "navigate": null + } + ], + "name": "ForeignKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Optional", + "label": null, + "navigate": null + } + ], + "name": "OptionalIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Generated", + "label": null, + "navigate": null + } + ], + "name": "GeneratedIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Primitive", + "label": null, + "navigate": null + } + ], + "name": "PrimitiveIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "TwoIdentifiers", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "tenantId" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "MultipleIdentifiers" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "AmbiguousKeys" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "name": "GuardedCollection" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "name": "GuardedRecord" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": null, + "outcome": "Hidden" + } + } + ], + "name": "LegacyGuarded" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + } + ], + "name": "MissingSubject" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "EquallyNear" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenSectionSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.itemId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "\"Details\"" + }, + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "retry", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "$context.name", + "query": null, + "rawText": null + }, + "name": "name" + }, + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "item.rowId", + "query": null, + "rawText": null + }, + "name": "itemId" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "global", + "parameters": [], + "presentation": [], + "subject": "Screen", + "syntaxKind": "Action", + "target": "Foreign" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "inferred", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "item.rowId", + "query": null, + "rawText": null + }, + "name": "itemId" + }, + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "item.name", + "query": null, + "rawText": null + }, + "name": "name" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + } + ], + "name": "" + } + ], + "name": "Nested" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "InvalidClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "DuplicateClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "go", + "parameters": [], + "presentation": [], + "syntaxKind": "Navigate", + "target": "InferredItem" + } + ], + "name": "" + } + ], + "name": "InapplicableClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "InvalidInput" + } + ], + "specifications": [], + "type": "StateView" + } + ] + } + ], + "fileImports": [], + "isPlacement": false, + "name": "Work" + } + ], + "personas": [], + "systems": [], + "types": [] +} diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json new file mode 100644 index 000000000..24cdb81b9 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json @@ -0,0 +1,1114 @@ +{ + "kind": "ApplicationSyntax", + "concepts": [ + { + "kind": "ConceptSyntax", + "attributes": [], + "name": "ItemId", + "type": "Uuid", + "values": [] + }, + { + "kind": "ConceptSyntax", + "attributes": [], + "name": "TenantId", + "type": "Uuid", + "values": [] + } + ], + "domain": null, + "eventSources": [], + "fileImports": [], + "imports": [], + "modules": [ + { + "kind": "ModuleSyntax", + "authorize": null, + "description": null, + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Items", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Foreign", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Optional", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": true, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Generated", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": true, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Primitive", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Uuid" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + }, + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "TwoIdentifiers", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "name": "List", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NamedRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "AmbiguousRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "One", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "tenantId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "TenantId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "ready", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Bool" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "NamedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "AmbiguousRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "otherId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "name", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "String" + } + } + ] + } + ], + "screens": [ + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "InferredItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.tenantId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": "Retry", + "navigate": null, + "subject": "Item" + } + ], + "name": "ExplicitItem" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Screen" + } + ], + "name": "ScreenScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "SameName" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Foreign", + "label": null, + "navigate": null + } + ], + "name": "ForeignKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Optional", + "label": null, + "navigate": null + } + ], + "name": "OptionalIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Generated", + "label": null, + "navigate": null + } + ], + "name": "GeneratedIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Primitive", + "label": null, + "navigate": null + } + ], + "name": "PrimitiveIdentifier" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "TwoIdentifiers", + "label": null, + "navigate": null + } + ], + "name": "MultipleIdentifiers" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "AmbiguousKeys" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "name": "GuardedCollection" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": "Retry", + "outcome": "Execute" + }, + "subject": "Screen" + } + ], + "name": "GuardedRecord" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "One", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": { + "kind": "ScreenActionOtherwiseSyntax", + "arguments": [], + "command": null, + "outcome": "Hidden" + } + } + ], + "name": "LegacyGuarded" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + } + ], + "name": "MissingSubject" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + }, + { + "kind": "ScreenGuardedActionSyntax", + "alternatives": [ + { + "kind": "ScreenActionAlternativeSyntax", + "arguments": [], + "command": "Retry", + "condition": { + "kind": "ComparisonConditionSyntax", + "left": "item.ready", + "operator": "Equal", + "right": { + "kind": "LiteralExpressionSyntax", + "value": true + } + } + } + ], + "label": "Retry", + "navigate": null, + "otherwise": null, + "subject": "Item" + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "EquallyNear" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenSectionSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "\"Details\"" + }, + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "retry", + "parameters": [ + { + "kind": "ScreenNavigationParameterSyntax", + "binding": { + "kind": "UiBindingSyntax", + "bindingKind": "DataContext", + "componentId": null, + "componentPropertyPath": null, + "expectedValueType": null, + "literal": null, + "mode": null, + "nullBehavior": null, + "path": "$context.name", + "query": null, + "rawText": null + }, + "name": "name" + } + ], + "presentation": [], + "subject": "Item", + "syntaxKind": "Action", + "target": "Retry" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "global", + "parameters": [], + "presentation": [], + "subject": "Screen", + "syntaxKind": "Action", + "target": "Foreign" + }, + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "inferred", + "parameters": [], + "presentation": [], + "syntaxKind": "Action", + "target": "Retry" + } + ], + "name": "" + } + ], + "name": "Nested" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "InvalidClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "DuplicateClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenToolbarSyntax", + "items": [ + { + "kind": "ToolbarItemSyntax", + "icon": null, + "label": null, + "name": "go", + "parameters": [], + "presentation": [], + "syntaxKind": "Navigate", + "target": "InferredItem" + } + ], + "name": "" + } + ], + "name": "InapplicableClause" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "$context.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "InvalidInput" + } + ], + "specifications": [], + "type": "StateView" + } + ] + } + ], + "fileImports": [], + "isPlacement": false, + "name": "Work" + } + ], + "personas": [], + "systems": [], + "types": [] +} diff --git a/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts b/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts new file mode 100644 index 000000000..68e535195 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts @@ -0,0 +1,58 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { readFileSync, writeFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; +import { parse } from '../../ScreenplayCompiler'; +import { resolveActionSubjects } from '../../ScreenActionSubjects'; +import { toSyntaxJson } from '../../Syntax/SyntaxJson'; + +const directory = fileURLToPath(new URL('../action-subjects/', import.meta.url)); +const compiled = parse(readFileSync(`${directory}source.play`, 'utf8')); +const raw = toSyntaxJson(compiled.value); +const effective = resolveActionSubjects(compiled.value).value; +const relevant = new Set(['PLAY0319', 'PLAY0345', 'PLAY0346', 'PLAY0815', 'PLAY0816', 'PLAY0817', 'PLAY0818', 'PLAY0819']); + +interface LocatedNode { + path: string; + kind: string; + location: { line: number; column: number }; +} + +function locations(value: unknown, path: string): LocatedNode[] { + if (Array.isArray(value)) return value.flatMap((child, index) => locations(child, `${path}[${index}]`)); + if (value === null || typeof value !== 'object') return []; + const node = value as Record; + const location = node.location as LocatedNode['location'] | undefined; + const own = typeof node.kind === 'string' && location !== undefined ? [{ path, kind: node.kind, location: { line: location.line, column: location.column } }] : []; + return [...own, ...Object.entries(node).filter(([name]) => name !== 'location').flatMap(([name, child]) => locations(child, `${path}.${name}`))]; +} + +const exports = { + 'raw.syntax': raw, + 'effective.syntax': toSyntaxJson(effective), + diagnostics: compiled.diagnostics.filter(diagnostic => relevant.has(diagnostic.code)).map(diagnostic => ({ code: diagnostic.code, severity: diagnostic.severity, message: diagnostic.message, location: { line: diagnostic.location.line, column: diagnostic.location.column } })), + context: { source: 'source.play', application: raw, locations: locations(compiled.value, '$').sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0) }, +}; + +const regenerate = process.env.SCREENPLAY_REGENERATE_ACTION_SUBJECT_FIXTURES === '1'; +if (regenerate) { + for (const [name, value] of Object.entries(exports)) writeFileSync(`${directory}typescript.${name}.json`, `${JSON.stringify(value, null, 2)}\n`); +} + +describe('when exporting action subject fixture packs', () => { + it('should preserve authored syntax', () => expect(toSyntaxJson(compiled.value)).toEqual(raw)); + it('should be idempotent', () => expect(toSyntaxJson(resolveActionSubjects(effective).value)).toEqual(toSyntaxJson(effective))); + for (const [name, value] of Object.entries(exports)) { + it(`should retain the typescript ${name} fixture`, () => { + expect(regenerate, 'Fixture pack regenerated; review and rerun without SCREENPLAY_REGENERATE_ACTION_SUBJECT_FIXTURES').toBe(false); + expect(value).toEqual(JSON.parse(readFileSync(`${directory}typescript.${name}.json`, 'utf8'))); + }); + } + it('should agree with native diagnostics', () => { + const native = JSON.parse(readFileSync(`${directory}native.diagnostics.json`, 'utf8')) as typeof exports.diagnostics; + const order = (value: typeof exports.diagnostics) => [...value].sort((left, right) => left.location.line - right.location.line || left.code.localeCompare(right.code)); + expect(order(exports.diagnostics)).toEqual(order(native)); + }); +}); diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts index 7ca62eb67..bb62ad27e 100644 --- a/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts @@ -9,15 +9,21 @@ import { InteractionArgumentSyntax, ScreenActionSubjectKind, ScreenDataSyntax } import { SliceSyntax } from '../Syntax/Structure'; import { RefusalDeclarations } from './RefusalDeclarations'; +export interface ActionSubjectContext { + readonly data: readonly ScreenDataSyntax[]; + readonly slice: SliceSyntax; + readonly location: SourceLocation; +} + export class ActionSubjectInputs { constructor(readonly declarations: RefusalDeclarations, readonly diagnostics: Diagnostic[]) {} - properties(subjects: readonly ScreenDataSyntax[], slice: SliceSyntax): readonly PropertySyntax[] { - return subjects.length === 1 ? this.declarations.resolve(subjects[0].type.name, slice, entry => entry.readModels)?.node.properties ?? [] : []; + properties(context: ActionSubjectContext): readonly PropertySyntax[] { + return context.data.length === 1 ? this.declarations.resolve(context.data[0].type.name, context.slice, entry => entry.readModels)?.node.properties ?? [] : []; } - command(name: string, slice: SliceSyntax): readonly PropertySyntax[] { - return this.declarations.resolve(name, slice, entry => entry.commands)?.node.properties ?? []; + command(name: string, context: ActionSubjectContext): readonly PropertySyntax[] { + return this.declarations.resolve(name, context.slice, entry => entry.commands)?.node.properties ?? []; } sameConcept(input: PropertySyntax, key: PropertySyntax): boolean { @@ -28,36 +34,61 @@ export class ActionSubjectInputs { return input.isIdentifier && !input.isGenerated && !input.type.isOptional && !input.type.isCollection; } - subject(authored: ScreenActionSubjectKind | null | undefined, command: string, subjects: readonly ScreenDataSyntax[], slice: SliceSyntax, location: SourceLocation): ScreenActionSubjectKind { + keys(input: PropertySyntax, properties: readonly PropertySyntax[]): readonly PropertySyntax[] { + return this.eligible(input) ? properties.filter(property => property.isKey && this.sameConcept(input, property)) : []; + } + + binding(input: PropertySyntax, properties: readonly PropertySyntax[]): PropertySyntax | null { + const named = properties.filter(property => property.name === input.name && this.declarations.compatible(property.type, input.type) === true); + if (named.length === 1) return named[0]; + const keys = this.keys(input, properties); + return keys.length === 1 ? keys[0] : null; + } + + subject(authored: ScreenActionSubjectKind | null | undefined, command: string, bound: readonly string[], context: ActionSubjectContext): ScreenActionSubjectKind | null { if (authored != null) return authored; - const inputs = this.command(command, slice); - const properties = this.properties(subjects, slice); - const keys = properties.filter(property => property.isKey); - const eligible = inputs.filter(input => this.eligible(input) && keys.some(key => this.sameConcept(input, key))); - const inferred = subjects.length === 1 && subjects[0].type.isCollection && eligible.length === 1 && keys.filter(key => this.sameConcept(eligible[0], key)).length === 1 ? 'Item' : 'Screen'; - this.diagnostics.push({ severity: 'information', code: DiagnosticCodes.InferredActionSubject, message: `Action '${command}' infers 'for ${inferred.toLowerCase()}' from its declared data and identifier types`, location }); - if (subjects.length === 1 && subjects[0].type.isCollection) { - const legacy = inputs.flatMap(input => properties.filter(property => input.name.toLowerCase() === property.name.toLowerCase()).map(property => `${input.name} from item.${property.name}`)); - if ((legacy.length > 0) !== (inferred === 'Item')) this.diagnostics.push({ severity: 'warning', code: DiagnosticCodes.ChangedActionSubject, message: `Action '${command}' now infers 'for ${inferred.toLowerCase()}'; legacy row-name matching would use ${legacy.length === 0 ? 'no row property' : legacy.join(', ')}`, location }); + const identifiers = this.command(command, context).filter(input => this.eligible(input)); + const keys = identifiers.length === 1 ? this.keys(identifiers[0], this.properties(context)) : []; + const item = context.data.length === 1 && context.data[0].type.isCollection && keys.length === 1; + this.diagnostics.push({ severity: 'information', code: DiagnosticCodes.InferredActionSubject, message: `Action '${command}' infers 'for ${item ? 'item' : 'screen'}' from its declared data and identifier types`, location: context.location }); + this.migration(command, bound, context, item); + return item ? 'Item' : null; + } + + migration(command: string, bound: readonly string[], context: ActionSubjectContext, item: boolean): void { + if (context.data.length !== 1 || !context.data[0].type.isCollection) return; + const properties = this.properties(context); + const inputs = this.command(command, context).filter(input => !input.isGenerated && !bound.includes(input.name)); + const legacy = inputs.flatMap(input => properties.filter(property => input.name.toLowerCase() === property.name.toLowerCase()).map(property => `${input.name} from item.${property.name}`)); + const current = item ? inputs.flatMap(input => { + const property = this.binding(input, properties); + return property === null ? [] : [`${input.name} from item.${property.name}`]; + }) : []; + if (JSON.stringify(legacy) !== JSON.stringify(current)) this.diagnostics.push({ severity: 'warning', code: DiagnosticCodes.ChangedActionSubject, message: `Action '${command}' now infers 'for ${item ? 'item' : 'screen'}'; legacy row-name matching would use ${legacy.length === 0 ? 'no row property' : legacy.join(', ')}`, location: context.location }); + } + + legacyInputs(command: string, authored: readonly InteractionArgumentSyntax[], context: ActionSubjectContext): readonly InteractionArgumentSyntax[] | null { + if (context.data.length !== 1 || !context.data[0].type.isCollection) return null; + const result = [...authored]; + const properties = this.properties(context); + for (const input of this.command(command, context).filter(input => !input.isGenerated)) { + if (result.some(argument => argument.name === input.name)) continue; + const matches = properties.filter(property => property.name.toLowerCase() === input.name.toLowerCase()); + if (matches.length > 1 || (matches.length === 0 && this.keys(input, properties).length > 0)) return null; + if (matches.length === 1) result.push({ kind: 'InteractionArgumentSyntax', name: input.name, binding: `item.${matches[0].name}`, location: context.location }); } - return inferred; + return result; } - inputs(command: string, authored: readonly InteractionArgumentSyntax[], subjects: readonly ScreenDataSyntax[], slice: SliceSyntax, location: SourceLocation): readonly InteractionArgumentSyntax[] { + inputs(command: string, authored: readonly InteractionArgumentSyntax[], context: ActionSubjectContext): readonly InteractionArgumentSyntax[] { const result = [...authored]; - if (subjects.length !== 1) return result; - const properties = this.properties(subjects, slice); - for (const input of this.command(command, slice).filter(input => !input.isGenerated)) { + if (context.data.length !== 1) return result; + const properties = this.properties(context); + for (const input of this.command(command, context).filter(input => !input.isGenerated)) { if (result.some(argument => argument.name === input.name)) continue; - const named = properties.filter(property => property.name === input.name); - if (named.length === 1) { - result.push({ kind: 'InteractionArgumentSyntax', name: input.name, binding: `item.${named[0].name}`, location }); - continue; - } - if (!this.eligible(input)) continue; - const keys = properties.filter(property => property.isKey && this.sameConcept(input, property)); - if (keys.length === 1) result.push({ kind: 'InteractionArgumentSyntax', name: input.name, binding: `item.${keys[0].name}`, location }); - else if (keys.length > 1) this.diagnostics.push({ severity: 'warning', code: DiagnosticCodes.AmbiguousActionInputBinding, message: `Input '${input.name}' of action '${command}' matches several declared key fields - write an explicit binding`, location }); + const property = this.binding(input, properties); + if (property !== null) result.push({ kind: 'InteractionArgumentSyntax', name: input.name, binding: `item.${property.name}`, location: context.location }); + else if (this.keys(input, properties).length > 1) this.diagnostics.push({ severity: 'warning', code: DiagnosticCodes.AmbiguousActionInputBinding, message: `Input '${input.name}' of action '${command}' matches several declared key fields - write an explicit binding`, location: context.location }); } return result; } diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts new file mode 100644 index 000000000..b52a5a55f --- /dev/null +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts @@ -0,0 +1,79 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { Diagnostic } from '../Diagnostics/Diagnostic'; +import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; +import type { CompilationResult } from '../ScreenplayCompiler'; +import { ApplicationSyntax, FeatureSyntax, SliceSyntax } from '../Syntax/Structure'; +import { ScreenActionSyntax, ScreenDirectiveSyntax, ScreenGuardedActionSyntax, ScreenSyntax, ToolbarItemSyntax } from '../Syntax/Screens'; +import { RefusalDeclarations } from './RefusalDeclarations'; +import { ActionSubjectContext, ActionSubjectInputs } from './ActionSubjectInputs'; + +export interface ActionSubjectEvidence { + readonly authored: ScreenActionSyntax | ToolbarItemSyntax; + readonly effective: ScreenActionSyntax | ToolbarItemSyntax; + readonly command: string; + readonly context: ActionSubjectContext; +} + +export function resolveActionSubjectApplication(application: ApplicationSyntax, observe?: (evidence: ActionSubjectEvidence) => void): CompilationResult { + const diagnostics: Diagnostic[] = []; + const resolver = new ActionSubjectInputs(new RefusalDeclarations(application), diagnostics); + const hasSubject = (context: ActionSubjectContext, guarded: boolean): boolean => { + if (context.data.length === 1) return true; + const message = guarded ? "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved" : "Action 'for item' requires one resolvable data subject - no item binding is inferred"; + diagnostics.push({ severity: 'warning', code: DiagnosticCodes.UnresolvedActionSubject, message, location: context.location }); + return false; + }; + const toolbar = (item: ToolbarItemSyntax, context: ActionSubjectContext): ToolbarItemSyntax => { + if (item.syntaxKind !== 'Action') return item; + const subject = resolver.subject(item.subject, item.target, item.parameters.map(parameter => parameter.name), context); + const authored = item.parameters.map(parameter => ({ kind: 'InteractionArgumentSyntax' as const, name: parameter.name, binding: parameter.binding.path, location: parameter.location })); + const additions = subject === 'Item' && hasSubject(context, false) ? resolver.inputs(item.target, authored, context).slice(authored.length) : []; + const parameters = [...item.parameters, ...additions.map(input => ({ kind: 'ScreenNavigationParameterSyntax' as const, name: input.name, binding: { kind: 'UiBindingSyntax' as const, bindingKind: 'DataContext' as const, path: input.binding, query: null, componentId: null, componentPropertyPath: null, mode: null, nullBehavior: null, expectedValueType: null, literal: null, rawText: null, location: input.location }, location: input.location }))]; + const effective = subject == null && additions.length === 0 ? item : { ...item, subject, parameters }; + observe?.({ authored: item, effective, command: item.target, context }); + return effective; + }; + const guarded = (action: ScreenGuardedActionSyntax, context: ActionSubjectContext): ScreenGuardedActionSyntax => { + if (!hasSubject(context, true)) return action; + if (action.subject === 'Screen' && context.data[0].type.isCollection) { + diagnostics.push({ severity: 'warning', code: DiagnosticCodes.UnsupportedActionSubjectContext, message: "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", location: action.location }); + return action; + } + const fallback = action.otherwise; + return { ...action, + alternatives: action.alternatives.map(alternative => ({ ...alternative, arguments: resolver.inputs(alternative.command, alternative.arguments, { ...context, location: alternative.location }) })), + otherwise: fallback !== null && fallback.command !== null ? { ...fallback, arguments: resolver.inputs(fallback.command, fallback.arguments, { ...context, location: fallback.location }) } : fallback, + }; + }; + const body = (directives: readonly ScreenDirectiveSyntax[], inherited: ActionSubjectContext): readonly ScreenDirectiveSyntax[] => { + const local = directives.filter((node): node is Extract => node.kind === 'ScreenDataSyntax'); + const scope = { ...inherited, data: local.length > 0 ? local : inherited.data }; + return directives.map(node => { + const context = { ...scope, location: node.location }; + switch (node.kind) { + case 'ScreenActionSyntax': { + const subject = resolver.subject(node.subject, node.command, (node.inputs ?? []).map(input => input.name), context); + const inputs = subject === 'Item' && hasSubject(context, false) ? resolver.inputs(node.command, node.inputs ?? [], context) : node.inputs; + const effective = subject == null && inputs === node.inputs ? node : { ...node, subject, inputs }; + observe?.({ authored: node, effective, command: node.command, context }); + return effective; + } + case 'ScreenGuardedActionSyntax': return guarded(node, context); + case 'ScreenToolbarSyntax': return { ...node, items: node.items.map(item => toolbar(item, { ...context, location: item.location })) }; + case 'ScreenSectionSyntax': return { ...node, directives: body(node.directives, scope) }; + case 'ScreenTemplateReferenceSyntax': return { ...node, slots: node.slots.map(slot => ({ ...slot, directives: body(slot.directives, scope) })) }; + case 'ScreenComponentSyntax': return { ...node, outlets: node.outlets.map(outlet => ({ ...outlet, directives: body(outlet.directives, scope) })) }; + default: return node; + } + }); + }; + const screen = (node: ScreenSyntax, slice: SliceSyntax): ScreenSyntax => { + const context = { data: [], slice, location: node.location }; + return { ...node, directives: body(node.directives, context), contributions: node.contributions?.map(contribution => ({ ...contribution, directives: body(contribution.directives, context) })) }; + }; + const feature = (node: FeatureSyntax): FeatureSyntax => ({ ...node, features: node.features.map(feature), slices: node.slices.map(slice => ({ ...slice, screens: slice.screens.map(node => screen(node, slice)) })) }); + const value = { ...application, modules: application.modules.map(module => ({ ...module, features: module.features.map(feature) })) }; + return { value, diagnostics, success: !diagnostics.some(diagnostic => diagnostic.severity === 'error') }; +} diff --git a/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts b/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts index 0c2bf7121..298bb0c52 100644 --- a/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts +++ b/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts @@ -18,7 +18,10 @@ export function viewProperties(name: string, slice: SliceSyntax | undefined, dec export function validateArguments(commandName: string, arguments_: readonly InteractionArgumentSyntax[], properties: readonly PropertySyntax[] | null, slice: SliceSyntax | undefined, declarations: RefusalDeclarations, context: ParserContext): void { const command = declarations.resolve(commandName, slice, candidate => candidate.commands)?.node; + const names = new Set(); for (const argument of arguments_) { + if (names.has(argument.name)) context.error(DiagnosticCodes.InvalidInteractionArgument, `Duplicate argument '${argument.name}' - supply each input only once`, argument.location); + names.add(argument.name); const inputs = command?.properties.filter(property => property.name === argument.name); if (inputs?.length === 0) context.warning(DiagnosticCodes.UnknownActionArgumentProperty, `Command '${commandName}' has no argument property '${argument.name}'`, argument.location); const subjectProperty = validateItemPath(argument.binding, argument.location, properties, slice, declarations, context, true); diff --git a/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts b/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts index 72749ee69..0ac465e92 100644 --- a/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts +++ b/Source/Screenplay/Compiler/Parsing/GuardedActionValidator.ts @@ -1,7 +1,6 @@ // Copyright (c) Cratis. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; import { resolveActionSubjects } from '../ScreenActionSubjects'; import { ScreenDataSyntax, ScreenDirectiveSyntax, ScreenGuardedActionSyntax, ScreenTableSyntax } from '../Syntax/Screens'; import { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure'; @@ -66,9 +65,6 @@ function validateContainer(directives: readonly ScreenDirectiveSyntax[], inherit function validateAction(action: ScreenGuardedActionSyntax, subjects: readonly ScreenDataSyntax[], slice: SliceSyntax, declarations: RefusalDeclarations, context: ParserContext): void { const properties = subjects.length === 1 ? viewProperties(subjects[0].type.name, slice, declarations) : null; - if (subjects.length !== 1) { - context.warning(DiagnosticCodes.UnresolvedActionSubject, "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved", action.location); - } for (const alternative of action.alternatives) { for (const comparison of comparisons(alternative.condition)) validateItemPath(comparison.left, comparison.location, properties, slice, declarations, context); validateArguments(alternative.command, alternative.arguments, properties, slice, declarations, context); diff --git a/Source/Screenplay/Compiler/ScreenActionSubjects.ts b/Source/Screenplay/Compiler/ScreenActionSubjects.ts index 67cd91d07..c646b2c25 100644 --- a/Source/Screenplay/Compiler/ScreenActionSubjects.ts +++ b/Source/Screenplay/Compiler/ScreenActionSubjects.ts @@ -1,60 +1,11 @@ // Copyright (c) Cratis. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -import { Diagnostic } from './Diagnostics/Diagnostic'; -import { DiagnosticCodes } from './Diagnostics/DiagnosticCodes'; -import { ActionSubjectInputs } from './Parsing/ActionSubjectInputs'; -import { RefusalDeclarations } from './Parsing/RefusalDeclarations'; import type { CompilationResult } from './ScreenplayCompiler'; -import { ScreenDataSyntax, ScreenDirectiveSyntax, ScreenGuardedActionSyntax, ToolbarItemSyntax } from './Syntax/Screens'; -import { ApplicationSyntax, FeatureSyntax, SliceSyntax } from './Syntax/Structure'; +import { resolveActionSubjectApplication } from './Parsing/ActionSubjectResolution'; +import { ApplicationSyntax } from './Syntax/Structure'; -/** Resolves effective action subjects and inputs without modifying authored syntax. */ +/** Resolves an immutable authored tree into its effective action-subject semantics without changing the authored syntax. */ export function resolveActionSubjects(application: ApplicationSyntax): CompilationResult { - const diagnostics: Diagnostic[] = []; - const resolver = new ActionSubjectInputs(new RefusalDeclarations(application), diagnostics); - - function toolbar(item: ToolbarItemSyntax, subjects: readonly ScreenDataSyntax[], slice: SliceSyntax): ToolbarItemSyntax { - if (item.syntaxKind !== 'Action') return item; - const subject = resolver.subject(item.subject, item.target, subjects, slice, item.location); - if (subject !== 'Item') return { ...item, subject }; - const authored = item.parameters.map(parameter => ({ kind: 'InteractionArgumentSyntax' as const, name: parameter.name, binding: '', location: parameter.location })); - const inferred = resolver.inputs(item.target, authored, subjects, slice, item.location).slice(authored.length); - return { ...item, subject, parameters: [...item.parameters, ...inferred.map(input => ({ kind: 'ScreenNavigationParameterSyntax' as const, name: input.name, binding: { kind: 'UiBindingSyntax' as const, bindingKind: 'DataContext' as const, path: input.binding, query: null, componentId: null, componentPropertyPath: null, mode: null, nullBehavior: null, expectedValueType: null, literal: null, rawText: null, location: input.location }, location: input.location }))] }; - } - - function guarded(action: ScreenGuardedActionSyntax, subjects: readonly ScreenDataSyntax[], slice: SliceSyntax): ScreenGuardedActionSyntax { - if (action.subject === 'Screen' && subjects.length === 1 && subjects[0].type.isCollection) { - diagnostics.push({ severity: 'warning', code: DiagnosticCodes.UnsupportedActionSubjectContext, message: "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", location: action.location }); - return action; - } - return { ...action, subject: action.subject ?? 'Item', alternatives: action.alternatives.map(alternative => ({ ...alternative, arguments: resolver.inputs(alternative.command, alternative.arguments, subjects, slice, alternative.location) })), otherwise: action.otherwise?.command != null ? { ...action.otherwise, arguments: resolver.inputs(action.otherwise.command, action.otherwise.arguments, subjects, slice, action.otherwise.location) } : action.otherwise }; - } - - function container(nodes: readonly ScreenDirectiveSyntax[], inherited: readonly ScreenDataSyntax[], slice: SliceSyntax): readonly ScreenDirectiveSyntax[] { - const local = nodes.filter((node): node is ScreenDataSyntax => node.kind === 'ScreenDataSyntax'); - const subjects = local.length === 0 ? inherited : local; - return nodes.map(node => { - switch (node.kind) { - case 'ScreenActionSyntax': { - const subject = resolver.subject(node.subject, node.command, subjects, slice, node.location); - const inputs = subject === 'Item' ? resolver.inputs(node.command, node.inputs ?? [], subjects, slice, node.location) : node.inputs; - return { ...node, subject, ...(inputs === undefined ? {} : { inputs }) }; - } - case 'ScreenGuardedActionSyntax': return guarded(node, subjects, slice); - case 'ScreenToolbarSyntax': return { ...node, items: node.items.map(item => toolbar(item, subjects, slice)) }; - case 'ScreenSectionSyntax': return { ...node, directives: container(node.directives, subjects, slice) }; - case 'ScreenTemplateReferenceSyntax': return { ...node, slots: node.slots.map(slot => ({ ...slot, directives: container(slot.directives, subjects, slice) })) }; - case 'ScreenComponentSyntax': return { ...node, outlets: node.outlets.map(outlet => ({ ...outlet, directives: container(outlet.directives, subjects, slice) })) }; - default: return node; - } - }); - } - - function feature(node: FeatureSyntax): FeatureSyntax { - return { ...node, features: node.features.map(feature), slices: node.slices.map(slice => ({ ...slice, screens: slice.screens.map(screen => ({ ...screen, directives: container(screen.directives, [], slice), ...(screen.contributions === undefined ? {} : { contributions: screen.contributions.map(contribution => ({ ...contribution, directives: container(contribution.directives, [], slice) })) }) })) })) }; - } - - const value = { ...application, modules: application.modules.map(module => ({ ...module, features: module.features.map(feature) })) }; - return { value, diagnostics, success: !diagnostics.some(diagnostic => diagnostic.severity === 'error') }; + return resolveActionSubjectApplication(application); } diff --git a/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts index 8c6cc3a97..a82d2bbf9 100644 --- a/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts +++ b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts @@ -25,7 +25,7 @@ describe('when resolving action subjects', () => { }); } it('should keep same-name precedence before key fallback', () => { - action(resolveActionSubjects(parse(source).value).value).inputs![0].binding.should.equal('item.itemId'); + action(resolveActionSubjects(parse(source.replace('itemId TenantId', 'itemId ItemId')).value).value).inputs![0].binding.should.equal('item.itemId'); }); it('should bind a renamed key by nominal concept', () => { const resolved = resolveActionSubjects(parse(source.replace(' itemId TenantId\n', '')).value); @@ -38,12 +38,12 @@ describe('when resolving action subjects', () => { }); for (const replacement of ['ItemId optional identifier', 'ItemId generated identifier', 'TenantId identifier']) { it(`should not infer an item from ${replacement}`, () => { - action(resolveActionSubjects(parse(source.replace('ItemId identifier', replacement)).value).value).subject!.should.equal('Screen'); + (action(resolveActionSubjects(parse(source.replace('ItemId identifier', replacement)).value).value).subject ?? 'Screen').should.equal('Screen'); }); } it('should not use primitive equality as nominal proof', () => { const primitive = source.replace('rowId ItemId key', 'rowId Uuid key').replace('itemId ItemId identifier', 'itemId Uuid identifier'); - action(resolveActionSubjects(parse(primitive).value).value).subject!.should.equal('Screen'); + (action(resolveActionSubjects(parse(primitive).value).value).subject ?? 'Screen').should.equal('Screen'); }); it('should leave ambiguous key input unresolved', () => { const ambiguous = source.replace(' itemId TenantId\n', ' otherId ItemId key\n') + ' for item'; diff --git a/Source/Screenplay/Monaco/screenplay-language/action-subject-authoring.ts b/Source/Screenplay/Monaco/screenplay-language/action-subject-authoring.ts new file mode 100644 index 000000000..8edcd9752 --- /dev/null +++ b/Source/Screenplay/Monaco/screenplay-language/action-subject-authoring.ts @@ -0,0 +1,12 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +export function actionSubjectHover(line: string, word: string, column: number): string | null { + const match = /^\s*(?:action\s+(?:"(?:[^"\\]|\\.)*"|\$strings\.[\w.]+|[\w.]+)|item\s+\w+\s+action\s+[\w.]+)\s+(for)\s+(item|screen)\b/.exec(line); + if (match === null || !['for', match[2]].includes(word)) return null; + const start = match[0].lastIndexOf('for'); + if (column - 1 < start || column - 1 >= match[0].length) return null; + return match[2] === 'item' + ? '`for item` uses one nearest data record or selected collection item. Explicit inputs win, followed by compatible same-name fields and one declared nominal identifier/key match. Missing or equally near data is not guessed.' + : '`for screen` scopes a plain or toolbar action to the screen, without row input filling. A guarded action can inspect a single record, but collection-valued data warns and does not choose a row.'; +} diff --git a/Source/Screenplay/Monaco/screenplay-language/completion-items.ts b/Source/Screenplay/Monaco/screenplay-language/completion-items.ts index faa3d9697..3fd3c05f5 100644 --- a/Source/Screenplay/Monaco/screenplay-language/completion-items.ts +++ b/Source/Screenplay/Monaco/screenplay-language/completion-items.ts @@ -367,8 +367,8 @@ export const validateItems: CompletionEntry[] = [ export const screenItems: CompletionEntry[] = [ { label: 'description', insertText: 'description "${1:screen intent}"', documentation: 'Report-only description, not a localizable screen title.' }, { label: 'data', insertText: 'data ${1:ReadModel} via query ${2:QueryName}', documentation: 'Binds a read model to the screen through a query.' }, - { label: 'action', insertText: 'action ${1:CommandName}', documentation: 'Makes a command available as an action on the screen.' }, - { label: 'action "…"', insertText: 'action "${1:Label}"\n when item.${2:status} == "${3:open}" execute ${4:CommandName}\n otherwise hidden', documentation: 'One labeled button selecting the first matching command; hidden without a subject or match.' }, + { label: 'action', insertText: 'action ${1:CommandName} for ${2|item,screen|}', documentation: 'Makes a command available for the selected item or for the screen as a whole.' }, + { label: 'action "…"', insertText: 'action "${1:Label}" for item\n when item.${2:status} == "${3:open}" execute ${4:CommandName}\n otherwise hidden', documentation: 'One labeled button selecting the first matching command; hidden without a subject or match.' }, { label: 'layout', insertText: 'layout ${1:LayoutName}', documentation: 'Uses a layout template and fills its slots.' }, { label: 'section', insertText: 'section ${1:name}', documentation: 'A named structural section of the screen.' }, { label: 'table', insertText: 'table ${1:name}\n column ${2:property} label "${3:text}"', documentation: 'A table widget over a read model or collection.' }, @@ -380,7 +380,15 @@ export const screenItems: CompletionEntry[] = [ { label: 'html', insertText: fenced('html'), documentation: 'Inline static HTML.' }, ]; +export const actionSubjectItems: CompletionEntry[] = [ + { label: 'for item', insertText: 'for item', documentation: 'Requires one nearest data subject (a record or selected collection item). Binds compatible same-name inputs, then a unique nominal identifier/key match.' }, + { label: 'for screen', insertText: 'for screen', documentation: 'The action is screen-scoped; plain and toolbar actions do not fill inputs from selected rows.' }, +]; + +export const actionSubjectValueItems: CompletionEntry[] = actionSubjectItems.map(item => ({ ...item, label: item.label.slice(4), insertText: item.insertText.slice(4) })); + export const actionItems: CompletionEntry[] = [ + { label: 'with … from', insertText: 'with ${1:property} from item.${2:property}', documentation: 'Explicit input binding, before compatible same-name and declared identifier/key bindings.' }, { label: 'navigate to', insertText: 'navigate to ${1:ScreenName}', documentation: 'Navigates to a screen after the action completes.' }, { label: 'label', insertText: 'label "${1:text}"', documentation: 'The display label of the action.' }, ]; @@ -389,7 +397,7 @@ export const guardedActionItems: CompletionEntry[] = [ { label: 'when … execute', insertText: 'when item.${1:status} == "${2:open}" execute ${3:CommandName}', documentation: 'First matching alternative selects the command; authorization never falls through.' }, { label: 'otherwise hidden', insertText: 'otherwise hidden', documentation: 'Hides the action when no alternative matches; also the default.' }, { label: 'otherwise execute', insertText: 'otherwise execute ${1:CommandName}', documentation: 'Selects a fallback command when no alternative matches and a subject exists.' }, - ...actionItems.filter(item => item.label !== 'label'), + ...actionItems.filter(item => item.label !== 'label' && item.label !== 'with … from'), ]; export const interactionActionItems: CompletionEntry[] = [ @@ -408,7 +416,7 @@ export const interactionChoiceItems: CompletionEntry[] = [ ]; export const actionArgumentItems: CompletionEntry[] = [ - { label: 'with … from', insertText: 'with ${1:property} from item.${2:property}', documentation: 'Explicit input binding for this command alternative, before same-name item fields or its form.' }, + { label: 'with … from', insertText: 'with ${1:property} from item.${2:property}', documentation: 'Explicit input binding for this command alternative, before compatible same-name fields, a unique nominal identifier/key match, or its form.' }, ]; export const tableItems: CompletionEntry[] = [ diff --git a/Source/Screenplay/Monaco/screenplay-language/completion-planner.ts b/Source/Screenplay/Monaco/screenplay-language/completion-planner.ts index c4a1b26d9..a5e62a895 100644 --- a/Source/Screenplay/Monaco/screenplay-language/completion-planner.ts +++ b/Source/Screenplay/Monaco/screenplay-language/completion-planner.ts @@ -251,6 +251,12 @@ export function planCompletions( textBefore.trim().length === 0 ? textBefore.length : indentOf(currentLine); const chain = enclosingChain(lines, fences, lineIndex, effectiveIndent); if (chain.includes('screen')) { + const subjectHeader = /^\s*(?:action\s+(?:"(?:[^"\\]|\\.)*"|\$strings\.[\w.]+|[\w.]+)|item\s+\w+\s+action\s+[\w.]+)\s+/; + if (subjectHeader.test(textBefore)) { + const suffix = textBefore.replace(subjectHeader, ''); + if (/^for\s+\w*$/.test(suffix)) return { kind: 'entries', entries: items.actionSubjectValueItems }; + if (/^(?:f|fo|for)?$/.test(suffix)) return { kind: 'entries', entries: items.actionSubjectItems }; + } let parentIndent = effectiveIndent; let guarded = false; for (let index = lineIndex - 1; index >= 0; index--) { diff --git a/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts b/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts index 1060b7de9..8623fded2 100644 --- a/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts +++ b/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts @@ -168,6 +168,11 @@ export const diagnosticCodes = { unsupportedActionConditionOperand: 'PLAY0344', unknownActionSubjectField: 'PLAY0345', unresolvedActionSubject: 'PLAY0346', + invalidActionSubjectClause: 'PLAY0815', + inferredActionSubject: 'PLAY0816', + changedActionSubject: 'PLAY0817', + ambiguousActionInputBinding: 'PLAY0818', + unsupportedActionSubjectContext: 'PLAY0819', unreachableActionAlternative: 'PLAY0347', unknownActionArgumentProperty: 'PLAY0348', invalidRefusalBranch: 'PLAY0538', diff --git a/Source/Screenplay/Monaco/screenplay-language/hover-content.ts b/Source/Screenplay/Monaco/screenplay-language/hover-content.ts index b4dd3b1cd..fea2f01e8 100644 --- a/Source/Screenplay/Monaco/screenplay-language/hover-content.ts +++ b/Source/Screenplay/Monaco/screenplay-language/hover-content.ts @@ -1,6 +1,7 @@ // Copyright (c) Cratis. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +import { actionSubjectHover } from './action-subject-authoring'; import { continuationResponseHover } from './continuation-responses'; import { reactionReferenceAt } from './reaction-authoring'; import { refusalContext } from './refusal-context'; @@ -41,6 +42,8 @@ export function hoverContent( else if (line[index] === '`' && !inString) inTemplate = !inTemplate; } if (inString || inTemplate) return null; + const actionSubject = actionSubjectHover(line, word, startColumn); + if (actionSubject) return actionSubject; const returned = continuationResponseHover(lines, lineIndex, word, startColumn, endColumn, application); if (returned) return returned; const reaction = reactionReferenceAt(lines, lineIndex, startColumn, endColumn, application); diff --git a/Source/Screenplay/Monaco/screenplay-language/tokens.ts b/Source/Screenplay/Monaco/screenplay-language/tokens.ts index 1e5f34654..0a6990ad2 100644 --- a/Source/Screenplay/Monaco/screenplay-language/tokens.ts +++ b/Source/Screenplay/Monaco/screenplay-language/tokens.ts @@ -108,6 +108,13 @@ export function createTokensProvider(subLanguages: SubLanguage[]): languages.IMo [/^(\s*)(then)(\s+)(events)(\s+)(in any order)(?=\s*(?:\/\/.*)?$)/, ['white', 'keyword', 'white', 'keyword', 'white', 'keyword']], [/^(\s*)(when)(\s+)(redelivered)(\s+)([\w.]+)(\s+)(to)(\s+)([\w.]+)(?=\s*(?:\/\/.*)?$)/, ['white', 'keyword', 'white', 'keyword', 'white', 'type.identifier', 'white', 'keyword', 'white', 'type.identifier']], + // Action subjects are header clauses, not new reserved property names. + [/^(\s*)(action)(\s+)("(?:[^"\\]|\\.)*"|\$strings\.[\w.]+)(\s+)(for)(\s+)(item|screen)\b/, + ['white', 'keyword', 'white', 'string', 'white', 'keyword', 'white', 'keyword']], + [/^(\s*)(action)(\s+)([\w.]+)(\s+)(for)(\s+)(item|screen)\b/, + ['white', 'keyword', 'white', 'type.identifier', 'white', 'keyword', 'white', 'keyword']], + [/^(\s*)(item)(\s+)(\w+)(\s+)(action)(\s+)([\w.]+)(\s+)(for)(\s+)(item|screen)\b/, + ['white', 'keyword', 'white', 'identifier', 'white', 'keyword', 'white', 'type.identifier', 'white', 'keyword', 'white', 'keyword']], // Guarded-action words are contextual; property names keep their ordinary meaning. [/^(\s*)(otherwise)(\s+)(hidden)(?=\s*(?:\/\/.*)?$)/, ['white', 'keyword', 'white', 'keyword']], [/^(\s*)(otherwise)(\s+)(execute)(\s+)([\w.]+)(?=\s*(?:\/\/.*)?$)/, diff --git a/Source/Screenplay/VSCodeExtension/syntaxes/screenplay.tmLanguage.json b/Source/Screenplay/VSCodeExtension/syntaxes/screenplay.tmLanguage.json index f0c7becd8..b323976c1 100644 --- a/Source/Screenplay/VSCodeExtension/syntaxes/screenplay.tmLanguage.json +++ b/Source/Screenplay/VSCodeExtension/syntaxes/screenplay.tmLanguage.json @@ -35,10 +35,27 @@ { "include": "#specification-stream" }, { "include": "#stream-id-parts" }, { "include": "#declared-dependency" }, + { "include": "#action-subjects" }, { "include": "#keywords" }, { "include": "#common" } ], "repository": { + "action-subjects": { + "patterns": [ + { + "match": "^(\\s*)(action)(\\s+)(\"(?:[^\"\\\\]|\\\\.)*\"|\\$strings\\.[\\w.]+)(\\s+)(for)(\\s+)(item|screen)\\b", + "captures": { "2": { "name": "keyword.other.screenplay" }, "4": { "name": "string.quoted.double.screenplay" }, "6": { "name": "keyword.other.screenplay" }, "8": { "name": "keyword.other.screenplay" } } + }, + { + "match": "^(\\s*)(action)(\\s+)([\\w.]+)(\\s+)(for)(\\s+)(item|screen)\\b", + "captures": { "2": { "name": "keyword.other.screenplay" }, "4": { "name": "entity.name.type.screenplay" }, "6": { "name": "keyword.other.screenplay" }, "8": { "name": "keyword.other.screenplay" } } + }, + { + "match": "^(\\s*)(item)(\\s+)(\\w+)(\\s+)(action)(\\s+)([\\w.]+)(\\s+)(for)(\\s+)(item|screen)\\b", + "captures": { "2": { "name": "keyword.other.screenplay" }, "4": { "name": "variable.other.screenplay" }, "6": { "name": "keyword.other.screenplay" }, "8": { "name": "entity.name.type.screenplay" }, "10": { "name": "keyword.other.screenplay" }, "12": { "name": "keyword.other.screenplay" } } + } + ] + }, "calendar-declarations": { "patterns": [ { "match": "^(time)(\\s+)(zone)(\\s+)(configurable\\s+default\\s+)?(?=\")", "captures": { "1": { "name": "keyword.control.screenplay" }, "3": { "name": "keyword.other.screenplay" }, "5": { "name": "keyword.other.screenplay" } } }, From 60fb48f1a0d8d8f9720f9bb8716e790f895d4e3c Mon Sep 17 00:00:00 2001 From: woksin Date: Sat, 24 Oct 2026 20:34:03 +0200 Subject: [PATCH 3/9] Complete action-subject conformance, repairs and editor assistance --- Documentation/screenplay/action-subjects.md | 6 + Documentation/screenplay/diagnostics.md | 14 +- .../Purchasing/model/suppliers.play | 2 +- .../Warehouse/model/dispatch.play | 2 +- Samples/Library/library.play | 3 +- .../Golden/screenplay-contract.json | 55 + .../when_a_discovered_form_submits.cs | 2 +- .../when_a_screen_action_navigates.cs | 2 +- ...g_the_invoicing_sample_through_a_folder.cs | 2 +- .../Parsing/GuardedActionValidator.cs | 2 - .../Parsing/ScreenParser.ActionSubjects.cs | 9 +- .../Parsing/ScreenParser.GuardedActions.cs | 4 +- .../DotNET/Screenplay/Parsing/ScreenParser.cs | 22 +- .../given/legacy_library_action_subjects.cs | 26 + .../for_SyntaxJson/given/syntax_examples.cs | 3 + ..._exporting_action_subject_fixture_packs.cs | 84 + ...hen_freezing_legacy_source_syntax_bytes.cs | 2 +- .../WorkspaceActionSubjectRepairs.cs | 6 +- .../Workspaces/WorkspaceDiagnosticRepairs.cs | 2 +- .../Workspaces/WorkspaceRepairVerification.cs | 7 +- .../when_repairing_action_subjects.cs | 82 + ...iling_a_document_with_a_dialog_template.cs | 2 +- ..._a_screen_with_an_invalid_strings_label.cs | 2 +- ...ompiling_a_screen_with_strings_operands.cs | 2 +- .../when_compiling_the_invoicing_sample.cs | 2 +- .../when_compiling_toolbar_buttons.cs | 2 +- ...hen_preserving_action_subject_contracts.cs | 89 + .../when_resolving_action_subjects.cs | 14 + .../when_printing_screen_composition.cs | 2 +- ...hen_printing_screen_release_ui_contract.cs | 2 +- .../and_it_is_a_screen_label.cs | 2 +- .../when_printing_the_invoicing_sample.cs | 2 +- .../Authoring/ActionSubjectQuickFixes.ts | 150 +- .../when_repairing_action_subjects.ts | 24 +- .../Conformance/action-subjects/README.md | 20 + .../action-subjects/native.context.json | 2065 +++++++++++++---- .../action-subjects/native.diagnostics.json | 203 +- .../native.effective.syntax.json | 509 +++- .../action-subjects/native.manifest.json | 118 + .../action-subjects/native.raw.syntax.json | 467 +++- .../Conformance/action-subjects/source.play | 46 +- .../action-subjects/typescript.context.json | 1986 ++++++++++++---- .../typescript.diagnostics.json | 199 +- .../typescript.effective.syntax.json | 450 +++- .../action-subjects/typescript.manifest.json | 118 + .../typescript.raw.syntax.json | 408 +++- ..._exporting_action_subject_fixture_packs.ts | 62 +- .../Conformance/library-sample.syntax.json | 23 +- .../Compiler/Parsing/ActionSubjectClause.ts | 12 +- .../Compiler/Parsing/ActionSubjectInputs.ts | 7 +- .../Parsing/ActionSubjectResolution.ts | 17 +- .../Compiler/Parsing/GuardedActionInputs.ts | 3 - .../Compiler/Parsing/ScreenParser.ts | 7 +- ...hen_preserving_action_subject_contracts.ts | 64 + .../for_parse/when_parsing_screens.ts | 4 +- .../when_parsing_the_repository_samples.ts | 5 + .../when_resolving_action_subjects.ts | 10 + .../when_drawing_guarded_actions.ts | 13 +- .../when_editing_action_subjects.ts | 80 + .../when_editing_guarded_actions.ts | 4 +- .../when_highlighting_guarded_actions.ts | 3 + .../with_a_problem_of_every_coded_kind.ts | 4 + .../Monaco/screenplay-language/validation.ts | 2 +- .../VSCodeExtension/WorkspaceApplication.ts | 5 + .../when_highlighting_action_subjects.ts | 33 + 65 files changed, 6498 insertions(+), 1081 deletions(-) create mode 100644 Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/legacy_library_action_subjects.cs create mode 100644 Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_action_subjects.cs create mode 100644 Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_action_subject_contracts.cs create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/README.md create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/native.manifest.json create mode 100644 Source/Screenplay/Compiler/Conformance/action-subjects/typescript.manifest.json create mode 100644 Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts create mode 100644 Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts create mode 100644 Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts diff --git a/Documentation/screenplay/action-subjects.md b/Documentation/screenplay/action-subjects.md index 645162916..1e96a26b9 100644 --- a/Documentation/screenplay/action-subjects.md +++ b/Documentation/screenplay/action-subjects.md @@ -55,3 +55,9 @@ Native `ScreenActionSubjects.Resolve(application)` and TypeScript `resolveAction The paired native/TypeScript fixture packs are under `Source/Screenplay/Compiler/Conformance/action-subjects`: authored source, raw syntax, effective syntax, diagnostics, and context/location sidecars. Each context includes the complete authored declaration tree and canonical-path source locations, so consumers can verify nominal identity without inventing it. Native/TS packs preserve their existing modeled syntax surfaces and assert common-member parity separately. Runtime execution and rendering proof are Scene-owned. Compiler fixtures and editor assistance do not claim renderer support or change the executable semantic model. + +## Corpus migration gate + +Before making inference part of a Scene release, compile each real application workspace with its imports and collect PLAY0816 and PLAY0817 by source path, line and command. Treat an unresolvable declaration as insufficient evidence, not a successful migration. For every PLAY0817, review the previous row-name bindings alongside the proposed effective inputs; either state `for screen`, state `for item` with the intended explicit inputs, or retain the previous bindings explicitly. Apply a proposed repair transactionally and compile the complete workspace again. Do not bulk-accept a binding based only on its spelling. + +Track that real-corpus scan and disposition review as a follow-up to Screenplay#1052, before the consuming Scene release. The repository samples and paired fixture packs are the compiler regression gate, not evidence that an external corpus has been migrated. Scene must separately verify selection, form/renderer inputs and guarded single-record behavior against the effective pack; it must not reinterpret the raw authored pack as resolved execution metadata. diff --git a/Documentation/screenplay/diagnostics.md b/Documentation/screenplay/diagnostics.md index 060732293..395fe92a1 100644 --- a/Documentation/screenplay/diagnostics.md +++ b/Documentation/screenplay/diagnostics.md @@ -11,10 +11,16 @@ A message is written for a person and gets reworded whenever a clearer wording i ## Action subject diagnostics -Decision 0110 reserves PLAY0815–PLAY0819: malformed/duplicate/misplaced clauses -(Error), inference (Information), changed legacy row behavior (Warning), ambiguous -input keys (Warning), and unsupported guarded screen/collection context (Warning), -respectively. See [action subjects](action-subjects.md#diagnostics-and-migration) +Decision 0110 adds the following catalog entries: + +| Code | Severity | Meaning | +|---|---|---| +| `PLAY0815` | Error | An action subject clause is malformed, duplicated, or attached to a non-action toolbar item. Use one `for item` or `for screen` before the inline label. | +| `PLAY0816` | Information | An omitted plain/toolbar action subject is inferred from its declared data and identifier types. | +| `PLAY0817` | Warning | Effective row binding differs from legacy case-insensitive name matching. Make intent explicit; a safe repair may retain legacy mappings. | +| `PLAY0818` | Warning | Several declared nominal keys could fill an input. Write an explicit binding. | +| `PLAY0819` | Warning | A guarded action `for screen` cannot choose an item from collection-valued data. | + See [action subjects](action-subjects.md#diagnostics-and-migration) for triggers and safe fixes. PLAY0319, PLAY0345 and PLAY0346 keep their existing meanings. ## Reading a diagnostic diff --git a/Samples/AcmeCommerce/Purchasing/model/suppliers.play b/Samples/AcmeCommerce/Purchasing/model/suppliers.play index 54e78d70c..bdf3c10be 100644 --- a/Samples/AcmeCommerce/Purchasing/model/suppliers.play +++ b/Samples/AcmeCommerce/Purchasing/model/suppliers.play @@ -55,7 +55,7 @@ module Buying list toolbar actions button register title "Register supplier" slice Buying.Suppliers.RegisterSupplier emphasis primary icon plus - action OfferSupplierProduct + action OfferSupplierProduct for item label "Offer product" data SupplierRow[] via query AllSuppliers table SupplierRow diff --git a/Samples/AcmeCommerce/Warehouse/model/dispatch.play b/Samples/AcmeCommerce/Warehouse/model/dispatch.play index 1a83bce74..088b9273d 100644 --- a/Samples/AcmeCommerce/Warehouse/model/dispatch.play +++ b/Samples/AcmeCommerce/Warehouse/model/dispatch.play @@ -229,7 +229,7 @@ module Stock property title = "Shipments" property subtitle = "Every parcel with its carrier and tracking number" toolbar - action DispatchShipment + action DispatchShipment for item label "Dispatch" // The stage of the selected parcel decides what can be done to it; the Picking board only shows the stages. data ShipmentRow[] via query AllShipments diff --git a/Samples/Library/library.play b/Samples/Library/library.play index 8e118f544..f05e18be3 100644 --- a/Samples/Library/library.play +++ b/Samples/Library/library.play @@ -459,7 +459,8 @@ module Lending column bookId label "Book" column dueDate label "Due" column status label "Status" - action ReturnBook + action ReturnBook for item + with bookId from item.bookId specification SeeingAReturnedLoan given caller diff --git a/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json b/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json index 44e4b4458..c785bf90d 100644 --- a/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json +++ b/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json @@ -45011,6 +45011,61 @@ "title": "A specification given time zone declaration is repeated or malformed.", "reserved": false, "retired": false + }, + { + "code": "PLAY0815", + "name": "InvalidActionSubjectClause", + "severity": "error", + "severities": [ + "error" + ], + "title": "Malformed, duplicate or inapplicable action subject clause.", + "reserved": false, + "retired": false + }, + { + "code": "PLAY0816", + "name": "InferredActionSubject", + "severity": "information", + "severities": [ + "information" + ], + "title": "The inferred subject of an action without an authored clause.", + "reserved": false, + "retired": false + }, + { + "code": "PLAY0817", + "name": "ChangedActionSubject", + "severity": "warning", + "severities": [ + "warning" + ], + "title": "An inferred action subject differs from legacy row-name matching.", + "reserved": false, + "retired": false + }, + { + "code": "PLAY0818", + "name": "AmbiguousActionInputBinding", + "severity": "warning", + "severities": [ + "warning" + ], + "title": "Several declared keys are eligible for an action input.", + "reserved": false, + "retired": false + }, + { + "code": "PLAY0819", + "name": "UnsupportedActionSubjectContext", + "severity": "warning", + "severities": [ + "warning" + ], + "title": "A guarded screen action cannot obtain an item from a collection.", + "reserved": false, + "retired": false } ], "mcpTools": [ diff --git a/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_discovered_form_submits.cs b/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_discovered_form_submits.cs index 74df73f0e..018b8eec4 100644 --- a/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_discovered_form_submits.cs +++ b/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_discovered_form_submits.cs @@ -5,7 +5,7 @@ namespace Cratis.Screenplay.Completeness.for_NavigationCompleteness; public class when_a_discovered_form_submits : given.screens { - void Establish() => Compile("command Go\nscreen Home\n action Go\nscreen Detail", "on load\n navigate to Home\nform Input for Go\n on submit navigate to Detail"); + void Establish() => Compile("command Go\nscreen Home\n action Go for screen\nscreen Detail", "on load\n navigate to Home\nform Input for Go\n on submit navigate to Detail"); void Because() => Findings = ModelCompleteness.Check(Compilation, new([CompletenessCheck.Navigation])); [Fact] void should_follow_the_discovered_forms_submit_edge() => Findings.ShouldBeEmpty(); diff --git a/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_screen_action_navigates.cs b/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_screen_action_navigates.cs index 5f1108e4f..13a82078a 100644 --- a/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_screen_action_navigates.cs +++ b/Source/DotNET/Screenplay/Completeness/for_NavigationCompleteness/when_a_screen_action_navigates.cs @@ -5,7 +5,7 @@ namespace Cratis.Screenplay.Completeness.for_NavigationCompleteness; public class when_a_screen_action_navigates : given.screens { - void Establish() => Compile("command Go\nscreen Home\n action Go\n navigate to Detail\nscreen Detail", "on load\n navigate to Home"); + void Establish() => Compile("command Go\nscreen Home\n action Go for screen\n navigate to Detail\nscreen Detail", "on load\n navigate to Home"); void Because() => Findings = ModelCompleteness.Check(Compilation, new([CompletenessCheck.Navigation])); [Fact] void should_follow_the_action_edge() => Findings.ShouldBeEmpty(); diff --git a/Source/DotNET/Screenplay/Files/for_PlayFileWriter/when_round_tripping_the_invoicing_sample_through_a_folder.cs b/Source/DotNET/Screenplay/Files/for_PlayFileWriter/when_round_tripping_the_invoicing_sample_through_a_folder.cs index e6eb89b50..1efe67295 100644 --- a/Source/DotNET/Screenplay/Files/for_PlayFileWriter/when_round_tripping_the_invoicing_sample_through_a_folder.cs +++ b/Source/DotNET/Screenplay/Files/for_PlayFileWriter/when_round_tripping_the_invoicing_sample_through_a_folder.cs @@ -36,7 +36,7 @@ void Because() } [Fact] void should_compile_the_folder_back() => _recompiled.Result.Success.ShouldBeTrue(); - [Fact] void should_resolve_every_reference_across_the_folder() => _recompiled.Result.Diagnostics.Where(diagnostic => diagnostic.Code != DiagnosticCodes.OmittedProductionDestination).Select(_ => _.Code).ShouldContainOnly(DiagnosticCodes.FileConstraintOnlySupportsUniqueness); + [Fact] void should_resolve_every_reference_across_the_folder() => _recompiled.Result.Diagnostics.Where(diagnostic => diagnostic.Code is not (DiagnosticCodes.OmittedProductionDestination or DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject)).Select(_ => _.Code).ShouldContainOnly(DiagnosticCodes.FileConstraintOnlySupportsUniqueness); [Fact] void should_discover_every_file_it_wrote() => _recompiled.Sources.Count().ShouldEqual(_written.Count()); [Fact] void should_write_a_file_per_module_feature_slice_and_one_for_the_application() => _written.Count().ShouldEqual(1 + Modules + Features + Slices); [Fact] void should_give_back_an_equivalent_application() => SyntaxJson.StructurallyEqual(_recompiled.Result.Value!, InPathOrder(_original)).ShouldBeTrue(); diff --git a/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs b/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs index 833bb8d47..f82d7ccd4 100644 --- a/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs +++ b/Source/DotNET/Screenplay/Parsing/GuardedActionValidator.cs @@ -109,10 +109,8 @@ static void ValidateArguments( ParserContext context) { var command = declarations.Resolve(commandName, scope, slice => slice.Commands, command => command.Name)?.Node; - var names = new HashSet(StringComparer.Ordinal); foreach (var argument in arguments) { - if (!names.Add(argument.Name)) context.Error(DiagnosticCodes.InvalidInteractionArgument, $"Duplicate argument '{argument.Name}' - supply each input only once", argument.Location); var inputs = command?.Properties.Where(property => property.Name == argument.Name).ToArray(); if (inputs is { Length: 0 }) { diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs index 8f8e607b9..45705fab9 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs @@ -41,10 +41,15 @@ internal static partial class ScreenParser return suffix.Groups[1].Value == "item" ? ScreenActionSubjectKind.Item : ScreenActionSubjectKind.Screen; } - static InteractionArgumentSyntax? ParsePlainActionInput(ParserContext context, SourceLine line) + static InteractionArgumentSyntax? ParsePlainActionInput(ParserContext context, SourceLine line, IReadOnlyList inputs) { var match = InteractionParser.WithRegex().Match(line.Content); - if (match.Success) return new(match.Groups[1].Value, match.Groups[2].Value.Trim(), line.Location); + if (match.Success) + { + var name = match.Groups[1].Value; + if (inputs.Any(input => input.Name == name)) context.Error(DiagnosticCodes.InvalidInteractionArgument, $"Duplicate argument '{name}' - supply each input only once", line.Location); + return new(name, match.Groups[2].Value.Trim(), line.Location); + } context.Error(DiagnosticCodes.InvalidInteractionArgument, $"Invalid argument '{line.Content}' - expected 'with from '", line.Location); context.SkipBlock(line.Indent); return null; diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.GuardedActions.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.GuardedActions.cs index a057531f0..408b1fe2b 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.GuardedActions.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.GuardedActions.cs @@ -12,7 +12,7 @@ internal static partial class ScreenParser { internal static void ValidateGuardedCondition(ParserContext context, ConditionSyntax condition) => ValidateActionCondition(context, condition); - static ScreenGuardedActionSyntax ParseGuardedAction(ParserContext context, SourceLine line, string label) + static ScreenGuardedActionSyntax ParseGuardedAction(ParserContext context, SourceLine line, string label, ScreenActionSubjectKind? subject) { var alternatives = new List(); ScreenActionOtherwiseSyntax? otherwise = null; @@ -82,7 +82,7 @@ static ScreenGuardedActionSyntax ParseGuardedAction(ParserContext context, Sourc context.Error(DiagnosticCodes.GuardedActionWithoutAlternatives, "A guarded action must declare at least one 'when' alternative", line.Location); } - return new(label, alternatives, line.Location) { Otherwise = otherwise, Navigate = navigate }; + return new(label, alternatives, line.Location) { Otherwise = otherwise, Navigate = navigate, Subject = subject }; } static List ParseActionArguments(ParserContext context, SourceLine line) diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs index 7f446e371..a58528dc5 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs @@ -225,10 +225,15 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi var guarded = GuardedActionRegex().Match(header); if (guarded.Success) { - return ParseGuardedAction(context, line, OperandText(guarded, 1)) with { Subject = subject }; + return ParseGuardedAction(context, line, OperandText(guarded, 1), subject); } - var match = ActionRegex().Match(header); + return ParsePlainAction(context, line, (header, inlineLabel, subject)); + } + + static ScreenActionSyntax? ParsePlainAction(ParserContext context, SourceLine line, (string Header, string? Label, ScreenActionSubjectKind? Subject) header) + { + var match = ActionRegex().Match(header.Header); if (!match.Success) { context.Error(DiagnosticCodes.InvalidActionDirective, $"Invalid action directive '{line.Content}' - expected 'action '", line.Location); @@ -236,8 +241,8 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi return null; } - var label = inlineLabel; - SourceLocation? labelLocation = inlineLabel is null ? null : line.Location; + var label = header.Label; + var labelLocation = label is null ? null : line.Location; ScreenNavigateSyntax? navigate = null; var inputs = new List(); @@ -256,7 +261,7 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi } else if (LineText.FirstWord(child.Content) == "with") { - if (ParsePlainActionInput(context, child) is { } input) inputs.Add(input); + AddPlainActionInput(context, child, inputs); } else { @@ -266,12 +271,17 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi return new ScreenActionSyntax(match.Groups[1].Value, label, navigate, line.Location) { - Subject = subject, + Subject = header.Subject, Inputs = inputs, DirectiveLocations = labelLocation is null ? [] : new Dictionary { ["label"] = labelLocation } }; } + static void AddPlainActionInput(ParserContext context, SourceLine child, List inputs) + { + if (ParsePlainActionInput(context, child, inputs) is { } input) inputs.Add(input); + } + static ScreenTemplateReferenceSyntax ParseTemplateReference(ParserContext context, SourceLine line) { var name = line.Content["template".Length..].Trim(); diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/legacy_library_action_subjects.cs b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/legacy_library_action_subjects.cs new file mode 100644 index 000000000..2ac0ff858 --- /dev/null +++ b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/legacy_library_action_subjects.cs @@ -0,0 +1,26 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Cratis.Screenplay.Syntax.Serialization.for_SyntaxJson.given; + +// Only the living Library sample uses this projection. The new action-subject vectors protect its +// current metadata; its pre-0110 frozen bytes still protect every preexisting member and value. +internal static class legacy_library_action_subjects +{ + internal static ApplicationSyntax Without(ApplicationSyntax application) => application with + { + Modules = application.Modules.Select(Module) + }; + + static ModuleSyntax Module(ModuleSyntax module) => module with { Features = module.Features.Select(Feature) }; + + static FeatureSyntax Feature(FeatureSyntax feature) => feature with { Features = feature.Features.Select(Feature), Slices = feature.Slices.Select(Slice) }; + + static SliceSyntax Slice(SliceSyntax slice) => slice with { Screens = slice.Screens.Select(Screen) }; + + static ScreenSyntax Screen(ScreenSyntax screen) => screen with { Directives = screen.Directives.Select(Directive) }; + + static ScreenDirectiveSyntax Directive(ScreenDirectiveSyntax directive) => directive is ScreenActionSyntax action + ? action with { Subject = null, Inputs = [] } + : directive; +} diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/syntax_examples.cs b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/syntax_examples.cs index 850d70143..177aaf0bc 100644 --- a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/syntax_examples.cs +++ b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/given/syntax_examples.cs @@ -32,6 +32,7 @@ internal static SyntaxNode Create(Type type, int depth = 0) // Implementation intent adds a single authoritative payload invariant; keep this example valid // while still independently populating every other structural member. + node = WithActionSubjectContract(node); return node switch { ConceptSyntax concept => concept with { Type = "Enum" }, @@ -63,6 +64,8 @@ internal static SyntaxNode Create(Type type, int depth = 0) }; } + static SyntaxNode WithActionSubjectContract(SyntaxNode node) => node is ToolbarItemSyntax item ? item with { Kind = ToolbarItemKind.Action } : node; + internal static bool SameValues(object? left, object? right) { if (left is SyntaxNode node && right is SyntaxNode other) diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs index 9fe32e864..9f03c7414 100644 --- a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs +++ b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_exporting_action_subject_fixture_packs.cs @@ -36,10 +36,21 @@ void Because() _effective = ScreenActionSubjects.Resolve(_raw).Value!; _exports["raw.syntax"] = SyntaxJson.Serialize(_raw); _exports["effective.syntax"] = SyntaxJson.Serialize(_effective); + _exports["manifest"] = JsonSerializer.SerializeToElement(new + { + protocol = "Cratis.ActionSubjects/1", + authored = "source.play", + rawSyntaxJson = "native.raw.syntax.json", + effectiveSyntaxJson = "native.effective.syntax.json", + diagnostics = "native.diagnostics.json", + context = "native.context.json", + cases = _raw.Modules.First().Features.First().Slices.First().Screens.Select((screen, index) => new { name = screen.Name, focusPath = $"$.modules[0].features[0].slices[0].screens[{index}]" }) + }); _exports["context"] = JsonSerializer.SerializeToElement(new { source = "source.play", application = _before, + subjects = Subjects(_before, "$", new(null, null, [])).ToArray(), locations = Locations(_raw, "$").OrderBy(entry => entry.Path, StringComparer.Ordinal).Select(entry => new { path = entry.Path, @@ -49,9 +60,52 @@ void Because() }); } + [Theory] + [InlineData("InferredItem", "item.rowId")] + [InlineData("SameName", "item.itemId")] + [InlineData("CaseMismatch", "item.rowId")] + [InlineData("QualifiedDeclarations", "item.rowId")] + [InlineData("SlotScope", "item.rowId")] + [InlineData("OutletScope", "item.itemId")] + void should_resolve_declared_identity_in_each_scope(string screen, string binding) + { + var action = Actions(screen).Single(); + action.Subject.ShouldEqual(ScreenActionSubjectKind.Item); + action.Inputs.Single(input => input.Name == "itemId").Binding.ShouldEqual(binding); + } + + [Theory] + [InlineData("ForeignKey")] + [InlineData("OptionalIdentifier")] + [InlineData("GeneratedIdentifier")] + [InlineData("PrimitiveIdentifier")] + [InlineData("AmbiguousInferred")] + [InlineData("MissingKey")] + [InlineData("UnresolvedDeclaration")] + void should_not_invent_identity(string screen) + { + var action = Actions(screen).Single(); + action.Subject.ShouldBeNull(); + action.Inputs.ShouldBeEmpty(); + } + + IEnumerable Actions(string name) + { + var walker = new Cratis.Screenplay.Syntax.for_ScreenplaySyntaxWalker.given.a_counting_walker(); + walker.VisitScreen(_effective.Modules.First().Features.First().Slices.First().Screens.Single(screen => screen.Name == name)); + return walker.Nodes.OfType(); + } + [Fact] void should_leave_authored_syntax_unchanged() => SyntaxJson.StructurallyEqual(_raw, SyntaxJson.Deserialize(_before)).ShouldBeTrue(); [Fact] void should_be_idempotent() => SyntaxJson.StructurallyEqual(_effective, ScreenActionSubjects.Resolve(_effective).Value!).ShouldBeTrue(); + [Fact] + void should_retain_locations_of_every_authored_node() + { + var effective = Locations(_effective, "$").ToDictionary(entry => entry.Path, entry => entry.Node.Location); + foreach (var (path, node) in Locations(_raw, "$")) effective[path].ShouldEqual(node.Location); + } + [Fact] void should_match_the_native_fixture_pack() { @@ -68,6 +122,8 @@ void should_match_the_native_fixture_pack() [Fact] void should_agree_with_typescript_on_authored_and_effective_members() { + var context = JsonDocument.Parse(File.ReadAllText(Path.Combine(_directory, "typescript.context.json"))).RootElement; + Assert.True(JsonElement.DeepEquals(context.GetProperty("subjects"), _exports["context"].GetProperty("subjects"))); foreach (var name in new[] { "raw.syntax", "effective.syntax" }) { var expected = JsonDocument.Parse(File.ReadAllText(Path.Combine(_directory, $"typescript.{name}.json"))).RootElement; @@ -75,6 +131,34 @@ void should_agree_with_typescript_on_authored_and_effective_members() } } + sealed record SubjectScope(string? Screen, string? Slice, string[] Data); + + static IEnumerable Subjects(JsonElement value, string path, SubjectScope inherited) + { + if (value.ValueKind == JsonValueKind.Array) + { + return value.EnumerateArray().SelectMany((child, index) => Subjects(child, $"{path}[{index}]", inherited)); + } + if (value.ValueKind != JsonValueKind.Object) return []; + var kind = value.TryGetProperty("kind", out var tag) ? tag.GetString() : null; + var scope = kind switch + { + "SliceSyntax" => inherited with { Slice = path }, + "ScreenSyntax" => inherited with { Screen = path, Data = [] }, + "ScreenContributionSyntax" => inherited with { Data = [] }, + _ => inherited + }; + if (value.TryGetProperty("directives", out var directives)) + { + var local = directives.EnumerateArray().Select((node, index) => (node, index)).Where(entry => entry.node.GetProperty("kind").GetString() == "ScreenDataSyntax").Select(entry => $"{path}.directives[{entry.index}]").ToArray(); + if (local.Length > 0) scope = scope with { Data = local }; + } + var children = value.EnumerateObject().SelectMany(property => Subjects(property.Value, $"{path}.{property.Name}", scope)); + return kind is "ScreenActionSyntax" or "ScreenGuardedActionSyntax" or "ToolbarItemSyntax" + ? new object[] { new { path, screen = scope.Screen, slice = scope.Slice, data = scope.Data } }.Concat(children) + : children; + } + static bool Relevant(Diagnostic diagnostic) => diagnostic.Code is DiagnosticCodes.InvalidInteractionArgument or DiagnosticCodes.UnknownActionSubjectField or DiagnosticCodes.UnresolvedActionSubject or DiagnosticCodes.InvalidActionSubjectClause or DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject or DiagnosticCodes.AmbiguousActionInputBinding or DiagnosticCodes.UnsupportedActionSubjectContext; static IEnumerable<(string Path, SyntaxNode Node)> Locations(SyntaxNode node, string path) diff --git a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_freezing_legacy_source_syntax_bytes.cs b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_freezing_legacy_source_syntax_bytes.cs index 7de4bd492..1f6d3d7d4 100644 --- a/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_freezing_legacy_source_syntax_bytes.cs +++ b/Source/DotNET/Screenplay/Syntax/Serialization/for_SyntaxJson/when_freezing_legacy_source_syntax_bytes.cs @@ -36,7 +36,7 @@ void should_preserve_the_complete_legacy_native_bytes_without_normalizing_values var legacy = name switch { "invoicing-sample" or "invoicing-editor-sample" => WithoutSampleTextRules(WithoutSampleRoutesAndKeys(WithoutGuardedSampleAction(WithoutSampleAdditions(WithoutSampleExamples(parsed))))), - "library-sample" => WithoutLibraryForms(parsed), + "library-sample" => WithoutLibraryForms(given.legacy_library_action_subjects.Without(parsed)), _ => parsed }; diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs index 6f47b08e1..68db144db 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs @@ -12,6 +12,8 @@ namespace Cratis.Screenplay.Workspaces; internal static class WorkspaceActionSubjectRepairs { + internal static bool Supports(string code) => code == DiagnosticCodes.InferredActionSubject || code == DiagnosticCodes.ChangedActionSubject; + internal static ImmutableArray Find(WorkspaceSyntaxIndex index, WorkspaceRevision revision, Diagnostic diagnostic, bool verifyRepair) { var matches = index.Entries.Where(entry => entry.Handle.Revision == revision && entry.Location == diagnostic.Location && @@ -38,7 +40,9 @@ internal static ImmutableArray Find(WorkspaceSyntaxIn var result = ImmutableArray.CreateBuilder(); foreach (var (node, title) in candidates) { - var repair = new WorkspaceDiagnosticRepair(diagnostic.Code, subject.Handle, + var repair = new WorkspaceDiagnosticRepair( + diagnostic.Code, + subject.Handle, [new ReplaceWorkspaceNode(subject.Handle, subject.Node, node)]) { Title = title, diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs index 1f6f7ba45..a7a479b80 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceDiagnosticRepairs.cs @@ -195,7 +195,7 @@ static ImmutableArray Find(WorkspaceSyntaxIndex index return WorkspaceProductionRepairs.Find(index, revision, diagnostic, verifyRepair); } - if (diagnostic.Code is DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject) + if (WorkspaceActionSubjectRepairs.Supports(diagnostic.Code)) { return WorkspaceActionSubjectRepairs.Find(index, revision, diagnostic, verifyRepair); } diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs index bb16c63fb..320ebe1b4 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs @@ -165,7 +165,12 @@ static WorkspaceAuthoringResult VerifyTransaction(WorkspaceSyntaxIndex index, Wo return Refuse(result, WorkspaceConflictKind.InvalidOperation, "Cannot prove that the timeline repair preserves the model, catalog, readiness, placements and simulated ranks without introducing findings or problems."); } - if (result.Accepted && repair.DiagnosticCode is DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject && + return VerifyActionSubjectRepair(index, repair, result); + } + + static WorkspaceAuthoringResult VerifyActionSubjectRepair(WorkspaceSyntaxIndex index, WorkspaceDiagnosticRepair repair, WorkspaceAuthoringResult result) + { + if (result.Accepted && WorkspaceActionSubjectRepairs.Supports(repair.DiagnosticCode) && !WorkspaceActionSubjectRepairs.Preserves(index, repair, result)) { return Refuse(result, WorkspaceConflictKind.InvalidOperation, "Cannot prove that the action subject repair preserves the model, catalog, comments and other diagnostics."); diff --git a/Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_action_subjects.cs b/Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_action_subjects.cs new file mode 100644 index 000000000..840b4d0e8 --- /dev/null +++ b/Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_action_subjects.cs @@ -0,0 +1,82 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Text; +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Semantics; + +namespace Cratis.Screenplay.Workspaces.for_WorkspaceAuthoring; + +public class when_repairing_action_subjects : Specification +{ + const string Source = """ + concept ItemId : Uuid + module Work + feature Items + slice StateView List + readmodel Row + itemId ItemId key + command Retry + itemId ItemId + query Rows => Row[] + screen List + data Row[] via query Rows + action Retry + """; + ScreenplayWorkspace _workspace; + WorkspaceSyntaxIndex _index; + + void Establish() + { + _workspace = ScreenplayWorkspace.Create("Model", [WorkspaceDocument.Create("model", PortablePlayPath.Parse("model.play"), Encoding.UTF8.GetBytes(Source))], SemanticIdentityCatalog.Empty(ApplicationIdentity.Create("Model"))); + _index = WorkspaceSyntaxIndex.Create(_workspace); + } + + [Fact] + void should_offer_both_exact_migration_choices() + { + var diagnostic = _index.RepairableDiagnostics.Single(value => value.Code == DiagnosticCodes.ChangedActionSubject); + var repairs = WorkspaceDiagnosticRepairs.Find(_index, _workspace.Revision, diagnostic); + repairs.Length.ShouldEqual(3); + repairs.Select(repair => repair.Title).ShouldContain("Keep legacy row bindings explicitly"); + } + + [Fact] + void should_preview_an_explicit_subject_without_mutating_the_snapshot() + { + var repair = Inference(); + var result = WorkspaceDiagnosticRepairs.ProposeRepair(_workspace, repair, Request()); + result.Accepted.ShouldBeTrue(); + result.Workspace!.Documents.Single().Text.ShouldContain("action Retry for screen"); + _workspace.Documents.Single().Text.ShouldEqual(Source); + result.AuthoringDiagnostics.Any(value => value.Code is DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject).ShouldBeFalse(); + } + + [Fact] + void should_encode_the_legacy_row_mapping_explicitly() + { + var diagnostic = _index.RepairableDiagnostics.Single(value => value.Code == DiagnosticCodes.ChangedActionSubject); + var repair = WorkspaceDiagnosticRepairs.Find(_index, _workspace.Revision, diagnostic).Single(value => value.Title == "Keep legacy row bindings explicitly"); + var result = WorkspaceDiagnosticRepairs.ProposeRepair(_workspace, repair, Request()); + result.Accepted.ShouldBeTrue(); + result.Workspace!.Documents.Single().Text.ShouldContain("action Retry for item"); + result.Workspace.Documents.Single().Text.ShouldContain("with itemId from item.itemId"); + result.AuthoringDiagnostics.Any(value => value.Code == DiagnosticCodes.ChangedActionSubject).ShouldBeFalse(); + } + + [Fact] + void should_refuse_stale_revisions() => WorkspaceDiagnosticRepairs.ProposeRepair(_workspace, Inference(), Request() with { ExpectedRevision = default }).Conflicts.Single().Kind.ShouldEqual(WorkspaceConflictKind.StaleWorkspaceRevision); + + [Fact] + void should_require_formatting_consent() => WorkspaceDiagnosticRepairs.ProposeRepair(_workspace, Inference(), Request() with { Formatting = WorkspaceAuthoringFormatting.PreserveExactSource }).Conflicts.Single().Kind.ShouldEqual(WorkspaceConflictKind.FormattingConsentRequired); + + WorkspaceDiagnosticRepair Inference() => WorkspaceDiagnosticRepairs.Find(_index, _workspace.Revision, _index.RepairableDiagnostics.Single(value => value.Code == DiagnosticCodes.InferredActionSubject)).Single(); + + WorkspaceAuthoringRequest Request() => new() + { + ExpectedRevision = _workspace.Revision, + ExpectedCatalogRevision = _workspace.IdentityCatalog.Revision, + Validation = WorkspaceAuthoringValidation.Authoring, + Formatting = WorkspaceAuthoringFormatting.CanonicalizeTouchedDocuments + }; +} diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_document_with_a_dialog_template.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_document_with_a_dialog_template.cs index 8e157f3c1..6fdf77e2d 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_document_with_a_dialog_template.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_document_with_a_dialog_template.cs @@ -25,7 +25,7 @@ template RegisterInvoiceDialog body title "Register invoice" actions - action RegisterInvoice + action RegisterInvoice for screen """; CompilationResult _result; diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_an_invalid_strings_label.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_an_invalid_strings_label.cs index c291e9d11..7d7746764 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_an_invalid_strings_label.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_an_invalid_strings_label.cs @@ -17,7 +17,7 @@ command RegisterInvoice invoiceId Uuid screen InvoiceList - action RegisterInvoice + action RegisterInvoice for screen label $strings. """; diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_strings_operands.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_strings_operands.cs index efd15eb91..21b771efe 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_strings_operands.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_a_screen_with_strings_operands.cs @@ -17,7 +17,7 @@ invoiceId Uuid screen InvoiceList title $strings.invoices.title - action RegisterInvoice + action RegisterInvoice for screen label $strings.invoices.actions.newInvoice table InvoiceListReadModel column invoiceNumber label $strings.invoices.columns.number diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_the_invoicing_sample.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_the_invoicing_sample.cs index 112ea471e..289d9ce1a 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_the_invoicing_sample.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_the_invoicing_sample.cs @@ -21,7 +21,7 @@ void Because() } [Fact] void should_succeed() => _result.Success.ShouldBeTrue(); - [Fact] void should_warn_about_legacy_forms() => _result.Diagnostics.Where(diagnostic => diagnostic.Code != DiagnosticCodes.OmittedProductionDestination && diagnostic.Code != DiagnosticCodes.EventFromLaterSlice).All(_ => _.Code == DiagnosticCodes.FileConstraintOnlySupportsUniqueness || _.Code == DiagnosticCodes.LegacyInlineCodeFence || _.Code == DiagnosticCodes.LegacyOptionalSuffix).ShouldBeTrue(); + [Fact] void should_warn_about_legacy_forms() => _result.Diagnostics.Where(diagnostic => diagnostic.Code is not (DiagnosticCodes.OmittedProductionDestination or DiagnosticCodes.EventFromLaterSlice or DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject)).All(_ => _.Code == DiagnosticCodes.FileConstraintOnlySupportsUniqueness || _.Code == DiagnosticCodes.LegacyInlineCodeFence || _.Code == DiagnosticCodes.LegacyOptionalSuffix).ShouldBeTrue(); [Fact] void should_report_exactly_the_backward_dashboard_reference() => _result.Diagnostics.Where(diagnostic => diagnostic.Code == DiagnosticCodes.EventFromLaterSlice).Select(diagnostic => $"{diagnostic.Code}@{diagnostic.Location.Line}").ShouldEqual("PLAY0516@999"); [Fact] void should_report_the_dashboard_reference_as_information() => _result.Diagnostics.Single(diagnostic => diagnostic.Code == DiagnosticCodes.EventFromLaterSlice).Severity.ShouldEqual(DiagnosticSeverity.Information); [Fact] void should_have_the_domain() => _result.Value!.Domain!.Name.ShouldEqual("Sales"); diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_toolbar_buttons.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_toolbar_buttons.cs index cee3fdb3d..adf95c269 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_toolbar_buttons.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_compiling_toolbar_buttons.cs @@ -13,7 +13,7 @@ public class when_compiling_toolbar_buttons : given.a_toolbar_document ToolbarButtonSyntax Button(string id) => Toolbar.Buttons.Single(button => button.Id == id); [Fact] void should_succeed() => _result.Success.ShouldBeTrue(); - [Fact] void should_report_only_the_missing_slice_warning() => _result.Diagnostics.Select(diagnostic => diagnostic.Code).Where(code => string.CompareOrdinal(code, "PLAY0760") >= 0).ShouldContainOnly(DiagnosticCodes.ToolbarButtonWithoutSlice); + [Fact] void should_report_only_the_missing_slice_warning() => _result.Diagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Warning).Select(diagnostic => diagnostic.Code).ShouldContainOnly(DiagnosticCodes.ToolbarButtonWithoutSlice); [Fact] void should_read_every_button() => Toolbar.Buttons.Select(button => button.Id).ShouldContainOnly("place", "invoice", "later"); [Fact] void should_read_the_title_slice_emphasis_and_icon() => (Button("place").Title, Button("place").Slice, Button("place").Emphasis, Button("place").Icon).ShouldEqual(("Place order", "Shop.Orders.PlaceOrder", ToolbarEmphasis.Primary, "plus")); [Fact] void should_read_a_localized_title_as_written() => Button("invoice").Title.ShouldEqual("$strings.orders.invoice"); diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_action_subject_contracts.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_action_subject_contracts.cs new file mode 100644 index 000000000..9385f95ac --- /dev/null +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_action_subject_contracts.cs @@ -0,0 +1,89 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Text.Json; +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Printing; +using Cratis.Screenplay.Syntax; +using Cratis.Screenplay.Syntax.Serialization; + +namespace Cratis.Screenplay.for_ScreenplayCompiler; + +public class when_preserving_action_subject_contracts : Specification +{ + const string Source = """ + module Work + feature Items + slice StateView Details + screen Details + action Retry for item label "Retry for screen" + with id from item.foreignKey + with note from $context.note + navigate to Details + action "Choose" for screen + when item.ready == true execute Retry + with id from item.foreignKey + otherwise execute Release + with id from item.foreignKey + toolbar + item retry action Retry for screen label "Try" + parameter id from item.foreignKey + icon "retry" + confirm "Sure?" + """; + ApplicationSyntax _application; + + void Establish() => _application = new ScreenplayCompiler().Parse(Source).Value!; + + [Fact] + void should_print_and_reparse_only_authored_metadata() + { + var printed = new ScreenplayPrinter().Print(_application); + var reparsed = new ScreenplayCompiler().Parse(printed).Value!; + SyntaxJson.StructurallyEqual(_application, reparsed).ShouldBeTrue(); + printed.ShouldContain("for item"); + printed.ShouldContain("for screen"); + } + + [Fact] + void should_roundtrip_new_json_members() => SyntaxJson.StructurallyEqual(_application, SyntaxJson.Deserialize(SyntaxJson.Serialize(_application))).ShouldBeTrue(); + + [Fact] + void should_keep_legacy_constructor_and_deconstruction_arity() + { + var action = new ScreenActionSyntax("Retry", null, null, SourceLocation.Start); + var (command, label, navigate, location) = action; + command.ShouldEqual("Retry"); + label.ShouldBeNull(); + navigate.ShouldBeNull(); + location.ShouldEqual(SourceLocation.Start); + SyntaxJson.Serialize(action).TryGetProperty("subject", out _).ShouldBeFalse(); + SyntaxJson.Serialize(action).TryGetProperty("inputs", out _).ShouldBeFalse(); + } + + [Fact] + void should_visit_each_plain_input_and_keep_its_source_location() + { + var walker = new Syntax.for_ScreenplaySyntaxWalker.given.a_counting_walker(); + walker.VisitApplication(_application); + var plain = walker.Nodes.OfType().Single(); + var inputs = plain.Inputs.ToArray(); + inputs.Select(input => input.Name).ShouldEqual(["id", "note"]); + inputs.Select(input => input.Location.Line).ShouldEqual([6, 7]); + walker.Nodes.OfType().Count().ShouldEqual(4); + } + + [Fact] + void should_refuse_unknown_subject_values() + { + var json = SyntaxJson.Serialize(_application).GetRawText().Replace("\"Item\"", "\"Row\"", StringComparison.Ordinal); + Assert.Throws(() => SyntaxJson.Deserialize(JsonDocument.Parse(json).RootElement)); + } + + [Fact] + void should_refuse_subject_metadata_on_navigation_toolbar_items() + { + var json = SyntaxJson.Serialize(_application).GetRawText().Replace("\"syntaxKind\":\"Action\"", "\"syntaxKind\":\"Navigate\"", StringComparison.Ordinal); + Assert.Throws(() => SyntaxJson.Deserialize(JsonDocument.Parse(json).RootElement)); + } +} diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs index 3d8ac60df..0b4b5db90 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_resolving_action_subjects.cs @@ -88,5 +88,19 @@ void should_retain_a_guard_without_selecting_from_a_screen_collection() } static ScreenSyntax Screen(ApplicationSyntax application) => application.Modules.Single().Features.Single().Slices.Single().Screens.Single(); + [Fact] + void should_not_infer_a_row_from_two_identifier_inputs_in_an_assembled_snapshot() + { + var raw = _compiler.Compile(Source).Value!; + var module = raw.Modules.Single(); + var feature = module.Features.Single(); + var slice = feature.Slices.Single(); + var command = slice.Commands.Single(); + var ambiguous = command with { Properties = [.. command.Properties, command.Properties.First() with { Name = "otherId" }] }; + var snapshot = raw with { Modules = [module with { Features = [feature with { Slices = [slice with { Commands = [ambiguous] }] }] }] }; + Action(ScreenActionSubjects.Resolve(snapshot).Value!).Subject.ShouldBeNull(); + Action(raw).Subject.ShouldBeNull(); + } + static ScreenActionSyntax Action(ApplicationSyntax application) => Screen(application).Directives.OfType().Single(); } diff --git a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_composition.cs b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_composition.cs index cf9d59a57..d2d09eb34 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_composition.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_composition.cs @@ -63,7 +63,7 @@ template Shell navigate to Browse outlet detail contribute to Actions order 10 - action Register + action Register for screen contribute to Navigation section filters title "Filters" diff --git a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_release_ui_contract.cs b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_release_ui_contract.cs index c6d19fa03..db4889173 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_release_ui_contract.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_screen_release_ui_contract.cs @@ -67,7 +67,7 @@ customerName String screen BrowseInvoices data InvoiceList via query AllInvoices toolbar main - item edit action EditInvoice + item edit action EditInvoice for screen label "Edit" icon edit presentation placement "primary" diff --git a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_text_containing_quotes/and_it_is_a_screen_label.cs b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_text_containing_quotes/and_it_is_a_screen_label.cs index a859d42f4..dcaf6d7af 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_text_containing_quotes/and_it_is_a_screen_label.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_text_containing_quotes/and_it_is_a_screen_label.cs @@ -16,7 +16,7 @@ command RegisterInvoice invoiceId Uuid screen InvoiceDashboard - action RegisterInvoice + action RegisterInvoice for screen label "Register a \"draft\" invoice" """; diff --git a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_the_invoicing_sample.cs b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_the_invoicing_sample.cs index 0f1e3c00f..94ab63077 100644 --- a/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_the_invoicing_sample.cs +++ b/Source/DotNET/Screenplay/for_ScreenplayPrinter/when_printing_the_invoicing_sample.cs @@ -23,7 +23,7 @@ void Because() } [Fact] void should_reparse_successfully() => _reparsed.Success.ShouldBeTrue(); - [Fact] void should_reparse_with_the_legacy_file_warning_and_backward_reference() => _reparsed.Diagnostics.Where(diagnostic => diagnostic.Code != DiagnosticCodes.OmittedProductionDestination).Select(_ => _.Code).ShouldContainOnly(DiagnosticCodes.FileConstraintOnlySupportsUniqueness, DiagnosticCodes.EventFromLaterSlice); + [Fact] void should_reparse_with_the_legacy_file_warning_and_backward_reference() => _reparsed.Diagnostics.Where(diagnostic => diagnostic.Code is not (DiagnosticCodes.OmittedProductionDestination or DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject)).Select(_ => _.Code).ShouldContainOnly(DiagnosticCodes.FileConstraintOnlySupportsUniqueness, DiagnosticCodes.EventFromLaterSlice); [Fact] void should_preserve_exactly_the_backward_dashboard_reference() => _reparsed.Diagnostics.Where(diagnostic => diagnostic.Code == DiagnosticCodes.EventFromLaterSlice).Select(diagnostic => diagnostic.Message).ShouldEqual(_original.Diagnostics.Where(diagnostic => diagnostic.Code == DiagnosticCodes.EventFromLaterSlice).Single().Message); [Fact] void should_report_the_dashboard_reference_as_information() => _reparsed.Diagnostics.Single(diagnostic => diagnostic.Code == DiagnosticCodes.EventFromLaterSlice).Severity.ShouldEqual(DiagnosticSeverity.Information); [Fact] void should_print_the_same_text_on_a_second_pass() => _printedAgain.ShouldEqual(_printed); diff --git a/Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts b/Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts index 16654923c..e51f2e9f6 100644 --- a/Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts +++ b/Source/Screenplay/Compiler/Authoring/ActionSubjectQuickFixes.ts @@ -1,6 +1,7 @@ // Copyright (c) Cratis. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +import { Diagnostic } from '../Diagnostics/Diagnostic'; import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; import { ActionSubjectEvidence, resolveActionSubjectApplication } from '../Parsing/ActionSubjectResolution'; import { ActionSubjectInputs } from '../Parsing/ActionSubjectInputs'; @@ -13,58 +14,115 @@ import { toSyntaxJson } from '../Syntax/SyntaxJson'; import { pattern } from '../Text/patterns'; import { applyQuickFixEdits, QuickFix, QuickFixEdit, QuickFixOptions } from './QuickFixes'; -export function prepareActionSubjectQuickFixes(source: string, options: Pick): (line?: number, code?: string) => QuickFix[] { +type Options = Pick; +interface RepairContext { + source: string; + options: Options; + application: ApplicationSyntax; + diagnostics: readonly Diagnostic[]; + declarations: RefusalDeclarations; + resolver: ActionSubjectInputs; + lines: ReturnType; + ending: string; +} +interface Proposal { + subject: ScreenActionSubjectKind; + title: string; + additions?: readonly InteractionArgumentSyntax[]; +} + +export function prepareActionSubjectQuickFixes(source: string, options: Options): (line?: number, code?: string) => QuickFix[] { + if (!/^\s*(?:action\s+|item\s+\w+\s+action\s+)/mu.test(source)) return () => []; // Imported application snapshots belong to the native workspace; never guess missing declarations in a buffer. if (options.documents !== undefined && options.documents.size > 1) return () => []; const original = parseForAuthoring(source, undefined, options.placement); if (!original.success) return () => []; const declarations = new RefusalDeclarations(original.value); - const resolver = new ActionSubjectInputs(declarations, []); + const context: RepairContext = { source, options, application: original.value, diagnostics: original.diagnostics, declarations, + resolver: new ActionSubjectInputs(declarations, []), lines: splitLines(source), ending: source.includes('\r\n') ? '\r\n' : '\n' }; const evidence: ActionSubjectEvidence[] = []; resolveActionSubjectApplication(original.value, entry => evidence.push(entry)); - const lines = splitLines(source); - const ending = source.includes('\r\n') ? '\r\n' : '\n'; - const fixes: QuickFix[] = []; - for (const entry of evidence) { - if (entry.authored.subject != null || declarations.resolve(entry.command, entry.context.slice, slice => slice.commands) === null) continue; - const diagnostic = original.diagnostics.find(diagnostic => diagnostic.location.line === entry.authored.location.line && diagnostic.code === DiagnosticCodes.InferredActionSubject); - if (diagnostic === undefined) continue; - const subject = entry.effective.subject ?? 'Screen'; - const explicit = candidate(entry, subject, `Make inferred 'for ${subject.toLowerCase()}' explicit`); - if (explicit !== undefined) fixes.push(explicit); - if (original.diagnostics.some(diagnostic => diagnostic.location.line === entry.authored.location.line && diagnostic.code === DiagnosticCodes.ChangedActionSubject)) { - const authored = entry.authored.kind === 'ScreenActionSyntax' ? entry.authored.inputs ?? [] : entry.authored.parameters.map(parameter => ({ kind: 'InteractionArgumentSyntax' as const, name: parameter.name, binding: parameter.binding.path, location: parameter.location })); - const retained = resolver.legacyInputs(entry.command, authored, entry.context); - if (retained !== null) { - const legacy = candidate(entry, 'Item', 'Retain legacy row behavior explicitly', retained.slice(authored.length)); - if (legacy !== undefined) fixes.push({ ...legacy, diagnosticCode: DiagnosticCodes.ChangedActionSubject }); - } - if (explicit !== undefined) fixes.push({ ...explicit, diagnosticCode: DiagnosticCodes.ChangedActionSubject }); - } - } - return (line, code) => fixes.filter(fix => (line === undefined || fix.line === line) && (code === undefined || fix.diagnosticCode === code)); + const fixes = evidence.flatMap(entry => entryFixes(context, entry)); + return (line, code) => selectFixes(fixes, line, code); +} + +function selectFixes(fixes: QuickFix[], line?: number, code?: string): QuickFix[] { + return fixes.filter(fix => (line === undefined || fix.line === line) && (code === undefined || fix.diagnosticCode === code)); +} + +function entryFixes(context: RepairContext, entry: ActionSubjectEvidence): QuickFix[] { + if (entry.authored.subject != null || context.declarations.resolve(entry.command, entry.context.slice, slice => slice.commands) === null) return []; + if (!hasDiagnostic(context, entry, DiagnosticCodes.InferredActionSubject)) return []; + const subject = entry.effective.subject ?? 'Screen'; + const explicit = candidate(context, entry, { subject, title: `Make inferred 'for ${subject.toLowerCase()}' explicit` }); + const fixes = explicit === undefined ? [] : [explicit]; + return hasDiagnostic(context, entry, DiagnosticCodes.ChangedActionSubject) ? [...fixes, ...changedFixes(context, entry)] : fixes; +} + +function hasDiagnostic(context: RepairContext, entry: ActionSubjectEvidence, code: string): boolean { + return context.diagnostics.some(diagnostic => diagnostic.location.line === entry.authored.location.line && diagnostic.code === code); +} + +function changedFixes(context: RepairContext, entry: ActionSubjectEvidence): QuickFix[] { + const proposals: Proposal[] = [ + { subject: 'Item', title: "Use 'for item' (item-bound action)" }, + { subject: 'Screen', title: "Use 'for screen' (no selection binding)" }, + ]; + const authored = authoredInputs(entry); + const retained = context.resolver.legacyInputs(entry.command, authored, entry.context); + if (retained !== null && retained.length > authored.length) proposals.push({ subject: 'Item', title: 'Keep legacy row bindings explicitly', additions: retained.slice(authored.length) }); + return proposals.flatMap(proposal => { + const fix = candidate(context, entry, proposal); + return fix === undefined ? [] : [{ ...fix, diagnosticCode: DiagnosticCodes.ChangedActionSubject }]; + }); +} + +function authoredInputs(entry: ActionSubjectEvidence): readonly InteractionArgumentSyntax[] { + return entry.authored.kind === 'ScreenActionSyntax' ? entry.authored.inputs ?? [] : entry.authored.parameters.map(parameter => ({ kind: 'InteractionArgumentSyntax', name: parameter.name, binding: parameter.binding.path, location: parameter.location })); +} + +function candidate(context: RepairContext, entry: ActionSubjectEvidence, proposal: Proposal): QuickFix | undefined { + const line = context.lines[entry.authored.location.line - 1]; + const header = pattern(entry.authored.kind === 'ScreenActionSyntax' ? '^(\\s*action\\s+[\\w.]+)' : '^(\\s*item\\s+\\w+\\s+action\\s+[\\w.]+)').exec(line.raw); + if (header === null) return undefined; + const edits: QuickFixEdit[] = [{ path: context.options.path, start: line.startOffset + header[0].length, length: 0, text: ` for ${proposal.subject.toLowerCase()}` }]; + if (proposal.additions !== undefined) edits.push(inputEdit(context, entry, proposal.additions)); + const replacement = replacementNode(entry, proposal); + const expected = JSON.parse(JSON.stringify(context.application, (_key, value: unknown) => value === entry.authored ? replacement : value)) as ApplicationSyntax; + if (!matchesExpected(context, entry, edits, expected)) return undefined; + return { line: line.number, diagnosticCode: DiagnosticCodes.InferredActionSubject, title: proposal.title, scope: 'occurrence', edits }; +} + +function inputEdit(context: RepairContext, entry: ActionSubjectEvidence, additions: readonly InteractionArgumentSyntax[]): QuickFixEdit { + const line = context.lines[entry.authored.location.line - 1]; + const prefix = /^\s*/.exec(line.raw)![0]; + const end = actionEnd(context, entry); + const indent = context.lines.find(child => child.number > line.number && child.startOffset < end && child.raw.trim().length > 0)?.raw.match(/^\s*/)![0] ?? `${prefix} `; + const text = additions.map(input => inputLine(entry, input, indent)).join(context.ending) + context.ending; + return { path: context.options.path, start: end, length: 0, text: (end > 0 && context.source[end - 1] !== '\n' ? context.ending : '') + text }; +} + +function actionEnd(context: RepairContext, entry: ActionSubjectEvidence): number { + const line = context.lines[entry.authored.location.line - 1]; + const prefix = /^\s*/.exec(line.raw)![0]; + return context.lines.find(child => child.number > line.number && child.raw.trim().length > 0 && /^\s*/.exec(child.raw)![0].length <= prefix.length)?.startOffset ?? context.source.length; +} + +function inputLine(entry: ActionSubjectEvidence, input: InteractionArgumentSyntax, indent: string): string { + return `${indent}${entry.authored.kind === 'ScreenActionSyntax' ? 'with' : 'parameter'} ${input.name} from ${entry.authored.kind === 'ScreenActionSyntax' ? '' : 'data '}${input.binding}`; +} + +function replacementNode(entry: ActionSubjectEvidence, proposal: Proposal): ActionSubjectEvidence['authored'] { + const additions = proposal.additions ?? []; + return entry.authored.kind === 'ScreenActionSyntax' + ? { ...entry.authored, subject: proposal.subject, inputs: [...(entry.authored.inputs ?? []), ...additions] } + : { ...entry.authored, subject: proposal.subject, parameters: [...entry.authored.parameters, ...additions.map(input => ({ kind: 'ScreenNavigationParameterSyntax' as const, name: input.name, binding: { kind: 'UiBindingSyntax' as const, bindingKind: 'DataContext' as const, path: input.binding, query: null, componentId: null, componentPropertyPath: null, mode: null, nullBehavior: null, expectedValueType: null, literal: null, rawText: null, location: input.location }, location: input.location }))] }; +} - function candidate(entry: ActionSubjectEvidence, subject: ScreenActionSubjectKind, title: string, additions: readonly InteractionArgumentSyntax[] = []): QuickFix | undefined { - const line = lines[entry.authored.location.line - 1]; - const header = pattern(entry.authored.kind === 'ScreenActionSyntax' ? '^(\\s*action\\s+[\\w.]+)' : '^(\\s*item\\s+\\w+\\s+action\\s+[\\w.]+)').exec(line.raw); - if (header === null) return undefined; - const edits: QuickFixEdit[] = [{ path: options.path, start: line.startOffset + header[0].length, length: 0, text: ` for ${subject.toLowerCase()}` }]; - const prefix = /^\s*/.exec(line.raw)![0]; - const end = lines.find(child => child.number > line.number && child.raw.trim().length > 0 && /^\s*/.exec(child.raw)![0].length <= prefix.length)?.startOffset ?? source.length; - if (additions.length > 0) { - const indent = lines.find(child => child.number > line.number && child.startOffset < end && child.raw.trim().length > 0)?.raw.match(/^\s*/)![0] ?? `${prefix} `; - const text = additions.map(input => `${indent}${entry.authored.kind === 'ScreenActionSyntax' ? 'with' : 'parameter'} ${input.name} from ${entry.authored.kind === 'ScreenActionSyntax' ? '' : 'data '}${input.binding}`).join(ending) + ending; - edits.push({ path: options.path, start: end, length: 0, text: (end > 0 && source[end - 1] !== '\n' ? ending : '') + text }); - } - const replacement = entry.authored.kind === 'ScreenActionSyntax' - ? { ...entry.authored, subject, inputs: [...(entry.authored.inputs ?? []), ...additions] } - : { ...entry.authored, subject, parameters: [...entry.authored.parameters, ...additions.map(input => ({ kind: 'ScreenNavigationParameterSyntax', name: input.name, binding: { kind: 'UiBindingSyntax', bindingKind: 'DataContext', path: input.binding, query: null, componentId: null, componentPropertyPath: null, mode: null, nullBehavior: null, expectedValueType: null, literal: null, rawText: null, location: input.location }, location: input.location }))] }; - const expected = JSON.parse(JSON.stringify(original.value, (_key, value: unknown) => value === entry.authored ? replacement : value)) as ApplicationSyntax; - const edited = applyQuickFixEdits(source, edits); - if (edited === undefined) return undefined; - const parsed = parseForAuthoring(edited, undefined, options.placement); - if (!parsed.success || JSON.stringify(toSyntaxJson(parsed.value)) !== JSON.stringify(toSyntaxJson(expected))) return undefined; - if (parsed.diagnostics.some(diagnostic => diagnostic.location.line === line.number && (diagnostic.code === DiagnosticCodes.InferredActionSubject || diagnostic.code === DiagnosticCodes.ChangedActionSubject))) return undefined; - return { line: line.number, diagnosticCode: DiagnosticCodes.InferredActionSubject, title, scope: 'occurrence', edits }; - } +function matchesExpected(context: RepairContext, entry: ActionSubjectEvidence, edits: QuickFixEdit[], expected: ApplicationSyntax): boolean { + const edited = applyQuickFixEdits(context.source, edits); + if (edited === undefined) return false; + const parsed = parseForAuthoring(edited, undefined, context.options.placement); + if (!parsed.success || JSON.stringify(toSyntaxJson(parsed.value)) !== JSON.stringify(toSyntaxJson(expected))) return false; + return !parsed.diagnostics.some(diagnostic => diagnostic.location.line === entry.authored.location.line && (diagnostic.code === DiagnosticCodes.InferredActionSubject || diagnostic.code === DiagnosticCodes.ChangedActionSubject)); } diff --git a/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts index 26aaf2bba..e5636da74 100644 --- a/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts +++ b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts @@ -4,6 +4,7 @@ import { describe, expect, it } from 'vitest'; import { parse } from '../../ScreenplayCompiler'; import { applyQuickFixEdits, findQuickFixes, isQuickFixDiagnostic } from '../QuickFixes'; +import { prepareActionSubjectQuickFixes } from '../ActionSubjectQuickFixes'; const source = `concept ItemId : Uuid module Work @@ -36,18 +37,35 @@ describe('when repairing action subjects', () => { expect(fixes(edited, 'PLAY0816')).toEqual([]); }); it('should suppress legacy intent that the effective key fallback cannot represent', () => { - expect(fixes(source).map(fix => fix.title)).toEqual(["Make inferred 'for item' explicit"]); + expect(fixes(source).map(fix => fix.title)).toEqual(["Use 'for item' (item-bound action)", "Use 'for screen' (no selection binding)"]); }); it('should offer explicit legacy row inputs when name matching is provable', () => { const legacy = source.replace('rowId ItemId key', 'itemId ItemId key').replace('itemId ItemId identifier', 'itemId ItemId'); const proposals = fixes(legacy); - expect(proposals).toHaveLength(2); - const retained = proposals.find(fix => fix.title === 'Retain legacy row behavior explicitly')!; + expect(proposals).toHaveLength(3); + const retained = proposals.find(fix => fix.title === 'Keep legacy row bindings explicitly')!; const edited = applyQuickFixEdits(legacy, retained.edits)!; expect(edited).toContain('action Retry for item'); expect(edited).toContain('with itemId from item.itemId'); expect(fixes(edited)).toEqual([]); }); + it('should preserve toolbar legacy bindings with existing parameters and CRLF endings', () => { + const toolbar = source.replace('rowId ItemId key', 'itemId ItemId key') + .replace('itemId ItemId identifier', 'itemId ItemId\n name String') + .replace(' action Retry // preserve this comment\n', ' toolbar\n item retry action Retry // preserve this comment\n parameter name from data item.name') + .replaceAll('\n', '\r\n'); + const proposals = fixes(toolbar); + expect(proposals).toHaveLength(3); + const retained = proposals.find(fix => fix.title === 'Keep legacy row bindings explicitly')!; + const edited = applyQuickFixEdits(toolbar, retained.edits)!; + expect(edited).toContain('item retry action Retry for item // preserve this comment'); + expect(edited).toContain('parameter name from data item.name\r\n parameter itemId from data item.itemId\r\n'); + expect(fixes(edited)).toEqual([]); + }); + it('should not propose subject repairs when the authored clause is invalid', () => { + const invalid = source.replace('action Retry //', 'action Retry for unknown //'); + expect(prepareActionSubjectQuickFixes(invalid, {})()).toEqual([]); + }); it('should not guess declarations in imported buffer snapshots', () => { expect(findQuickFixes(source, { documents: new Map([['a.play', source], ['b.play', '']]), path: 'a.play', diagnosticCode: 'PLAY0816' })).toEqual([]); }); diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/README.md b/Source/Screenplay/Compiler/Conformance/action-subjects/README.md new file mode 100644 index 000000000..7eb225e56 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/README.md @@ -0,0 +1,20 @@ +# Action-subject consumer fixture protocol + +`native.manifest.json` and `typescript.manifest.json` enumerate the same per-screen cases. Each envelope references all five parts: authored source, raw canonical application, effective canonical application, relevant diagnostics (code, severity, message and source coordinates), and a context sidecar. `focusPath` selects the case without cropping its declarations out of the application. + +The sidecar contains the complete raw declaration tree, canonical-path locations for authored nodes, and subject relations (`path`, owning `screen`/`slice`, and nearest `data` paths). Input flags (`isIdentifier`, `isGenerated`, `isKey`), nominal concepts, optionality/cardinality, command properties, forms and qualified references remain in the application. Location paths refer to that tree, not synthetic runtime action IDs. Missing declarations stay missing; consumers must not invent identity from primitive types or names. Generated effective inputs carry the action/alternative's source location; original locations are retained. + +Both compiler profiles preserve their existing modeled syntax surfaces: native can include older native-only empty/default members. The paired specs compare every TS-modeled raw/effective member and all subject relations, and compare diagnostic code/severity/message/location. They also assert source immutability, idempotence, authored locations and explicit semantic expectations. These are compiler contracts, not renderer/runtime execution proof. + +Cases cover explicit scope and bindings, same-name compatibility and precedence, mismatched non-key names, casing, one identifier/key, unmarked foreign keys, optional/generated/primitive identifiers, multiple keys, missing keys, qualified declarations, unresolved references, forms, slots/outlets and nearest sibling scopes, missing/equally near subjects, guarded record/collection behavior, toolbar parameters, malformed/duplicate/inapplicable clauses and malformed/duplicate inputs. `RecoveredSecondIdentifier` records existing parser recovery (the second identifier flag is cleared); direct immutable-snapshot specs separately prove the resolver does not infer Item from two identifier inputs. + +## Regeneration + +The owners are: + +- Native `Syntax.Serialization.for_SyntaxJson.when_exporting_action_subject_fixture_packs.should_match_the_native_fixture_pack`. +- TS `Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts`. + +Set `SCREENPLAY_REGENERATE_ACTION_SUBJECT_FIXTURES=1` only for those specs. Regeneration intentionally fails its sentinel assertion; review outputs and rerun with the variable unset. Never hand-edit canonical outputs or sidecars. Native specs run in **Debug**; build separately, then test with `--no-build --no-restore`. Generated golden/collection/schema contracts have their own separate owner generators. + +Scene consumes a case's full raw application through native `ScreenActionSubjects.Resolve` or TS `resolveActionSubjects`. It must compare the effective result, not treat raw syntax as resolved. Absent-item availability, stable action identity and click-time item-source proofs remain Scene-owned. No runtime fields or executable semantic-model serialization were added here. diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json index d0ad78be3..c4f885c98 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.context.json @@ -321,6 +321,40 @@ "name": "Row" }, "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "CasedRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NoKeyRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + }, + "scope": null } ], "reactions": [], @@ -439,6 +473,59 @@ } ] }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "CasedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemID", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "NoKeyRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, { "kind": "ReadModelSyntax", "description": null, @@ -716,7 +803,7 @@ } ], "file": null, - "name": "MultipleIdentifiers" + "name": "RecoveredSecondIdentifier" }, { "kind": "ScreenSyntax", @@ -743,6 +830,218 @@ "file": null, "name": "AmbiguousKeys" }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "AmbiguousInferred" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "CasedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "CaseMismatch" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NoKeyRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "MissingKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Imported.Inventory.Views.Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Imported.Inventory.Views.Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Imported.Inventory.Commands.Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "QualifiedDeclarations" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Missing.Commands.Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "UnresolvedDeclaration" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenTemplateReferenceSyntax", + "name": "Detail", + "slots": [ + { + "kind": "ScreenSlotSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "actions" + } + ] + } + ], + "file": null, + "name": "SlotScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenComponentSyntax", + "behaviors": [], + "component": "scene.web.Panel", + "context": null, + "exposes": [], + "icon": null, + "name": "panel", + "outlets": [ + { + "kind": "ComponentOutletSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "detail" + } + ], + "presentation": [], + "properties": [], + "stableId": null, + "usedBehaviors": [] + } + ], + "file": null, + "name": "OutletScope" + }, { "kind": "ScreenSyntax", "directives": [ @@ -1162,25 +1461,431 @@ } ], "fileImports": [], - "forms": [], + "forms": [ + { + "kind": "FormSyntax", + "behaviors": [], + "columnMode": "Unspecified", + "columns": [], + "fields": [ + { + "kind": "FormFieldSyntax", + "composeUsing": null, + "from": null, + "label": null, + "property": "name" + } + ], + "for": "Work.Items.List.Retry", + "generationMode": "Unspecified", + "layout": null, + "name": "RetryForm", + "onSubmit": null, + "populate": null, + "usedBehaviors": [] + } + ], "isPlacement": false, "name": "Work", "screenTemplates": [], "templates": [], "usedBehaviors": [] - } - ], - "personas": [], - "policies": [], - "sampleDataPacks": [], - "seeds": [], - "systems": [], - "templates": [], - "themes": [], + }, + { + "kind": "ModuleSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "dialogTemplates": [], + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Inventory", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "Commands", + "operations": [], + "projections": [], + "queries": [], + "reactions": [], + "readModels": [], + "reducers": [], + "screens": [], + "specifications": [], + "templates": [], + "type": "StateChange" + }, + { + "kind": "SliceSyntax", + "captures": [], + "commands": [], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "Views", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + } + ], + "reducers": [], + "screens": [], + "specifications": [], + "templates": [], + "type": "StateView" + } + ], + "templates": [], + "usedBehaviors": [] + } + ], + "fileImports": [], + "forms": [], + "isPlacement": false, + "name": "Imported", + "screenTemplates": [], + "templates": [], + "usedBehaviors": [] + } + ], + "personas": [], + "policies": [], + "sampleDataPacks": [], + "seeds": [], + "systems": [], + "templates": [], + "themes": [], "triggers": [], "types": [], "uiProfiles": [] }, + "subjects": [ + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[0]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[0].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[1]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[1].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[2]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[2].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[3]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[3].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[4]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[4].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[5]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[5].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[6]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[6].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[7]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[7].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[8]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[8].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[9]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[9].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[10]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[10].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[11]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[11].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[12]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[12].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[13]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[13].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[14]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[14].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].slots[0].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[15]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[15].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[16]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[17]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[17].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[18]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[18].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[19]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[19].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[20]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2]", + "screen": "$.modules[0].features[0].slices[0].screens[21]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[21].directives[0]", + "$.modules[0].features[0].slices[0].screens[21].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[21].directives[3]", + "screen": "$.modules[0].features[0].slices[0].screens[21]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[21].directives[0]", + "$.modules[0].features[0].slices[0].screens[21].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[1]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[2]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[23].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[23]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[24].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[24]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[25].directives[0].items[0]", + "screen": "$.modules[0].features[0].slices[0].screens[25]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[26]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + } + ], "locations": [ { "path": "$", @@ -1191,1082 +1896,1450 @@ } }, { - "path": "$.concepts[0]", - "kind": "ConceptSyntax", + "path": "$.concepts[0]", + "kind": "ConceptSyntax", + "location": { + "line": 1, + "column": 1 + } + }, + { + "path": "$.concepts[1]", + "kind": "ConceptSyntax", + "location": { + "line": 2, + "column": 1 + } + }, + { + "path": "$.modules[0]", + "kind": "ModuleSyntax", + "location": { + "line": 3, + "column": 1 + } + }, + { + "path": "$.modules[0].features[0]", + "kind": "FeatureSyntax", + "location": { + "line": 6, + "column": 3 + } + }, + { + "path": "$.modules[0].features[0].slices[0]", + "kind": "SliceSyntax", + "location": { + "line": 7, + "column": 5 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0]", + "kind": "CommandSyntax", + "location": { + "line": 27, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 28, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 28, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 29, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 29, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1]", + "kind": "CommandSyntax", + "location": { + "line": 30, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 31, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 31, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2]", + "kind": "CommandSyntax", + "location": { + "line": 32, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 33, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 33, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3]", + "kind": "CommandSyntax", + "location": { + "line": 34, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 35, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 35, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4]", + "kind": "CommandSyntax", + "location": { + "line": 36, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 37, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 37, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5]", + "kind": "CommandSyntax", + "location": { + "line": 38, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 39, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 39, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 40, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 40, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0]", + "kind": "QuerySyntax", + "location": { + "line": 41, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 41, + "column": 21 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1]", + "kind": "QuerySyntax", + "location": { + "line": 42, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 42, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2]", + "kind": "QuerySyntax", + "location": { + "line": 43, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 43, + "column": 30 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3]", + "kind": "QuerySyntax", + "location": { + "line": 44, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 44, + "column": 20 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[4]", + "kind": "QuerySyntax", + "location": { + "line": 45, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[4].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 45, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[5]", + "kind": "QuerySyntax", + "location": { + "line": 46, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[5].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 46, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0]", + "kind": "ReadModelSyntax", + "location": { + "line": 8, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 9, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 9, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 10, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 10, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2]", + "kind": "PropertySyntax", + "location": { + "line": 11, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2].type", + "kind": "TypeRefSyntax", + "location": { + "line": 11, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3]", + "kind": "PropertySyntax", + "location": { + "line": 12, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3].type", + "kind": "TypeRefSyntax", "location": { - "line": 1, - "column": 1 + "line": 12, + "column": 14 } }, { - "path": "$.concepts[1]", - "kind": "ConceptSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4]", + "kind": "PropertySyntax", "location": { - "line": 2, - "column": 1 + "line": 13, + "column": 9 } }, { - "path": "$.modules[0]", - "kind": "ModuleSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4].type", + "kind": "TypeRefSyntax", "location": { - "line": 3, - "column": 1 + "line": 13, + "column": 15 } }, { - "path": "$.modules[0].features[0]", - "kind": "FeatureSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[1]", + "kind": "ReadModelSyntax", "location": { - "line": 4, - "column": 3 + "line": 14, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0]", - "kind": "SliceSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0]", + "kind": "PropertySyntax", "location": { - "line": 5, - "column": 5 + "line": 15, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0].type", + "kind": "TypeRefSyntax", "location": { - "line": 20, - "column": 7 + "line": 15, + "column": 15 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1]", "kind": "PropertySyntax", "location": { - "line": 21, + "line": 16, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1].type", "kind": "TypeRefSyntax", "location": { - "line": 21, + "line": 16, "column": 16 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[1]", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2]", "kind": "PropertySyntax", "location": { - "line": 22, + "line": 17, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[1].type", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2].type", "kind": "TypeRefSyntax", "location": { - "line": 22, + "line": 17, "column": 14 } }, { - "path": "$.modules[0].features[0].slices[0].commands[1]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[2]", + "kind": "ReadModelSyntax", "location": { - "line": 23, + "line": 18, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].commands[1].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0]", "kind": "PropertySyntax", "location": { - "line": 24, + "line": 19, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[1].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0].type", "kind": "TypeRefSyntax", "location": { - "line": 24, - "column": 18 - } - }, - { - "path": "$.modules[0].features[0].slices[0].commands[2]", - "kind": "CommandSyntax", - "location": { - "line": 25, - "column": 7 + "line": 19, + "column": 15 } }, { - "path": "$.modules[0].features[0].slices[0].commands[2].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1]", "kind": "PropertySyntax", "location": { - "line": 26, + "line": 20, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[2].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1].type", "kind": "TypeRefSyntax", "location": { - "line": 26, + "line": 20, "column": 16 } }, { - "path": "$.modules[0].features[0].slices[0].commands[3]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[3]", + "kind": "ReadModelSyntax", "location": { - "line": 27, + "line": 21, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].commands[3].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[3].properties[0]", "kind": "PropertySyntax", "location": { - "line": 28, + "line": 22, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[3].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[3].properties[0].type", "kind": "TypeRefSyntax", "location": { - "line": 28, + "line": 22, "column": 16 } }, { - "path": "$.modules[0].features[0].slices[0].commands[4]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[4]", + "kind": "ReadModelSyntax", "location": { - "line": 29, + "line": 23, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].commands[4].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[0]", "kind": "PropertySyntax", "location": { - "line": 30, + "line": 24, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[4].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[0].type", "kind": "TypeRefSyntax", "location": { - "line": 30, - "column": 16 - } - }, - { - "path": "$.modules[0].features[0].slices[0].commands[5]", - "kind": "CommandSyntax", - "location": { - "line": 31, - "column": 7 + "line": 24, + "column": 15 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[1]", "kind": "PropertySyntax", "location": { - "line": 32, + "line": 25, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[1].type", "kind": "TypeRefSyntax", "location": { - "line": 32, - "column": 16 + "line": 25, + "column": 17 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[1]", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[2]", "kind": "PropertySyntax", "location": { - "line": 33, + "line": 26, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[1].type", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[2].type", "kind": "TypeRefSyntax", "location": { - "line": 33, - "column": 18 + "line": 26, + "column": 14 } }, { - "path": "$.modules[0].features[0].slices[0].queries[0]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].screens[0]", + "kind": "ScreenSyntax", "location": { - "line": 34, + "line": 47, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].queries[0].returnType", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 34, - "column": 21 + "line": 48, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[1]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0].type", + "kind": "TypeRefSyntax", "location": { - "line": 35, - "column": 7 + "line": 48, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[1].returnType", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 35, - "column": 26 + "line": 49, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[2]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].screens[10]", + "kind": "ScreenSyntax", "location": { - "line": 36, + "line": 79, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].queries[2].returnType", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 36, - "column": 30 + "line": 80, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[3]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0].type", + "kind": "TypeRefSyntax", "location": { - "line": 37, - "column": 7 + "line": 80, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[3].returnType", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 37, - "column": 20 + "line": 81, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0]", - "kind": "ReadModelSyntax", + "path": "$.modules[0].features[0].slices[0].screens[11]", + "kind": "ScreenSyntax", "location": { - "line": 6, + "line": 82, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 7, + "line": 83, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0].type", + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 7, - "column": 15 + "line": 83, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 8, + "line": 84, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1].type", + "path": "$.modules[0].features[0].slices[0].screens[12]", + "kind": "ScreenSyntax", + "location": { + "line": 85, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 86, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 8, - "column": 16 + "line": 86, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 9, + "line": 87, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[13]", + "kind": "ScreenSyntax", "location": { - "line": 9, - "column": 18 + "line": 88, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 10, + "line": 89, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3].type", + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 10, - "column": 14 - } - }, - { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4]", - "kind": "PropertySyntax", - "location": { - "line": 11, + "line": 89, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[13].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 11, - "column": 15 + "line": 90, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1]", - "kind": "ReadModelSyntax", + "path": "$.modules[0].features[0].slices[0].screens[14]", + "kind": "ScreenSyntax", "location": { - "line": 12, + "line": 91, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 13, + "line": 92, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0].type", + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 13, - "column": 15 + "line": 92, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 14, + "line": 93, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[15]", + "kind": "ScreenSyntax", "location": { - "line": 14, - "column": 16 + "line": 94, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 15, + "line": 95, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2].type", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 15, - "column": 14 + "line": 95, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2]", - "kind": "ReadModelSyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1]", + "kind": "ScreenTemplateReferenceSyntax", "location": { - "line": 16, - "column": 7 + "line": 96, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].slots[0]", + "kind": "ScreenSlotSyntax", "location": { - "line": 17, - "column": 9 + "line": 97, + "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].slots[0].directives[0]", + "kind": "ScreenActionSyntax", "location": { - "line": 17, - "column": 15 + "line": 98, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[16]", + "kind": "ScreenSyntax", "location": { - "line": 18, - "column": 9 + "line": 99, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 18, - "column": 17 + "line": 100, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[0].type", + "kind": "TypeRefSyntax", "location": { - "line": 19, + "line": 100, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1]", + "kind": "ScreenComponentSyntax", "location": { - "line": 19, - "column": 14 + "line": 101, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0]", - "kind": "ScreenSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0]", + "kind": "ComponentOutletSyntax", "location": { - "line": 38, - "column": 7 + "line": 102, + "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0].directives[0]", - "kind": "ScreenDataSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[0]", + "kind": "ScreenActionSyntax", "location": { - "line": 39, - "column": 9 + "line": 103, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0].directives[0].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[1]", + "kind": "ScreenDataSyntax", "location": { - "line": 39, - "column": 9 + "line": 104, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", - "kind": "ScreenActionSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[1].type", + "kind": "TypeRefSyntax", "location": { - "line": 40, - "column": 9 + "line": 104, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10]", + "path": "$.modules[0].features[0].slices[0].screens[17]", "kind": "ScreenSyntax", "location": { - "line": 70, + "line": 105, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 71, + "line": 106, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 71, + "line": 106, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 72, + "line": 107, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 73, + "line": 108, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 73, + "line": 108, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 73, + "line": 108, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].otherwise", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].otherwise", "kind": "ScreenActionOtherwiseSyntax", "location": { - "line": 74, + "line": 109, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11]", + "path": "$.modules[0].features[0].slices[0].screens[18]", "kind": "ScreenSyntax", "location": { - "line": 75, + "line": 110, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 76, + "line": 111, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 76, + "line": 111, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 77, + "line": 112, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 78, + "line": 113, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 78, + "line": 113, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 78, + "line": 113, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].otherwise", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].otherwise", "kind": "ScreenActionOtherwiseSyntax", "location": { - "line": 79, + "line": 114, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12]", + "path": "$.modules[0].features[0].slices[0].screens[19]", "kind": "ScreenSyntax", "location": { - "line": 80, + "line": 115, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 81, + "line": 116, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 81, + "line": 116, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 82, + "line": 117, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 83, + "line": 118, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[0]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].arguments[0]", "kind": "InteractionArgumentSyntax", "location": { - "line": 84, + "line": 119, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[1]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].arguments[1]", "kind": "InteractionArgumentSyntax", "location": { - "line": 85, + "line": 120, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 83, + "line": 118, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 83, + "line": 118, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].otherwise", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].otherwise", "kind": "ScreenActionOtherwiseSyntax", "location": { - "line": 86, + "line": 121, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1]", + "kind": "ScreenSyntax", + "location": { + "line": 50, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 51, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 51, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 52, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[0]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 53, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[1]", + "kind": "InteractionArgumentSyntax", + "location": { + "line": 54, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13]", + "path": "$.modules[0].features[0].slices[0].screens[20]", "kind": "ScreenSyntax", "location": { - "line": 87, + "line": 122, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 88, + "line": 123, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 89, + "line": 124, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 89, + "line": 124, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 89, + "line": 124, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14]", + "path": "$.modules[0].features[0].slices[0].screens[21]", "kind": "ScreenSyntax", "location": { - "line": 90, + "line": 125, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 91, + "line": 126, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 91, + "line": 126, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[1]", "kind": "ScreenDataSyntax", "location": { - "line": 92, + "line": 127, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[1].type", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[1].type", "kind": "TypeRefSyntax", "location": { - "line": 92, + "line": 127, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 93, + "line": 128, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 94, + "line": 129, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 94, + "line": 129, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 94, + "line": 129, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[3]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[3]", "kind": "ScreenActionSyntax", "location": { - "line": 95, + "line": 130, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15]", + "path": "$.modules[0].features[0].slices[0].screens[22]", "kind": "ScreenSyntax", "location": { - "line": 96, + "line": 131, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 97, + "line": 132, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 97, + "line": 132, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1]", "kind": "ScreenSectionSyntax", "location": { - "line": 98, + "line": 133, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 99, + "line": 134, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[1]", "kind": "ScreenDataSyntax", "location": { - "line": 100, + "line": 135, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1].type", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[1].type", "kind": "TypeRefSyntax", "location": { - "line": 100, + "line": 135, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2]", "kind": "ScreenToolbarSyntax", "location": { - "line": 101, + "line": 136, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0]", "kind": "ToolbarItemSyntax", "location": { - "line": 102, + "line": 137, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0].parameters[0]", "kind": "ScreenNavigationParameterSyntax", "location": { - "line": 103, + "line": 138, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0].binding", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0].parameters[0].binding", "kind": "UiBindingSyntax", "location": { - "line": 103, + "line": 138, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[1]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[1]", "kind": "ToolbarItemSyntax", "location": { - "line": 104, + "line": 139, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[2]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[2]", "kind": "ToolbarItemSyntax", "location": { - "line": 105, + "line": 140, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[16]", + "path": "$.modules[0].features[0].slices[0].screens[23]", "kind": "ScreenSyntax", "location": { - "line": 106, + "line": 141, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[16].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[23].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 107, + "line": 142, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[17]", + "path": "$.modules[0].features[0].slices[0].screens[24]", "kind": "ScreenSyntax", "location": { - "line": 108, + "line": 143, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[17].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[24].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 109, + "line": 144, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[18]", + "path": "$.modules[0].features[0].slices[0].screens[25]", "kind": "ScreenSyntax", "location": { - "line": 110, + "line": 145, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[18].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[25].directives[0]", "kind": "ScreenToolbarSyntax", "location": { - "line": 111, + "line": 146, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[18].directives[0].items[0]", + "path": "$.modules[0].features[0].slices[0].screens[25].directives[0].items[0]", "kind": "ToolbarItemSyntax", "location": { - "line": 112, - "column": 11 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19]", - "kind": "ScreenSyntax", - "location": { - "line": 113, - "column": 7 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19].directives[0]", - "kind": "ScreenActionSyntax", - "location": { - "line": 114, - "column": 9 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[0]", - "kind": "InteractionArgumentSyntax", - "location": { - "line": 116, - "column": 11 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[1]", - "kind": "InteractionArgumentSyntax", - "location": { - "line": 117, + "line": 147, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1]", + "path": "$.modules[0].features[0].slices[0].screens[26]", "kind": "ScreenSyntax", "location": { - "line": 41, + "line": 148, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[0]", - "kind": "ScreenDataSyntax", - "location": { - "line": 42, - "column": 9 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[0].type", - "kind": "TypeRefSyntax", - "location": { - "line": 42, - "column": 9 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 43, + "line": 149, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[0]", + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0].inputs[0]", "kind": "InteractionArgumentSyntax", "location": { - "line": 44, + "line": 151, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[1]", + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0].inputs[1]", "kind": "InteractionArgumentSyntax", "location": { - "line": 45, + "line": 152, "column": 11 } }, @@ -2274,7 +3347,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2]", "kind": "ScreenSyntax", "location": { - "line": 46, + "line": 55, "column": 7 } }, @@ -2282,7 +3355,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 47, + "line": 56, "column": 9 } }, @@ -2290,7 +3363,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 47, + "line": 56, "column": 9 } }, @@ -2298,7 +3371,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 48, + "line": 57, "column": 9 } }, @@ -2306,7 +3379,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3]", "kind": "ScreenSyntax", "location": { - "line": 49, + "line": 58, "column": 7 } }, @@ -2314,7 +3387,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 50, + "line": 59, "column": 9 } }, @@ -2322,7 +3395,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 50, + "line": 59, "column": 9 } }, @@ -2330,7 +3403,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 51, + "line": 60, "column": 9 } }, @@ -2338,7 +3411,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4]", "kind": "ScreenSyntax", "location": { - "line": 52, + "line": 61, "column": 7 } }, @@ -2346,7 +3419,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 53, + "line": 62, "column": 9 } }, @@ -2354,7 +3427,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 53, + "line": 62, "column": 9 } }, @@ -2362,7 +3435,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 54, + "line": 63, "column": 9 } }, @@ -2370,7 +3443,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5]", "kind": "ScreenSyntax", "location": { - "line": 55, + "line": 64, "column": 7 } }, @@ -2378,7 +3451,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 56, + "line": 65, "column": 9 } }, @@ -2386,7 +3459,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 56, + "line": 65, "column": 9 } }, @@ -2394,7 +3467,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 57, + "line": 66, "column": 9 } }, @@ -2402,7 +3475,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6]", "kind": "ScreenSyntax", "location": { - "line": 58, + "line": 67, "column": 7 } }, @@ -2410,7 +3483,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 59, + "line": 68, "column": 9 } }, @@ -2418,7 +3491,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 59, + "line": 68, "column": 9 } }, @@ -2426,7 +3499,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 60, + "line": 69, "column": 9 } }, @@ -2434,7 +3507,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7]", "kind": "ScreenSyntax", "location": { - "line": 61, + "line": 70, "column": 7 } }, @@ -2442,7 +3515,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 62, + "line": 71, "column": 9 } }, @@ -2450,7 +3523,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 62, + "line": 71, "column": 9 } }, @@ -2458,7 +3531,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 63, + "line": 72, "column": 9 } }, @@ -2466,7 +3539,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8]", "kind": "ScreenSyntax", "location": { - "line": 64, + "line": 73, "column": 7 } }, @@ -2474,7 +3547,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 65, + "line": 74, "column": 9 } }, @@ -2482,7 +3555,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 65, + "line": 74, "column": 9 } }, @@ -2490,7 +3563,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 66, + "line": 75, "column": 9 } }, @@ -2498,7 +3571,7 @@ "path": "$.modules[0].features[0].slices[0].screens[9]", "kind": "ScreenSyntax", "location": { - "line": 67, + "line": 76, "column": 7 } }, @@ -2506,7 +3579,7 @@ "path": "$.modules[0].features[0].slices[0].screens[9].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 68, + "line": 77, "column": 9 } }, @@ -2514,7 +3587,7 @@ "path": "$.modules[0].features[0].slices[0].screens[9].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 68, + "line": 77, "column": 9 } }, @@ -2522,9 +3595,121 @@ "path": "$.modules[0].features[0].slices[0].screens[9].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 69, + "line": 78, + "column": 9 + } + }, + { + "path": "$.modules[0].forms[0]", + "kind": "FormSyntax", + "location": { + "line": 4, + "column": 3 + } + }, + { + "path": "$.modules[0].forms[0].fields[0]", + "kind": "FormFieldSyntax", + "location": { + "line": 5, + "column": 5 + } + }, + { + "path": "$.modules[1]", + "kind": "ModuleSyntax", + "location": { + "line": 153, + "column": 1 + } + }, + { + "path": "$.modules[1].features[0]", + "kind": "FeatureSyntax", + "location": { + "line": 154, + "column": 3 + } + }, + { + "path": "$.modules[1].features[0].slices[0]", + "kind": "SliceSyntax", + "location": { + "line": 155, + "column": 5 + } + }, + { + "path": "$.modules[1].features[0].slices[0].commands[0]", + "kind": "CommandSyntax", + "location": { + "line": 156, + "column": 7 + } + }, + { + "path": "$.modules[1].features[0].slices[0].commands[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 157, + "column": 9 + } + }, + { + "path": "$.modules[1].features[0].slices[0].commands[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 157, + "column": 16 + } + }, + { + "path": "$.modules[1].features[0].slices[1]", + "kind": "SliceSyntax", + "location": { + "line": 158, + "column": 5 + } + }, + { + "path": "$.modules[1].features[0].slices[1].queries[0]", + "kind": "QuerySyntax", + "location": { + "line": 161, + "column": 7 + } + }, + { + "path": "$.modules[1].features[0].slices[1].queries[0].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 161, + "column": 21 + } + }, + { + "path": "$.modules[1].features[0].slices[1].readModels[0]", + "kind": "ReadModelSyntax", + "location": { + "line": 159, + "column": 7 + } + }, + { + "path": "$.modules[1].features[0].slices[1].readModels[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 160, "column": 9 } + }, + { + "path": "$.modules[1].features[0].slices[1].readModels[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 160, + "column": 15 + } } ] } diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json index 640d35bbc..f1e67cec0 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json @@ -4,7 +4,7 @@ "severity": "error", "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", "location": { - "line": 107, + "line": 142, "column": 9 } }, @@ -13,7 +13,7 @@ "severity": "error", "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", "location": { - "line": 109, + "line": 144, "column": 9 } }, @@ -22,7 +22,7 @@ "severity": "error", "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", "location": { - "line": 112, + "line": 147, "column": 11 } }, @@ -31,34 +31,16 @@ "severity": "error", "message": "Invalid argument \u0027with itemId\u0027 - expected \u0027with \u003Cname\u003E from \u003Cbinding\u003E\u0027", "location": { - "line": 115, + "line": 150, "column": 11 } }, - { - "code": "PLAY0346", - "severity": "warning", - "message": "A guarded action requires exactly one nearest \u0027data\u0027 subject; no data or equally near data bindings leave \u0027item\u0027 unresolved", - "location": { - "line": 88, - "column": 9 - } - }, - { - "code": "PLAY0346", - "severity": "warning", - "message": "A guarded action requires exactly one nearest \u0027data\u0027 subject; no data or equally near data bindings leave \u0027item\u0027 unresolved", - "location": { - "line": 93, - "column": 9 - } - }, { "code": "PLAY0319", "severity": "error", "message": "Duplicate argument \u0027name\u0027 - supply each input only once", "location": { - "line": 117, + "line": 152, "column": 11 } }, @@ -67,7 +49,7 @@ "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { - "line": 40, + "line": 49, "column": 9 } }, @@ -76,7 +58,7 @@ "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { - "line": 40, + "line": 49, "column": 9 } }, @@ -85,7 +67,7 @@ "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { - "line": 51, + "line": 60, "column": 9 } }, @@ -94,7 +76,7 @@ "severity": "information", "message": "Action \u0027Foreign\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { - "line": 54, + "line": 63, "column": 9 } }, @@ -103,7 +85,7 @@ "severity": "warning", "message": "Action \u0027Foreign\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use tenantId from item.tenantId", "location": { - "line": 54, + "line": 63, "column": 9 } }, @@ -112,7 +94,7 @@ "severity": "information", "message": "Action \u0027Optional\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { - "line": 57, + "line": 66, "column": 9 } }, @@ -121,7 +103,7 @@ "severity": "warning", "message": "Action \u0027Optional\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", "location": { - "line": 57, + "line": 66, "column": 9 } }, @@ -130,7 +112,7 @@ "severity": "information", "message": "Action \u0027Generated\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { - "line": 60, + "line": 69, "column": 9 } }, @@ -139,7 +121,7 @@ "severity": "information", "message": "Action \u0027Primitive\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { - "line": 63, + "line": 72, "column": 9 } }, @@ -148,7 +130,7 @@ "severity": "warning", "message": "Action \u0027Primitive\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", "location": { - "line": 63, + "line": 72, "column": 9 } }, @@ -157,7 +139,7 @@ "severity": "information", "message": "Action \u0027TwoIdentifiers\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { - "line": 66, + "line": 75, "column": 9 } }, @@ -166,7 +148,7 @@ "severity": "warning", "message": "Action \u0027TwoIdentifiers\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, tenantId from item.tenantId", "location": { - "line": 66, + "line": 75, "column": 9 } }, @@ -175,16 +157,142 @@ "severity": "warning", "message": "Input \u0027itemId\u0027 of action \u0027Retry\u0027 matches several declared key fields - write an explicit binding", "location": { - "line": 69, + "line": 78, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 81, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Retry\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use name from item.name", + "location": { + "line": 81, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 84, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemID", + "location": { + "line": 84, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 87, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Retry\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", + "location": { + "line": 87, "column": 9 } }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Imported.Inventory.Commands.Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 90, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Imported.Inventory.Commands.Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use no row property", + "location": { + "line": 90, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Missing.Commands.Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", + "location": { + "line": 93, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 98, + "column": 13 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", + "location": { + "line": 98, + "column": 13 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", + "location": { + "line": 103, + "column": 13 + } + }, { "code": "PLAY0819", "severity": "warning", "message": "A guarded action \u0027for screen\u0027 cannot use a collection as \u0027item\u0027 - use a single-record data context or \u0027for item\u0027", "location": { - "line": 72, + "line": 107, + "column": 9 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "A guarded action requires exactly one nearest \u0027data\u0027 subject; no data or equally near data bindings leave \u0027item\u0027 unresolved", + "location": { + "line": 123, + "column": 9 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "A guarded action requires exactly one nearest \u0027data\u0027 subject; no data or equally near data bindings leave \u0027item\u0027 unresolved", + "location": { + "line": 128, "column": 9 } }, @@ -193,7 +301,7 @@ "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { - "line": 95, + "line": 130, "column": 9 } }, @@ -202,7 +310,7 @@ "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { - "line": 99, + "line": 134, "column": 11 } }, @@ -211,7 +319,7 @@ "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { - "line": 105, + "line": 140, "column": 11 } }, @@ -220,7 +328,7 @@ "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { - "line": 105, + "line": 140, "column": 11 } }, @@ -229,7 +337,7 @@ "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { - "line": 107, + "line": 142, "column": 9 } }, @@ -238,7 +346,16 @@ "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { - "line": 109, + "line": 144, + "column": 9 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "Action \u0027for item\u0027 requires one resolvable data subject - no item binding is inferred", + "location": { + "line": 149, "column": 9 } } diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json index a61186d3f..31603106c 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.effective.syntax.json @@ -319,6 +319,40 @@ "name": "Row" }, "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "CasedRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NoKeyRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + }, + "scope": null } ], "reactions": [], @@ -437,6 +471,59 @@ } ] }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "CasedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemID", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "NoKeyRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, { "kind": "ReadModelSyntax", "description": null, @@ -753,7 +840,7 @@ } ], "file": null, - "name": "MultipleIdentifiers" + "name": "RecoveredSecondIdentifier" }, { "kind": "ScreenSyntax", @@ -787,6 +874,260 @@ "file": null, "name": "AmbiguousKeys" }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "AmbiguousInferred" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "CasedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "CaseMismatch" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NoKeyRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "MissingKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Imported.Inventory.Views.Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Imported.Inventory.Views.Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Imported.Inventory.Commands.Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "file": null, + "name": "QualifiedDeclarations" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Missing.Commands.Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "UnresolvedDeclaration" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenTemplateReferenceSyntax", + "name": "Detail", + "slots": [ + { + "kind": "ScreenSlotSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "actions" + } + ] + } + ], + "file": null, + "name": "SlotScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenComponentSyntax", + "behaviors": [], + "component": "scene.web.Panel", + "context": null, + "exposes": [], + "icon": null, + "name": "panel", + "outlets": [ + { + "kind": "ComponentOutletSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.itemId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "detail" + } + ], + "presentation": [], + "properties": [], + "stableId": null, + "usedBehaviors": [] + } + ], + "file": null, + "name": "OutletScope" + }, { "kind": "ScreenSyntax", "directives": [ @@ -1294,12 +1635,176 @@ } ], "fileImports": [], - "forms": [], + "forms": [ + { + "kind": "FormSyntax", + "behaviors": [], + "columnMode": "Unspecified", + "columns": [], + "fields": [ + { + "kind": "FormFieldSyntax", + "composeUsing": null, + "from": null, + "label": null, + "property": "name" + } + ], + "for": "Work.Items.List.Retry", + "generationMode": "Unspecified", + "layout": null, + "name": "RetryForm", + "onSubmit": null, + "populate": null, + "usedBehaviors": [] + } + ], "isPlacement": false, "name": "Work", "screenTemplates": [], "templates": [], "usedBehaviors": [] + }, + { + "kind": "ModuleSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "dialogTemplates": [], + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Inventory", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "Commands", + "operations": [], + "projections": [], + "queries": [], + "reactions": [], + "readModels": [], + "reducers": [], + "screens": [], + "specifications": [], + "templates": [], + "type": "StateChange" + }, + { + "kind": "SliceSyntax", + "captures": [], + "commands": [], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "Views", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + } + ], + "reducers": [], + "screens": [], + "specifications": [], + "templates": [], + "type": "StateView" + } + ], + "templates": [], + "usedBehaviors": [] + } + ], + "fileImports": [], + "forms": [], + "isPlacement": false, + "name": "Imported", + "screenTemplates": [], + "templates": [], + "usedBehaviors": [] } ], "personas": [], diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.manifest.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.manifest.json new file mode 100644 index 000000000..230eaef5b --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.manifest.json @@ -0,0 +1,118 @@ +{ + "protocol": "Cratis.ActionSubjects/1", + "authored": "source.play", + "rawSyntaxJson": "native.raw.syntax.json", + "effectiveSyntaxJson": "native.effective.syntax.json", + "diagnostics": "native.diagnostics.json", + "context": "native.context.json", + "cases": [ + { + "name": "InferredItem", + "focusPath": "$.modules[0].features[0].slices[0].screens[0]" + }, + { + "name": "ExplicitItem", + "focusPath": "$.modules[0].features[0].slices[0].screens[1]" + }, + { + "name": "ScreenScope", + "focusPath": "$.modules[0].features[0].slices[0].screens[2]" + }, + { + "name": "SameName", + "focusPath": "$.modules[0].features[0].slices[0].screens[3]" + }, + { + "name": "ForeignKey", + "focusPath": "$.modules[0].features[0].slices[0].screens[4]" + }, + { + "name": "OptionalIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[5]" + }, + { + "name": "GeneratedIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[6]" + }, + { + "name": "PrimitiveIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[7]" + }, + { + "name": "RecoveredSecondIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[8]" + }, + { + "name": "AmbiguousKeys", + "focusPath": "$.modules[0].features[0].slices[0].screens[9]" + }, + { + "name": "AmbiguousInferred", + "focusPath": "$.modules[0].features[0].slices[0].screens[10]" + }, + { + "name": "CaseMismatch", + "focusPath": "$.modules[0].features[0].slices[0].screens[11]" + }, + { + "name": "MissingKey", + "focusPath": "$.modules[0].features[0].slices[0].screens[12]" + }, + { + "name": "QualifiedDeclarations", + "focusPath": "$.modules[0].features[0].slices[0].screens[13]" + }, + { + "name": "UnresolvedDeclaration", + "focusPath": "$.modules[0].features[0].slices[0].screens[14]" + }, + { + "name": "SlotScope", + "focusPath": "$.modules[0].features[0].slices[0].screens[15]" + }, + { + "name": "OutletScope", + "focusPath": "$.modules[0].features[0].slices[0].screens[16]" + }, + { + "name": "GuardedCollection", + "focusPath": "$.modules[0].features[0].slices[0].screens[17]" + }, + { + "name": "GuardedRecord", + "focusPath": "$.modules[0].features[0].slices[0].screens[18]" + }, + { + "name": "LegacyGuarded", + "focusPath": "$.modules[0].features[0].slices[0].screens[19]" + }, + { + "name": "MissingSubject", + "focusPath": "$.modules[0].features[0].slices[0].screens[20]" + }, + { + "name": "EquallyNear", + "focusPath": "$.modules[0].features[0].slices[0].screens[21]" + }, + { + "name": "Nested", + "focusPath": "$.modules[0].features[0].slices[0].screens[22]" + }, + { + "name": "InvalidClause", + "focusPath": "$.modules[0].features[0].slices[0].screens[23]" + }, + { + "name": "DuplicateClause", + "focusPath": "$.modules[0].features[0].slices[0].screens[24]" + }, + { + "name": "InapplicableClause", + "focusPath": "$.modules[0].features[0].slices[0].screens[25]" + }, + { + "name": "InvalidInput", + "focusPath": "$.modules[0].features[0].slices[0].screens[26]" + } + ] +} diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json index 844837db1..ff902b5de 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.raw.syntax.json @@ -319,6 +319,40 @@ "name": "Row" }, "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "CasedRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NoKeyRows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + }, + "scope": null } ], "reactions": [], @@ -437,6 +471,59 @@ } ] }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "CasedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemID", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "NoKeyRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, { "kind": "ReadModelSyntax", "description": null, @@ -714,7 +801,7 @@ } ], "file": null, - "name": "MultipleIdentifiers" + "name": "RecoveredSecondIdentifier" }, { "kind": "ScreenSyntax", @@ -741,6 +828,218 @@ "file": null, "name": "AmbiguousKeys" }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "AmbiguousInferred" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "CasedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "CaseMismatch" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NoKeyRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "MissingKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Imported.Inventory.Views.Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Imported.Inventory.Views.Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Imported.Inventory.Commands.Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "QualifiedDeclarations" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Missing.Commands.Retry", + "label": null, + "navigate": null + } + ], + "file": null, + "name": "UnresolvedDeclaration" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenTemplateReferenceSyntax", + "name": "Detail", + "slots": [ + { + "kind": "ScreenSlotSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "actions" + } + ] + } + ], + "file": null, + "name": "SlotScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenComponentSyntax", + "behaviors": [], + "component": "scene.web.Panel", + "context": null, + "exposes": [], + "icon": null, + "name": "panel", + "outlets": [ + { + "kind": "ComponentOutletSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "detail" + } + ], + "presentation": [], + "properties": [], + "stableId": null, + "usedBehaviors": [] + } + ], + "file": null, + "name": "OutletScope" + }, { "kind": "ScreenSyntax", "directives": [ @@ -1160,12 +1459,176 @@ } ], "fileImports": [], - "forms": [], + "forms": [ + { + "kind": "FormSyntax", + "behaviors": [], + "columnMode": "Unspecified", + "columns": [], + "fields": [ + { + "kind": "FormFieldSyntax", + "composeUsing": null, + "from": null, + "label": null, + "property": "name" + } + ], + "for": "Work.Items.List.Retry", + "generationMode": "Unspecified", + "layout": null, + "name": "RetryForm", + "onSubmit": null, + "populate": null, + "usedBehaviors": [] + } + ], "isPlacement": false, "name": "Work", "screenTemplates": [], "templates": [], "usedBehaviors": [] + }, + { + "kind": "ModuleSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "dialogTemplates": [], + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "behaviors": [], + "contributions": [], + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Inventory", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "concurrency": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "reads": [], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "Commands", + "operations": [], + "projections": [], + "queries": [], + "reactions": [], + "readModels": [], + "reducers": [], + "screens": [], + "specifications": [], + "templates": [], + "type": "StateChange" + }, + { + "kind": "SliceSyntax", + "captures": [], + "commands": [], + "constraints": [], + "description": null, + "events": [], + "file": null, + "name": "Views", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "performer": null, + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "file": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + } + ], + "reducers": [], + "screens": [], + "specifications": [], + "templates": [], + "type": "StateView" + } + ], + "templates": [], + "usedBehaviors": [] + } + ], + "fileImports": [], + "forms": [], + "isPlacement": false, + "name": "Imported", + "screenTemplates": [], + "templates": [], + "usedBehaviors": [] } ], "personas": [], diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/source.play b/Source/Screenplay/Compiler/Conformance/action-subjects/source.play index 1d8aded8a..e02f2ec1b 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/source.play +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/source.play @@ -1,6 +1,8 @@ concept ItemId : Uuid concept TenantId : Uuid module Work + form RetryForm for Work.Items.List.Retry + field name feature Items slice StateView List readmodel Row @@ -13,6 +15,11 @@ module Work rowId ItemId key itemId ItemId name String + readmodel CasedRow + rowId ItemId key + itemID ItemId + readmodel NoKeyRow + itemId ItemId readmodel AmbiguousRow rowId ItemId key otherId ItemId key @@ -35,6 +42,8 @@ module Work query NamedRows => NamedRow[] query AmbiguousRows => AmbiguousRow[] query One => Row + query CasedRows => CasedRow[] + query NoKeyRows => NoKeyRow[] screen InferredItem data Row[] via query Rows action Retry @@ -61,12 +70,38 @@ module Work screen PrimitiveIdentifier data Row[] via query Rows action Primitive - screen MultipleIdentifiers + screen RecoveredSecondIdentifier data Row[] via query Rows action TwoIdentifiers screen AmbiguousKeys data AmbiguousRow[] via query AmbiguousRows action Retry for item + screen AmbiguousInferred + data AmbiguousRow[] via query AmbiguousRows + action Retry + screen CaseMismatch + data CasedRow[] via query CasedRows + action Retry + screen MissingKey + data NoKeyRow[] via query NoKeyRows + action Retry + screen QualifiedDeclarations + data Imported.Inventory.Views.Row[] via query Imported.Inventory.Views.Rows + action Imported.Inventory.Commands.Retry + screen UnresolvedDeclaration + data Row[] via query Rows + action Missing.Commands.Retry + screen SlotScope + data Row[] via query Rows + template Detail + actions + action Retry + screen OutletScope + data Row[] via query Rows + component scene.web.Panel panel + outlet detail + action Retry + data NamedRow[] via query NamedRows screen GuardedCollection data Row[] via query Rows action "Retry" for screen @@ -115,3 +150,12 @@ module Work with itemId with name from item.name with name from $context.name +module Imported + feature Inventory + slice StateChange Commands + command Retry + itemId ItemId identifier + slice StateView Views + readmodel Row + rowId ItemId key + query Rows => Row[] diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json index f24e48faf..20661401f 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.context.json @@ -292,6 +292,38 @@ "name": "Row" }, "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "CasedRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NoKeyRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + }, + "scope": null } ], "reactions": [], @@ -408,6 +440,57 @@ } ] }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "CasedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemID", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "NoKeyRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, { "kind": "ReadModelSyntax", "description": null, @@ -674,7 +757,7 @@ "navigate": null } ], - "name": "MultipleIdentifiers" + "name": "RecoveredSecondIdentifier" }, { "kind": "ScreenSyntax", @@ -700,6 +783,209 @@ ], "name": "AmbiguousKeys" }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "AmbiguousInferred" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "CasedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "CaseMismatch" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NoKeyRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "MissingKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Imported.Inventory.Views.Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Imported.Inventory.Views.Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Imported.Inventory.Commands.Retry", + "label": null, + "navigate": null + } + ], + "name": "QualifiedDeclarations" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Missing.Commands.Retry", + "label": null, + "navigate": null + } + ], + "name": "UnresolvedDeclaration" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenTemplateReferenceSyntax", + "name": "Detail", + "slots": [ + { + "kind": "ScreenSlotSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "actions" + } + ] + } + ], + "name": "SlotScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenComponentSyntax", + "component": "scene.web.Panel", + "context": null, + "exposes": [], + "icon": null, + "name": "panel", + "outlets": [ + { + "kind": "ComponentOutletSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "detail" + } + ], + "presentation": [], + "properties": [], + "stableId": null + } + ], + "name": "OutletScope" + }, { "kind": "ScreenSyntax", "directives": [ @@ -1108,35 +1394,397 @@ "fileImports": [], "isPlacement": false, "name": "Work" - } - ], - "personas": [], - "systems": [], - "types": [] - }, - "locations": [ - { - "path": "$", - "kind": "ApplicationSyntax", - "location": { - "line": 1, - "column": 1 - } - }, - { - "path": "$.concepts[0]", - "kind": "ConceptSyntax", - "location": { - "line": 1, - "column": 1 - } - }, - { - "path": "$.concepts[1]", - "kind": "ConceptSyntax", - "location": { - "line": 2, - "column": 1 + }, + { + "kind": "ModuleSyntax", + "authorize": null, + "description": null, + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Inventory", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "name": "Commands", + "operations": [], + "projections": [], + "queries": [], + "reactions": [], + "readModels": [], + "screens": [], + "specifications": [], + "type": "StateChange" + }, + { + "kind": "SliceSyntax", + "captures": [], + "commands": [], + "constraints": [], + "description": null, + "events": [], + "name": "Views", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + } + ], + "screens": [], + "specifications": [], + "type": "StateView" + } + ] + } + ], + "fileImports": [], + "isPlacement": false, + "name": "Imported" + } + ], + "personas": [], + "systems": [], + "types": [] + }, + "subjects": [ + { + "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[0]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[0].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[1]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[1].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[2].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[2]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[2].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[3].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[3]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[3].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[4].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[4]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[4].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[5].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[5]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[5].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[6].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[6]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[6].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[7].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[7]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[7].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[8].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[8]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[8].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[9].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[9]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[9].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[10]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[10].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[11]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[11].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[12]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[12].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[13].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[13]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[13].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[14]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[14].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].slots[0].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[15]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[15].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[16]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[17]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[17].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[18]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[18].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1]", + "screen": "$.modules[0].features[0].slices[0].screens[19]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[19].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[20]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2]", + "screen": "$.modules[0].features[0].slices[0].screens[21]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[21].directives[0]", + "$.modules[0].features[0].slices[0].screens[21].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[21].directives[3]", + "screen": "$.modules[0].features[0].slices[0].screens[21]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[21].directives[0]", + "$.modules[0].features[0].slices[0].screens[21].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[1]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[1]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[2]", + "screen": "$.modules[0].features[0].slices[0].screens[22]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [ + "$.modules[0].features[0].slices[0].screens[22].directives[0]" + ] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[23].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[23]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[24].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[24]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[25].directives[0].items[0]", + "screen": "$.modules[0].features[0].slices[0].screens[25]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + }, + { + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0]", + "screen": "$.modules[0].features[0].slices[0].screens[26]", + "slice": "$.modules[0].features[0].slices[0]", + "data": [] + } + ], + "locations": [ + { + "path": "$", + "kind": "ApplicationSyntax", + "location": { + "line": 1, + "column": 1 + } + }, + { + "path": "$.concepts[0]", + "kind": "ConceptSyntax", + "location": { + "line": 1, + "column": 1 + } + }, + { + "path": "$.concepts[1]", + "kind": "ConceptSyntax", + "location": { + "line": 2, + "column": 1 } }, { @@ -1148,1058 +1796,1426 @@ } }, { - "path": "$.modules[0].features[0]", - "kind": "FeatureSyntax", + "path": "$.modules[0].features[0]", + "kind": "FeatureSyntax", + "location": { + "line": 6, + "column": 3 + } + }, + { + "path": "$.modules[0].features[0].slices[0]", + "kind": "SliceSyntax", + "location": { + "line": 7, + "column": 5 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0]", + "kind": "CommandSyntax", + "location": { + "line": 27, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 28, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 28, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 29, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[0].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 29, + "column": 14 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1]", + "kind": "CommandSyntax", + "location": { + "line": 30, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 31, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[1].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 31, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2]", + "kind": "CommandSyntax", + "location": { + "line": 32, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 33, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[2].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 33, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3]", + "kind": "CommandSyntax", + "location": { + "line": 34, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 35, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[3].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 35, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4]", + "kind": "CommandSyntax", + "location": { + "line": 36, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 37, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[4].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 37, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5]", + "kind": "CommandSyntax", + "location": { + "line": 38, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 39, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 39, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 40, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].commands[5].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 40, + "column": 18 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0]", + "kind": "QuerySyntax", + "location": { + "line": 41, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[0].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 41, + "column": 21 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1]", + "kind": "QuerySyntax", + "location": { + "line": 42, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[1].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 42, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2]", + "kind": "QuerySyntax", + "location": { + "line": 43, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[2].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 43, + "column": 30 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3]", + "kind": "QuerySyntax", + "location": { + "line": 44, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[3].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 44, + "column": 20 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[4]", + "kind": "QuerySyntax", + "location": { + "line": 45, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[4].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 45, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[5]", + "kind": "QuerySyntax", + "location": { + "line": 46, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].queries[5].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 46, + "column": 26 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0]", + "kind": "ReadModelSyntax", + "location": { + "line": 8, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 9, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 9, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 10, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1].type", + "kind": "TypeRefSyntax", "location": { - "line": 4, - "column": 3 + "line": 10, + "column": 16 } }, { - "path": "$.modules[0].features[0].slices[0]", - "kind": "SliceSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2]", + "kind": "PropertySyntax", "location": { - "line": 5, - "column": 5 + "line": 11, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2].type", + "kind": "TypeRefSyntax", "location": { - "line": 20, - "column": 7 + "line": 11, + "column": 18 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3]", "kind": "PropertySyntax", "location": { - "line": 21, + "line": 12, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3].type", "kind": "TypeRefSyntax", "location": { - "line": 21, - "column": 16 + "line": 12, + "column": 14 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[1]", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4]", "kind": "PropertySyntax", "location": { - "line": 22, + "line": 13, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[0].properties[1].type", + "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4].type", "kind": "TypeRefSyntax", "location": { - "line": 22, - "column": 14 + "line": 13, + "column": 15 } }, { - "path": "$.modules[0].features[0].slices[0].commands[1]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[1]", + "kind": "ReadModelSyntax", "location": { - "line": 23, + "line": 14, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].commands[1].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0]", "kind": "PropertySyntax", "location": { - "line": 24, + "line": 15, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[1].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0].type", "kind": "TypeRefSyntax", "location": { - "line": 24, - "column": 18 + "line": 15, + "column": 15 } }, { - "path": "$.modules[0].features[0].slices[0].commands[2]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1]", + "kind": "PropertySyntax", "location": { - "line": 25, - "column": 7 + "line": 16, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[2].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 16, + "column": 16 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2]", "kind": "PropertySyntax", "location": { - "line": 26, + "line": 17, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[2].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2].type", "kind": "TypeRefSyntax", "location": { - "line": 26, - "column": 16 + "line": 17, + "column": 14 } }, { - "path": "$.modules[0].features[0].slices[0].commands[3]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[2]", + "kind": "ReadModelSyntax", "location": { - "line": 27, + "line": 18, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].commands[3].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0]", "kind": "PropertySyntax", "location": { - "line": 28, + "line": 19, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[3].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0].type", "kind": "TypeRefSyntax", "location": { - "line": 28, + "line": 19, + "column": 15 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1]", + "kind": "PropertySyntax", + "location": { + "line": 20, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1].type", + "kind": "TypeRefSyntax", + "location": { + "line": 20, "column": 16 } }, { - "path": "$.modules[0].features[0].slices[0].commands[4]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[3]", + "kind": "ReadModelSyntax", "location": { - "line": 29, + "line": 21, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].commands[4].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[3].properties[0]", "kind": "PropertySyntax", "location": { - "line": 30, + "line": 22, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[4].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[3].properties[0].type", "kind": "TypeRefSyntax", "location": { - "line": 30, + "line": 22, "column": 16 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5]", - "kind": "CommandSyntax", + "path": "$.modules[0].features[0].slices[0].readModels[4]", + "kind": "ReadModelSyntax", "location": { - "line": 31, + "line": 23, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[0]", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[0]", "kind": "PropertySyntax", "location": { - "line": 32, + "line": 24, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[0].type", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[0].type", "kind": "TypeRefSyntax", "location": { - "line": 32, - "column": 16 + "line": 24, + "column": 15 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[1]", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[1]", "kind": "PropertySyntax", "location": { - "line": 33, + "line": 25, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].commands[5].properties[1].type", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[1].type", "kind": "TypeRefSyntax", "location": { - "line": 33, - "column": 18 + "line": 25, + "column": 17 } }, { - "path": "$.modules[0].features[0].slices[0].queries[0]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[2]", + "kind": "PropertySyntax", "location": { - "line": 34, - "column": 7 + "line": 26, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[0].returnType", + "path": "$.modules[0].features[0].slices[0].readModels[4].properties[2].type", "kind": "TypeRefSyntax", "location": { - "line": 34, - "column": 21 + "line": 26, + "column": 14 } }, { - "path": "$.modules[0].features[0].slices[0].queries[1]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].screens[0]", + "kind": "ScreenSyntax", "location": { - "line": 35, + "line": 47, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].queries[1].returnType", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 35, - "column": 26 + "line": 48, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[2]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].screens[0].directives[0].type", + "kind": "TypeRefSyntax", "location": { - "line": 36, - "column": 7 + "line": 48, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[2].returnType", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 36, - "column": 30 + "line": 49, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].queries[3]", - "kind": "QuerySyntax", + "path": "$.modules[0].features[0].slices[0].screens[10]", + "kind": "ScreenSyntax", "location": { - "line": 37, + "line": 79, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].queries[3].returnType", + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 80, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[10].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 37, - "column": 20 + "line": 80, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0]", - "kind": "ReadModelSyntax", + "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 6, + "line": 81, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[11]", + "kind": "ScreenSyntax", + "location": { + "line": 82, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 7, + "line": 83, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[0].type", + "path": "$.modules[0].features[0].slices[0].screens[11].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 7, - "column": 15 + "line": 83, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 8, + "line": 84, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[1].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[12]", + "kind": "ScreenSyntax", "location": { - "line": 8, - "column": 16 + "line": 85, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 9, + "line": 86, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[2].type", + "path": "$.modules[0].features[0].slices[0].screens[12].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 9, - "column": 18 + "line": 86, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 10, + "line": 87, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[3].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[13]", + "kind": "ScreenSyntax", "location": { - "line": 10, - "column": 14 + "line": 88, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 11, + "line": 89, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[0].properties[4].type", + "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 11, - "column": 15 + "line": 89, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1]", - "kind": "ReadModelSyntax", + "path": "$.modules[0].features[0].slices[0].screens[13].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 12, + "line": 90, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[14]", + "kind": "ScreenSyntax", + "location": { + "line": 91, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 13, + "line": 92, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[0].type", + "path": "$.modules[0].features[0].slices[0].screens[14].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 13, - "column": 15 + "line": 92, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "kind": "ScreenActionSyntax", "location": { - "line": 14, + "line": 93, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[1].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[15]", + "kind": "ScreenSyntax", "location": { - "line": 14, - "column": 16 + "line": 94, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 15, + "line": 95, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[1].properties[2].type", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 15, - "column": 14 + "line": 95, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2]", - "kind": "ReadModelSyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1]", + "kind": "ScreenTemplateReferenceSyntax", "location": { - "line": 16, - "column": 7 + "line": 96, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].slots[0]", + "kind": "ScreenSlotSyntax", "location": { - "line": 17, - "column": 9 + "line": 97, + "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[0].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].slots[0].directives[0]", + "kind": "ScreenActionSyntax", "location": { - "line": 17, - "column": 15 + "line": 98, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[16]", + "kind": "ScreenSyntax", "location": { - "line": 18, - "column": 9 + "line": 99, + "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[1].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[0]", + "kind": "ScreenDataSyntax", "location": { - "line": 18, - "column": 17 + "line": 100, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2]", - "kind": "PropertySyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[0].type", + "kind": "TypeRefSyntax", "location": { - "line": 19, + "line": 100, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].readModels[2].properties[2].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1]", + "kind": "ScreenComponentSyntax", "location": { - "line": 19, - "column": 14 + "line": 101, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0]", - "kind": "ScreenSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0]", + "kind": "ComponentOutletSyntax", "location": { - "line": 38, - "column": 7 + "line": 102, + "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0].directives[0]", - "kind": "ScreenDataSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[0]", + "kind": "ScreenActionSyntax", "location": { - "line": 39, - "column": 9 + "line": 103, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0].directives[0].type", - "kind": "TypeRefSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[1]", + "kind": "ScreenDataSyntax", "location": { - "line": 39, - "column": 9 + "line": 104, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[0].directives[1]", - "kind": "ScreenActionSyntax", + "path": "$.modules[0].features[0].slices[0].screens[16].directives[1].outlets[0].directives[1].type", + "kind": "TypeRefSyntax", "location": { - "line": 40, - "column": 9 + "line": 104, + "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10]", + "path": "$.modules[0].features[0].slices[0].screens[17]", "kind": "ScreenSyntax", "location": { - "line": 70, + "line": 105, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 71, + "line": 106, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 71, + "line": 106, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 72, + "line": 107, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 73, + "line": 108, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 73, + "line": 108, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 73, + "line": 108, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[10].directives[1].otherwise", + "path": "$.modules[0].features[0].slices[0].screens[17].directives[1].otherwise", "kind": "ScreenActionOtherwiseSyntax", "location": { - "line": 74, + "line": 109, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11]", + "path": "$.modules[0].features[0].slices[0].screens[18]", "kind": "ScreenSyntax", "location": { - "line": 75, + "line": 110, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 76, + "line": 111, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 76, + "line": 111, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 77, + "line": 112, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 78, + "line": 113, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 78, + "line": 113, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 78, + "line": 113, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[11].directives[1].otherwise", + "path": "$.modules[0].features[0].slices[0].screens[18].directives[1].otherwise", "kind": "ScreenActionOtherwiseSyntax", "location": { - "line": 79, + "line": 114, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12]", + "path": "$.modules[0].features[0].slices[0].screens[19]", "kind": "ScreenSyntax", "location": { - "line": 80, + "line": 115, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 81, + "line": 116, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 81, + "line": 116, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 82, + "line": 117, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 83, + "line": 118, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[0]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].arguments[0]", "kind": "InteractionArgumentSyntax", "location": { - "line": 84, + "line": 119, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].arguments[1]", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].arguments[1]", "kind": "InteractionArgumentSyntax", "location": { - "line": 85, + "line": 120, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 83, - "column": 11 + "line": 118, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].alternatives[0].condition.right", + "kind": "LiteralExpressionSyntax", + "location": { + "line": 118, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[19].directives[1].otherwise", + "kind": "ScreenActionOtherwiseSyntax", + "location": { + "line": 121, + "column": 11 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1]", + "kind": "ScreenSyntax", + "location": { + "line": 50, + "column": 7 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0]", + "kind": "ScreenDataSyntax", + "location": { + "line": 51, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 51, + "column": 9 + } + }, + { + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "kind": "ScreenActionSyntax", + "location": { + "line": 52, + "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].alternatives[0].condition.right", - "kind": "LiteralExpressionSyntax", + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[0]", + "kind": "InteractionArgumentSyntax", "location": { - "line": 83, + "line": 53, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[12].directives[1].otherwise", - "kind": "ScreenActionOtherwiseSyntax", + "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[1]", + "kind": "InteractionArgumentSyntax", "location": { - "line": 86, + "line": 54, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13]", + "path": "$.modules[0].features[0].slices[0].screens[20]", "kind": "ScreenSyntax", "location": { - "line": 87, + "line": 122, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 88, + "line": 123, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 89, + "line": 124, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 89, + "line": 124, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[13].directives[0].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[20].directives[0].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 89, + "line": 124, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14]", + "path": "$.modules[0].features[0].slices[0].screens[21]", "kind": "ScreenSyntax", "location": { - "line": 90, + "line": 125, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 91, + "line": 126, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 91, + "line": 126, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[1]", "kind": "ScreenDataSyntax", "location": { - "line": 92, + "line": 127, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[1].type", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[1].type", "kind": "TypeRefSyntax", "location": { - "line": 92, + "line": 127, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2]", "kind": "ScreenGuardedActionSyntax", "location": { - "line": 93, + "line": 128, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2].alternatives[0]", "kind": "ScreenActionAlternativeSyntax", "location": { - "line": 94, + "line": 129, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2].alternatives[0].condition", "kind": "ComparisonConditionSyntax", "location": { - "line": 94, + "line": 129, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[2].alternatives[0].condition.right", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[2].alternatives[0].condition.right", "kind": "LiteralExpressionSyntax", "location": { - "line": 94, + "line": 129, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[14].directives[3]", + "path": "$.modules[0].features[0].slices[0].screens[21].directives[3]", "kind": "ScreenActionSyntax", "location": { - "line": 95, + "line": 130, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15]", + "path": "$.modules[0].features[0].slices[0].screens[22]", "kind": "ScreenSyntax", "location": { - "line": 96, + "line": 131, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 97, + "line": 132, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[0].type", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 97, + "line": 132, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1]", "kind": "ScreenSectionSyntax", "location": { - "line": 98, + "line": 133, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 99, + "line": 134, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[1]", "kind": "ScreenDataSyntax", "location": { - "line": 100, + "line": 135, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[1].directives[1].type", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[1].directives[1].type", "kind": "TypeRefSyntax", "location": { - "line": 100, + "line": 135, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2]", "kind": "ScreenToolbarSyntax", "location": { - "line": 101, + "line": 136, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0]", "kind": "ToolbarItemSyntax", "location": { - "line": 102, + "line": 137, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0].parameters[0]", "kind": "ScreenNavigationParameterSyntax", "location": { - "line": 103, + "line": 138, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[0].parameters[0].binding", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[0].parameters[0].binding", "kind": "UiBindingSyntax", "location": { - "line": 103, + "line": 138, "column": 13 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[1]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[1]", "kind": "ToolbarItemSyntax", "location": { - "line": 104, + "line": 139, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[15].directives[2].items[2]", + "path": "$.modules[0].features[0].slices[0].screens[22].directives[2].items[2]", "kind": "ToolbarItemSyntax", "location": { - "line": 105, + "line": 140, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[16]", + "path": "$.modules[0].features[0].slices[0].screens[23]", "kind": "ScreenSyntax", "location": { - "line": 106, + "line": 141, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[16].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[23].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 107, + "line": 142, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[17]", + "path": "$.modules[0].features[0].slices[0].screens[24]", "kind": "ScreenSyntax", "location": { - "line": 108, + "line": 143, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[17].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[24].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 109, + "line": 144, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[18]", + "path": "$.modules[0].features[0].slices[0].screens[25]", "kind": "ScreenSyntax", "location": { - "line": 110, + "line": 145, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[18].directives[0]", + "path": "$.modules[0].features[0].slices[0].screens[25].directives[0]", "kind": "ScreenToolbarSyntax", "location": { - "line": 111, + "line": 146, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[18].directives[0].items[0]", + "path": "$.modules[0].features[0].slices[0].screens[25].directives[0].items[0]", "kind": "ToolbarItemSyntax", "location": { - "line": 112, - "column": 11 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19]", - "kind": "ScreenSyntax", - "location": { - "line": 113, - "column": 7 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19].directives[0]", - "kind": "ScreenActionSyntax", - "location": { - "line": 114, - "column": 9 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[0]", - "kind": "InteractionArgumentSyntax", - "location": { - "line": 116, - "column": 11 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[19].directives[0].inputs[1]", - "kind": "InteractionArgumentSyntax", - "location": { - "line": 117, + "line": 147, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1]", + "path": "$.modules[0].features[0].slices[0].screens[26]", "kind": "ScreenSyntax", "location": { - "line": 41, + "line": 148, "column": 7 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[0]", - "kind": "ScreenDataSyntax", - "location": { - "line": 42, - "column": 9 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[0].type", - "kind": "TypeRefSyntax", - "location": { - "line": 42, - "column": 9 - } - }, - { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[1]", + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0]", "kind": "ScreenActionSyntax", "location": { - "line": 43, + "line": 149, "column": 9 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[0]", + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0].inputs[0]", "kind": "InteractionArgumentSyntax", "location": { - "line": 44, + "line": 151, "column": 11 } }, { - "path": "$.modules[0].features[0].slices[0].screens[1].directives[1].inputs[1]", + "path": "$.modules[0].features[0].slices[0].screens[26].directives[0].inputs[1]", "kind": "InteractionArgumentSyntax", "location": { - "line": 45, + "line": 152, "column": 11 } }, @@ -2207,7 +3223,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2]", "kind": "ScreenSyntax", "location": { - "line": 46, + "line": 55, "column": 7 } }, @@ -2215,7 +3231,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 47, + "line": 56, "column": 9 } }, @@ -2223,7 +3239,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 47, + "line": 56, "column": 9 } }, @@ -2231,7 +3247,7 @@ "path": "$.modules[0].features[0].slices[0].screens[2].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 48, + "line": 57, "column": 9 } }, @@ -2239,7 +3255,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3]", "kind": "ScreenSyntax", "location": { - "line": 49, + "line": 58, "column": 7 } }, @@ -2247,7 +3263,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 50, + "line": 59, "column": 9 } }, @@ -2255,7 +3271,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 50, + "line": 59, "column": 9 } }, @@ -2263,7 +3279,7 @@ "path": "$.modules[0].features[0].slices[0].screens[3].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 51, + "line": 60, "column": 9 } }, @@ -2271,7 +3287,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4]", "kind": "ScreenSyntax", "location": { - "line": 52, + "line": 61, "column": 7 } }, @@ -2279,7 +3295,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 53, + "line": 62, "column": 9 } }, @@ -2287,7 +3303,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 53, + "line": 62, "column": 9 } }, @@ -2295,7 +3311,7 @@ "path": "$.modules[0].features[0].slices[0].screens[4].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 54, + "line": 63, "column": 9 } }, @@ -2303,7 +3319,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5]", "kind": "ScreenSyntax", "location": { - "line": 55, + "line": 64, "column": 7 } }, @@ -2311,7 +3327,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 56, + "line": 65, "column": 9 } }, @@ -2319,7 +3335,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 56, + "line": 65, "column": 9 } }, @@ -2327,7 +3343,7 @@ "path": "$.modules[0].features[0].slices[0].screens[5].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 57, + "line": 66, "column": 9 } }, @@ -2335,7 +3351,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6]", "kind": "ScreenSyntax", "location": { - "line": 58, + "line": 67, "column": 7 } }, @@ -2343,7 +3359,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 59, + "line": 68, "column": 9 } }, @@ -2351,7 +3367,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 59, + "line": 68, "column": 9 } }, @@ -2359,7 +3375,7 @@ "path": "$.modules[0].features[0].slices[0].screens[6].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 60, + "line": 69, "column": 9 } }, @@ -2367,7 +3383,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7]", "kind": "ScreenSyntax", "location": { - "line": 61, + "line": 70, "column": 7 } }, @@ -2375,7 +3391,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 62, + "line": 71, "column": 9 } }, @@ -2383,7 +3399,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 62, + "line": 71, "column": 9 } }, @@ -2391,7 +3407,7 @@ "path": "$.modules[0].features[0].slices[0].screens[7].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 63, + "line": 72, "column": 9 } }, @@ -2399,7 +3415,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8]", "kind": "ScreenSyntax", "location": { - "line": 64, + "line": 73, "column": 7 } }, @@ -2407,7 +3423,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 65, + "line": 74, "column": 9 } }, @@ -2415,7 +3431,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 65, + "line": 74, "column": 9 } }, @@ -2423,7 +3439,7 @@ "path": "$.modules[0].features[0].slices[0].screens[8].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 66, + "line": 75, "column": 9 } }, @@ -2431,7 +3447,7 @@ "path": "$.modules[0].features[0].slices[0].screens[9]", "kind": "ScreenSyntax", "location": { - "line": 67, + "line": 76, "column": 7 } }, @@ -2439,7 +3455,7 @@ "path": "$.modules[0].features[0].slices[0].screens[9].directives[0]", "kind": "ScreenDataSyntax", "location": { - "line": 68, + "line": 77, "column": 9 } }, @@ -2447,7 +3463,7 @@ "path": "$.modules[0].features[0].slices[0].screens[9].directives[0].type", "kind": "TypeRefSyntax", "location": { - "line": 68, + "line": 77, "column": 9 } }, @@ -2455,9 +3471,105 @@ "path": "$.modules[0].features[0].slices[0].screens[9].directives[1]", "kind": "ScreenActionSyntax", "location": { - "line": 69, + "line": 78, + "column": 9 + } + }, + { + "path": "$.modules[1]", + "kind": "ModuleSyntax", + "location": { + "line": 153, + "column": 1 + } + }, + { + "path": "$.modules[1].features[0]", + "kind": "FeatureSyntax", + "location": { + "line": 154, + "column": 3 + } + }, + { + "path": "$.modules[1].features[0].slices[0]", + "kind": "SliceSyntax", + "location": { + "line": 155, + "column": 5 + } + }, + { + "path": "$.modules[1].features[0].slices[0].commands[0]", + "kind": "CommandSyntax", + "location": { + "line": 156, + "column": 7 + } + }, + { + "path": "$.modules[1].features[0].slices[0].commands[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 157, + "column": 9 + } + }, + { + "path": "$.modules[1].features[0].slices[0].commands[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 157, + "column": 16 + } + }, + { + "path": "$.modules[1].features[0].slices[1]", + "kind": "SliceSyntax", + "location": { + "line": 158, + "column": 5 + } + }, + { + "path": "$.modules[1].features[0].slices[1].queries[0]", + "kind": "QuerySyntax", + "location": { + "line": 161, + "column": 7 + } + }, + { + "path": "$.modules[1].features[0].slices[1].queries[0].returnType", + "kind": "TypeRefSyntax", + "location": { + "line": 161, + "column": 21 + } + }, + { + "path": "$.modules[1].features[0].slices[1].readModels[0]", + "kind": "ReadModelSyntax", + "location": { + "line": 159, + "column": 7 + } + }, + { + "path": "$.modules[1].features[0].slices[1].readModels[0].properties[0]", + "kind": "PropertySyntax", + "location": { + "line": 160, "column": 9 } + }, + { + "path": "$.modules[1].features[0].slices[1].readModels[0].properties[0].type", + "kind": "TypeRefSyntax", + "location": { + "line": 160, + "column": 15 + } } ] } diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json index c997a4e36..cd76bfb59 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json @@ -4,7 +4,7 @@ "severity": "error", "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", "location": { - "line": 107, + "line": 142, "column": 9 } }, @@ -13,7 +13,7 @@ "severity": "error", "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", "location": { - "line": 109, + "line": 144, "column": 9 } }, @@ -22,7 +22,7 @@ "severity": "error", "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", "location": { - "line": 112, + "line": 147, "column": 11 } }, @@ -31,7 +31,16 @@ "severity": "error", "message": "Invalid argument 'with itemId' - expected 'with from '", "location": { - "line": 115, + "line": 150, + "column": 11 + } + }, + { + "code": "PLAY0319", + "severity": "error", + "message": "Duplicate argument 'name' - supply each input only once", + "location": { + "line": 152, "column": 11 } }, @@ -40,7 +49,7 @@ "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { - "line": 40, + "line": 49, "column": 9 } }, @@ -49,7 +58,7 @@ "severity": "warning", "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { - "line": 40, + "line": 49, "column": 9 } }, @@ -58,7 +67,7 @@ "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { - "line": 51, + "line": 60, "column": 9 } }, @@ -67,7 +76,7 @@ "severity": "information", "message": "Action 'Foreign' infers 'for screen' from its declared data and identifier types", "location": { - "line": 54, + "line": 63, "column": 9 } }, @@ -76,7 +85,7 @@ "severity": "warning", "message": "Action 'Foreign' now infers 'for screen'; legacy row-name matching would use tenantId from item.tenantId", "location": { - "line": 54, + "line": 63, "column": 9 } }, @@ -85,7 +94,7 @@ "severity": "information", "message": "Action 'Optional' infers 'for screen' from its declared data and identifier types", "location": { - "line": 57, + "line": 66, "column": 9 } }, @@ -94,7 +103,7 @@ "severity": "warning", "message": "Action 'Optional' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", "location": { - "line": 57, + "line": 66, "column": 9 } }, @@ -103,7 +112,7 @@ "severity": "information", "message": "Action 'Generated' infers 'for screen' from its declared data and identifier types", "location": { - "line": 60, + "line": 69, "column": 9 } }, @@ -112,7 +121,7 @@ "severity": "information", "message": "Action 'Primitive' infers 'for screen' from its declared data and identifier types", "location": { - "line": 63, + "line": 72, "column": 9 } }, @@ -121,7 +130,7 @@ "severity": "warning", "message": "Action 'Primitive' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", "location": { - "line": 63, + "line": 72, "column": 9 } }, @@ -130,7 +139,7 @@ "severity": "information", "message": "Action 'TwoIdentifiers' infers 'for item' from its declared data and identifier types", "location": { - "line": 66, + "line": 75, "column": 9 } }, @@ -139,7 +148,7 @@ "severity": "warning", "message": "Action 'TwoIdentifiers' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, tenantId from item.tenantId", "location": { - "line": 66, + "line": 75, "column": 9 } }, @@ -148,70 +157,124 @@ "severity": "warning", "message": "Input 'itemId' of action 'Retry' matches several declared key fields - write an explicit binding", "location": { - "line": 69, + "line": 78, "column": 9 } }, { - "code": "PLAY0819", + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 81, + "column": 9 + } + }, + { + "code": "PLAY0817", "severity": "warning", - "message": "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", + "message": "Action 'Retry' now infers 'for screen'; legacy row-name matching would use name from item.name", "location": { - "line": 72, + "line": 81, "column": 9 } }, { "code": "PLAY0816", "severity": "information", - "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { - "line": 95, + "line": 84, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemID", + "location": { + "line": 84, "column": 9 } }, { "code": "PLAY0816", "severity": "information", - "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", "location": { - "line": 99, - "column": 11 + "line": 87, + "column": 9 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Retry' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", + "location": { + "line": 87, + "column": 9 } }, { "code": "PLAY0816", "severity": "information", - "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "message": "Action 'Imported.Inventory.Commands.Retry' infers 'for item' from its declared data and identifier types", "location": { - "line": 105, - "column": 11 + "line": 90, + "column": 9 } }, { "code": "PLAY0817", "severity": "warning", - "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", + "message": "Action 'Imported.Inventory.Commands.Retry' now infers 'for item'; legacy row-name matching would use no row property", "location": { - "line": 105, - "column": 11 + "line": 90, + "column": 9 } }, { "code": "PLAY0816", "severity": "information", - "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "message": "Action 'Missing.Commands.Retry' infers 'for screen' from its declared data and identifier types", "location": { - "line": 107, + "line": 93, "column": 9 } }, { "code": "PLAY0816", "severity": "information", - "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "location": { + "line": 98, + "column": 13 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", + "location": { + "line": 98, + "column": 13 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { - "line": 109, + "line": 103, + "column": 13 + } + }, + { + "code": "PLAY0819", + "severity": "warning", + "message": "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", + "location": { + "line": 107, "column": 9 } }, @@ -220,7 +283,7 @@ "severity": "warning", "message": "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved", "location": { - "line": 88, + "line": 123, "column": 9 } }, @@ -229,17 +292,71 @@ "severity": "warning", "message": "A guarded action requires exactly one nearest 'data' subject; no data or equally near data bindings leave 'item' unresolved", "location": { - "line": 93, + "line": 128, "column": 9 } }, { - "code": "PLAY0319", - "severity": "error", - "message": "Duplicate argument 'name' - supply each input only once", + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 130, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { - "line": 117, + "line": 134, "column": 11 } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", + "location": { + "line": 140, + "column": 11 + } + }, + { + "code": "PLAY0817", + "severity": "warning", + "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", + "location": { + "line": 140, + "column": 11 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 142, + "column": 9 + } + }, + { + "code": "PLAY0816", + "severity": "information", + "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", + "location": { + "line": 144, + "column": 9 + } + }, + { + "code": "PLAY0346", + "severity": "warning", + "message": "Action 'for item' requires one resolvable data subject - no item binding is inferred", + "location": { + "line": 149, + "column": 9 + } } ] diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json index 3edcbf406..503079c30 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.effective.syntax.json @@ -290,6 +290,38 @@ "name": "Row" }, "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "CasedRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NoKeyRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + }, + "scope": null } ], "reactions": [], @@ -406,6 +438,57 @@ } ] }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "CasedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemID", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "NoKeyRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, { "kind": "ReadModelSyntax", "description": null, @@ -711,7 +794,7 @@ "subject": "Item" } ], - "name": "MultipleIdentifiers" + "name": "RecoveredSecondIdentifier" }, { "kind": "ScreenSyntax", @@ -744,6 +827,251 @@ ], "name": "AmbiguousKeys" }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "AmbiguousInferred" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "CasedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "CaseMismatch" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NoKeyRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "MissingKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Imported.Inventory.Views.Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Imported.Inventory.Views.Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Imported.Inventory.Commands.Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "QualifiedDeclarations" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Missing.Commands.Retry", + "label": null, + "navigate": null + } + ], + "name": "UnresolvedDeclaration" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenTemplateReferenceSyntax", + "name": "Detail", + "slots": [ + { + "kind": "ScreenSlotSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.rowId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + } + ], + "name": "actions" + } + ] + } + ], + "name": "SlotScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenComponentSyntax", + "component": "scene.web.Panel", + "context": null, + "exposes": [], + "icon": null, + "name": "panel", + "outlets": [ + { + "kind": "ComponentOutletSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.itemId", + "name": "itemId" + }, + { + "kind": "InteractionArgumentSyntax", + "binding": "item.name", + "name": "name" + } + ], + "label": null, + "navigate": null, + "subject": "Item" + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "detail" + } + ], + "presentation": [], + "properties": [], + "stableId": null + } + ], + "name": "OutletScope" + }, { "kind": "ScreenSyntax", "directives": [ @@ -1240,6 +1568,126 @@ "fileImports": [], "isPlacement": false, "name": "Work" + }, + { + "kind": "ModuleSyntax", + "authorize": null, + "description": null, + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Inventory", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "name": "Commands", + "operations": [], + "projections": [], + "queries": [], + "reactions": [], + "readModels": [], + "screens": [], + "specifications": [], + "type": "StateChange" + }, + { + "kind": "SliceSyntax", + "captures": [], + "commands": [], + "constraints": [], + "description": null, + "events": [], + "name": "Views", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + } + ], + "screens": [], + "specifications": [], + "type": "StateView" + } + ] + } + ], + "fileImports": [], + "isPlacement": false, + "name": "Imported" } ], "personas": [], diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.manifest.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.manifest.json new file mode 100644 index 000000000..a2006f5a1 --- /dev/null +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.manifest.json @@ -0,0 +1,118 @@ +{ + "protocol": "Cratis.ActionSubjects/1", + "authored": "source.play", + "rawSyntaxJson": "typescript.raw.syntax.json", + "effectiveSyntaxJson": "typescript.effective.syntax.json", + "diagnostics": "typescript.diagnostics.json", + "context": "typescript.context.json", + "cases": [ + { + "name": "InferredItem", + "focusPath": "$.modules[0].features[0].slices[0].screens[0]" + }, + { + "name": "ExplicitItem", + "focusPath": "$.modules[0].features[0].slices[0].screens[1]" + }, + { + "name": "ScreenScope", + "focusPath": "$.modules[0].features[0].slices[0].screens[2]" + }, + { + "name": "SameName", + "focusPath": "$.modules[0].features[0].slices[0].screens[3]" + }, + { + "name": "ForeignKey", + "focusPath": "$.modules[0].features[0].slices[0].screens[4]" + }, + { + "name": "OptionalIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[5]" + }, + { + "name": "GeneratedIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[6]" + }, + { + "name": "PrimitiveIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[7]" + }, + { + "name": "RecoveredSecondIdentifier", + "focusPath": "$.modules[0].features[0].slices[0].screens[8]" + }, + { + "name": "AmbiguousKeys", + "focusPath": "$.modules[0].features[0].slices[0].screens[9]" + }, + { + "name": "AmbiguousInferred", + "focusPath": "$.modules[0].features[0].slices[0].screens[10]" + }, + { + "name": "CaseMismatch", + "focusPath": "$.modules[0].features[0].slices[0].screens[11]" + }, + { + "name": "MissingKey", + "focusPath": "$.modules[0].features[0].slices[0].screens[12]" + }, + { + "name": "QualifiedDeclarations", + "focusPath": "$.modules[0].features[0].slices[0].screens[13]" + }, + { + "name": "UnresolvedDeclaration", + "focusPath": "$.modules[0].features[0].slices[0].screens[14]" + }, + { + "name": "SlotScope", + "focusPath": "$.modules[0].features[0].slices[0].screens[15]" + }, + { + "name": "OutletScope", + "focusPath": "$.modules[0].features[0].slices[0].screens[16]" + }, + { + "name": "GuardedCollection", + "focusPath": "$.modules[0].features[0].slices[0].screens[17]" + }, + { + "name": "GuardedRecord", + "focusPath": "$.modules[0].features[0].slices[0].screens[18]" + }, + { + "name": "LegacyGuarded", + "focusPath": "$.modules[0].features[0].slices[0].screens[19]" + }, + { + "name": "MissingSubject", + "focusPath": "$.modules[0].features[0].slices[0].screens[20]" + }, + { + "name": "EquallyNear", + "focusPath": "$.modules[0].features[0].slices[0].screens[21]" + }, + { + "name": "Nested", + "focusPath": "$.modules[0].features[0].slices[0].screens[22]" + }, + { + "name": "InvalidClause", + "focusPath": "$.modules[0].features[0].slices[0].screens[23]" + }, + { + "name": "DuplicateClause", + "focusPath": "$.modules[0].features[0].slices[0].screens[24]" + }, + { + "name": "InapplicableClause", + "focusPath": "$.modules[0].features[0].slices[0].screens[25]" + }, + { + "name": "InvalidInput", + "focusPath": "$.modules[0].features[0].slices[0].screens[26]" + } + ] +} diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json index 24cdb81b9..3a5c016bb 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.raw.syntax.json @@ -290,6 +290,38 @@ "name": "Row" }, "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "CasedRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + }, + "scope": null + }, + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "NoKeyRows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + }, + "scope": null } ], "reactions": [], @@ -406,6 +438,57 @@ } ] }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "CasedRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + }, + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemID", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, + { + "kind": "ReadModelSyntax", + "description": null, + "name": "NoKeyRow", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + }, { "kind": "ReadModelSyntax", "description": null, @@ -672,7 +755,7 @@ "navigate": null } ], - "name": "MultipleIdentifiers" + "name": "RecoveredSecondIdentifier" }, { "kind": "ScreenSyntax", @@ -698,6 +781,209 @@ ], "name": "AmbiguousKeys" }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "AmbiguousRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "AmbiguousRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "AmbiguousInferred" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "CasedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "CasedRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "CaseMismatch" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NoKeyRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NoKeyRow" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "MissingKey" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Imported.Inventory.Views.Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Imported.Inventory.Views.Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Imported.Inventory.Commands.Retry", + "label": null, + "navigate": null + } + ], + "name": "QualifiedDeclarations" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenActionSyntax", + "command": "Missing.Commands.Retry", + "label": null, + "navigate": null + } + ], + "name": "UnresolvedDeclaration" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenTemplateReferenceSyntax", + "name": "Detail", + "slots": [ + { + "kind": "ScreenSlotSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + } + ], + "name": "actions" + } + ] + } + ], + "name": "SlotScope" + }, + { + "kind": "ScreenSyntax", + "directives": [ + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "Rows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + } + }, + { + "kind": "ScreenComponentSyntax", + "component": "scene.web.Panel", + "context": null, + "exposes": [], + "icon": null, + "name": "panel", + "outlets": [ + { + "kind": "ComponentOutletSyntax", + "directives": [ + { + "kind": "ScreenActionSyntax", + "command": "Retry", + "label": null, + "navigate": null + }, + { + "kind": "ScreenDataSyntax", + "by": null, + "query": "NamedRows", + "type": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "NamedRow" + } + } + ], + "name": "detail" + } + ], + "presentation": [], + "properties": [], + "stableId": null + } + ], + "name": "OutletScope" + }, { "kind": "ScreenSyntax", "directives": [ @@ -1106,6 +1392,126 @@ "fileImports": [], "isPlacement": false, "name": "Work" + }, + { + "kind": "ModuleSyntax", + "authorize": null, + "description": null, + "features": [ + { + "kind": "FeatureSyntax", + "authorize": null, + "description": null, + "features": [], + "fileImports": [], + "isPlacement": false, + "name": "Inventory", + "slices": [ + { + "kind": "SliceSyntax", + "captures": [], + "commands": [ + { + "kind": "CommandSyntax", + "authorize": null, + "description": null, + "handler": null, + "name": "Retry", + "produces": [], + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": true, + "name": "itemId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ], + "response": null, + "stream": null, + "streamCandidates": [], + "validations": [] + } + ], + "constraints": [], + "description": null, + "events": [], + "name": "Commands", + "operations": [], + "projections": [], + "queries": [], + "reactions": [], + "readModels": [], + "screens": [], + "specifications": [], + "type": "StateChange" + }, + { + "kind": "SliceSyntax", + "captures": [], + "commands": [], + "constraints": [], + "description": null, + "events": [], + "name": "Views", + "operations": [], + "projections": [], + "queries": [ + { + "kind": "QuerySyntax", + "authorize": null, + "by": null, + "description": null, + "filters": [], + "isObservable": false, + "name": "Rows", + "returnType": { + "kind": "TypeRefSyntax", + "isCollection": true, + "isOptional": false, + "name": "Row" + }, + "scope": null + } + ], + "reactions": [], + "readModels": [ + { + "kind": "ReadModelSyntax", + "description": null, + "name": "Row", + "properties": [ + { + "kind": "PropertySyntax", + "isGenerated": false, + "isIdentifier": false, + "isKey": true, + "name": "rowId", + "type": { + "kind": "TypeRefSyntax", + "isCollection": false, + "isOptional": false, + "name": "ItemId" + } + } + ] + } + ], + "screens": [], + "specifications": [], + "type": "StateView" + } + ] + } + ], + "fileImports": [], + "isPlacement": false, + "name": "Imported" } ], "personas": [], diff --git a/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts b/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts index 68e535195..433e840a9 100644 --- a/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts +++ b/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts @@ -6,6 +6,9 @@ import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; import { parse } from '../../ScreenplayCompiler'; import { resolveActionSubjects } from '../../ScreenActionSubjects'; +import { ScreenActionSyntax } from '../../Syntax/Screens'; +import { ScreenplaySyntaxWalker } from '../../Syntax/ScreenplaySyntaxWalker'; +import { SyntaxNode } from '../../Syntax/SyntaxNode'; import { toSyntaxJson } from '../../Syntax/SyntaxJson'; const directory = fileURLToPath(new URL('../action-subjects/', import.meta.url)); @@ -29,11 +32,39 @@ function locations(value: unknown, path: string): LocatedNode[] { return [...own, ...Object.entries(node).filter(([name]) => name !== 'location').flatMap(([name, child]) => locations(child, `${path}.${name}`))]; } +interface SubjectScope { screen: string | null; slice: string | null; data: readonly string[] } + +function subjects(value: unknown, path: string, inherited: SubjectScope): unknown[] { + if (Array.isArray(value)) return value.flatMap((child, index) => subjects(child, `${path}[${index}]`, inherited)); + if (value === null || typeof value !== 'object') return []; + const node = value as Record; + let scope = subjectScope(node, path, inherited); + if (Array.isArray(node.directives)) { + const local = node.directives.flatMap((child: { kind: string }, index) => child.kind === 'ScreenDataSyntax' ? [`${path}.directives[${index}]`] : []); + if (local.length > 0) scope = { ...scope, data: local }; + } + const own = ['ScreenActionSyntax', 'ScreenGuardedActionSyntax', 'ToolbarItemSyntax'].includes(String(node.kind)) ? [{ path, ...scope }] : []; + return [...own, ...Object.entries(node).flatMap(([name, child]) => subjects(child, `${path}.${name}`, scope))]; +} + +function subjectScope(node: Record, path: string, inherited: SubjectScope): SubjectScope { + switch (node.kind) { + case 'SliceSyntax': return { ...inherited, slice: path }; + case 'ScreenSyntax': return { ...inherited, screen: path, data: [] }; + case 'ScreenContributionSyntax': return { ...inherited, data: [] }; + default: return inherited; + } +} + const exports = { 'raw.syntax': raw, 'effective.syntax': toSyntaxJson(effective), + manifest: { + protocol: 'Cratis.ActionSubjects/1', authored: 'source.play', rawSyntaxJson: 'typescript.raw.syntax.json', effectiveSyntaxJson: 'typescript.effective.syntax.json', diagnostics: 'typescript.diagnostics.json', context: 'typescript.context.json', + cases: compiled.value.modules[0].features[0].slices[0].screens.map((screen, index) => ({ name: screen.name, focusPath: `$.modules[0].features[0].slices[0].screens[${index}]` })), + }, diagnostics: compiled.diagnostics.filter(diagnostic => relevant.has(diagnostic.code)).map(diagnostic => ({ code: diagnostic.code, severity: diagnostic.severity, message: diagnostic.message, location: { line: diagnostic.location.line, column: diagnostic.location.column } })), - context: { source: 'source.play', application: raw, locations: locations(compiled.value, '$').sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0) }, + context: { source: 'source.play', application: raw, subjects: subjects(raw, '$', { screen: null, slice: null, data: [] }), locations: locations(compiled.value, '$').sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0) }, }; const regenerate = process.env.SCREENPLAY_REGENERATE_ACTION_SUBJECT_FIXTURES === '1'; @@ -41,8 +72,37 @@ if (regenerate) { for (const [name, value] of Object.entries(exports)) writeFileSync(`${directory}typescript.${name}.json`, `${JSON.stringify(value, null, 2)}\n`); } +class ActionCollector extends ScreenplaySyntaxWalker { + readonly actions: ScreenActionSyntax[] = []; + override visitNode(node: SyntaxNode): void { if (node.kind === 'ScreenActionSyntax') this.actions.push(node as ScreenActionSyntax); } +} + +function action(name: string): ScreenActionSyntax { + const screen = effective.modules[0].features[0].slices[0].screens.find(screen => screen.name === name)!; + const walker = new ActionCollector(); + walker.visitScreen(screen); + expect(walker.actions).toHaveLength(1); + return walker.actions[0]; +} + describe('when exporting action subject fixture packs', () => { + for (const [screen, binding] of [['InferredItem', 'item.rowId'], ['SameName', 'item.itemId'], ['CaseMismatch', 'item.rowId'], ['QualifiedDeclarations', 'item.rowId'], ['SlotScope', 'item.rowId'], ['OutletScope', 'item.itemId']]) { + it(`should resolve nominal identity in ${screen}`, () => { + expect(action(screen).subject).toBe('Item'); + expect(action(screen).inputs!.find(input => input.name === 'itemId')!.binding).toBe(binding); + }); + } + for (const screen of ['ForeignKey', 'OptionalIdentifier', 'GeneratedIdentifier', 'PrimitiveIdentifier', 'AmbiguousInferred', 'MissingKey', 'UnresolvedDeclaration']) { + it(`should not invent identity in ${screen}`, () => { + expect(action(screen).subject ?? 'Screen').toBe('Screen'); + expect(action(screen).inputs ?? []).toEqual([]); + }); + } it('should preserve authored syntax', () => expect(toSyntaxJson(compiled.value)).toEqual(raw)); + it('should retain authored source locations', () => { + const resolved = new Map(locations(effective, '$').map(entry => [entry.path, entry.location])); + for (const entry of locations(compiled.value, '$')) expect(resolved.get(entry.path)).toEqual(entry.location); + }); it('should be idempotent', () => expect(toSyntaxJson(resolveActionSubjects(effective).value)).toEqual(toSyntaxJson(effective))); for (const [name, value] of Object.entries(exports)) { it(`should retain the typescript ${name} fixture`, () => { diff --git a/Source/Screenplay/Compiler/Conformance/library-sample.syntax.json b/Source/Screenplay/Compiler/Conformance/library-sample.syntax.json index 180554f91..ead4cd251 100644 --- a/Source/Screenplay/Compiler/Conformance/library-sample.syntax.json +++ b/Source/Screenplay/Compiler/Conformance/library-sample.syntax.json @@ -838,13 +838,22 @@ "kind": "ScreenActionSyntax", "command": "AddBook", "label": null, - "navigate": null + "navigate": null, + "subject": "Screen" }, { "kind": "ScreenActionSyntax", "command": "BorrowBook", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.bookId", + "name": "bookId" + } + ], "label": null, - "navigate": null + "navigate": null, + "subject": "Item" } ], "name": "BookCatalog" @@ -2674,8 +2683,16 @@ { "kind": "ScreenActionSyntax", "command": "ReturnBook", + "inputs": [ + { + "kind": "InteractionArgumentSyntax", + "binding": "item.bookId", + "name": "bookId" + } + ], "label": null, - "navigate": null + "navigate": null, + "subject": "Item" } ], "name": "MyLoans" diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts index 56a10fae6..358c9dabc 100644 --- a/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; -import { ScreenActionSubjectKind } from '../Syntax/Screens'; +import { InteractionArgumentSyntax, ScreenActionSubjectKind } from '../Syntax/Screens'; import { stringBodyPattern, unescapeString } from '../Text/StringLiteral'; import { pattern } from '../Text/patterns'; import { ParserContext } from './ParserContext'; @@ -12,6 +12,16 @@ const word = new RegExp(pattern(`"${stringBodyPattern}"|\\S+`).source, 'gu'); const label = pattern(`^label\\s+(?:"(${stringBodyPattern})"|(\\$strings\\.\\w+(?:\\.\\w+)*))$`); const clause = pattern('^for\\s+(item|screen)$'); +export function parsePlainActionInput(context: ParserContext, line: SourceLine, inputs: readonly InteractionArgumentSyntax[]): InteractionArgumentSyntax | undefined { + const input = pattern('^with\\s+([A-Za-z_]\\w*)\\s+from\\s+(.+)$').exec(line.content); + if (input === null) { + context.error(DiagnosticCodes.InvalidInteractionArgument, `Invalid argument '${line.content}' - expected 'with from '`, locationOf(line)); + return undefined; + } + if (inputs.some(argument => argument.name === input[1])) context.error(DiagnosticCodes.InvalidInteractionArgument, `Duplicate argument '${input[1]}' - supply each input only once`, locationOf(line)); + return { kind: 'InteractionArgumentSyntax', name: input[1], binding: input[2].trim(), location: locationOf(line) }; +} + export function parseSubjectClause(context: ParserContext, line: SourceLine, action: boolean): { header: string; subject?: ScreenActionSubjectKind; label?: string } { const words = [...line.content.matchAll(word)]; const clauses = words.filter(part => part[0] === 'for'); diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts index bb62ad27e..bbd3ce484 100644 --- a/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectInputs.ts @@ -74,12 +74,17 @@ export class ActionSubjectInputs { for (const input of this.command(command, context).filter(input => !input.isGenerated)) { if (result.some(argument => argument.name === input.name)) continue; const matches = properties.filter(property => property.name.toLowerCase() === input.name.toLowerCase()); - if (matches.length > 1 || (matches.length === 0 && this.keys(input, properties).length > 0)) return null; + if (!this.legacyMatchIsSafe(input, properties, matches.length)) return null; if (matches.length === 1) result.push({ kind: 'InteractionArgumentSyntax', name: input.name, binding: `item.${matches[0].name}`, location: context.location }); } return result; } + private legacyMatchIsSafe(input: PropertySyntax, properties: readonly PropertySyntax[], matches: number): boolean { + if (matches > 1) return false; + return matches > 0 || this.keys(input, properties).length === 0; + } + inputs(command: string, authored: readonly InteractionArgumentSyntax[], context: ActionSubjectContext): readonly InteractionArgumentSyntax[] { const result = [...authored]; if (context.data.length !== 1) return result; diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts index b52a5a55f..269e1981b 100644 --- a/Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectResolution.ts @@ -47,19 +47,20 @@ export function resolveActionSubjectApplication(application: ApplicationSyntax, otherwise: fallback !== null && fallback.command !== null ? { ...fallback, arguments: resolver.inputs(fallback.command, fallback.arguments, { ...context, location: fallback.location }) } : fallback, }; }; + const plain = (node: ScreenActionSyntax, context: ActionSubjectContext): ScreenActionSyntax => { + const subject = resolver.subject(node.subject, node.command, (node.inputs ?? []).map(input => input.name), context); + const inputs = subject === 'Item' && hasSubject(context, false) ? resolver.inputs(node.command, node.inputs ?? [], context) : node.inputs; + const effective = subject == null && inputs === node.inputs ? node : { ...node, subject, ...(inputs === undefined ? {} : { inputs }) }; + observe?.({ authored: node, effective, command: node.command, context }); + return effective; + }; const body = (directives: readonly ScreenDirectiveSyntax[], inherited: ActionSubjectContext): readonly ScreenDirectiveSyntax[] => { const local = directives.filter((node): node is Extract => node.kind === 'ScreenDataSyntax'); const scope = { ...inherited, data: local.length > 0 ? local : inherited.data }; return directives.map(node => { const context = { ...scope, location: node.location }; switch (node.kind) { - case 'ScreenActionSyntax': { - const subject = resolver.subject(node.subject, node.command, (node.inputs ?? []).map(input => input.name), context); - const inputs = subject === 'Item' && hasSubject(context, false) ? resolver.inputs(node.command, node.inputs ?? [], context) : node.inputs; - const effective = subject == null && inputs === node.inputs ? node : { ...node, subject, inputs }; - observe?.({ authored: node, effective, command: node.command, context }); - return effective; - } + case 'ScreenActionSyntax': return plain(node, context); case 'ScreenGuardedActionSyntax': return guarded(node, context); case 'ScreenToolbarSyntax': return { ...node, items: node.items.map(item => toolbar(item, { ...context, location: item.location })) }; case 'ScreenSectionSyntax': return { ...node, directives: body(node.directives, scope) }; @@ -71,7 +72,7 @@ export function resolveActionSubjectApplication(application: ApplicationSyntax, }; const screen = (node: ScreenSyntax, slice: SliceSyntax): ScreenSyntax => { const context = { data: [], slice, location: node.location }; - return { ...node, directives: body(node.directives, context), contributions: node.contributions?.map(contribution => ({ ...contribution, directives: body(contribution.directives, context) })) }; + return { ...node, directives: body(node.directives, context), ...(node.contributions === undefined ? {} : { contributions: node.contributions.map(contribution => ({ ...contribution, directives: body(contribution.directives, context) })) }) }; }; const feature = (node: FeatureSyntax): FeatureSyntax => ({ ...node, features: node.features.map(feature), slices: node.slices.map(slice => ({ ...slice, screens: slice.screens.map(node => screen(node, slice)) })) }); const value = { ...application, modules: application.modules.map(module => ({ ...module, features: module.features.map(feature) })) }; diff --git a/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts b/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts index 298bb0c52..0c2bf7121 100644 --- a/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts +++ b/Source/Screenplay/Compiler/Parsing/GuardedActionInputs.ts @@ -18,10 +18,7 @@ export function viewProperties(name: string, slice: SliceSyntax | undefined, dec export function validateArguments(commandName: string, arguments_: readonly InteractionArgumentSyntax[], properties: readonly PropertySyntax[] | null, slice: SliceSyntax | undefined, declarations: RefusalDeclarations, context: ParserContext): void { const command = declarations.resolve(commandName, slice, candidate => candidate.commands)?.node; - const names = new Set(); for (const argument of arguments_) { - if (names.has(argument.name)) context.error(DiagnosticCodes.InvalidInteractionArgument, `Duplicate argument '${argument.name}' - supply each input only once`, argument.location); - names.add(argument.name); const inputs = command?.properties.filter(property => property.name === argument.name); if (inputs?.length === 0) context.warning(DiagnosticCodes.UnknownActionArgumentProperty, `Command '${commandName}' has no argument property '${argument.name}'`, argument.location); const subjectProperty = validateItemPath(argument.binding, argument.location, properties, slice, declarations, context, true); diff --git a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts index 2699a68d0..50dcbe6ce 100644 --- a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts +++ b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts @@ -12,7 +12,7 @@ import { AuthorizeSyntax } from '../Syntax/Authorization'; import { stringBodyPattern, unescapeString } from '../Text/StringLiteral'; import { pattern } from '../Text/patterns'; import { parseAuthorize } from './AuthorizeParser'; -import { parseSubjectClause } from './ActionSubjectClause'; +import { parsePlainActionInput, parseSubjectClause } from './ActionSubjectClause'; import { InteractionArgumentSyntax } from '../Syntax/Screens'; import { parseFencedText } from './CodeBlockParser'; import { parseMappingSource } from './ExpressionParser'; @@ -184,9 +184,8 @@ function parseAction(context: ParserContext, line: SourceLine): ScreenActionSynt } else if (firstWord(child.content) === 'navigate') { target = parseNavigate(context, child.content, child) ?? null; } else if (firstWord(child.content) === 'with') { - const input = pattern('^with\\s+([A-Za-z_]\\w*)\\s+from\\s+(.+)$').exec(child.content); - if (input !== null) inputs.push({ kind: 'InteractionArgumentSyntax', name: input[1], binding: input[2].trim(), location: locationOf(child) }); - else context.error(DiagnosticCodes.InvalidInteractionArgument, `Invalid argument '${child.content}' - expected 'with from '`, locationOf(child)); + const input = parsePlainActionInput(context, child, inputs); + if (input !== undefined) inputs.push(input); } else { context.error(DiagnosticCodes.UnknownActionDirective, `Unexpected '${child.content}' in action - expected 'label "..."' or 'navigate to ...'`, locationOf(child)); } diff --git a/Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts b/Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts new file mode 100644 index 000000000..d7a71abe2 --- /dev/null +++ b/Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts @@ -0,0 +1,64 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { describe, expect, it } from 'vitest'; +import { parse } from '../../ScreenplayCompiler'; +import { ApplicationSyntax } from '../Structure'; +import { ScreenActionSyntax } from '../Screens'; +import { decodeExactSyntaxJson, InvalidSyntaxJson } from '../StrictSyntaxJson'; +import { toSyntaxJson } from '../SyntaxJson'; +import { ScreenplaySyntaxWalker } from '../ScreenplaySyntaxWalker'; +import { SyntaxNode } from '../SyntaxNode'; + +const source = `module Work + feature Items + slice StateView Details + screen Details + action Retry for item label "Retry for screen" + with id from item.foreignKey + with note from $context.note + navigate to Details + action "Choose" for screen + when item.ready == true execute Retry + with id from item.foreignKey + otherwise execute Release + with id from item.foreignKey + toolbar + item retry action Retry for screen label "Try" + parameter id from item.foreignKey +`; +const raw = parse(source).value; +const action = (application: ApplicationSyntax) => application.modules[0].features[0].slices[0].screens[0].directives[0] as ScreenActionSyntax; +const wire = JSON.stringify(toSyntaxJson(parse(`numbers exact\n${source}`).value)); + +class CountingWalker extends ScreenplaySyntaxWalker { + readonly nodes: SyntaxNode[] = []; + override visitNode(node: SyntaxNode): void { this.nodes.push(node); } +} + +describe('when preserving action subject contracts', () => { + it('should strictly restore new metadata and ordered inputs', () => { + const restored = decodeExactSyntaxJson(wire) as ApplicationSyntax; + expect(toSyntaxJson(action(restored))).toMatchObject(toSyntaxJson(action(raw)) as object); + expect(action(restored).inputs!.map(input => input.name)).toEqual(['id', 'note']); + }); + it('should omit legacy default additions', () => { + const legacy = parse(source.replace(' for item', '').replace(' with id from item.foreignKey\n with note from $context.note\n', '')).value; + const encoded = toSyntaxJson(action(legacy)); + expect(encoded).not.toHaveProperty('subject'); + expect(encoded).not.toHaveProperty('inputs'); + }); + it('should refuse unknown enum values', () => expect(() => decodeExactSyntaxJson(wire.replace('"Item"', '"Row"'))).toThrow(InvalidSyntaxJson)); + it('should refuse subject metadata on non-action toolbar items', () => expect(() => decodeExactSyntaxJson(wire.replace('"syntaxKind":"Action"', '"syntaxKind":"Navigate"'))).toThrow(InvalidSyntaxJson)); + it('should walk plain inputs and preserve authored locations', () => { + const walker = new CountingWalker(); + walker.visitApplication(raw); + expect(walker.nodes.filter(node => node.kind === 'InteractionArgumentSyntax')).toHaveLength(4); + expect(action(raw).inputs!.map(input => input.location.line)).toEqual([6, 7]); + }); + for (const header of ['action Retry for', 'action Retry for planet', 'action Retry for item for screen', 'toolbar\n item go navigate to Details for item']) { + it(`should reject malformed or inapplicable scope: ${header}`, () => { + expect(parse(source.replace('action Retry for item label "Retry for screen"', header)).diagnostics.some(diagnostic => diagnostic.code === 'PLAY0815')).toBe(true); + }); + } +}); diff --git a/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts b/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts index 200a489c9..9a428246a 100644 --- a/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts +++ b/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts @@ -51,7 +51,7 @@ describe('when parsing screens', () => { screens = result.value.modules[0].features[0].slices[0].screens; }); - it('should report nothing', () => result.diagnostics.should.deep.equal([])); + it('should explain the omitted action subject', () => result.diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity]).should.deep.equal([['PLAY0816', 'information']])); it('should read both screens', () => screens.map(screen => screen.name).should.deep.equal(['Invoices', 'Details'])); it('should read the directives in order', () => screens[0].directives.map(directive => directive.kind).should.deep.equal([ @@ -123,7 +123,7 @@ describe('when parsing screen release UI bindings', () => { component = result.value.modules[0].features[0].slices[0].screens[0].directives[1] as import('../Syntax/Screens').ScreenComponentSyntax; }); - it('should report nothing', () => result.diagnostics.should.deep.equal([])); + it('should explain the omitted toolbar action subject', () => result.diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity]).should.deep.equal([['PLAY0816', 'information']])); it('should read toolbar parameters as component bindings', () => toolbar.items[0].parameters[0].binding.should.deep.include({ bindingKind: 'ComponentProperty', componentId: 'invoices', path: 'selectedItem.id' })); it('should read toolbar presentation', () => toolbar.items[1].presentation[0].value!.should.equal('primary')); it('should read component query context', () => component.context!.should.deep.include({ bindingKind: 'QueryResult', query: 'AllInvoices', path: 'items' })); diff --git a/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts b/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts index d8cace0b6..9f6cae0f1 100644 --- a/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts +++ b/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts @@ -68,6 +68,11 @@ describe('when parsing the repository samples', () => { `${join(eventRoutes, 'specifications/source/module.play')}:50 PLAY0549 Stream 'Account.Notes' is NotFound; routing requires one physical source and stream.`, `${join(corpus, 'GeneratedConceptRules/v20/source/declarations.play')}:8 PLAY0699 Match pattern: lookaround at offset 1. ${portableMatchSuggestions.lookaround}`, `${generatedInputSource}:10 PLAY0485 Generated property 'projectId' cannot be supplied as request or form input.`, + // Action-subject packs include deliberate parser recovery and malformed clause/input cases. + `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:40 PLAY0036 Command 'TwoIdentifiers' already marks 'itemId' as identifier - only one property can be the identifier`, + ...[142, 144, 147].map(line => `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:${line} PLAY0815 Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action`), + `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:150 PLAY0319 Invalid argument 'with itemId' - expected 'with from '`, + `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:152 PLAY0319 Duplicate argument 'name' - supply each input only once`, // The metadata-only fixture deliberately declares no operational public output. `${join(repository, 'Source/Screenplay/Compiler/Conformance/public-events.play')}:6 PLAY0609 Outbound Translate slice 'PublishInvoice' must produce exactly one local public event type; found 0.` ]); diff --git a/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts index a82d2bbf9..87d595548 100644 --- a/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts +++ b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts @@ -41,6 +41,16 @@ describe('when resolving action subjects', () => { (action(resolveActionSubjects(parse(source.replace('ItemId identifier', replacement)).value).value).subject ?? 'Screen').should.equal('Screen'); }); } + it('should not infer a row from two identifier inputs in an assembled snapshot', () => { + const raw = parse(source).value; + const module = raw.modules[0]; + const feature = module.features[0]; + const slice = feature.slices[0]; + const command = slice.commands[0]; + const ambiguous = { ...command, properties: [...command.properties, { ...command.properties[0], name: 'otherId' }] }; + const snapshot = { ...raw, modules: [{ ...module, features: [{ ...feature, slices: [{ ...slice, commands: [ambiguous] }] }] }] }; + (action(resolveActionSubjects(snapshot).value).subject ?? 'Screen').should.equal('Screen'); + }); it('should not use primitive equality as nominal proof', () => { const primitive = source.replace('rowId ItemId key', 'rowId Uuid key').replace('itemId ItemId identifier', 'itemId Uuid identifier'); (action(resolveActionSubjects(parse(primitive).value).value).subject ?? 'Screen').should.equal('Screen'); diff --git a/Source/Screenplay/EventModels/Prototypes/for_toUserExperience/when_drawing_guarded_actions.ts b/Source/Screenplay/EventModels/Prototypes/for_toUserExperience/when_drawing_guarded_actions.ts index dadf851e5..33dbf667f 100644 --- a/Source/Screenplay/EventModels/Prototypes/for_toUserExperience/when_drawing_guarded_actions.ts +++ b/Source/Screenplay/EventModels/Prototypes/for_toUserExperience/when_drawing_guarded_actions.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. import { beforeEach, describe, it } from 'vitest'; +import { toSyntaxJson } from '@cratis/screenplay-compiler'; import { UserExperienceActorDocument } from '../../Document/EventModelDocument'; import { toUserExperience } from '../toUserExperience'; import { drawn, screens_of } from './given/screens_of'; @@ -10,17 +11,23 @@ describe('when drawing guarded actions', () => { let actors: UserExperienceActorDocument[]; beforeEach(() => { actors = toUserExperience(screens_of('screen V', ' template Detail', ' actions', ' section choices', - ' action "Close invoice"', ' when item.status == "draft" execute Cancel', + ' action "Close invoice" for item', ' when item.status == "draft" execute Cancel', ' when item.status == "sent" execute Archive', ' otherwise execute Review', - ' navigate to List', ' action $strings.actions.retry', + ' navigate to List', ' action $strings.actions.retry for screen', ' when item.failed == true execute Retry', ' otherwise hidden', - ' action Register', ' label "Register invoice"'), 'M#S', ['staff', 'accountant']); + ' action Register for screen', ' label "Register invoice"'), 'M#S', ['staff', 'accountant']); }); it('should draw one labeled button per guarded action alongside plain actions', () => actors[0].elements.map(drawn).should.deep.equal([ ['button-hot', 'Close invoice', 24, 24, 160, 40], ['button', '$strings.actions.retry', 200, 24, 160, 40], ['button', 'Register invoice', 376, 24, 160, 40], ])); + it('should preserve authored subjects and arguments without evaluating selection', () => { + const screens = screens_of('screen S', ' action "Choose" for item', ' when item.ready == true execute Retry', ' with id from item.foreignKey', ' otherwise hidden'); + const before = screens.map(toSyntaxJson); + toUserExperience(screens, 'M#S', ['staff']); + screens.map(toSyntaxJson).should.deep.equal(before); + }); it('should preserve the supplied audience', () => actors.map(actor => actor.id).should.deep.equal(['staff', 'accountant'])); it('should share the same prototype across the audience', () => actors[1].elements.should.deep.equal(actors[0].elements)); }); diff --git a/Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts b/Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts new file mode 100644 index 000000000..cba5c1fb7 --- /dev/null +++ b/Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts @@ -0,0 +1,80 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { parse } from '@cratis/screenplay-compiler'; +import { readFileSync } from 'node:fs'; +import type { CancellationToken, editor, languages, Range } from 'monaco-editor'; +import { describe, expect, it, vi } from 'vitest'; +import { createCodeActionProvider } from '../code-actions'; +import { planCompletions } from '../completion-planner'; +import { hoverContent } from '../hover-content'; +import { validateLines } from '../validation'; + +const source = `concept ItemId : Uuid +module Work + feature Items + slice StateView List + readmodel Row + rowId ItemId key + command Retry + itemId ItemId identifier + query Rows => Row[] + screen List + data Row[] via query Rows + action Retry +`; +const range = { startLineNumber: 12, startColumn: 9, endLineNumber: 12, endColumn: 21 } as Range; +const context = { only: 'quickfix', markers: [{ ...range, code: 'PLAY0816', message: 'Infer subject', severity: 1 }], trigger: 1 } as languages.CodeActionContext; +const token = { isCancellationRequested: false } as CancellationToken; + +function model(): editor.ITextModel { + return { + uri: { toString: () => 'file:///model.play' }, + getValue: () => source, + getVersionId: () => 1, + getPositionAt: (offset: number) => { + const lines = source.slice(0, offset).split('\n'); + return { lineNumber: lines.length, column: lines.at(-1)!.length + 1 }; + }, + } as unknown as editor.ITextModel; +} + +const labels = (line: string) => { + const plan = planCompletions(['screen List', ` ${line}`], 1, ` ${line}`); + return plan.kind === 'entries' ? plan.entries.map(entry => entry.label) : []; +}; + +describe('when editing action subjects', () => { + it('should surface every action-subject diagnostic from the shared compiler fixture', () => { + const fixture = readFileSync(new URL('../../../Compiler/Conformance/action-subjects/source.play', import.meta.url), 'utf8'); + const codes = validateLines(fixture.split('\n')).map(issue => issue.code); + for (const code of ['PLAY0815', 'PLAY0816', 'PLAY0817', 'PLAY0818', 'PLAY0819']) expect(codes).toContain(code); + }); + for (const header of ['action Retry ', 'action "Choose" ', 'item retry action Retry ']) { + it(`should offer explicit scope on ${header}`, () => expect(labels(header)).toEqual(['for item', 'for screen'])); + it(`should complete contextual values on ${header}`, () => expect(labels(`${header}for `)).toEqual(['item', 'screen'])); + } + it('should explain scope without treating a label string as a clause', () => { + expect(hoverContent(['screen S', ' action Retry for item'], 1, 'item', 20, 24)).toContain('nominal'); + expect(hoverContent(['screen S', ' action "for item"'], 1, 'item', 15, 19)).toBeNull(); + }); + it('should forward inference code severity message and source location', () => { + const diagnostics = parse(source).diagnostics.filter(diagnostic => diagnostic.code === 'PLAY0816'); + const expected = diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity, diagnostic.message, diagnostic.location.line - 1, diagnostic.location.column]); + for (const context of [undefined, { compilerDiagnostics: diagnostics }]) { + expect(validateLines(source.split('\n'), context).filter(marker => marker.code === 'PLAY0816').map(marker => [marker.code, marker.severity, marker.message, marker.line, marker.startColumn])).toEqual(expected); + } + }); + it('should offer a version-bound compiler repair', async () => { + const result = await createCodeActionProvider().provideCodeActions(model(), range, context, token); + expect(result?.actions.map(action => action.title)).toEqual(["Make inferred 'for item' explicit"]); + expect(result?.actions[0].edit?.edits.every(edit => 'versionId' in edit && edit.versionId === 1)).toBe(true); + }); + it('should refuse a repair when the analyzed buffer changes', async () => { + const document = model(); + let revision = 0; + vi.spyOn(document, 'getVersionId').mockImplementation(() => ++revision); + const result = await createCodeActionProvider().provideCodeActions(document, range, context, token); + expect(result?.actions).toEqual([]); + }); +}); diff --git a/Source/Screenplay/Monaco/screenplay-language/for_planCompletions/when_editing_guarded_actions.ts b/Source/Screenplay/Monaco/screenplay-language/for_planCompletions/when_editing_guarded_actions.ts index ee264a768..280422048 100644 --- a/Source/Screenplay/Monaco/screenplay-language/for_planCompletions/when_editing_guarded_actions.ts +++ b/Source/Screenplay/Monaco/screenplay-language/for_planCompletions/when_editing_guarded_actions.ts @@ -13,7 +13,7 @@ const labels = (lines: string[]) => { describe('when editing guarded actions', () => { it('should offer a label headed snippet inside a screen section', () => labels(['screen V', ' section actions', ' ']).should.contain('action "…"')); - for (const header of ['action "Choose"', 'action $strings.actions.choose']) { + for (const header of ['action "Choose"', 'action $strings.actions.choose', 'action "Choose" for item', 'action $strings.actions.choose for screen']) { it(`should offer alternatives and fallback but not label under ${header}`, () => labels(['screen V', ` ${header}`, ' ']) .should.deep.equal(['when … execute', 'otherwise hidden', 'otherwise execute', 'navigate to'])); for (const clause of ['when item.ready == true execute ', 'otherwise execute ']) { @@ -24,7 +24,7 @@ describe('when editing guarded actions', () => { it(`should offer input bindings under ${clause}`, () => labels(['screen V', ' action "Choose"', ` ${clause}`, ' ']).should.deep.equal(['with … from'])); } it('should offer no arguments under hidden', () => labels(['screen V', ' action "Choose"', ' otherwise hidden', ' ']).should.deep.equal([])); - it('should preserve plain action completions', () => labels(['screen V', ' action C', ' ']).should.deep.equal(['navigate to', 'label'])); + it('should preserve plain action completions', () => labels(['screen V', ' action C', ' ']).should.deep.equal(['with … from', 'navigate to', 'label'])); it('should not treat specification steps as guarded alternatives', () => { const plan = planCompletions(['specification S', ' when C', ' '], 2, ' '); (plan.kind === 'entries' && plan.entries.some(entry => entry.label === 'with … from')).should.be.false; diff --git a/Source/Screenplay/Monaco/screenplay-language/for_tokens/when_highlighting_guarded_actions.ts b/Source/Screenplay/Monaco/screenplay-language/for_tokens/when_highlighting_guarded_actions.ts index 6e23c452d..3aa517392 100644 --- a/Source/Screenplay/Monaco/screenplay-language/for_tokens/when_highlighting_guarded_actions.ts +++ b/Source/Screenplay/Monaco/screenplay-language/for_tokens/when_highlighting_guarded_actions.ts @@ -27,6 +27,9 @@ describe('when highlighting guarded actions', () => { [' otherwise execute Choose', 'otherwise', 'keyword.play'], [' otherwise execute Choose', 'execute', 'keyword.play'], [' otherwise hidden', 'hidden', 'keyword.play'], + [' action Retry for item', 'for', 'keyword.play'], + [' action "Choose" for screen', 'screen', 'keyword.play'], + [' item retry action Retry for item', 'for', 'keyword.play'], ...contextualWords.flatMap(word => [ [`${word} String`, word, 'identifier.play'], [`${word} = "value"`, word, 'identifier.play'], diff --git a/Source/Screenplay/Monaco/screenplay-language/for_validateLines/when_validating_a_document/with_a_problem_of_every_coded_kind.ts b/Source/Screenplay/Monaco/screenplay-language/for_validateLines/when_validating_a_document/with_a_problem_of_every_coded_kind.ts index 0f1c1141a..c2329779a 100644 --- a/Source/Screenplay/Monaco/screenplay-language/for_validateLines/when_validating_a_document/with_a_problem_of_every_coded_kind.ts +++ b/Source/Screenplay/Monaco/screenplay-language/for_validateLines/when_validating_a_document/with_a_problem_of_every_coded_kind.ts @@ -176,6 +176,10 @@ describe('when validating a document with a problem of every coded kind', () => issues.push(...validateLines(['import Invalid from " "', 'module M', ' feature F', ' slice Translate S', ' direction sideways', ' public event E from " "'])); }); + beforeEach(() => { + issues.push(...validateLines(readFileSync(new URL('../../../../Compiler/Conformance/action-subjects/source.play', import.meta.url), 'utf8').split('\n'))); + }); + it('should give every issue it reports a code', () => { issues.filter((issue) => !issue.code).should.be.empty; }); diff --git a/Source/Screenplay/Monaco/screenplay-language/validation.ts b/Source/Screenplay/Monaco/screenplay-language/validation.ts index 5a199905a..7a9b1660a 100644 --- a/Source/Screenplay/Monaco/screenplay-language/validation.ts +++ b/Source/Screenplay/Monaco/screenplay-language/validation.ts @@ -170,7 +170,7 @@ export function validateLines(lines: string[], context: ValidationContext = {}): const dependencyCodes = new Set([DiagnosticCodes.UndeclaredDependency, DiagnosticCodes.UnusedDependencyDeclaration, DiagnosticCodes.InvalidDependencyTarget, DiagnosticCodes.RepeatedDependencyDeclaration, DiagnosticCodes.MutualDependencyDeclarations, DiagnosticCodes.AmbiguousReference]); // These parser diagnostics must reach the marker adapter. C#-only completeness and reference // checks are not synthesized here, but are preserved when a caller supplies compiler diagnostics. - const authoringCodes = new Set([DiagnosticCodes.InvalidTimeZoneDeclaration, DiagnosticCodes.InvalidCommandCalendar, DiagnosticCodes.InvalidSpecificationTimeZone, DiagnosticCodes.InvalidCommandReadsDeclaration, DiagnosticCodes.UnknownMatchPattern, DiagnosticCodes.InvalidMatchPattern, DiagnosticCodes.PatternOutsidePortableMatchDialect, DiagnosticCodes.AmbiguousMatchPattern, DiagnosticCodes.DeprecatedStudioTextRulePattern, DiagnosticCodes.MismatchedSpecificationQueryResult, DiagnosticCodes.DirectionlessTranslationReactsToOwnCapture, DiagnosticCodes.CaptureEventsFromSeveralOrigins, DiagnosticCodes.CaptureEventsKeyNotRequired, DiagnosticCodes.CaptureEventsRecordFixture, DiagnosticCodes.EventIdPinNotCarriedToRenderers, DiagnosticCodes.ResponseNameUsedOnFailure, DiagnosticCodes.InvalidEventDeclaration, DiagnosticCodes.InvalidImportDeclaration, DiagnosticCodes.InvalidSliceDeclaration, DiagnosticCodes.InvalidDescription, DiagnosticCodes.DuplicateDescription, DiagnosticCodes.EmptyDescription, DiagnosticCodes.DuplicateEventSubject, DiagnosticCodes.InvalidSubjectType, DiagnosticCodes.ProtectedSubjectType, DiagnosticCodes.InvalidSubjectOwner, DiagnosticCodes.ReadModelSubjectNotSupported, DiagnosticCodes.InvalidSubjectModifierOrder, DiagnosticCodes.UnsupportedInteractionAlternatives, DiagnosticCodes.MixedInteractionAlternatives, DiagnosticCodes.InteractionAlternativeWithoutActions, DiagnosticCodes.InlineInteractionAlternative, DiagnosticCodes.LegacyInteractionWhere, DiagnosticCodes.InvalidSpecificationParameter, DiagnosticCodes.InvalidSpecificationCase, DiagnosticCodes.DuplicateSpecificationParameter, DiagnosticCodes.DuplicateSpecificationCase, DiagnosticCodes.IncompleteSpecificationTable, DiagnosticCodes.InvalidSpecificationCaseAssignment, DiagnosticCodes.InvalidSpecificationCaseValue, DiagnosticCodes.InvalidSpecificationCaseReference, DiagnosticCodes.OptionalSpecificationParameterTarget, DiagnosticCodes.SpecificationCaseNameCollision, DiagnosticCodes.IncompatibleSpecificationParameterType, DiagnosticCodes.UnusedSpecificationParameter, DiagnosticCodes.SingularSpecificationTableExpansion, DiagnosticCodes.InvalidSpecificationCallerPersona, DiagnosticCodes.UnsynthesizablePersonaCaller, DiagnosticCodes.PersonaWithoutGate, DiagnosticCodes.GateWithoutPersona, DiagnosticCodes.AmbiguousPersonaCaller, DiagnosticCodes.InvalidDocumentation, DiagnosticCodes.ConflictingDocumentationAcrossFiles, DiagnosticCodes.InvalidAbsentReadModelStep, DiagnosticCodes.UnknownConstraintProperty, DiagnosticCodes.OmittedProductionDestination, DiagnosticCodes.InvalidSpecificationExample, DiagnosticCodes.DuplicateSpecificationAssignment, DiagnosticCodes.InvalidReactionBatchesDeclaration, DiagnosticCodes.DescribedCommandNotImplemented, DiagnosticCodes.DescribedCommandWithoutProductions, DiagnosticCodes.DescribedCommandCardinalityNotAdmitted, DiagnosticCodes.CommandHandlerRequiresAttachment, DiagnosticCodes.PendingIntentWithOtherHandler, DiagnosticCodes.DuplicateEventInProjectionScope, DiagnosticCodes.ReservedStoredName]); + const authoringCodes = new Set([DiagnosticCodes.InvalidActionSubjectClause, DiagnosticCodes.InferredActionSubject, DiagnosticCodes.ChangedActionSubject, DiagnosticCodes.AmbiguousActionInputBinding, DiagnosticCodes.UnsupportedActionSubjectContext, DiagnosticCodes.InvalidTimeZoneDeclaration, DiagnosticCodes.InvalidCommandCalendar, DiagnosticCodes.InvalidSpecificationTimeZone, DiagnosticCodes.InvalidCommandReadsDeclaration, DiagnosticCodes.UnknownMatchPattern, DiagnosticCodes.InvalidMatchPattern, DiagnosticCodes.PatternOutsidePortableMatchDialect, DiagnosticCodes.AmbiguousMatchPattern, DiagnosticCodes.DeprecatedStudioTextRulePattern, DiagnosticCodes.MismatchedSpecificationQueryResult, DiagnosticCodes.DirectionlessTranslationReactsToOwnCapture, DiagnosticCodes.CaptureEventsFromSeveralOrigins, DiagnosticCodes.CaptureEventsKeyNotRequired, DiagnosticCodes.CaptureEventsRecordFixture, DiagnosticCodes.EventIdPinNotCarriedToRenderers, DiagnosticCodes.ResponseNameUsedOnFailure, DiagnosticCodes.InvalidEventDeclaration, DiagnosticCodes.InvalidImportDeclaration, DiagnosticCodes.InvalidSliceDeclaration, DiagnosticCodes.InvalidDescription, DiagnosticCodes.DuplicateDescription, DiagnosticCodes.EmptyDescription, DiagnosticCodes.DuplicateEventSubject, DiagnosticCodes.InvalidSubjectType, DiagnosticCodes.ProtectedSubjectType, DiagnosticCodes.InvalidSubjectOwner, DiagnosticCodes.ReadModelSubjectNotSupported, DiagnosticCodes.InvalidSubjectModifierOrder, DiagnosticCodes.UnsupportedInteractionAlternatives, DiagnosticCodes.MixedInteractionAlternatives, DiagnosticCodes.InteractionAlternativeWithoutActions, DiagnosticCodes.InlineInteractionAlternative, DiagnosticCodes.LegacyInteractionWhere, DiagnosticCodes.InvalidSpecificationParameter, DiagnosticCodes.InvalidSpecificationCase, DiagnosticCodes.DuplicateSpecificationParameter, DiagnosticCodes.DuplicateSpecificationCase, DiagnosticCodes.IncompleteSpecificationTable, DiagnosticCodes.InvalidSpecificationCaseAssignment, DiagnosticCodes.InvalidSpecificationCaseValue, DiagnosticCodes.InvalidSpecificationCaseReference, DiagnosticCodes.OptionalSpecificationParameterTarget, DiagnosticCodes.SpecificationCaseNameCollision, DiagnosticCodes.IncompatibleSpecificationParameterType, DiagnosticCodes.UnusedSpecificationParameter, DiagnosticCodes.SingularSpecificationTableExpansion, DiagnosticCodes.InvalidSpecificationCallerPersona, DiagnosticCodes.UnsynthesizablePersonaCaller, DiagnosticCodes.PersonaWithoutGate, DiagnosticCodes.GateWithoutPersona, DiagnosticCodes.AmbiguousPersonaCaller, DiagnosticCodes.InvalidDocumentation, DiagnosticCodes.ConflictingDocumentationAcrossFiles, DiagnosticCodes.InvalidAbsentReadModelStep, DiagnosticCodes.UnknownConstraintProperty, DiagnosticCodes.OmittedProductionDestination, DiagnosticCodes.InvalidSpecificationExample, DiagnosticCodes.DuplicateSpecificationAssignment, DiagnosticCodes.InvalidReactionBatchesDeclaration, DiagnosticCodes.DescribedCommandNotImplemented, DiagnosticCodes.DescribedCommandWithoutProductions, DiagnosticCodes.DescribedCommandCardinalityNotAdmitted, DiagnosticCodes.CommandHandlerRequiresAttachment, DiagnosticCodes.PendingIntentWithOtherHandler, DiagnosticCodes.DuplicateEventInProjectionScope, DiagnosticCodes.ReservedStoredName]); const complianceCodes = new Set([DiagnosticCodes.InvalidPurposeDeclaration, DiagnosticCodes.InvalidPurposeVocabulary, DiagnosticCodes.DuplicatePurposeField, DiagnosticCodes.DuplicatePurposeDeclaration, DiagnosticCodes.UnknownPurpose, DiagnosticCodes.PurposeInterestMismatch, DiagnosticCodes.PersonalDataWithoutPurpose, DiagnosticCodes.SpecialDataWithoutCondition, DiagnosticCodes.CriminalDataWithoutAuthorization, DiagnosticCodes.PurposeWithoutBasis, DiagnosticCodes.UnusedPurpose, DiagnosticCodes.UnknownConceptDirective, DiagnosticCodes.AttributeReasonWithoutAttribute, DiagnosticCodes.DuplicateAttributeReason, DiagnosticCodes.LegacyComplianceMarker, DiagnosticCodes.DuplicateComplianceMarker, DiagnosticCodes.UnknownComplianceMarker, DiagnosticCodes.InvalidSecretScope, DiagnosticCodes.DuplicateSecretScope, DiagnosticCodes.SecretScopeIgnoredForPii, DiagnosticCodes.InvalidPersonalDataQualifier, DiagnosticCodes.DuplicateSpecialCategory]); const compilerUnknownEventLines = new Set(); for (const diagnostic of context.compilerDiagnostics ?? analysis.diagnostics) { diff --git a/Source/Screenplay/VSCodeExtension/WorkspaceApplication.ts b/Source/Screenplay/VSCodeExtension/WorkspaceApplication.ts index 8370b3b1d..ff39d623b 100644 --- a/Source/Screenplay/VSCodeExtension/WorkspaceApplication.ts +++ b/Source/Screenplay/VSCodeExtension/WorkspaceApplication.ts @@ -8,6 +8,11 @@ import { analyzeOperations, DocumentSymbols, importablePaths, mergeSymbols, scan // imports resolve, and whether it holds what the module or feature it is placed in can. An import with the // wrong shape is left out - the editor reports that itself, as it is typed. const surfacedCodes = new Set([ + DiagnosticCodes.InvalidActionSubjectClause, + DiagnosticCodes.InferredActionSubject, + DiagnosticCodes.ChangedActionSubject, + DiagnosticCodes.AmbiguousActionInputBinding, + DiagnosticCodes.UnsupportedActionSubjectContext, DiagnosticCodes.InvalidEventDeclaration, DiagnosticCodes.InvalidImportDeclaration, DiagnosticCodes.InvalidSliceDeclaration, diff --git a/Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts b/Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts new file mode 100644 index 000000000..1d6d54427 --- /dev/null +++ b/Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts @@ -0,0 +1,33 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { readFileSync } from 'node:fs'; +import { describe, expect, it } from 'vitest'; +import { parse } from '@cratis/screenplay-compiler'; +import { WorkspaceApplication } from '../WorkspaceApplication'; + +const grammar = JSON.parse(readFileSync(new URL('../syntaxes/screenplay.tmLanguage.json', import.meta.url), 'utf8')); +const clauses = (grammar.repository['action-subjects'].patterns as { match: string }[]).map(rule => new RegExp(rule.match)); +const source = readFileSync(new URL('../../Compiler/Conformance/action-subjects/source.play', import.meta.url), 'utf8'); +const relevant = (code: string) => /^PLAY081[5-9]$/.test(code); + +describe('when highlighting action subjects', () => { + for (const line of ['action Retry for item', 'action "Choose" for screen', 'action $strings.choose for item', 'item retry action Work.Items.Retry for screen']) { + it(`should highlight the contextual clause in ${line}`, () => { + const match = clauses.map(rule => rule.exec(line)).find(match => match !== null)!; + expect(match).not.toBeUndefined(); + expect(match.at(-3)).toBe('for'); + expect(match.at(-1)).toBe(line.endsWith('item') ? 'item' : 'screen'); + }); + } + for (const line of ['for String', 'item String', 'screen String', 'action "for item"', 'action Retry label "for screen"', '// action Retry for item']) { + it(`should not create a subject clause in ${line}`, () => expect(clauses.some(rule => rule.test(line))).toBe(false)); + } + it('should carry every action-subject diagnostic through the workspace facade', () => { + const workspace = new WorkspaceApplication(); + workspace.set('application.play', source); + const expected = parse(source, 'application.play').diagnostics.filter(diagnostic => relevant(diagnostic.code)); + expect(new Set(expected.map(diagnostic => diagnostic.code)).size).toBe(5); + expect(workspace.diagnosticsFor('application.play').filter(diagnostic => relevant(diagnostic.code))).toEqual(expected); + }); +}); From 4fdc9c829dd63da918718665ba0fb2cb5a0b12e3 Mon Sep 17 00:00:00 2001 From: woksin Date: Sun, 25 Oct 2026 01:36:18 +0200 Subject: [PATCH 4/9] Align toolbar action subjects across parsers and keep Code Health (Cratis/Screenplay#1052) --- .../Parsing/ScreenParser.ActionSubjects.cs | 41 ++++++++++++------- .../DotNET/Screenplay/Parsing/ScreenParser.cs | 8 ++-- .../Printing/ScreenplayPrinter.Screens.cs | 4 +- .../Workspaces/WorkspaceRepairVerification.cs | 6 ++- ...ng_subjects_on_non_action_toolbar_items.cs | 35 ++++++++++++++++ .../Compiler/Authoring/QuickFixes.ts | 15 ++++++- .../Compiler/Parsing/ScreenParser.ts | 18 ++++++-- .../Syntax/ActionSubjectInvariants.ts | 22 ++++++++++ .../Compiler/Syntax/SyntaxInvariants.ts | 9 +--- ...ng_subjects_on_non_action_toolbar_items.ts | 27 ++++++++++++ 10 files changed, 152 insertions(+), 33 deletions(-) create mode 100644 Source/DotNET/Screenplay/for_ScreenplayCompiler/when_rejecting_subjects_on_non_action_toolbar_items.cs create mode 100644 Source/Screenplay/Compiler/Syntax/ActionSubjectInvariants.ts create mode 100644 Source/Screenplay/Compiler/for_parse/when_rejecting_subjects_on_non_action_toolbar_items.ts diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs index 45705fab9..587982b4d 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs @@ -10,29 +10,20 @@ namespace Cratis.Screenplay.Parsing; internal static partial class ScreenParser { - static ScreenActionSubjectKind? ParseSubjectClause(ParserContext context, SourceLine line, bool action, out string header, out string? label) + static ScreenActionSubjectKind? ParseSubjectClause(SubjectClauseRequest request, out string header, out string? label) { - header = line.Content; - label = null; + header = request.Line.Content; var words = HeaderWordRegex().Matches(header).Cast().ToArray(); var clauses = words.Where(word => word.Value == "for").ToArray(); var labelWord = words.FirstOrDefault(word => word.Value == "label"); - if (labelWord is not null) - { - var match = LabelRegex().Match(header[labelWord.Index..]); - if (match.Success) - { - label = OperandText(match, 1); - header = header[..labelWord.Index].TrimEnd(); - } - } + label = ParseSubjectLabel(ref header, labelWord); if (clauses.Length == 0) return null; var clause = clauses[0]; var suffix = SubjectClauseRegex().Match(header[clause.Index..]); - if (!action || clauses.Length != 1 || !suffix.Success || (labelWord is not null && labelWord.Index < clause.Index)) + if (IsInvalidSubjectClause(request, clauses, suffix, labelWord)) { - context.Error(DiagnosticCodes.InvalidActionSubjectClause, "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", line.Location); + request.Context.Error(DiagnosticCodes.InvalidActionSubjectClause, "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", request.Line.Location); header = header[..Math.Min(clause.Index, header.Length)].TrimEnd(); return null; } @@ -41,6 +32,23 @@ internal static partial class ScreenParser return suffix.Groups[1].Value == "item" ? ScreenActionSubjectKind.Item : ScreenActionSubjectKind.Screen; } + static string? ParseSubjectLabel(ref string header, Match? labelWord) + { + if (labelWord is null) return null; + var match = LabelRegex().Match(header[labelWord.Index..]); + if (!match.Success) return null; + var label = OperandText(match, 1); + header = header[..labelWord.Index].TrimEnd(); + return label; + } + + static bool IsInvalidSubjectClause(SubjectClauseRequest request, Match[] clauses, Match suffix, Match? labelWord) + { + if (!request.Action) return true; + if (clauses.Length != 1) return true; + return !suffix.Success || (labelWord is not null && labelWord.Index < clauses[0].Index); + } + static InteractionArgumentSyntax? ParsePlainActionInput(ParserContext context, SourceLine line, IReadOnlyList inputs) { var match = InteractionParser.WithRegex().Match(line.Content); @@ -58,6 +66,11 @@ internal static partial class ScreenParser [GeneratedRegex("\"" + StringLiteral.BodyPattern + "\"|\\S+", RegexOptions.NonBacktracking)] private static partial Regex HeaderWordRegex(); + [GeneratedRegex(@"^item\s+\S+\s+action\s", RegexOptions.NonBacktracking)] + private static partial Regex ToolbarActionHeaderRegex(); + [GeneratedRegex(@"^for\s+(item|screen)$", RegexOptions.NonBacktracking)] private static partial Regex SubjectClauseRegex(); + + sealed record SubjectClauseRequest(ParserContext Context, SourceLine Line, bool Action); } diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs index a58528dc5..128d25205 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs @@ -160,7 +160,7 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi { if (LineText.FirstWord(line.Content) != "action") { - ParseSubjectClause(context, line, false, out _, out _); + ParseSubjectClause(new(context, line, false), out _, out _); } switch (LineText.FirstWord(line.Content)) @@ -221,7 +221,7 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi static ScreenDirectiveSyntax? ParseAction(ParserContext context, SourceLine line) { - var subject = ParseSubjectClause(context, line, true, out var header, out var inlineLabel); + var subject = ParseSubjectClause(new(context, line, true), out var header, out var inlineLabel); var guarded = GuardedActionRegex().Match(header); if (guarded.Success) { @@ -553,8 +553,8 @@ static ComponentOutletSyntax ParseComponentOutlet(ParserContext context, SourceL static ToolbarItemSyntax? ParseToolbarItem(ParserContext context, SourceLine line) { - var isAction = HeaderWordRegex().Matches(line.Content).Cast().Any(word => word.Value == "action"); - var subject = ParseSubjectClause(context, line, isAction, out var header, out var inlineLabel); + var isAction = ToolbarActionHeaderRegex().IsMatch(line.Content); + var subject = ParseSubjectClause(new(context, line, isAction), out var header, out var inlineLabel); var match = ToolbarItemRegex().Match(header); if (!match.Success) { diff --git a/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs b/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs index a5c9cfaef..18ec38c30 100644 --- a/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs +++ b/Source/DotNET/Screenplay/Printing/ScreenplayPrinter.Screens.cs @@ -10,6 +10,8 @@ namespace Cratis.Screenplay.Printing; /// public partial class ScreenplayPrinter { + static bool HasScreenActionBody(ScreenActionSyntax action) => action.Label is not null || action.Navigate is not null || action.Inputs.Any(); + void WriteScreen(ScreenplayWriter writer, ScreenSyntax screen) { using var anchor = writer.Anchor(screen); @@ -157,7 +159,7 @@ void WriteScreenAction(ScreenplayWriter writer, ScreenActionSyntax action) { using var anchor = writer.Anchor(action); writer.Line($"action {action.Command}{WriteActionSubject(action.Subject)}"); - if (action.Label is null && action.Navigate is null && !action.Inputs.Any()) + if (!HasScreenActionBody(action)) { return; } diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs index 320ebe1b4..1aeff8f14 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceRepairVerification.cs @@ -170,8 +170,7 @@ static WorkspaceAuthoringResult VerifyTransaction(WorkspaceSyntaxIndex index, Wo static WorkspaceAuthoringResult VerifyActionSubjectRepair(WorkspaceSyntaxIndex index, WorkspaceDiagnosticRepair repair, WorkspaceAuthoringResult result) { - if (result.Accepted && WorkspaceActionSubjectRepairs.Supports(repair.DiagnosticCode) && - !WorkspaceActionSubjectRepairs.Preserves(index, repair, result)) + if (RequiresActionSubjectVerification(repair, result) && !WorkspaceActionSubjectRepairs.Preserves(index, repair, result)) { return Refuse(result, WorkspaceConflictKind.InvalidOperation, "Cannot prove that the action subject repair preserves the model, catalog, comments and other diagnostics."); } @@ -179,6 +178,9 @@ static WorkspaceAuthoringResult VerifyActionSubjectRepair(WorkspaceSyntaxIndex i return result; } + static bool RequiresActionSubjectVerification(WorkspaceDiagnosticRepair repair, WorkspaceAuthoringResult result) => + result.Accepted && WorkspaceActionSubjectRepairs.Supports(repair.DiagnosticCode); + sealed record Verdict(bool Accepted, ImmutableArray Conflicts) { internal static Verdict From(WorkspaceAuthoringResult result) => new(result.Accepted, result.Accepted ? [] : result.Conflicts); diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_rejecting_subjects_on_non_action_toolbar_items.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_rejecting_subjects_on_non_action_toolbar_items.cs new file mode 100644 index 000000000..7ab67e227 --- /dev/null +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_rejecting_subjects_on_non_action_toolbar_items.cs @@ -0,0 +1,35 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay.for_ScreenplayCompiler; + +public class when_rejecting_subjects_on_non_action_toolbar_items : given.a_compiler +{ + CompilationResult _result; + ToolbarItemSyntax[] _items; + + void Because() + { + _result = _compiler.Compile( + """ + module Work + feature Items + slice StateView Details + screen Details + toolbar + item action navigate to Details for item + item go navigate to action for screen + item open dialog action for item + """); + _items = [.. _result.Value!.Modules.Single().Features.Single().Slices.Single().Screens.Single().Directives.OfType().Single().Items]; + } + + [Fact] void should_reject_each_inapplicable_subject_clause() => _result.Diagnostics.Count(diagnostic => diagnostic.Code == DiagnosticCodes.InvalidActionSubjectClause).ShouldEqual(3); + [Fact] void should_not_attach_subjects_to_non_action_items() => _items.All(item => item.Subject is null).ShouldBeTrue(); + [Fact] void should_preserve_the_navigation_named_action() => _items[1].Target.ShouldEqual("action"); + [Fact] void should_preserve_the_item_named_action() => _items[0].Name.ShouldEqual("action"); + [Fact] void should_preserve_the_dialog_named_action() => _items[2].Target.ShouldEqual("action"); +} diff --git a/Source/Screenplay/Compiler/Authoring/QuickFixes.ts b/Source/Screenplay/Compiler/Authoring/QuickFixes.ts index d2f76d31b..b15da56cf 100644 --- a/Source/Screenplay/Compiler/Authoring/QuickFixes.ts +++ b/Source/Screenplay/Compiler/Authoring/QuickFixes.ts @@ -44,8 +44,21 @@ export interface QuickFixOptions { readonly diagnosticCode?: string; } +const quickFixDiagnosticCodes: ReadonlySet = new Set([ + DiagnosticCodes.InferredActionSubject, + DiagnosticCodes.ChangedActionSubject, + DiagnosticCodes.EventFromLaterSlice, + DiagnosticCodes.DeprecatedStudioTextRulePattern, + DiagnosticCodes.DuplicateComplianceMarker, + DiagnosticCodes.LegacyOptionalSuffix, + DiagnosticCodes.LegacyComplianceMarker, + DiagnosticCodes.RedundantEventId, + DiagnosticCodes.PublicTranslationRequiresDirection, + DiagnosticCodes.LegacyProfileLayout, +]); + export function isQuickFixDiagnostic(code: unknown): code is string { - return code === DiagnosticCodes.InferredActionSubject || code === DiagnosticCodes.ChangedActionSubject || code === DiagnosticCodes.EventFromLaterSlice || code === DiagnosticCodes.DeprecatedStudioTextRulePattern || code === DiagnosticCodes.DuplicateComplianceMarker || code === DiagnosticCodes.LegacyOptionalSuffix || code === DiagnosticCodes.LegacyComplianceMarker || code === DiagnosticCodes.RedundantEventId || code === DiagnosticCodes.PublicTranslationRequiresDirection || code === DiagnosticCodes.LegacyProfileLayout; + return quickFixDiagnosticCodes.has(code); } // Diagnostics point at the complete type, not at the suffix. Never derive edits from message text. diff --git a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts index 50dcbe6ce..56e76b1cc 100644 --- a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts +++ b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts @@ -165,8 +165,14 @@ function parseData(context: ParserContext, line: SourceLine): ScreenDataSyntax | function parseAction(context: ParserContext, line: SourceLine): ScreenActionSyntax | ScreenGuardedActionSyntax | undefined { const parsed = parseSubjectClause(context, line, true); + const result = parseActionHeader(context, line, parsed); + if (result === undefined || parsed.subject === undefined) return result; + return { ...result, subject: parsed.subject }; +} + +function parseActionHeader(context: ParserContext, line: SourceLine, parsed: ReturnType): ScreenActionSyntax | ScreenGuardedActionSyntax | undefined { const guarded = guardedAction.exec(parsed.header); - if (guarded !== null) return { ...parseGuardedAction(context, line, operandText(guarded, 1), parseNavigate), ...(parsed.subject === undefined ? {} : { subject: parsed.subject }) }; + if (guarded !== null) return parseGuardedAction(context, line, operandText(guarded, 1), parseNavigate); const match = action.exec(parsed.header); if (match === null) { context.error(DiagnosticCodes.InvalidActionDirective, `Invalid action directive '${line.content}' - expected 'action '`, locationOf(line)); @@ -184,13 +190,17 @@ function parseAction(context: ParserContext, line: SourceLine): ScreenActionSynt } else if (firstWord(child.content) === 'navigate') { target = parseNavigate(context, child.content, child) ?? null; } else if (firstWord(child.content) === 'with') { - const input = parsePlainActionInput(context, child, inputs); - if (input !== undefined) inputs.push(input); + addPlainActionInput(context, child, inputs); } else { context.error(DiagnosticCodes.UnknownActionDirective, `Unexpected '${child.content}' in action - expected 'label "..."' or 'navigate to ...'`, locationOf(child)); } } - return { kind: 'ScreenActionSyntax', command: match[1], label: text, navigate: target, ...(parsed.subject === undefined ? {} : { subject: parsed.subject }), ...(inputs.length === 0 ? {} : { inputs }), location: locationOf(line) }; + return { kind: 'ScreenActionSyntax', command: match[1], label: text, navigate: target, ...(inputs.length === 0 ? {} : { inputs }), location: locationOf(line) }; +} + +function addPlainActionInput(context: ParserContext, line: SourceLine, inputs: InteractionArgumentSyntax[]): void { + const input = parsePlainActionInput(context, line, inputs); + if (input !== undefined) inputs.push(input); } function parseNavigate(context: ParserContext, text: string, line: SourceLine): ScreenNavigateSyntax | undefined { diff --git a/Source/Screenplay/Compiler/Syntax/ActionSubjectInvariants.ts b/Source/Screenplay/Compiler/Syntax/ActionSubjectInvariants.ts new file mode 100644 index 000000000..f230940d3 --- /dev/null +++ b/Source/Screenplay/Compiler/Syntax/ActionSubjectInvariants.ts @@ -0,0 +1,22 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { InvalidSyntaxJson } from './InvalidSyntaxJson'; +import { ScreenActionSyntax, ScreenGuardedActionSyntax, ToolbarItemSyntax } from './Screens'; +import { SyntaxNode } from './SyntaxNode'; + +export function validateActionSubject(node: SyntaxNode, validateCollection: (value: unknown, kind: string, message: string) => void): void { + if (!['ScreenActionSyntax', 'ScreenGuardedActionSyntax', 'ToolbarItemSyntax'].includes(node.kind)) return; + const action = node as ScreenActionSyntax | ScreenGuardedActionSyntax | ToolbarItemSyntax; + if (!isValidActionSubject(action.subject)) throw new InvalidSyntaxJson('An action subject must be Item or Screen.'); + if (hasInapplicableToolbarSubject(action)) throw new InvalidSyntaxJson('Only an action toolbar item can have a subject.'); + if (action.kind === 'ScreenActionSyntax' && action.inputs !== undefined) validateCollection(action.inputs, 'InteractionArgumentSyntax', 'Action inputs must be a collection of arguments.'); +} + +function isValidActionSubject(subject: unknown): boolean { + return subject == null || subject === 'Item' || subject === 'Screen'; +} + +function hasInapplicableToolbarSubject(action: ScreenActionSyntax | ScreenGuardedActionSyntax | ToolbarItemSyntax): boolean { + return action.kind === 'ToolbarItemSyntax' && action.subject != null && action.syntaxKind !== 'Action'; +} diff --git a/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts b/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts index 94ea45d95..2f80c5512 100644 --- a/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts +++ b/Source/Screenplay/Compiler/Syntax/SyntaxInvariants.ts @@ -13,7 +13,7 @@ import { OperationPhaseSyntax } from './Operations'; import { ProducesSyntax } from './Reactions'; import { ObserverFilterSyntax } from './ObserverFilterSyntax'; import { SyntaxNode } from './SyntaxNode'; -import { ScreenActionSyntax, ScreenGuardedActionSyntax, ToolbarItemSyntax } from './Screens'; +import { validateActionSubject } from './ActionSubjectInvariants'; import { SpecificationEventSyntax, SpecificationStreamSyntax } from './Specifications'; import { isBlankImplementationHint } from '../Text/ImplementationHintText'; import { isSourceStreamName, isSourceStreamTypeName, sourceStreamPattern } from '../Text/SourceStreamNames'; @@ -32,12 +32,7 @@ const collection = (value: unknown, kind: string, message: string): void => { // The native ImplementationInvariants / OperationInvariants / EventSourceInvariants contracts. // Shared by the isolated strict reader and the writer, without pulling the transport schema into Monaco. export function validateSyntaxInvariants(node: SyntaxNode): void { - if (['ScreenActionSyntax', 'ScreenGuardedActionSyntax', 'ToolbarItemSyntax'].includes(node.kind)) { - const action = node as ScreenActionSyntax | ScreenGuardedActionSyntax | ToolbarItemSyntax; - if (action.subject != null && action.subject !== 'Item' && action.subject !== 'Screen') refuse('An action subject must be Item or Screen.'); - if (action.kind === 'ToolbarItemSyntax' && action.subject != null && action.syntaxKind !== 'Action') refuse('Only an action toolbar item can have a subject.'); - if (action.kind === 'ScreenActionSyntax' && action.inputs !== undefined) collection(action.inputs, 'InteractionArgumentSyntax', 'Action inputs must be a collection of arguments.'); - } + validateActionSubject(node, collection); const metadataError = publicEventMetadataError(node); if (metadataError !== undefined) refuse(metadataError); if (node.kind === 'ConceptSyntax') { diff --git a/Source/Screenplay/Compiler/for_parse/when_rejecting_subjects_on_non_action_toolbar_items.ts b/Source/Screenplay/Compiler/for_parse/when_rejecting_subjects_on_non_action_toolbar_items.ts new file mode 100644 index 000000000..29c66ccbf --- /dev/null +++ b/Source/Screenplay/Compiler/for_parse/when_rejecting_subjects_on_non_action_toolbar_items.ts @@ -0,0 +1,27 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { beforeEach, describe, it } from 'vitest'; +import { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes'; +import { ScreenToolbarSyntax } from '../Syntax/Screens'; +import { a_parsed_document } from './given/a_parsed_document'; + +describe('when rejecting subjects on non action toolbar items', () => { + let result: ReturnType; + let toolbar: ScreenToolbarSyntax; + + beforeEach(() => { + result = a_parsed_document('module Work', ' feature Items', ' slice StateView Details', + ' screen Details', ' toolbar', + ' item action navigate to Details for item', + ' item go navigate to action for screen', + ' item open dialog action for item'); + toolbar = result.value.modules[0].features[0].slices[0].screens[0].directives[0] as ScreenToolbarSyntax; + }); + + it('should reject each inapplicable subject clause', () => result.diagnostics.filter(diagnostic => diagnostic.code === DiagnosticCodes.InvalidActionSubjectClause).should.have.lengthOf(3)); + it('should not attach subjects to non action items', () => toolbar.items.every(item => item.subject == null).should.be.true); + it('should preserve the navigation named action', () => toolbar.items[1].target.should.equal('action')); + it('should preserve the item named action', () => toolbar.items[0].name.should.equal('action')); + it('should preserve the dialog named action', () => toolbar.items[2].target.should.equal('action')); +}); From 362be539bd53424453689ed35783cc52b73d37aa Mon Sep 17 00:00:00 2001 From: woksin Date: Sun, 25 Oct 2026 13:41:46 +0100 Subject: [PATCH 5/9] Pin the 0110 action subject advisories separately from the frozen v1 ESM boundary in the canonical vector specs (Cratis/Screenplay#1052) --- .../ActionSubjectAdvisories.cs | 73 +++++++++++++++++++ ...iling_the_v1_screen_composition_vectors.cs | 28 ++++++- .../when_loading_the_v1_screen_corpus.cs | 53 +++++++++++++- 3 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs diff --git a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs new file mode 100644 index 000000000..85fdf48fb --- /dev/null +++ b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs @@ -0,0 +1,73 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Diagnostics; + +namespace Cratis.Screenplay.CanonicalVectors.Specs.for_ScreenCompositionCorpus; + +/// +/// Separates the 0110 action subject advisories (PLAY0816/PLAY0817) from the frozen published corpus diagnostics. +/// +static class ActionSubjectAdvisories +{ + /// + /// Determines whether a diagnostic is an action subject advisory the compiler reports but the frozen corpus does not pin. + /// + /// The diagnostic to inspect. + /// True when the diagnostic is an inferred or changed action subject advisory. + public static bool IsAdvisory(Diagnostic diagnostic) => + string.Equals(diagnostic.Code, DiagnosticCodes.InferredActionSubject, StringComparison.Ordinal) || + string.Equals(diagnostic.Code, DiagnosticCodes.ChangedActionSubject, StringComparison.Ordinal); + + /// + /// Gets the diagnostics that belong to the frozen corpus boundary. + /// + /// The compile diagnostics. + /// The diagnostics without action subject advisories. + public static Diagnostic[] WithoutAdvisories(IEnumerable diagnostics) => [.. diagnostics.Where(diagnostic => !IsAdvisory(diagnostic))]; + + /// + /// Gets the action subject advisories as ordinally sorted "code: message" lines. + /// + /// The compile diagnostics. + /// The sorted advisory lines. + public static string[] Describe(IEnumerable diagnostics) => [.. diagnostics.Where(IsAdvisory).Select(diagnostic => $"{diagnostic.Code}: {diagnostic.Message}").Order(StringComparer.Ordinal)]; + + /// + /// Gets the action subject advisories as ordinally sorted "code@line action" lines. + /// + /// The compile diagnostics. + /// The sorted advisory locations. + public static string[] DescribeLocations(IEnumerable diagnostics) => [.. diagnostics.Where(IsAdvisory).Select(diagnostic => $"{diagnostic.Code}@{diagnostic.Location.Line} {ActionName(diagnostic)}").Order(StringComparer.Ordinal)]; + + /// + /// Gets the source line an advisory points at. + /// + /// The advisory. + /// The documents of the compiled source form, as display path, stable key and text. + /// The source line, or null when the location does not resolve to a document line. + public static string? SourceLineOf(Diagnostic diagnostic, IReadOnlyList<(string DisplayPath, string StableKey, string Text)> documents) + { + var document = documents.Count == 1 && diagnostic.Location.Path is null + ? documents[0] + : documents.FirstOrDefault(candidate => string.Equals(candidate.DisplayPath, diagnostic.Location.Path, StringComparison.Ordinal) || string.Equals(candidate.StableKey, diagnostic.Location.Path, StringComparison.Ordinal)); + if (document.Text is null) + { + return null; + } + + var lines = document.Text.Split('\n'); + return diagnostic.Location.Line >= 1 && diagnostic.Location.Line <= lines.Length ? lines[diagnostic.Location.Line - 1] : null; + } + + /// + /// Gets the action an advisory names. + /// + /// The advisory. + /// The action name quoted first in the message. + public static string ActionName(Diagnostic diagnostic) + { + var start = diagnostic.Message.IndexOf('\'', StringComparison.Ordinal) + 1; + return diagnostic.Message[start..diagnostic.Message.IndexOf('\'', start)]; + } +} diff --git a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs index 6cd417c0f..c95d4af4b 100644 --- a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs +++ b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs @@ -25,7 +25,33 @@ void Because() .ToArray()); } - [Fact] void should_compile_the_positive_composition_without_diagnostics() => _positive.Diagnostics.ShouldBeEmpty(); + [Fact] void should_compile_the_positive_composition_without_diagnostics_beyond_the_action_subject_advisories() => ActionSubjectAdvisories.WithoutAdvisories(_positive.Diagnostics).ShouldBeEmpty(); + + [Fact] + void should_report_the_action_subject_advisories_for_the_positive_composition() + { + string[] expected = + [ + "PLAY0816: Action 'CloseWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0816: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0816: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0816: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0816: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0817: Action 'CreateWorkItem' now infers 'for screen'; legacy row-name matching would use workItemId from item.workItemId, title from item.title, priority from item.priority" + ]; + ActionSubjectAdvisories.Describe(_positive.Diagnostics).ShouldEqual(expected); + } + + [Fact] + void should_locate_the_action_subject_advisories_for_the_positive_composition() => + ActionSubjectAdvisories.DescribeLocations(_positive.Diagnostics).ShouldEqual( + "PLAY0816@210 CreateWorkItem", + "PLAY0816@236 CreateWorkItem", + "PLAY0816@259 RenameWorkItem", + "PLAY0816@263 CloseWorkItem", + "PLAY0816@293 RenameWorkItem", + "PLAY0817@210 CreateWorkItem"); + [Fact] void should_carry_screen_contributions() => Screens(_positive.Value!).SelectMany(screen => screen.Contributions).Count().ShouldEqual(2); [Fact] void should_carry_document_level_exposures() => _positive.Value!.Exposures.Select(exposure => exposure.Owner).ShouldEqual(["WorkspaceFeatureShell", "EditWorkItemDialog"]); [Fact] void should_carry_instance_contributions() => _positive.Value!.InstanceContributions.Single().Contributions.Last().Items.Select(item => item.Id).ShouldEqual(["export:csv", "archive"]); diff --git a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs index 07a5c552c..283af0240 100644 --- a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs +++ b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs @@ -46,8 +46,9 @@ void Because() [Fact] void should_fail_backend_esm_admission_with_the_expected_diagnostics() { - ((string[])[.. _diagnostics.Select(diagnostic => diagnostic.Code)]).ShouldEqual([.. _corpus.EsmDiagnostics.Select(diagnostic => diagnostic.Code)]); - ((string[])[.. _diagnostics.Select(diagnostic => diagnostic.Message)]).ShouldEqual([.. _corpus.EsmDiagnostics.Select(diagnostic => diagnostic.Message)]); + var boundary = ActionSubjectAdvisories.WithoutAdvisories(_diagnostics); + ((string[])[.. boundary.Select(diagnostic => diagnostic.Code)]).ShouldEqual([.. _corpus.EsmDiagnostics.Select(diagnostic => diagnostic.Code)]); + ((string[])[.. boundary.Select(diagnostic => diagnostic.Message)]).ShouldEqual([.. _corpus.EsmDiagnostics.Select(diagnostic => diagnostic.Message)]); } [Fact] @@ -55,12 +56,58 @@ void should_keep_every_source_form_at_the_same_backend_esm_boundary() { foreach (var form in _corpus.SourceForms) { - var diagnostics = CompileForExecutableModel(form).ToArray(); + var diagnostics = ActionSubjectAdvisories.WithoutAdvisories(CompileForExecutableModel(form)); ((string[])[.. diagnostics.Select(diagnostic => diagnostic.Code).Order()]).ShouldEqual([.. _corpus.EsmDiagnostics.Select(diagnostic => diagnostic.Code).Order()]); ((string[])[.. diagnostics.Select(diagnostic => diagnostic.Message).Order()]).ShouldEqual([.. _corpus.EsmDiagnostics.Select(diagnostic => diagnostic.Message).Order()]); } } + [Fact] + void should_report_the_action_subject_advisories_for_the_screen_actions() + { + string[] expected = + [ + "PLAY0816: Action 'AddComment' infers 'for screen' from its declared data and identifier types", + "PLAY0816: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0816: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0817: Action 'AddComment' now infers 'for screen'; legacy row-name matching would use commentId from item.commentId, workItemId from item.workItemId, text from item.text" + ]; + ActionSubjectAdvisories.Describe(_diagnostics).ShouldEqual(expected); + } + + [Fact] + void should_report_the_same_action_subject_advisories_for_every_source_form() + { + var expected = ActionSubjectAdvisories.Describe(_diagnostics); + foreach (var form in _corpus.SourceForms) + { + ActionSubjectAdvisories.Describe(CompileForExecutableModel(form)).ShouldEqual(expected); + } + } + + [Fact] + void should_locate_the_action_subject_advisories_for_the_screen_actions() => + ActionSubjectAdvisories.DescribeLocations(_diagnostics).ShouldEqual( + "PLAY0816@229 CreateWorkItem", + "PLAY0816@276 RenameWorkItem", + "PLAY0816@290 AddComment", + "PLAY0817@290 AddComment"); + + [Fact] + void should_point_every_action_subject_advisory_at_its_action_in_every_source_form() + { + foreach (var form in _corpus.SourceForms) + { + var documents = form.Documents.Select(document => (document.DisplayPath, document.StableKey, document.Text)).ToArray(); + var advisories = CompileForExecutableModel(form).Where(ActionSubjectAdvisories.IsAdvisory).ToArray(); + advisories.Length.ShouldEqual(4); + foreach (var advisory in advisories) + { + (ActionSubjectAdvisories.SourceLineOf(advisory, documents) ?? string.Empty).ShouldContain($"action {ActionSubjectAdvisories.ActionName(advisory)}"); + } + } + } + [Fact] void should_keep_every_probe_backed_by_authored_syntax() { From d7ea66357c8db4a9d86687b3c45e69dda002f0d5 Mon Sep 17 00:00:00 2001 From: woksin Date: Sun, 25 Oct 2026 17:26:56 +0100 Subject: [PATCH 6/9] Renumber the action subject diagnostics to PLAY0817-PLAY0821 after main took PLAY0815/0816 (Cratis/Screenplay#1052) --- Documentation/screenplay/action-subjects.md | 12 ++-- Documentation/screenplay/diagnostics.md | 10 +-- .../ActionSubjectAdvisories.cs | 2 +- ...iling_the_v1_screen_composition_vectors.cs | 24 +++---- .../when_loading_the_v1_screen_corpus.cs | 16 ++--- .../Golden/screenplay-contract.json | 10 +-- .../Screenplay/Diagnostics/DiagnosticCodes.cs | 10 +-- .../when_repairing_action_subjects.ts | 14 ++-- .../action-subjects/native.diagnostics.json | 70 +++++++++---------- .../typescript.diagnostics.json | 70 +++++++++---------- ..._exporting_action_subject_fixture_packs.ts | 2 +- .../Compiler/Diagnostics/DiagnosticCodes.ts | 10 +-- ...hen_preserving_action_subject_contracts.ts | 2 +- .../for_parse/when_parsing_screens.ts | 4 +- .../when_parsing_the_repository_samples.ts | 2 +- .../when_resolving_action_subjects.ts | 6 +- .../screenplay-language/diagnostic-codes.ts | 10 +-- .../when_editing_action_subjects.ts | 8 +-- 18 files changed, 141 insertions(+), 141 deletions(-) diff --git a/Documentation/screenplay/action-subjects.md b/Documentation/screenplay/action-subjects.md index 1e96a26b9..5a0084e79 100644 --- a/Documentation/screenplay/action-subjects.md +++ b/Documentation/screenplay/action-subjects.md @@ -40,11 +40,11 @@ Without a clause, a plain or toolbar action infers Item only for exactly one col | Code | Severity | Meaning | |---|---|---| -| PLAY0815 | Error | Malformed, duplicate or misplaced subject clause. | -| PLAY0816 | Information | Explains an omitted plain/toolbar subject's inference. | -| PLAY0817 | Warning | Effective row binding differs from legacy case-insensitive name matching. | -| PLAY0818 | Warning | Multiple nominal keys could bind an input; write an explicit binding. | -| PLAY0819 | Warning | Guarded `for screen` has collection-valued data and cannot choose one item. | +| PLAY0817 | Error | Malformed, duplicate or misplaced subject clause. | +| PLAY0818 | Information | Explains an omitted plain/toolbar subject's inference. | +| PLAY0819 | Warning | Effective row binding differs from legacy case-insensitive name matching. | +| PLAY0820 | Warning | Multiple nominal keys could bind an input; write an explicit binding. | +| PLAY0821 | Warning | Guarded `for screen` has collection-valued data and cannot choose one item. | PLAY0319 still covers malformed/duplicate input syntax, PLAY0345 still covers unknown subject fields, and PLAY0346 still covers a missing or ambiguous guarded subject. Fixes can make inference explicit or retain legacy row behavior using explicit bindings when declaration proof is unambiguous. No fix silently rewrites source or guesses an imported declaration. @@ -58,6 +58,6 @@ Runtime execution and rendering proof are Scene-owned. Compiler fixtures and edi ## Corpus migration gate -Before making inference part of a Scene release, compile each real application workspace with its imports and collect PLAY0816 and PLAY0817 by source path, line and command. Treat an unresolvable declaration as insufficient evidence, not a successful migration. For every PLAY0817, review the previous row-name bindings alongside the proposed effective inputs; either state `for screen`, state `for item` with the intended explicit inputs, or retain the previous bindings explicitly. Apply a proposed repair transactionally and compile the complete workspace again. Do not bulk-accept a binding based only on its spelling. +Before making inference part of a Scene release, compile each real application workspace with its imports and collect PLAY0818 and PLAY0819 by source path, line and command. Treat an unresolvable declaration as insufficient evidence, not a successful migration. For every PLAY0819, review the previous row-name bindings alongside the proposed effective inputs; either state `for screen`, state `for item` with the intended explicit inputs, or retain the previous bindings explicitly. Apply a proposed repair transactionally and compile the complete workspace again. Do not bulk-accept a binding based only on its spelling. Track that real-corpus scan and disposition review as a follow-up to Screenplay#1052, before the consuming Scene release. The repository samples and paired fixture packs are the compiler regression gate, not evidence that an external corpus has been migrated. Scene must separately verify selection, form/renderer inputs and guarded single-record behavior against the effective pack; it must not reinterpret the raw authored pack as resolved execution metadata. diff --git a/Documentation/screenplay/diagnostics.md b/Documentation/screenplay/diagnostics.md index 07075f40e..bc8aa5780 100644 --- a/Documentation/screenplay/diagnostics.md +++ b/Documentation/screenplay/diagnostics.md @@ -15,11 +15,11 @@ Decision 0110 adds the following catalog entries: | Code | Severity | Meaning | |---|---|---| -| `PLAY0815` | Error | An action subject clause is malformed, duplicated, or attached to a non-action toolbar item. Use one `for item` or `for screen` before the inline label. | -| `PLAY0816` | Information | An omitted plain/toolbar action subject is inferred from its declared data and identifier types. | -| `PLAY0817` | Warning | Effective row binding differs from legacy case-insensitive name matching. Make intent explicit; a safe repair may retain legacy mappings. | -| `PLAY0818` | Warning | Several declared nominal keys could fill an input. Write an explicit binding. | -| `PLAY0819` | Warning | A guarded action `for screen` cannot choose an item from collection-valued data. | +| `PLAY0817` | Error | An action subject clause is malformed, duplicated, or attached to a non-action toolbar item. Use one `for item` or `for screen` before the inline label. | +| `PLAY0818` | Information | An omitted plain/toolbar action subject is inferred from its declared data and identifier types. | +| `PLAY0819` | Warning | Effective row binding differs from legacy case-insensitive name matching. Make intent explicit; a safe repair may retain legacy mappings. | +| `PLAY0820` | Warning | Several declared nominal keys could fill an input. Write an explicit binding. | +| `PLAY0821` | Warning | A guarded action `for screen` cannot choose an item from collection-valued data. | See [action subjects](action-subjects.md#diagnostics-and-migration) for triggers and safe fixes. PLAY0319, PLAY0345 and PLAY0346 keep their existing meanings. diff --git a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs index 85fdf48fb..042573483 100644 --- a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs +++ b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/ActionSubjectAdvisories.cs @@ -6,7 +6,7 @@ namespace Cratis.Screenplay.CanonicalVectors.Specs.for_ScreenCompositionCorpus; /// -/// Separates the 0110 action subject advisories (PLAY0816/PLAY0817) from the frozen published corpus diagnostics. +/// Separates the 0110 action subject advisories (PLAY0818/PLAY0819) from the frozen published corpus diagnostics. /// static class ActionSubjectAdvisories { diff --git a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs index c95d4af4b..c9c0e9e9a 100644 --- a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs +++ b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_compiling_the_v1_screen_composition_vectors.cs @@ -32,12 +32,12 @@ void should_report_the_action_subject_advisories_for_the_positive_composition() { string[] expected = [ - "PLAY0816: Action 'CloseWorkItem' infers 'for screen' from its declared data and identifier types", - "PLAY0816: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", - "PLAY0816: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", - "PLAY0816: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", - "PLAY0816: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", - "PLAY0817: Action 'CreateWorkItem' now infers 'for screen'; legacy row-name matching would use workItemId from item.workItemId, title from item.title, priority from item.priority" + "PLAY0818: Action 'CloseWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0818: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0818: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0818: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0818: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0819: Action 'CreateWorkItem' now infers 'for screen'; legacy row-name matching would use workItemId from item.workItemId, title from item.title, priority from item.priority" ]; ActionSubjectAdvisories.Describe(_positive.Diagnostics).ShouldEqual(expected); } @@ -45,12 +45,12 @@ void should_report_the_action_subject_advisories_for_the_positive_composition() [Fact] void should_locate_the_action_subject_advisories_for_the_positive_composition() => ActionSubjectAdvisories.DescribeLocations(_positive.Diagnostics).ShouldEqual( - "PLAY0816@210 CreateWorkItem", - "PLAY0816@236 CreateWorkItem", - "PLAY0816@259 RenameWorkItem", - "PLAY0816@263 CloseWorkItem", - "PLAY0816@293 RenameWorkItem", - "PLAY0817@210 CreateWorkItem"); + "PLAY0818@210 CreateWorkItem", + "PLAY0818@236 CreateWorkItem", + "PLAY0818@259 RenameWorkItem", + "PLAY0818@263 CloseWorkItem", + "PLAY0818@293 RenameWorkItem", + "PLAY0819@210 CreateWorkItem"); [Fact] void should_carry_screen_contributions() => Screens(_positive.Value!).SelectMany(screen => screen.Contributions).Count().ShouldEqual(2); [Fact] void should_carry_document_level_exposures() => _positive.Value!.Exposures.Select(exposure => exposure.Owner).ShouldEqual(["WorkspaceFeatureShell", "EditWorkItemDialog"]); diff --git a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs index 283af0240..4d9894d49 100644 --- a/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs +++ b/Source/DotNET/Screenplay.CanonicalVectors.Specs/for_ScreenCompositionCorpus/when_loading_the_v1_screen_corpus.cs @@ -67,10 +67,10 @@ void should_report_the_action_subject_advisories_for_the_screen_actions() { string[] expected = [ - "PLAY0816: Action 'AddComment' infers 'for screen' from its declared data and identifier types", - "PLAY0816: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", - "PLAY0816: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", - "PLAY0817: Action 'AddComment' now infers 'for screen'; legacy row-name matching would use commentId from item.commentId, workItemId from item.workItemId, text from item.text" + "PLAY0818: Action 'AddComment' infers 'for screen' from its declared data and identifier types", + "PLAY0818: Action 'CreateWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0818: Action 'RenameWorkItem' infers 'for screen' from its declared data and identifier types", + "PLAY0819: Action 'AddComment' now infers 'for screen'; legacy row-name matching would use commentId from item.commentId, workItemId from item.workItemId, text from item.text" ]; ActionSubjectAdvisories.Describe(_diagnostics).ShouldEqual(expected); } @@ -88,10 +88,10 @@ void should_report_the_same_action_subject_advisories_for_every_source_form() [Fact] void should_locate_the_action_subject_advisories_for_the_screen_actions() => ActionSubjectAdvisories.DescribeLocations(_diagnostics).ShouldEqual( - "PLAY0816@229 CreateWorkItem", - "PLAY0816@276 RenameWorkItem", - "PLAY0816@290 AddComment", - "PLAY0817@290 AddComment"); + "PLAY0818@229 CreateWorkItem", + "PLAY0818@276 RenameWorkItem", + "PLAY0818@290 AddComment", + "PLAY0819@290 AddComment"); [Fact] void should_point_every_action_subject_advisory_at_its_action_in_every_source_form() diff --git a/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json b/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json index 785309102..e5bd0205a 100644 --- a/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json +++ b/Source/DotNET/Screenplay.Contracts/Golden/screenplay-contract.json @@ -45038,7 +45038,7 @@ "retired": false }, { - "code": "PLAY0815", + "code": "PLAY0817", "name": "InvalidActionSubjectClause", "severity": "error", "severities": [ @@ -45049,7 +45049,7 @@ "retired": false }, { - "code": "PLAY0816", + "code": "PLAY0818", "name": "InferredActionSubject", "severity": "information", "severities": [ @@ -45060,7 +45060,7 @@ "retired": false }, { - "code": "PLAY0817", + "code": "PLAY0819", "name": "ChangedActionSubject", "severity": "warning", "severities": [ @@ -45071,7 +45071,7 @@ "retired": false }, { - "code": "PLAY0818", + "code": "PLAY0820", "name": "AmbiguousActionInputBinding", "severity": "warning", "severities": [ @@ -45082,7 +45082,7 @@ "retired": false }, { - "code": "PLAY0819", + "code": "PLAY0821", "name": "UnsupportedActionSubjectContext", "severity": "warning", "severities": [ diff --git a/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs b/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs index 1740ec85d..4f8e52d22 100644 --- a/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs +++ b/Source/DotNET/Screenplay/Diagnostics/DiagnosticCodes.cs @@ -27,19 +27,19 @@ namespace Cratis.Screenplay.Diagnostics; public static class DiagnosticCodes { /// Malformed, duplicate or inapplicable action subject clause. - public const string InvalidActionSubjectClause = "PLAY0815"; + public const string InvalidActionSubjectClause = "PLAY0817"; /// The inferred subject of an action without an authored clause. - public const string InferredActionSubject = "PLAY0816"; + public const string InferredActionSubject = "PLAY0818"; /// An inferred action subject differs from legacy row-name matching. - public const string ChangedActionSubject = "PLAY0817"; + public const string ChangedActionSubject = "PLAY0819"; /// Several declared keys are eligible for an action input. - public const string AmbiguousActionInputBinding = "PLAY0818"; + public const string AmbiguousActionInputBinding = "PLAY0820"; /// A guarded screen action cannot obtain an item from a collection. - public const string UnsupportedActionSubjectContext = "PLAY0819"; + public const string UnsupportedActionSubjectContext = "PLAY0821"; // The document and its top level. diff --git a/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts index e5636da74..8b2ffd43f 100644 --- a/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts +++ b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts @@ -21,20 +21,20 @@ module Work action Retry // preserve this comment `; -const fixes = (text: string, code = 'PLAY0817') => findQuickFixes(text, { diagnosticCode: code }); +const fixes = (text: string, code = 'PLAY0819') => findQuickFixes(text, { diagnosticCode: code }); describe('when repairing action subjects', () => { it('should advertise both inference diagnostics', () => { - expect(isQuickFixDiagnostic('PLAY0816')).toBe(true); - expect(isQuickFixDiagnostic('PLAY0817')).toBe(true); + expect(isQuickFixDiagnostic('PLAY0818')).toBe(true); + expect(isQuickFixDiagnostic('PLAY0819')).toBe(true); }); it('should make the inferred item subject explicit without rewriting comments', () => { - const fix = fixes(source, 'PLAY0816'); + const fix = fixes(source, 'PLAY0818'); expect(fix).toHaveLength(1); const edited = applyQuickFixEdits(source, fix[0].edits)!; expect(edited).toContain('action Retry for item // preserve this comment'); - expect(parse(edited).diagnostics.some(diagnostic => ['PLAY0816', 'PLAY0817'].includes(diagnostic.code))).toBe(false); - expect(fixes(edited, 'PLAY0816')).toEqual([]); + expect(parse(edited).diagnostics.some(diagnostic => ['PLAY0818', 'PLAY0819'].includes(diagnostic.code))).toBe(false); + expect(fixes(edited, 'PLAY0818')).toEqual([]); }); it('should suppress legacy intent that the effective key fallback cannot represent', () => { expect(fixes(source).map(fix => fix.title)).toEqual(["Use 'for item' (item-bound action)", "Use 'for screen' (no selection binding)"]); @@ -67,6 +67,6 @@ describe('when repairing action subjects', () => { expect(prepareActionSubjectQuickFixes(invalid, {})()).toEqual([]); }); it('should not guess declarations in imported buffer snapshots', () => { - expect(findQuickFixes(source, { documents: new Map([['a.play', source], ['b.play', '']]), path: 'a.play', diagnosticCode: 'PLAY0816' })).toEqual([]); + expect(findQuickFixes(source, { documents: new Map([['a.play', source], ['b.play', '']]), path: 'a.play', diagnosticCode: 'PLAY0818' })).toEqual([]); }); }); diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json b/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json index f1e67cec0..83f1ac3e1 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/native.diagnostics.json @@ -1,6 +1,6 @@ [ { - "code": "PLAY0815", + "code": "PLAY0817", "severity": "error", "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", "location": { @@ -9,7 +9,7 @@ } }, { - "code": "PLAY0815", + "code": "PLAY0817", "severity": "error", "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", "location": { @@ -18,7 +18,7 @@ } }, { - "code": "PLAY0815", + "code": "PLAY0817", "severity": "error", "message": "Invalid action subject clause - expected one \u0027for item\u0027 or \u0027for screen\u0027 before the label on an action", "location": { @@ -45,7 +45,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -54,7 +54,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { @@ -63,7 +63,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -72,7 +72,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Foreign\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -81,7 +81,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Foreign\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use tenantId from item.tenantId", "location": { @@ -90,7 +90,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Optional\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -99,7 +99,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Optional\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", "location": { @@ -108,7 +108,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Generated\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -117,7 +117,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Primitive\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -126,7 +126,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Primitive\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", "location": { @@ -135,7 +135,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027TwoIdentifiers\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -144,7 +144,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027TwoIdentifiers\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, tenantId from item.tenantId", "location": { @@ -153,7 +153,7 @@ } }, { - "code": "PLAY0818", + "code": "PLAY0820", "severity": "warning", "message": "Input \u0027itemId\u0027 of action \u0027Retry\u0027 matches several declared key fields - write an explicit binding", "location": { @@ -162,7 +162,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -171,7 +171,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use name from item.name", "location": { @@ -180,7 +180,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -189,7 +189,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemID", "location": { @@ -198,7 +198,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -207,7 +207,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for screen\u0027; legacy row-name matching would use itemId from item.itemId", "location": { @@ -216,7 +216,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Imported.Inventory.Commands.Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -225,7 +225,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Imported.Inventory.Commands.Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use no row property", "location": { @@ -234,7 +234,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Missing.Commands.Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -243,7 +243,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -252,7 +252,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { @@ -261,7 +261,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -270,7 +270,7 @@ } }, { - "code": "PLAY0819", + "code": "PLAY0821", "severity": "warning", "message": "A guarded action \u0027for screen\u0027 cannot use a collection as \u0027item\u0027 - use a single-record data context or \u0027for item\u0027", "location": { @@ -297,7 +297,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -306,7 +306,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -315,7 +315,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for item\u0027 from its declared data and identifier types", "location": { @@ -324,7 +324,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action \u0027Retry\u0027 now infers \u0027for item\u0027; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { @@ -333,7 +333,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { @@ -342,7 +342,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action \u0027Retry\u0027 infers \u0027for screen\u0027 from its declared data and identifier types", "location": { diff --git a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json index cd76bfb59..4722c9d69 100644 --- a/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json +++ b/Source/Screenplay/Compiler/Conformance/action-subjects/typescript.diagnostics.json @@ -1,6 +1,6 @@ [ { - "code": "PLAY0815", + "code": "PLAY0817", "severity": "error", "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", "location": { @@ -9,7 +9,7 @@ } }, { - "code": "PLAY0815", + "code": "PLAY0817", "severity": "error", "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", "location": { @@ -18,7 +18,7 @@ } }, { - "code": "PLAY0815", + "code": "PLAY0817", "severity": "error", "message": "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", "location": { @@ -45,7 +45,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -54,7 +54,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { @@ -63,7 +63,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -72,7 +72,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Foreign' infers 'for screen' from its declared data and identifier types", "location": { @@ -81,7 +81,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Foreign' now infers 'for screen'; legacy row-name matching would use tenantId from item.tenantId", "location": { @@ -90,7 +90,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Optional' infers 'for screen' from its declared data and identifier types", "location": { @@ -99,7 +99,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Optional' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", "location": { @@ -108,7 +108,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Generated' infers 'for screen' from its declared data and identifier types", "location": { @@ -117,7 +117,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Primitive' infers 'for screen' from its declared data and identifier types", "location": { @@ -126,7 +126,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Primitive' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", "location": { @@ -135,7 +135,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'TwoIdentifiers' infers 'for item' from its declared data and identifier types", "location": { @@ -144,7 +144,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'TwoIdentifiers' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, tenantId from item.tenantId", "location": { @@ -153,7 +153,7 @@ } }, { - "code": "PLAY0818", + "code": "PLAY0820", "severity": "warning", "message": "Input 'itemId' of action 'Retry' matches several declared key fields - write an explicit binding", "location": { @@ -162,7 +162,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", "location": { @@ -171,7 +171,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Retry' now infers 'for screen'; legacy row-name matching would use name from item.name", "location": { @@ -180,7 +180,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -189,7 +189,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemID", "location": { @@ -198,7 +198,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", "location": { @@ -207,7 +207,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Retry' now infers 'for screen'; legacy row-name matching would use itemId from item.itemId", "location": { @@ -216,7 +216,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Imported.Inventory.Commands.Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -225,7 +225,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Imported.Inventory.Commands.Retry' now infers 'for item'; legacy row-name matching would use no row property", "location": { @@ -234,7 +234,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Missing.Commands.Retry' infers 'for screen' from its declared data and identifier types", "location": { @@ -243,7 +243,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -252,7 +252,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { @@ -261,7 +261,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -270,7 +270,7 @@ } }, { - "code": "PLAY0819", + "code": "PLAY0821", "severity": "warning", "message": "A guarded action 'for screen' cannot use a collection as 'item' - use a single-record data context or 'for item'", "location": { @@ -297,7 +297,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", "location": { @@ -306,7 +306,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -315,7 +315,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for item' from its declared data and identifier types", "location": { @@ -324,7 +324,7 @@ } }, { - "code": "PLAY0817", + "code": "PLAY0819", "severity": "warning", "message": "Action 'Retry' now infers 'for item'; legacy row-name matching would use itemId from item.itemId, name from item.name", "location": { @@ -333,7 +333,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", "location": { @@ -342,7 +342,7 @@ } }, { - "code": "PLAY0816", + "code": "PLAY0818", "severity": "information", "message": "Action 'Retry' infers 'for screen' from its declared data and identifier types", "location": { diff --git a/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts b/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts index 433e840a9..8b79d0058 100644 --- a/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts +++ b/Source/Screenplay/Compiler/Conformance/for_Conformance/when_exporting_action_subject_fixture_packs.ts @@ -15,7 +15,7 @@ const directory = fileURLToPath(new URL('../action-subjects/', import.meta.url)) const compiled = parse(readFileSync(`${directory}source.play`, 'utf8')); const raw = toSyntaxJson(compiled.value); const effective = resolveActionSubjects(compiled.value).value; -const relevant = new Set(['PLAY0319', 'PLAY0345', 'PLAY0346', 'PLAY0815', 'PLAY0816', 'PLAY0817', 'PLAY0818', 'PLAY0819']); +const relevant = new Set(['PLAY0319', 'PLAY0345', 'PLAY0346', 'PLAY0817', 'PLAY0818', 'PLAY0819', 'PLAY0820', 'PLAY0821']); interface LocatedNode { path: string; diff --git a/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts b/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts index b5881cda5..4f8c329d3 100644 --- a/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts +++ b/Source/Screenplay/Compiler/Diagnostics/DiagnosticCodes.ts @@ -4,11 +4,11 @@ // Shared diagnostic names, including the explicitly C#-only checks below. Catalogue membership does // not imply TypeScript validation support; see Documentation/screenplay/editor-diagnostics.md. export const DiagnosticCodes = { - InvalidActionSubjectClause: 'PLAY0815', - InferredActionSubject: 'PLAY0816', - ChangedActionSubject: 'PLAY0817', - AmbiguousActionInputBinding: 'PLAY0818', - UnsupportedActionSubjectContext: 'PLAY0819', + InvalidActionSubjectClause: 'PLAY0817', + InferredActionSubject: 'PLAY0818', + ChangedActionSubject: 'PLAY0819', + AmbiguousActionInputBinding: 'PLAY0820', + UnsupportedActionSubjectContext: 'PLAY0821', DuplicateBehaviorAttachment: 'PLAY0340', UnknownMatchPattern: 'PLAY0366', InvalidMatchPattern: 'PLAY0367', diff --git a/Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts b/Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts index d7a71abe2..17c099c45 100644 --- a/Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts +++ b/Source/Screenplay/Compiler/Syntax/for_SyntaxJson/when_preserving_action_subject_contracts.ts @@ -58,7 +58,7 @@ describe('when preserving action subject contracts', () => { }); for (const header of ['action Retry for', 'action Retry for planet', 'action Retry for item for screen', 'toolbar\n item go navigate to Details for item']) { it(`should reject malformed or inapplicable scope: ${header}`, () => { - expect(parse(source.replace('action Retry for item label "Retry for screen"', header)).diagnostics.some(diagnostic => diagnostic.code === 'PLAY0815')).toBe(true); + expect(parse(source.replace('action Retry for item label "Retry for screen"', header)).diagnostics.some(diagnostic => diagnostic.code === 'PLAY0817')).toBe(true); }); } }); diff --git a/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts b/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts index 9a428246a..90e727b39 100644 --- a/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts +++ b/Source/Screenplay/Compiler/for_parse/when_parsing_screens.ts @@ -51,7 +51,7 @@ describe('when parsing screens', () => { screens = result.value.modules[0].features[0].slices[0].screens; }); - it('should explain the omitted action subject', () => result.diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity]).should.deep.equal([['PLAY0816', 'information']])); + it('should explain the omitted action subject', () => result.diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity]).should.deep.equal([['PLAY0818', 'information']])); it('should read both screens', () => screens.map(screen => screen.name).should.deep.equal(['Invoices', 'Details'])); it('should read the directives in order', () => screens[0].directives.map(directive => directive.kind).should.deep.equal([ @@ -123,7 +123,7 @@ describe('when parsing screen release UI bindings', () => { component = result.value.modules[0].features[0].slices[0].screens[0].directives[1] as import('../Syntax/Screens').ScreenComponentSyntax; }); - it('should explain the omitted toolbar action subject', () => result.diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity]).should.deep.equal([['PLAY0816', 'information']])); + it('should explain the omitted toolbar action subject', () => result.diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity]).should.deep.equal([['PLAY0818', 'information']])); it('should read toolbar parameters as component bindings', () => toolbar.items[0].parameters[0].binding.should.deep.include({ bindingKind: 'ComponentProperty', componentId: 'invoices', path: 'selectedItem.id' })); it('should read toolbar presentation', () => toolbar.items[1].presentation[0].value!.should.equal('primary')); it('should read component query context', () => component.context!.should.deep.include({ bindingKind: 'QueryResult', query: 'AllInvoices', path: 'items' })); diff --git a/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts b/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts index 9f6cae0f1..8b4797461 100644 --- a/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts +++ b/Source/Screenplay/Compiler/for_parse/when_parsing_the_repository_samples.ts @@ -70,7 +70,7 @@ describe('when parsing the repository samples', () => { `${generatedInputSource}:10 PLAY0485 Generated property 'projectId' cannot be supplied as request or form input.`, // Action-subject packs include deliberate parser recovery and malformed clause/input cases. `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:40 PLAY0036 Command 'TwoIdentifiers' already marks 'itemId' as identifier - only one property can be the identifier`, - ...[142, 144, 147].map(line => `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:${line} PLAY0815 Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action`), + ...[142, 144, 147].map(line => `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:${line} PLAY0817 Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action`), `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:150 PLAY0319 Invalid argument 'with itemId' - expected 'with from '`, `${join(repository, 'Source/Screenplay/Compiler/Conformance/action-subjects/source.play')}:152 PLAY0319 Duplicate argument 'name' - supply each input only once`, // The metadata-only fixture deliberately declares no operational public output. diff --git a/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts index 87d595548..6024f8818 100644 --- a/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts +++ b/Source/Screenplay/Compiler/for_parse/when_resolving_action_subjects.ts @@ -30,7 +30,7 @@ describe('when resolving action subjects', () => { it('should bind a renamed key by nominal concept', () => { const resolved = resolveActionSubjects(parse(source.replace(' itemId TenantId\n', '')).value); action(resolved.value).inputs![0].binding.should.equal('item.rowId'); - resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0817').should.equal(true); + resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0819').should.equal(true); }); it('should retain an explicit mapping', () => { const effective = resolveActionSubjects(parse(source + ' for item\n with itemId from $context.currentItem').value).value; @@ -59,12 +59,12 @@ describe('when resolving action subjects', () => { const ambiguous = source.replace(' itemId TenantId\n', ' otherId ItemId key\n') + ' for item'; const resolved = resolveActionSubjects(parse(ambiguous).value); action(resolved.value).inputs!.should.deep.equal([]); - resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0818' && diagnostic.severity === 'warning').should.equal(true); + resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0820' && diagnostic.severity === 'warning').should.equal(true); }); it('should retain a guarded screen collection without selecting an item', () => { const guarded = source.replace(' action Retry', ' action "Retry" for screen\n when item.ready == true execute Retry'); const resolved = resolveActionSubjects(parse(guarded).value); (screen(resolved.value).directives[1] as ScreenGuardedActionSyntax).alternatives[0].arguments.should.deep.equal([]); - resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0819' && diagnostic.severity === 'warning').should.equal(true); + resolved.diagnostics.some(diagnostic => diagnostic.code === 'PLAY0821' && diagnostic.severity === 'warning').should.equal(true); }); }); diff --git a/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts b/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts index 9dcb64e04..03173ef7b 100644 --- a/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts +++ b/Source/Screenplay/Monaco/screenplay-language/diagnostic-codes.ts @@ -169,11 +169,11 @@ export const diagnosticCodes = { unsupportedActionConditionOperand: 'PLAY0344', unknownActionSubjectField: 'PLAY0345', unresolvedActionSubject: 'PLAY0346', - invalidActionSubjectClause: 'PLAY0815', - inferredActionSubject: 'PLAY0816', - changedActionSubject: 'PLAY0817', - ambiguousActionInputBinding: 'PLAY0818', - unsupportedActionSubjectContext: 'PLAY0819', + invalidActionSubjectClause: 'PLAY0817', + inferredActionSubject: 'PLAY0818', + changedActionSubject: 'PLAY0819', + ambiguousActionInputBinding: 'PLAY0820', + unsupportedActionSubjectContext: 'PLAY0821', unreachableActionAlternative: 'PLAY0347', unknownActionArgumentProperty: 'PLAY0348', invalidRefusalBranch: 'PLAY0538', diff --git a/Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts b/Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts index cba5c1fb7..a5221c78f 100644 --- a/Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts +++ b/Source/Screenplay/Monaco/screenplay-language/for_actionSubjects/when_editing_action_subjects.ts @@ -24,7 +24,7 @@ module Work action Retry `; const range = { startLineNumber: 12, startColumn: 9, endLineNumber: 12, endColumn: 21 } as Range; -const context = { only: 'quickfix', markers: [{ ...range, code: 'PLAY0816', message: 'Infer subject', severity: 1 }], trigger: 1 } as languages.CodeActionContext; +const context = { only: 'quickfix', markers: [{ ...range, code: 'PLAY0818', message: 'Infer subject', severity: 1 }], trigger: 1 } as languages.CodeActionContext; const token = { isCancellationRequested: false } as CancellationToken; function model(): editor.ITextModel { @@ -48,7 +48,7 @@ describe('when editing action subjects', () => { it('should surface every action-subject diagnostic from the shared compiler fixture', () => { const fixture = readFileSync(new URL('../../../Compiler/Conformance/action-subjects/source.play', import.meta.url), 'utf8'); const codes = validateLines(fixture.split('\n')).map(issue => issue.code); - for (const code of ['PLAY0815', 'PLAY0816', 'PLAY0817', 'PLAY0818', 'PLAY0819']) expect(codes).toContain(code); + for (const code of ['PLAY0817', 'PLAY0818', 'PLAY0819', 'PLAY0820', 'PLAY0821']) expect(codes).toContain(code); }); for (const header of ['action Retry ', 'action "Choose" ', 'item retry action Retry ']) { it(`should offer explicit scope on ${header}`, () => expect(labels(header)).toEqual(['for item', 'for screen'])); @@ -59,10 +59,10 @@ describe('when editing action subjects', () => { expect(hoverContent(['screen S', ' action "for item"'], 1, 'item', 15, 19)).toBeNull(); }); it('should forward inference code severity message and source location', () => { - const diagnostics = parse(source).diagnostics.filter(diagnostic => diagnostic.code === 'PLAY0816'); + const diagnostics = parse(source).diagnostics.filter(diagnostic => diagnostic.code === 'PLAY0818'); const expected = diagnostics.map(diagnostic => [diagnostic.code, diagnostic.severity, diagnostic.message, diagnostic.location.line - 1, diagnostic.location.column]); for (const context of [undefined, { compilerDiagnostics: diagnostics }]) { - expect(validateLines(source.split('\n'), context).filter(marker => marker.code === 'PLAY0816').map(marker => [marker.code, marker.severity, marker.message, marker.line, marker.startColumn])).toEqual(expected); + expect(validateLines(source.split('\n'), context).filter(marker => marker.code === 'PLAY0818').map(marker => [marker.code, marker.severity, marker.message, marker.line, marker.startColumn])).toEqual(expected); } }); it('should offer a version-bound compiler repair', async () => { From 28da1fa22e3a0bf81ae916aa40642161ab23b6e6 Mon Sep 17 00:00:00 2001 From: woksin Date: Sun, 25 Oct 2026 20:49:21 +0100 Subject: [PATCH 7/9] Regenerate native-owned writer collection contracts after merging invocation and action subject syntax (Cratis/Screenplay#1052) --- Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts b/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts index df56f2538..ac5c295b4 100644 --- a/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts +++ b/Source/Screenplay/Compiler/Syntax/SyntaxCollections.ts @@ -2,4 +2,4 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // Generated from C# SyntaxSchema; all typed member contracts are native-owned. -export const syntaxCollections = {"kinds":["AddMappingSyntax","AllSyntax","ApplicationSyntax","ApplicationTriggerInteractionTriggerSyntax","ArrangementContainerSyntax","ArrangementOverrideSyntax","ArrangementSlotSyntax","ArrangementSyntax","AuthenticatedConditionSyntax","AuthenticationProviderSyntax","AuthenticationSyntax","AuthorizeSyntax","NavigationItemSyntax","NavigationLogoSyntax","NavigationRegionSyntax","NavigationTargetSyntax","BehaviorArgumentSyntax","BehaviorParameterSyntax","BehaviorSyntax","BuiltInInteractionTriggerSyntax","CaptureAppendSyntax","CaptureChildrenSyntax","CaptureMapEntrySyntax","CaptureNestedSyntax","CaptureSourceSettingSyntax","CaptureSourceSyntax","CaptureSplitSyntax","CaptureSyntax","CaptureTranslationSyntax","CaptureWhenSyntax","CausedByExpressionSyntax","ClockOffsetExpressionSyntax","CommandCalendarSyntax","DateOfExpressionSyntax","SpecificationTimeZoneSyntax","TimeZoneSyntax","CaseValueExpressionSyntax","ChildrenSyntax","ClaimConditionSyntax","ClaimIdentitySourceSyntax","CodeIdentitySourceSyntax","FileIdentitySourceSyntax","IdentitySyntax","IdentityDetailSyntax","QueryIdentitySourceSyntax","ClearMappingSyntax","ClearWithSyntax","CloseDialogActionSyntax","CodeBlockSyntax","ComponentExposedValueSyntax","ComponentOutletSyntax","ComponentPropertySyntax","CodeValidateSyntax","CommandSyntax","CommandStreamSyntax","ObserverFilterSyntax","ComparisonConditionSyntax","CompositeKeySyntax","ConceptAttributeSyntax","ConceptSyntax","GenerationSyntax","ConcurrencySyntax","ConfirmActionSyntax","ContextExpressionSyntax","IdentityExpressionSyntax","ContributionSyntax","ContributionDestinationSyntax","CountMappingSyntax","DeclarativeValidateSyntax","DecrementMappingSyntax","DialogTemplateSyntax","DomainSyntax","EnvironmentExpressionSyntax","EventContextExpressionSyntax","EventInteractionTriggerSyntax","EventSourceIdExpressionSyntax","EventSourceSyntax","EventStreamIdPartSyntax","EventStreamSyntax","EventSpecSyntax","EventSyntax","EverySyntax","ExecuteCommandActionSyntax","ExpressionKeySyntax","FeatureSyntax","FileConstraintSyntax","FileImportSyntax","FileReferenceSyntax","FormColumnSyntax","ExposureSyntax","ExposedPropertySyntax","InstanceContributionsSyntax","InstanceContributionSyntax","ContributedItemSyntax","ContributedItemValueSyntax","ScreenContributionSyntax","TemplateSlotContentSyntax","CommandFormLayoutSyntax","FormLayoutColumnSyntax","FormFieldPlacementSyntax","FormWidthSyntax","FormFieldSyntax","FormPopulateFromItemSyntax","FormPopulateViaQuerySyntax","FormSyntax","FromSyntax","HandlerSyntax","ImplementationSyntax","ImplementationHintSyntax","SystemSyntax","OperationSyntax","OperationPhaseSyntax","SpecificationExampleSyntax","SpecificationParameterSyntax","SpecificationCaseSyntax","SpecificationOperationFailureSyntax","SpecificationOperationSyntax","SpecificationCompensatedSyntax","ImportSyntax","IncrementMappingSyntax","InteractionAlternativeSyntax","InteractionOtherwiseSyntax","InteractionArgumentSyntax","InteractionBindingSyntax","IntervalInteractionTriggerSyntax","IntervalTriggerSourceSyntax","InvokesSyntax","InvocationRefusalSyntax","JoinEventSyntax","JoinSyntax","KeyPartSyntax","LayoutSyntax","ListExpressionSyntax","LiteralExpressionSyntax","LogicalConditionSyntax","LogicalPolicyConditionSyntax","LogicalPolicyRequirementSyntax","ModuleSyntax","NamedTriggerSourceSyntax","NavigateActionSyntax","NavigateBackActionSyntax","NestedSyntax","NotPolicyConditionSyntax","NotifyActionSyntax","OpenDialogActionSyntax","ObjectExpressionSyntax","ObjectMemberSyntax","PathExpressionSyntax","PerformerSyntax","PersonaSyntax","StickyNoteSyntax","PlaceSyntax","PolicyReferenceSyntax","PolicySyntax","PurposeSyntax","PurposeReferenceSyntax","PurposeTransferSyntax","ProducesSyntax","ProjectionEntersOnSyntax","ProjectionSyntax","ProjectionVariantSyntax","PresentationValueSyntax","PropertyMappingSyntax","PropertySyntax","PropertyResponseSourceSyntax","ResponseFieldSyntax","ScalarCommandResponseSyntax","RecordCommandResponseSyntax","ScalarSpecificationReturnSyntax","RecordSpecificationReturnSyntax","QueryParameterSyntax","QuerySyntax","RaiseTriggerActionSyntax","RawExpressionSyntax","ReactionIdentitySyntax","ReactionSyntax","ReactionTriggerSyntax","RefusalExpressionSyntax","ReadModelSyntax","ReadsSyntax","ReducerRuleSyntax","ReducerSyntax","RefreshQueryActionSyntax","RemoveViaJoinSyntax","RemoveWithSyntax","RequirementSyntax","RoleConditionSyntax","ScheduleTriggerSourceSyntax","ScreenActionSyntax","ScreenNavigationParameterSyntax","ScreenGuardedActionSyntax","ScreenActionAlternativeSyntax","ScreenActionOtherwiseSyntax","ScreenBehaviorSyntax","ScreenCodeSyntax","ScreenComponentSyntax","ScreenColumnSyntax","ScreenDataSyntax","ScreenFieldSyntax","ScreenNavigateSyntax","ScreenSectionSyntax","ScreenSlotSyntax","ScreenSummarySyntax","ScreenSyntax","ScreenTableSyntax","ScreenTemplateReferenceSyntax","ScreenTemplateSyntax","ScreenTitleSyntax","ScreenToolbarSyntax","ScreenUsesBehaviorSyntax","SeedEventSyntax","SeedGroupSyntax","SeedSyntax","SetMappingSyntax","TemplateAssignmentSyntax","TemplateExposedValueSyntax","TemplateOutletSyntax","SetStateActionSyntax","SliceSyntax","SlotSyntax","SourceItemExpressionSyntax","SpecificationAbsentReadModelSyntax","SpecificationCallerClaimSyntax","SpecificationCallerPersonaSyntax","SpecificationCallerSyntax","SpecificationCaptureSyntax","SpecificationClockSyntax","SpecificationGeneratedValueSyntax","SpecificationInvocationSyntax","SpecificationCommandSyntax","SpecificationDeniedSyntax","SpecificationErrorSyntax","SpecificationEventSyntax","NewScreenTemplateSyntax","ProfileAppearanceSyntax","ProfileIdentitySyntax","RootTemplateSyntax","SampleDataBindingSyntax","ShellOptionSyntax","SampleDataFieldSyntax","SampleDataMappingSyntax","SampleDataPackReferenceSyntax","SampleDataPackSyntax","SampleDataRowSyntax","SampleDataSelectionSyntax","SampleDataSetSyntax","SpecificationNoResultSyntax","SpecificationStreamSyntax","SpecificationNoStreamSyntax","SpecificationQueryResultSyntax","SpecificationQuerySyntax","SpecificationReadModelSyntax","SpecificationRedeliverySyntax","SpecificationSyntax","SpecificationTriggerSyntax","SpecificationWhenQuerySyntax","StringsExpressionSyntax","SubtractMappingSyntax","TagSyntax","ToolbarButtonSyntax","ToolbarItemSyntax","TemplateExpressionSyntax","TemplateInterpolationSyntax","TemplateTextSyntax","ThemeSyntax","TriggerDataSyntax","TriggerSyntax","TypeRefSyntax","TypeSyntax","UiBindingSyntax","UiProfileSyntax","UniqueEventConstraintSyntax","UniquePropertyConstraintSyntax","DependsOnSyntax","UsesBehaviorSyntax","ValidationRuleSyntax","VariantSyntax","AnonymousConditionSyntax"],"names":["factor","property","value","autoMap","mappings","authentication","behaviors","commandReadMode","concepts","domain","eventSources","examples","exposures","fileImports","identity","imports","instanceContributions","layouts","modules","personas","policies","purposes","reactionProductionMode","sampleDataPacks","seeds","sourceOptions","numericMode","stickyNotes","systems","templates","themes","timeZone","triggers","types","uiProfiles","triggerName","children","columns","gap","grow","rows","span","syntaxKind","height","root","width","growFactor","name","mode","overrides","variants","alias","providers","requirement","icon","id","slot","target","title","image","buttons","items","logo","region","feature","module","type","bindings","description","file","order","parameters","event","tags","when","appends","identifiedBy","map","source","translations","settings","separator","targets","key","keyIsEventSource","nested","from","to","expression","fromValue","properties","toValue","amount","clock","unit","contextMember","operand","configurable","parameter","blocks","claim","matches","matchesSubject","code","details","by","query","arguments","onFailure","onResult","onSuccess","language","binding","directives","authorize","calendar","concurrency","documentation","handler","produces","reads","response","stream","streamCandidates","validations","eventSource","propertyCandidate","streamId","streamIdParts","left","leftExpression","operator","right","parts","criminal","reason","scope","specialCategory","attributes","generation","valueNumbers","values","alphabet","case","checksum","count","encoding","pattern","prefix","range","rule","size","strategy","eventSourceType","eventStreamId","eventStreamType","eventTypes","message","messageIsLiteral","path","contributionPoint","destination","group","label","navigate","presentation","requirements","rules","arrangement","category","content","displayName","exposes","outlets","restrictsScopes","scopes","sliceKinds","slots","templateType","usedBehaviors","eventName","identifier","streams","x","y","hasGenerationMarker","origin","visibility","includeChildren","command","contributions","dependsOn","features","isPlacement","slices","toolbars","additionalRules","ignoreCasing","releasedBy","owner","component","editableFields","isCollection","operations","reExposes","restrictsFields","instance","field","columnGap","placements","rowGap","index","maxWidth","minWidth","column","columnSpan","row","rowSpan","composeUsing","columnMode","fields","for","generationMode","layout","onSubmit","populate","events","parentKey","implementation","hints","text","compensate","execute","inputs","uses","generatedValues","noStream","operation","qualifiedName","actions","condition","alternatives","otherwise","trigger","onRefused","acknowledge","constraint","selector","on","navigation","literalType","dialogTemplates","forms","screenTemplates","screen","level","dialogTemplate","members","goals","canvas","colour","hidden","sizeHeight","sizeWidth","slotName","authorization","basis","basisReference","conditionReference","erasureException","interest","recipients","retention","subjects","transfers","safeguard","inlineEvent","inlineOperation","readModel","sequence","entersOn","isGenerated","isIdentifier","isKey","isSubject","byParts","filters","isObservable","performer","returnType","roles","runsAs","where","data","invokes","member","partsKey","severity","role","dayOfMonth","dayOfWeek","time","outcome","behavior","context","stableId","outlet","route","rowClick","blueprint","version","fitsSlot","eventSourceId","groups","captures","commands","constraints","direction","projections","queries","reactions","readModels","reducers","screens","specifications","contributes","authenticated","claims","capture","record","instant","commandType","inlineProperty","caseValue","eventType","accent","colorScheme","corners","font","logoKind","logoValue","showName","options","pack","shape","isBlueprint","locale","sets","active","exactly","results","reaction","cases","given","givenCaller","givenCallerPersona","givenCaptures","givenClock","givenGenerated","givenOperationFailures","givenReadModels","givenTimeZone","thenAbsentReadModels","thenCompensated","thenDenied","thenErrors","thenEvents","thenEventsInAnyOrder","thenInvocations","thenNoEvents","thenNoResult","thenOperations","thenQueries","thenReadModels","thenResults","thenReturns","whenAppended","whenCapture","whenClock","whenQuery","whenRedelivered","whenTrigger","confirm","emphasis","slice","compatibleWith","isOptional","bindingKind","componentId","componentPropertyPath","expectedValueType","literal","nullBehavior","rawText","appearance","defaultSizeClass","icons","newScreenTemplate","packages","platforms","sampleData","theme","additionalProperties","places","subject"],"rules":[["ref",30,31,33,36,63,64,72,73,75,132,133,145,147,173,177,220,256,261],["null"],["union",0,1],["string"],["object",[[0,2,false],[1,3,true],[2,0,true]]],["enum","Inherit","Disabled","Enabled"],["ref",0,45,67,69,119,213,257],["array",6],["object",[[3,5,true],[4,7,false]]],["ref",10],["union",9,1],["ref",18],["array",11],["enum","Protected"],["union",13,1],["ref",59],["array",15],["ref",71],["union",17,1],["ref",76],["array",19],["ref",112],["array",21],["ref",89],["array",23],["ref",86],["array",25],["ref",42],["union",27,1],["ref",118],["array",29],["ref",91],["array",31],["ref",131],["array",33],["union",34,1],["ref",137],["array",36],["ref",149],["array",38],["union",39,1],["ref",153],["array",41],["ref",154],["array",43],["enum","Atomic"],["union",45,1],["ref",242],["array",47],["ref",212],["array",49],["union",50,1],["enum","legacy","exact"],["object",[[26,52,true]]],["ref",150],["array",54],["ref",109],["array",56],["ref",214],["array",58],["ref",264],["array",60],["union",61,1],["ref",35],["union",63,1],["ref",266],["array",65],["union",66,1],["ref",268],["array",68],["union",69,1],["ref",270],["array",71],["union",72,1],["object",[[5,10,false],[6,12,false],[7,14,false],[8,16,false],[9,18,false],[10,20,false],[11,22,false],[12,24,false],[13,26,false],[14,28,false],[15,30,false],[16,32,false],[17,35,false],[18,37,false],[19,40,false],[20,42,false],[21,44,false],[22,46,false],[23,48,false],[24,51,false],[25,53,false],[27,55,false],[28,57,false],[29,59,false],[30,62,false],[31,64,false],[32,67,false],[33,70,false],[34,73,false]]],["object",[[35,3,true]]],["ref",4,6],["array",76],["integer",-2147483648,2147483647],["union",78,1],["number"],["union",80,1],["enum","Flat","Row","Column","Grid"],["object",[[36,77,false],[37,79,false],[38,79,false],[39,81,false],[40,79,false],[41,79,false],[42,82,true]]],["union",3,1],["object",[[43,84,false],[44,76,true],[45,84,false]]],["boolean"],["object",[[39,86,false],[46,81,false],[43,79,false],[47,3,true],[41,79,false],[45,79,false]]],["enum","Flow","Freeform"],["ref",5],["array",89],["union",90,1],["union",76,1],["ref",276],["array",93],["union",94,1],["object",[[48,88,true],[49,91,false],[44,92,false],[50,95,false]]],["object",[]],["object",[[51,84,false],[47,3,true]]],["ref",9],["array",99],["object",[[52,100,false]]],["ref",136,152],["object",[[53,102,true]]],["ref",12],["array",104],["ref",15],["union",106,1],["object",[[36,105,false],[54,84,false],[55,3,true],[56,84,false],[57,107,false],[58,3,true]]],["object",[[59,3,true],[58,3,true]]],["ref",259],["array",110],["ref",13],["union",112,1],["enum","Unspecified","Inherit","Extend","Override"],["enum","Topbar","Sidebar"],["object",[[60,111,false],[61,105,false],[62,113,false],[48,114,true],[63,115,true]]],["object",[[64,84,false],[65,3,true]]],["object",[[47,3,true],[2,3,true]]],["ref",267],["union",119,1],["object",[[47,3,true],[66,120,false]]],["ref",123],["array",122],["ref",87],["union",124,1],["ref",17],["array",126],["object",[[67,123,false],[68,84,false],[69,125,false],[47,84,false],[70,79,false],[71,127,false]]],["enum","Click","DoubleClick","Select","Submit","Change","Load","Unload","Enter","Leave","Unknown"],["object",[[42,129,true]]],["ref",162],["array",131],["ref",258],["array",133],["union",134,1],["ref",29],["union",136,1],["object",[[72,3,true],[4,132,false],[73,135,false],[74,137,false]]],["ref",20],["array",139],["ref",22,26],["array",141],["object",[[75,140,false],[76,3,true],[77,142,false],[1,3,true]]],["ref",28],["array",144],["object",[[1,3,true],[78,0,true],[79,145,false]]],["object",[[75,140,false],[77,142,false],[1,3,true]]],["ref",24],["array",148],["object",[[80,149,false],[42,3,true]]],["array",3],["object",[[81,3,true],[78,0,true],[82,151,false]]],["ref",21],["array",153],["ref",23],["array",155],["ref",25],["union",157,1],["object",[[75,140,false],[36,154,false],[83,84,false],[84,86,false],[77,142,false],[47,3,true],[85,156,false],[78,158,false],[25,53,false]]],["object",[[86,3,true],[87,3,true]]],["enum","PropertyChanged","Added","Removed","Changed","LogicalOr","LogicalAnd","ValueTransition","Expression"],["object",[[88,84,false],[89,84,false],[90,151,false],[42,161,true],[91,84,false]]],["object",[[1,84,false]]],["object",[[92,78,true],[93,3,true],[94,3,true]]],["object",[[95,84,false],[55,84,false]]],["object",[[96,0,true]]],["object",[[55,3,true]]],["object",[[97,86,true],[55,3,true]]],["object",[[98,3,true]]],["ref",1,37,46,81,105,129,141,160,183,184],["array",170],["object",[[3,5,true],[99,171,false],[76,0,true],[1,3,true]]],["object",[[100,3,true],[101,2,false],[102,86,true]]],["object",[[100,3,true]]],["ref",48],["object",[[103,175,true]]],["object",[[69,124,true]]],["ref",43],["array",178],["object",[[68,84,false],[104,179,false]]],["ref",39,40,41,44],["object",[[47,3,true],[78,181,true],[66,119,true]]],["object",[[105,0,true],[106,3,true]]],["object",[[1,3,true]]],["object",[[72,3,true]]],["ref",122],["array",186],["ref",47,62,82,139,140,143,144,172,182,217],["array",188],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false]]],["object",[[103,3,true],[111,3,true]]],["ref",269],["object",[[112,192,true],[47,3,true]]],["ref",188,190,193,194,195,197,199,200,201,202,204,205,207,208,209],["array",194],["object",[[113,195,false],[47,3,true]]],["union",192,1],["object",[[112,197,false],[1,3,true],[2,2,false]]],["ref",11],["union",199,1],["ref",32],["union",201,1],["ref",61],["union",203,1],["ref",106],["union",205,1],["ref",157],["array",207],["ref",163],["array",209],["ref",179],["array",211],["union",212,1],["ref",166,167],["union",214,1],["ref",54],["union",216,1],["array",216],["ref",52,68],["array",219],["object",[[114,200,false],[115,202,false],[116,204,false],[68,84,false],[117,84,false],[118,206,false],[47,3,true],[119,208,false],[90,210,false],[120,213,false],[121,215,false],[122,217,false],[123,218,false],[124,220,false]]],["union",209,1],["union",131,1],["object",[[125,3,true],[126,222,false],[122,3,true],[127,223,false],[128,132,false]]],["object",[[125,3,true],[122,84,false]]],["enum","Equal","NotEqual","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Contains","StartsWith"],["object",[[129,3,true],[130,2,false],[131,226,true],[132,0,true]]],["ref",130],["array",228],["object",[[133,229,false],[66,3,true]]],["object",[[134,86,false],[47,3,true],[135,84,false],[136,84,false],[137,84,false]]],["ref",58],["array",232],["ref",60],["union",234,1],["union",220,1],["array",78],["union",237,1],["object",[[138,233,false],[68,84,false],[69,125,false],[139,235,false],[47,3,true],[66,3,true],[124,236,false],[140,238,false],[141,151,false]]],["union",175,1],["object",[[142,84,false],[143,84,false],[144,84,false],[103,240,false],[145,79,false],[146,84,false],[69,125,false],[147,84,false],[148,84,false],[149,84,false],[150,84,false],[151,79,false],[152,3,true]]],["object",[[125,86,true],[153,84,false],[154,84,false],[155,84,false],[156,151,false]]],["object",[[107,187,false],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[159,3,true]]],["ref",66],["union",245,1],["ref",199],["union",247,1],["object",[[160,3,true],[161,246,false],[162,84,false],[54,84,false],[55,84,false],[163,84,false],[164,248,false],[70,79,false],[165,84,false]]],["enum","Outlet","Dialog","External"],["object",[[42,250,true],[57,3,true]]],["ref",185],["array",252],["union",253,1],["ref",275],["array",255],["object",[[166,254,false],[167,256,false]]],["ref",7],["union",258,1],["ref",96],["array",260],["ref",215],["array",262],["ref",216],["array",264],["ref",219],["array",266],["ref",274],["array",268],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["object",[[47,3,true]]],["object",[[180,3,true]]],["ref",78],["array",273],["object",[[68,84,false],[55,84,false],[181,120,false],[47,3,true],[182,274,false],[183,79,false],[184,79,false]]],["object",[[47,3,true],[66,119,true]]],["ref",77],["array",277],["object",[[68,84,false],[55,84,false],[47,3,true],[127,120,false],[128,278,false]]],["object",[[72,3,true],[83,2,false]]],["integer",0,4294967295],["enum","Private","Public"],["object",[[68,84,false],[117,84,false],[69,125,false],[139,281,false],[185,86,false],[55,84,false],[47,3,true],[186,84,false],[90,210,false],[73,135,false],[187,282,false]]],["object",[[3,5,true],[188,86,true],[4,7,false]]],["object",[[107,187,false],[189,3,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[88,0,true]]],["ref",65],["array",287],["union",288,1],["ref",273],["array",290],["ref",84],["array",292],["ref",155],["array",294],["ref",218],["array",296],["ref",208],["array",298],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[193,86,true],[47,3,true],[21,295,false],[194,297,false],[29,59,false],[195,299,false],[179,269,false]]],["ref",85,271,272],["array",301],["object",[[196,302,false],[68,84,false],[69,124,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[147,3,true]]],["object",[[163,84,false],[1,3,true]]],["ref",90],["array",306],["object",[[199,3,true],[90,307,false]]],["object",[[200,3,true],[201,151,false],[202,86,true],[163,84,false],[203,151,false],[159,3,true],[204,84,false],[205,86,true]]],["ref",92],["array",310],["object",[[190,311,false],[206,3,true]]],["ref",93],["array",313],["object",[[200,3,true],[61,314,false],[159,3,true],[2,2,false]]],["ref",94],["array",316],["object",[[55,3,true],[141,317,false]]],["object",[[207,3,true],[2,0,true]]],["object",[[160,3,true],[113,195,false],[70,79,false]]],["object",[[113,195,false],[56,3,true]]],["ref",100],["union",322,1],["ref",98],["array",324],["ref",99],["array",326],["object",[[208,323,false],[37,325,false],[209,327,false],[210,323,false]]],["object",[[211,78,true],[212,323,false],[213,323,false],[45,323,false]]],["object",[[214,78,true],[215,79,false],[207,3,true],[216,78,true],[217,79,false],[45,323,false]]],["enum","Fraction","Pixels","Percent","Auto"],["object",[[94,331,true],[2,81,false]]],["object",[[218,84,false],[86,84,false],[163,84,false],[1,3,true]]],["object",[[105,84,false],[106,3,true]]],["enum","Unspecified","Auto","Manual"],["ref",88],["array",336],["ref",101],["array",338],["ref",97],["union",340,1],["ref",102,103],["union",342,1],["object",[[6,12,false],[219,335,true],[37,337,false],[68,84,false],[220,339,false],[221,3,true],[222,335,true],[223,341,false],[47,3,true],[224,248,false],[225,343,false],[179,269,false]]],["ref",79],["array",345],["ref",57,83],["union",347,1],["object",[[226,346,false],[83,348,false],[4,7,false],[227,2,false]]],["ref",107],["union",350,1],["object",[[103,240,false],[69,125,false],[228,351,false]]],["ref",108],["array",353],["object",[[229,354,false]]],["object",[[230,3,true]]],["object",[[68,84,false],[47,3,true]]],["ref",111],["union",358,1],["object",[[231,359,false],[68,84,false],[232,359,false],[233,210,false],[47,3,true],[234,3,true]]],["object",[[103,240,false],[68,84,false],[69,125,false],[228,351,false]]],["ref",248],["union",362,1],["ref",247],["union",364,1],["object",[[68,84,false],[221,2,false],[235,132,false],[47,3,true],[236,363,false],[122,365,false],[66,3,true],[141,132,false]]],["object",[[47,3,true],[141,132,false]]],["object",[[237,3,true]]],["object",[[237,3,true],[141,132,false]]],["object",[[186,84,false],[238,3,true],[187,282,false]]],["ref",56,134],["object",[[239,189,false],[240,371,true]]],["object",[[239,189,false]]],["object",[[112,3,true],[47,3,true]]],["ref",120],["array",375],["ref",121],["union",377,1],["ref",3,19,74,124],["object",[[239,189,false],[241,376,false],[240,84,false],[242,378,false],[243,379,true]]],["enum","Seconds","Minutes","Hours","Days"],["object",[[92,78,true],[94,381,true]]],["ref",127],["array",383],["object",[[189,3,true],[4,132,false],[244,384,false]]],["object",[[245,86,true],[246,84,false],[119,208,false],[247,3,true]]],["object",[[3,5,true],[72,3,true],[4,7,false]]],["ref",128],["array",388],["object",[[226,389,false],[248,3,true],[1,3,true]]],["object",[[88,0,true],[1,3,true]]],["ref",14],["array",392],["object",[[168,259,false],[6,12,false],[169,84,false],[172,263,false],[47,3,true],[249,393,false],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["array",0],["object",[[61,395,false]]],["union",3,86,1],["number",-1.7976931348623157E+308,1.7976931348623157E+308],["enum","Int32","Int64","Decimal","Single"],["string","^-?[0-9]\u002B(\\.[0-9]\u002B)?([Ee][\u002B-]?[0-9]\u002B)?$"],["object",[[250,399,true],[2,400,true]]],["const","ExactNumber"],["string","^(?:0|-?(?:[1-9][0-9]{0,28}|(?:0|[1-9][0-9]{0,28})\\.[0-9]{0,27}[1-9]))$"],["object",[[250,402,true],[2,403,true]]],["union",397,398,401,404],["object",[[2,405,false]]],["enum","And","Or"],["object",[[129,371,true],[131,407,true],[132,371,true]]],["ref",8,38,135,142,186,277],["object",[[129,409,true],[131,407,true],[132,409,true]]],["object",[[129,102,true],[131,407,true],[132,102,true]]],["ref",70],["array",412],["union",413,1],["ref",104],["array",415],["union",416,1],["ref",206],["array",418],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[251,414,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[252,417,false],[193,86,true],[47,3,true],[249,393,false],[21,295,false],[253,419,false],[29,59,false],[195,299,false],[179,269,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[254,3,true]]],["object",[[3,5,true],[99,171,false],[1,3,true]]],["object",[[96,409,true]]],["enum","Info","Warning","Error","Unknown"],["object",[[107,187,false],[255,424,true],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[107,187,false],[256,3,true],[108,189,false],[109,189,false],[110,189,false]]],["ref",146],["array",427],["object",[[257,428,false]]],["object",[[47,3,true],[2,0,true]]],["object",[[103,240,false],[69,125,false]]],["object",[[68,84,false],[258,151,false],[43,79,false],[47,3,true],[20,151,false],[45,79,false],[183,79,false],[184,79,false]]],["object",[[259,3,true],[260,84,false],[43,79,false],[230,3,true],[45,79,false],[183,78,true],[184,78,true]]],["object",[[261,86,false],[262,84,false],[263,84,false],[264,3,true],[183,79,false],[184,79,false]]],["union",409,1],["object",[[103,240,false],[240,435,false],[68,84,false],[69,125,false],[47,3,true]]],["ref",156],["array",437],["object",[[265,84,false],[266,84,false],[267,84,false],[240,84,false],[268,84,false],[68,84,false],[269,84,false],[270,84,false],[47,3,true],[271,151,false],[272,84,false],[273,151,false],[274,438,false]]],["object",[[161,3,true],[275,3,true]]],["ref",80],["union",441,1],["ref",110],["union",443,1],["union",371,1],["object",[[72,3,true],[221,2,false],[276,442,false],[277,444,false],[4,132,false],[122,217,false],[73,135,false],[74,445,false]]],["object",[[3,5,true],[99,171,false],[68,84,false],[69,125,false],[83,348,false],[47,3,true],[278,84,false],[279,84,false],[25,53,false]]],["ref",158],["array",448],["object",[[99,171,false],[280,449,false],[47,3,true]]],["object",[[1,3,true],[78,0,true]]],["object",[[281,86,false],[282,86,false],[283,86,false],[284,86,false],[47,3,true],[66,119,true]]],["ref",164],["object",[[47,3,true],[78,453,true],[66,120,false]]],["object",[[78,453,true]]],["ref",165],["array",456],["object",[[220,457,false]]],["object",[[2,0,true]]],["object",[[220,132,false]]],["object",[[47,3,true],[78,2,false],[66,119,true]]],["ref",170],["union",462,1],["array",462],["ref",148],["union",465,1],["object",[[114,200,false],[105,463,false],[285,464,false],[68,84,false],[286,464,false],[287,86,false],[47,3,true],[288,466,false],[289,119,true],[136,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[243,3,true]]],["object",[[290,151,false],[42,3,true]]],["ref",55],["union",470,1],["ref",174],["union",472,1],["ref",176],["array",474],["object",[[68,84,false],[117,84,false],[86,471,false],[47,3,true],[291,473,false],[32,475,false],[292,445,false]]],["ref",265],["array",477],["ref",126],["array",479],["union",480,1],["union",208,1],["ref",125,138,187],["object",[[103,240,false],[293,478,false],[68,84,false],[69,125,false],[294,481,false],[119,482,false],[120,213,false],[78,483,true]]],["object",[[295,3,true]]],["object",[[68,84,false],[117,84,false],[69,125,false],[47,3,true],[90,210,false]]],["object",[[51,84,false],[105,84,false],[285,132,false],[278,3,true]]],["object",[[103,240,false],[68,84,false],[72,3,true],[69,125,false]]],["ref",180],["array",489],["object",[[68,84,false],[86,471,false],[47,3,true],[278,3,true],[167,490,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[106,3,true]]],["ref",57],["union",493,1],["object",[[72,3,true],[83,2,false],[227,2,false],[296,494,false]]],["enum","Error","Information","Warning"],["object",[[240,371,true],[157,84,false],[297,496,true]]],["object",[[298,3,true]]],["enum","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["union",499,1],["string","^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,7})?$"],["object",[[299,79,false],[300,500,false],[301,501,true]]],["object",[[189,3,true],[233,187,false],[163,84,false],[164,248,false],[404,726,false]]],["ref",191],["array",504],["ref",192],["union",506,1],["object",[[241,505,false],[163,3,true],[164,248,false],[242,507,false],[404,726,false]]],["object",[[107,187,false],[189,3,true],[240,371,true]]],["enum","Hidden","Execute","Unknown"],["object",[[107,187,false],[189,84,false],[302,510,true]]],["object",[[303,11,true]]],["ref",49],["array",513],["ref",50],["array",515],["ref",161],["array",517],["ref",51],["array",519],["object",[[6,12,false],[200,3,true],[304,197,false],[172,514,false],[54,84,false],[47,3,true],[173,516,false],[165,518,false],[90,520,false],[305,84,false],[179,269,false]]],["object",[[105,84,false],[106,3,true],[66,119,true]]],["object",[[163,3,true],[1,3,true]]],["ref",189],["array",524],["object",[[105,84,false],[306,84,false],[71,525,false],[307,84,false],[254,3,true]]],["ref",198],["array",527],["object",[[220,528,false],[57,3,true]]],["ref",95],["array",530],["object",[[190,531,false],[68,84,false],[113,195,false],[69,125,false],[47,3,true]]],["ref",196],["array",533],["object",[[6,12,false],[37,534,false],[308,248,false],[57,3,true],[179,269,false]]],["ref",201],["array",536],["object",[[309,84,false],[47,3,true],[177,537,false],[310,84,false]]],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[311,84,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["ref",260],["array",540],["object",[[60,111,false],[61,541,false],[47,3,true]]],["object",[[234,268,true]]],["object",[[72,3,true],[90,132,false]]],["ref",210],["array",545],["object",[[312,3,true],[226,546,false]]],["ref",211],["array",548],["object",[[313,549,false],[47,84,false],[183,79,false],[184,79,false]]],["object",[[309,84,false],[47,3,true],[310,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[57,3,true],[2,3,true]]],["ref",27],["array",553],["ref",53],["array",555],["enum","Inbound","Outbound"],["union",557,1],["array",441],["array",443],["ref",159],["array",561],["ref",171],["array",563],["ref",175],["array",565],["ref",178],["array",567],["union",568,1],["ref",181],["array",570],["union",571,1],["ref",203],["array",573],["ref",253],["array",575],["enum","StateChange","StateView","Automation","Translate"],["object",[[314,554,false],[315,556,false],[316,302,false],[68,84,false],[317,558,false],[117,84,false],[226,559,false],[11,22,false],[69,125,false],[47,3,true],[203,560,false],[318,562,false],[21,295,false],[319,564,false],[320,566,false],[321,569,false],[322,572,false],[323,574,false],[324,576,false],[29,59,false],[66,577,true]]],["object",[[325,84,false],[47,3,true]]],["object",[[83,0,true],[47,3,true]]],["object",[[66,3,true],[2,3,true]]],["ref",222],["array",582],["object",[[326,86,true],[327,583,false],[290,151,false]]],["object",[[328,3,true],[329,132,false]]],["object",[[330,3,true]]],["object",[[189,3,true],[1,3,true],[78,0,true]]],["object",[[189,3,true],[141,132,false]]],["object",[[331,3,true],[221,2,false],[235,132,false],[332,84,false],[141,132,false]]],["ref",36],["union",590,1],["object",[[333,591,false],[47,84,false]]],["object",[[334,3,true],[221,2,false],[332,84,false],[236,363,false],[122,365,false],[141,132,false]]],["object",[[335,84,false],[336,84,false],[337,84,false],[338,84,false]]],["union",86,1],["object",[[339,84,false],[340,84,false],[47,84,false],[341,595,false]]],["ref",238],["array",597],["object",[[309,84,false],[47,3,true],[342,598,false],[310,84,false]]],["ref",241],["object",[[343,600,true],[278,3,true]]],["enum","Word","Text","Number","Flag"],["object",[[47,3,true],[42,602,true],[2,3,true]]],["enum","Text","Number","Flag","Null"],["object",[[47,3,true],[42,604,true],[2,84,false]]],["object",[[278,3,true],[344,3,true]]],["object",[[345,86,true],[47,3,true]]],["ref",245],["array",608],["object",[[346,84,false],[47,3,true],[347,609,false],[58,84,false]]],["ref",239],["array",611],["object",[[220,612,false]]],["union",600,1],["ref",237],["array",615],["ref",240],["array",617],["object",[[348,614,false],[67,616,false],[4,618,false]]],["ref",243],["array",620],["object",[[40,621,false],[344,3,true]]],["object",[[125,3,true],[122,3,true],[127,223,false],[128,132,false]]],["object",[[349,86,true],[90,132,false]]],["ref",249],["array",625],["object",[[107,132,false],[349,86,true],[106,3,true],[350,626,false]]],["object",[[349,86,true],[332,84,false],[47,3,true],[90,132,false]]],["object",[[334,3,true],[221,2,false],[236,363,false],[351,3,true],[122,365,false],[141,132,false]]],["ref",114],["array",630],["ref",232],["array",632],["ref",224],["union",634,1],["ref",223],["union",636,1],["ref",225],["array",638],["ref",226],["union",640,1],["ref",227],["array",642],["ref",115],["array",644],["ref",251],["array",646],["union",647,1],["ref",34],["union",649,1],["ref",113],["array",651],["ref",221],["array",653],["ref",117],["array",655],["ref",230],["union",657,1],["ref",231],["array",659],["ref",228],["array",661],["ref",246],["union",663,1],["ref",116],["array",665],["ref",250],["array",667],["ref",168,169],["union",669,1],["ref",229],["union",671,1],["union",632,1],["union",638,1],["ref",255],["union",675,1],["ref",252],["union",677,1],["ref",254],["union",679,1],["object",[[352,631,false],[68,84,false],[11,22,false],[69,125,false],[353,633,false],[354,635,false],[355,637,false],[356,639,false],[357,641,false],[358,643,false],[359,645,false],[360,648,false],[361,650,false],[47,3,true],[71,652,false],[25,53,false],[362,654,false],[363,656,false],[364,658,false],[365,660,false],[366,633,false],[367,86,true],[368,662,false],[369,86,false],[370,664,false],[371,666,false],[372,668,false],[373,648,false],[374,626,false],[375,670,false],[74,672,false],[376,673,false],[377,674,false],[378,641,false],[379,676,false],[380,678,false],[381,680,false]]],["object",[[243,3,true],[141,132,false]]],["object",[[107,132,false],[106,3,true]]],["object",[[83,3,true]]],["enum","Primary","Secondary","Quiet"],["union",685,1],["object",[[114,200,false],[382,84,false],[383,686,false],[54,84,false],[55,3,true],[384,84,false],[58,3,true]]],["enum","Unknown","Action","Navigate","Dialog"],["object",[[382,84,false],[54,84,false],[163,84,false],[47,3,true],[71,525,false],[165,518,false],[404,726,false],[42,688,true],[57,3,true]]],["ref",262,263],["array",690],["object",[[133,691,false]]],["object",[[385,151,false],[47,3,true]]],["object",[[293,478,false],[68,84,false],[69,125,false],[47,3,true]]],["object",[[202,86,true],[386,86,true],[47,3,true]]],["object",[[68,84,false],[69,125,false],[47,3,true],[90,210,false]]],["enum","Invalid","DataContext","QueryResult","ComponentProperty","Literal"],["enum","OneWay","TwoWay"],["union",698,1],["enum","Propagate","Clear","Preserve"],["union",700,1],["object",[[387,697,true],[388,84,false],[389,84,false],[390,84,false],[391,2,false],[48,699,false],[392,701,false],[159,3,true],[106,84,false],[393,84,false]]],["ref",234],["union",703,1],["ref",235],["union",705,1],["ref",233],["union",707,1],["ref",236],["union",709,1],["ref",244],["union",711,1],["object",[[394,704,false],[395,84,false],[396,151,false],[14,706,false],[223,84,false],[47,3,true],[397,708,false],[398,151,false],[399,151,false],[44,710,false],[400,712,false],[401,84,false]]],["object",[[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[402,151,false],[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[1,3,true],[198,151,false]]],["object",[[57,3,true]]],["ref",16],["array",717],["object",[[107,718,false],[303,3,true]]],["enum","NotEmpty","Max","Min","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Equal","Length","Matches","AllGreaterThan","AllGreaterThanOrEqual","Rule","NotEqual","Checksum","Contains","NotContains","StartsWith","EndsWith","DecimalPlaces"],["object",[[103,240,false],[69,125,false],[228,351,false],[157,84,false],[1,3,true],[150,720,true],[297,496,true],[2,2,false]]],["ref",151],["array",722],["object",[[43,3,true],[403,723,false],[45,3,true]]],["enum","Item","Screen"],["union",725,1]],"contracts":[4,8,74,75,83,85,87,96,97,98,101,103,108,109,116,117,118,121,128,130,138,143,146,147,118,150,152,159,160,162,163,164,165,166,167,168,169,172,173,174,176,177,180,182,183,184,185,190,191,193,196,198,176,221,224,225,227,230,231,239,241,242,243,244,244,249,251,184,257,184,270,271,271,244,272,97,275,276,279,280,283,284,285,286,300,303,304,244,305,308,309,312,315,318,319,320,321,328,329,330,332,333,97,334,344,349,352,355,356,357,360,361,366,276,367,368,369,368,370,184,372,373,374,380,382,382,385,386,387,390,391,394,396,406,408,410,411,420,271,421,190,422,423,425,426,429,430,244,431,432,433,434,271,436,439,271,440,446,280,447,450,118,451,452,184,454,455,458,459,460,461,467,468,356,469,476,484,485,486,487,488,491,492,280,495,497,498,502,503,193,508,509,511,512,176,521,305,522,523,526,196,196,529,532,535,538,539,356,542,543,544,547,550,451,551,121,271,552,578,579,244,580,581,271,584,585,586,587,588,589,97,592,593,551,594,596,599,601,603,605,606,607,610,613,619,622,97,623,97,624,627,628,629,681,682,683,684,4,459,687,689,692,286,356,693,121,694,695,696,702,713,714,715,716,719,721,724,97]} as const; +export const syntaxCollections = {"kinds":["AddMappingSyntax","AllSyntax","ApplicationSyntax","ApplicationTriggerInteractionTriggerSyntax","ArrangementContainerSyntax","ArrangementOverrideSyntax","ArrangementSlotSyntax","ArrangementSyntax","AuthenticatedConditionSyntax","AuthenticationProviderSyntax","AuthenticationSyntax","AuthorizeSyntax","NavigationItemSyntax","NavigationLogoSyntax","NavigationRegionSyntax","NavigationTargetSyntax","BehaviorArgumentSyntax","BehaviorParameterSyntax","BehaviorSyntax","BuiltInInteractionTriggerSyntax","CaptureAppendSyntax","CaptureChildrenSyntax","CaptureMapEntrySyntax","CaptureNestedSyntax","CaptureSourceSettingSyntax","CaptureSourceSyntax","CaptureSplitSyntax","CaptureSyntax","CaptureTranslationSyntax","CaptureWhenSyntax","CausedByExpressionSyntax","ClockOffsetExpressionSyntax","CommandCalendarSyntax","DateOfExpressionSyntax","SpecificationTimeZoneSyntax","TimeZoneSyntax","CaseValueExpressionSyntax","ChildrenSyntax","ClaimConditionSyntax","ClaimIdentitySourceSyntax","CodeIdentitySourceSyntax","FileIdentitySourceSyntax","IdentitySyntax","IdentityDetailSyntax","QueryIdentitySourceSyntax","ClearMappingSyntax","ClearWithSyntax","CloseDialogActionSyntax","CodeBlockSyntax","ComponentExposedValueSyntax","ComponentOutletSyntax","ComponentPropertySyntax","CodeValidateSyntax","CommandSyntax","CommandStreamSyntax","ObserverFilterSyntax","ComparisonConditionSyntax","CompositeKeySyntax","ConceptAttributeSyntax","ConceptSyntax","GenerationSyntax","ConcurrencySyntax","ConfirmActionSyntax","ContextExpressionSyntax","IdentityExpressionSyntax","ContributionSyntax","ContributionDestinationSyntax","CountMappingSyntax","DeclarativeValidateSyntax","DecrementMappingSyntax","DialogTemplateSyntax","DomainSyntax","EnvironmentExpressionSyntax","EventContextExpressionSyntax","EventInteractionTriggerSyntax","EventSourceIdExpressionSyntax","EventSourceSyntax","EventStreamIdPartSyntax","EventStreamSyntax","EventSpecSyntax","EventSyntax","EverySyntax","ExecuteCommandActionSyntax","ExpressionKeySyntax","FeatureSyntax","FileConstraintSyntax","FileImportSyntax","FileReferenceSyntax","FormColumnSyntax","ExposureSyntax","ExposedPropertySyntax","InstanceContributionsSyntax","InstanceContributionSyntax","ContributedItemSyntax","ContributedItemValueSyntax","ScreenContributionSyntax","TemplateSlotContentSyntax","CommandFormLayoutSyntax","FormLayoutColumnSyntax","FormFieldPlacementSyntax","FormWidthSyntax","FormFieldSyntax","FormPopulateFromItemSyntax","FormPopulateViaQuerySyntax","FormSyntax","FromSyntax","HandlerSyntax","ImplementationSyntax","ImplementationHintSyntax","SystemSyntax","OperationSyntax","OperationPhaseSyntax","SpecificationExampleSyntax","SpecificationParameterSyntax","SpecificationCaseSyntax","SpecificationOperationFailureSyntax","SpecificationOperationSyntax","SpecificationCompensatedSyntax","ImportSyntax","IncrementMappingSyntax","InteractionAlternativeSyntax","InteractionOtherwiseSyntax","InteractionArgumentSyntax","InteractionBindingSyntax","IntervalInteractionTriggerSyntax","IntervalTriggerSourceSyntax","InvokesSyntax","InvocationRefusalSyntax","JoinEventSyntax","JoinSyntax","KeyPartSyntax","LayoutSyntax","ListExpressionSyntax","LiteralExpressionSyntax","LogicalConditionSyntax","LogicalPolicyConditionSyntax","LogicalPolicyRequirementSyntax","ModuleSyntax","NamedTriggerSourceSyntax","NavigateActionSyntax","NavigateBackActionSyntax","NestedSyntax","NotPolicyConditionSyntax","NotifyActionSyntax","OpenDialogActionSyntax","ObjectExpressionSyntax","ObjectMemberSyntax","PathExpressionSyntax","PerformerSyntax","PersonaSyntax","StickyNoteSyntax","PlaceSyntax","PolicyReferenceSyntax","PolicySyntax","PurposeSyntax","PurposeReferenceSyntax","PurposeTransferSyntax","ProducesSyntax","ProjectionEntersOnSyntax","ProjectionSyntax","ProjectionVariantSyntax","PresentationValueSyntax","PropertyMappingSyntax","PropertySyntax","PropertyResponseSourceSyntax","ResponseFieldSyntax","ScalarCommandResponseSyntax","RecordCommandResponseSyntax","ScalarSpecificationReturnSyntax","RecordSpecificationReturnSyntax","QueryParameterSyntax","QuerySyntax","RaiseTriggerActionSyntax","RawExpressionSyntax","ReactionIdentitySyntax","ReactionSyntax","ReactionTriggerSyntax","RefusalExpressionSyntax","ReadModelSyntax","ReadsSyntax","ReducerRuleSyntax","ReducerSyntax","RefreshQueryActionSyntax","RemoveViaJoinSyntax","RemoveWithSyntax","RequirementSyntax","RoleConditionSyntax","ScheduleTriggerSourceSyntax","ScreenActionSyntax","ScreenNavigationParameterSyntax","ScreenGuardedActionSyntax","ScreenActionAlternativeSyntax","ScreenActionOtherwiseSyntax","ScreenBehaviorSyntax","ScreenCodeSyntax","ScreenComponentSyntax","ScreenColumnSyntax","ScreenDataSyntax","ScreenFieldSyntax","ScreenNavigateSyntax","ScreenSectionSyntax","ScreenSlotSyntax","ScreenSummarySyntax","ScreenSyntax","ScreenTableSyntax","ScreenTemplateReferenceSyntax","ScreenTemplateSyntax","ScreenTitleSyntax","ScreenToolbarSyntax","ScreenUsesBehaviorSyntax","SeedEventSyntax","SeedGroupSyntax","SeedSyntax","SetMappingSyntax","TemplateAssignmentSyntax","TemplateExposedValueSyntax","TemplateOutletSyntax","SetStateActionSyntax","SliceSyntax","SlotSyntax","SourceItemExpressionSyntax","SpecificationAbsentReadModelSyntax","SpecificationCallerClaimSyntax","SpecificationCallerPersonaSyntax","SpecificationCallerSyntax","SpecificationCaptureSyntax","SpecificationClockSyntax","SpecificationGeneratedValueSyntax","SpecificationInvocationSyntax","SpecificationCommandSyntax","SpecificationDeniedSyntax","SpecificationErrorSyntax","SpecificationEventSyntax","NewScreenTemplateSyntax","ProfileAppearanceSyntax","ProfileIdentitySyntax","RootTemplateSyntax","SampleDataBindingSyntax","ShellOptionSyntax","SampleDataFieldSyntax","SampleDataMappingSyntax","SampleDataPackReferenceSyntax","SampleDataPackSyntax","SampleDataRowSyntax","SampleDataSelectionSyntax","SampleDataSetSyntax","SpecificationNoResultSyntax","SpecificationStreamSyntax","SpecificationNoStreamSyntax","SpecificationQueryResultSyntax","SpecificationQuerySyntax","SpecificationReadModelSyntax","SpecificationRedeliverySyntax","SpecificationSyntax","SpecificationTriggerSyntax","SpecificationWhenQuerySyntax","StringsExpressionSyntax","SubtractMappingSyntax","TagSyntax","ToolbarButtonSyntax","ToolbarItemSyntax","TemplateExpressionSyntax","TemplateInterpolationSyntax","TemplateTextSyntax","ThemeSyntax","TriggerDataSyntax","TriggerSyntax","TypeRefSyntax","TypeSyntax","UiBindingSyntax","UiProfileSyntax","UniqueEventConstraintSyntax","UniquePropertyConstraintSyntax","DependsOnSyntax","UsesBehaviorSyntax","ValidationRuleSyntax","VariantSyntax","AnonymousConditionSyntax"],"names":["factor","property","value","autoMap","mappings","authentication","behaviors","commandReadMode","concepts","domain","eventSources","examples","exposures","fileImports","identity","imports","instanceContributions","layouts","modules","personas","policies","purposes","reactionProductionMode","sampleDataPacks","seeds","sourceOptions","numericMode","stickyNotes","systems","templates","themes","timeZone","triggers","types","uiProfiles","triggerName","children","columns","gap","grow","rows","span","syntaxKind","height","root","width","growFactor","name","mode","overrides","variants","alias","providers","requirement","icon","id","slot","target","title","image","buttons","items","logo","region","feature","module","type","bindings","description","file","order","parameters","event","tags","when","appends","identifiedBy","map","source","translations","settings","separator","targets","key","keyIsEventSource","nested","from","to","expression","fromValue","properties","toValue","amount","clock","unit","contextMember","operand","configurable","parameter","blocks","claim","matches","matchesSubject","code","details","by","query","arguments","onFailure","onResult","onSuccess","language","binding","directives","authorize","calendar","concurrency","documentation","handler","produces","reads","response","stream","streamCandidates","validations","eventSource","propertyCandidate","streamId","streamIdParts","left","leftExpression","operator","right","parts","criminal","reason","scope","specialCategory","attributes","generation","valueNumbers","values","alphabet","case","checksum","count","encoding","pattern","prefix","range","rule","size","strategy","eventSourceType","eventStreamId","eventStreamType","eventTypes","message","messageIsLiteral","path","contributionPoint","destination","group","label","navigate","presentation","requirements","rules","arrangement","category","content","displayName","exposes","outlets","restrictsScopes","scopes","sliceKinds","slots","templateType","usedBehaviors","eventName","identifier","streams","x","y","hasGenerationMarker","origin","visibility","includeChildren","command","contributions","dependsOn","features","isPlacement","slices","toolbars","additionalRules","ignoreCasing","releasedBy","owner","component","editableFields","isCollection","operations","reExposes","restrictsFields","instance","field","columnGap","placements","rowGap","index","maxWidth","minWidth","column","columnSpan","row","rowSpan","composeUsing","columnMode","fields","for","generationMode","layout","onSubmit","populate","events","parentKey","implementation","hints","text","compensate","execute","inputs","uses","generatedValues","noStream","operation","qualifiedName","actions","condition","alternatives","otherwise","trigger","onRefused","acknowledge","constraint","selector","on","navigation","literalType","dialogTemplates","forms","screenTemplates","screen","level","dialogTemplate","members","goals","canvas","colour","hidden","sizeHeight","sizeWidth","slotName","authorization","basis","basisReference","conditionReference","erasureException","interest","recipients","retention","subjects","transfers","safeguard","inlineEvent","inlineOperation","readModel","sequence","entersOn","isGenerated","isIdentifier","isKey","isSubject","byParts","filters","isObservable","performer","returnType","roles","runsAs","where","data","invokes","member","partsKey","severity","role","dayOfMonth","dayOfWeek","time","subject","outcome","behavior","context","stableId","outlet","route","rowClick","blueprint","version","fitsSlot","eventSourceId","groups","captures","commands","constraints","direction","projections","queries","reactions","readModels","reducers","screens","specifications","contributes","authenticated","claims","capture","record","instant","commandType","inlineProperty","caseValue","eventType","accent","colorScheme","corners","font","logoKind","logoValue","showName","options","pack","shape","isBlueprint","locale","sets","active","exactly","results","reaction","cases","given","givenCaller","givenCallerPersona","givenCaptures","givenClock","givenGenerated","givenOperationFailures","givenReadModels","givenTimeZone","thenAbsentReadModels","thenCompensated","thenDenied","thenErrors","thenEvents","thenEventsInAnyOrder","thenInvocations","thenNoEvents","thenNoResult","thenOperations","thenQueries","thenReadModels","thenResults","thenReturns","whenAppended","whenCapture","whenClock","whenQuery","whenRedelivered","whenTrigger","confirm","emphasis","slice","compatibleWith","isOptional","bindingKind","componentId","componentPropertyPath","expectedValueType","literal","nullBehavior","rawText","appearance","defaultSizeClass","icons","newScreenTemplate","packages","platforms","sampleData","theme","additionalProperties","places"],"rules":[["ref",30,31,33,36,63,64,72,73,75,132,133,145,147,173,177,220,256,261],["null"],["union",0,1],["string"],["object",[[0,2,false],[1,3,true],[2,0,true]]],["enum","Inherit","Disabled","Enabled"],["ref",0,45,67,69,119,213,257],["array",6],["object",[[3,5,true],[4,7,false]]],["ref",10],["union",9,1],["ref",18],["array",11],["enum","Protected"],["union",13,1],["ref",59],["array",15],["ref",71],["union",17,1],["ref",76],["array",19],["ref",112],["array",21],["ref",89],["array",23],["ref",86],["array",25],["ref",42],["union",27,1],["ref",118],["array",29],["ref",91],["array",31],["ref",131],["array",33],["union",34,1],["ref",137],["array",36],["ref",149],["array",38],["union",39,1],["ref",153],["array",41],["ref",154],["array",43],["enum","Atomic"],["union",45,1],["ref",242],["array",47],["ref",212],["array",49],["union",50,1],["enum","legacy","exact"],["object",[[26,52,true]]],["ref",150],["array",54],["ref",109],["array",56],["ref",214],["array",58],["ref",264],["array",60],["union",61,1],["ref",35],["union",63,1],["ref",266],["array",65],["union",66,1],["ref",268],["array",68],["union",69,1],["ref",270],["array",71],["union",72,1],["object",[[5,10,false],[6,12,false],[7,14,false],[8,16,false],[9,18,false],[10,20,false],[11,22,false],[12,24,false],[13,26,false],[14,28,false],[15,30,false],[16,32,false],[17,35,false],[18,37,false],[19,40,false],[20,42,false],[21,44,false],[22,46,false],[23,48,false],[24,51,false],[25,53,false],[27,55,false],[28,57,false],[29,59,false],[30,62,false],[31,64,false],[32,67,false],[33,70,false],[34,73,false]]],["object",[[35,3,true]]],["ref",4,6],["array",76],["integer",-2147483648,2147483647],["union",78,1],["number"],["union",80,1],["enum","Flat","Row","Column","Grid"],["object",[[36,77,false],[37,79,false],[38,79,false],[39,81,false],[40,79,false],[41,79,false],[42,82,true]]],["union",3,1],["object",[[43,84,false],[44,76,true],[45,84,false]]],["boolean"],["object",[[39,86,false],[46,81,false],[43,79,false],[47,3,true],[41,79,false],[45,79,false]]],["enum","Flow","Freeform"],["ref",5],["array",89],["union",90,1],["union",76,1],["ref",276],["array",93],["union",94,1],["object",[[48,88,true],[49,91,false],[44,92,false],[50,95,false]]],["object",[]],["object",[[51,84,false],[47,3,true]]],["ref",9],["array",99],["object",[[52,100,false]]],["ref",136,152],["object",[[53,102,true]]],["ref",12],["array",104],["ref",15],["union",106,1],["object",[[36,105,false],[54,84,false],[55,3,true],[56,84,false],[57,107,false],[58,3,true]]],["object",[[59,3,true],[58,3,true]]],["ref",259],["array",110],["ref",13],["union",112,1],["enum","Unspecified","Inherit","Extend","Override"],["enum","Topbar","Sidebar"],["object",[[60,111,false],[61,105,false],[62,113,false],[48,114,true],[63,115,true]]],["object",[[64,84,false],[65,3,true]]],["object",[[47,3,true],[2,3,true]]],["ref",267],["union",119,1],["object",[[47,3,true],[66,120,false]]],["ref",123],["array",122],["ref",87],["union",124,1],["ref",17],["array",126],["object",[[67,123,false],[68,84,false],[69,125,false],[47,84,false],[70,79,false],[71,127,false]]],["enum","Click","DoubleClick","Select","Submit","Change","Load","Unload","Enter","Leave","Unknown"],["object",[[42,129,true]]],["ref",162],["array",131],["ref",258],["array",133],["union",134,1],["ref",29],["union",136,1],["object",[[72,3,true],[4,132,false],[73,135,false],[74,137,false]]],["ref",20],["array",139],["ref",22,26],["array",141],["object",[[75,140,false],[76,3,true],[77,142,false],[1,3,true]]],["ref",28],["array",144],["object",[[1,3,true],[78,0,true],[79,145,false]]],["object",[[75,140,false],[77,142,false],[1,3,true]]],["ref",24],["array",148],["object",[[80,149,false],[42,3,true]]],["array",3],["object",[[81,3,true],[78,0,true],[82,151,false]]],["ref",21],["array",153],["ref",23],["array",155],["ref",25],["union",157,1],["object",[[75,140,false],[36,154,false],[83,84,false],[84,86,false],[77,142,false],[47,3,true],[85,156,false],[78,158,false],[25,53,false]]],["object",[[86,3,true],[87,3,true]]],["enum","PropertyChanged","Added","Removed","Changed","LogicalOr","LogicalAnd","ValueTransition","Expression"],["object",[[88,84,false],[89,84,false],[90,151,false],[42,161,true],[91,84,false]]],["object",[[1,84,false]]],["object",[[92,78,true],[93,3,true],[94,3,true]]],["object",[[95,84,false],[55,84,false]]],["object",[[96,0,true]]],["object",[[55,3,true]]],["object",[[97,86,true],[55,3,true]]],["object",[[98,3,true]]],["ref",1,37,46,81,105,129,141,160,183,184],["array",170],["object",[[3,5,true],[99,171,false],[76,0,true],[1,3,true]]],["object",[[100,3,true],[101,2,false],[102,86,true]]],["object",[[100,3,true]]],["ref",48],["object",[[103,175,true]]],["object",[[69,124,true]]],["ref",43],["array",178],["object",[[68,84,false],[104,179,false]]],["ref",39,40,41,44],["object",[[47,3,true],[78,181,true],[66,119,true]]],["object",[[105,0,true],[106,3,true]]],["object",[[1,3,true]]],["object",[[72,3,true]]],["ref",122],["array",186],["ref",47,62,82,139,140,143,144,172,182,217],["array",188],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false]]],["object",[[103,3,true],[111,3,true]]],["ref",269],["object",[[112,192,true],[47,3,true]]],["ref",188,190,193,194,195,197,199,200,201,202,204,205,207,208,209],["array",194],["object",[[113,195,false],[47,3,true]]],["union",192,1],["object",[[112,197,false],[1,3,true],[2,2,false]]],["ref",11],["union",199,1],["ref",32],["union",201,1],["ref",61],["union",203,1],["ref",106],["union",205,1],["ref",157],["array",207],["ref",163],["array",209],["ref",179],["array",211],["union",212,1],["ref",166,167],["union",214,1],["ref",54],["union",216,1],["array",216],["ref",52,68],["array",219],["object",[[114,200,false],[115,202,false],[116,204,false],[68,84,false],[117,84,false],[118,206,false],[47,3,true],[119,208,false],[90,210,false],[120,213,false],[121,215,false],[122,217,false],[123,218,false],[124,220,false]]],["union",209,1],["union",131,1],["object",[[125,3,true],[126,222,false],[122,3,true],[127,223,false],[128,132,false]]],["object",[[125,3,true],[122,84,false]]],["enum","Equal","NotEqual","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Contains","StartsWith"],["object",[[129,3,true],[130,2,false],[131,226,true],[132,0,true]]],["ref",130],["array",228],["object",[[133,229,false],[66,3,true]]],["object",[[134,86,false],[47,3,true],[135,84,false],[136,84,false],[137,84,false]]],["ref",58],["array",232],["ref",60],["union",234,1],["union",220,1],["array",78],["union",237,1],["object",[[138,233,false],[68,84,false],[69,125,false],[139,235,false],[47,3,true],[66,3,true],[124,236,false],[140,238,false],[141,151,false]]],["union",175,1],["object",[[142,84,false],[143,84,false],[144,84,false],[103,240,false],[145,79,false],[146,84,false],[69,125,false],[147,84,false],[148,84,false],[149,84,false],[150,84,false],[151,79,false],[152,3,true]]],["object",[[125,86,true],[153,84,false],[154,84,false],[155,84,false],[156,151,false]]],["object",[[107,187,false],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[159,3,true]]],["ref",66],["union",245,1],["ref",199],["union",247,1],["object",[[160,3,true],[161,246,false],[162,84,false],[54,84,false],[55,84,false],[163,84,false],[164,248,false],[70,79,false],[165,84,false]]],["enum","Outlet","Dialog","External"],["object",[[42,250,true],[57,3,true]]],["ref",185],["array",252],["union",253,1],["ref",275],["array",255],["object",[[166,254,false],[167,256,false]]],["ref",7],["union",258,1],["ref",96],["array",260],["ref",215],["array",262],["ref",216],["array",264],["ref",219],["array",266],["ref",274],["array",268],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["object",[[47,3,true]]],["object",[[180,3,true]]],["ref",78],["array",273],["object",[[68,84,false],[55,84,false],[181,120,false],[47,3,true],[182,274,false],[183,79,false],[184,79,false]]],["object",[[47,3,true],[66,119,true]]],["ref",77],["array",277],["object",[[68,84,false],[55,84,false],[47,3,true],[127,120,false],[128,278,false]]],["object",[[72,3,true],[83,2,false]]],["integer",0,4294967295],["enum","Private","Public"],["object",[[68,84,false],[117,84,false],[69,125,false],[139,281,false],[185,86,false],[55,84,false],[47,3,true],[186,84,false],[90,210,false],[73,135,false],[187,282,false]]],["object",[[3,5,true],[188,86,true],[4,7,false]]],["object",[[107,187,false],[189,3,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[88,0,true]]],["ref",65],["array",287],["union",288,1],["ref",273],["array",290],["ref",84],["array",292],["ref",155],["array",294],["ref",218],["array",296],["ref",208],["array",298],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[193,86,true],[47,3,true],[21,295,false],[194,297,false],[29,59,false],[195,299,false],[179,269,false]]],["ref",85,271,272],["array",301],["object",[[196,302,false],[68,84,false],[69,124,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[147,3,true]]],["object",[[163,84,false],[1,3,true]]],["ref",90],["array",306],["object",[[199,3,true],[90,307,false]]],["object",[[200,3,true],[201,151,false],[202,86,true],[163,84,false],[203,151,false],[159,3,true],[204,84,false],[205,86,true]]],["ref",92],["array",310],["object",[[190,311,false],[206,3,true]]],["ref",93],["array",313],["object",[[200,3,true],[61,314,false],[159,3,true],[2,2,false]]],["ref",94],["array",316],["object",[[55,3,true],[141,317,false]]],["object",[[207,3,true],[2,0,true]]],["object",[[160,3,true],[113,195,false],[70,79,false]]],["object",[[113,195,false],[56,3,true]]],["ref",100],["union",322,1],["ref",98],["array",324],["ref",99],["array",326],["object",[[208,323,false],[37,325,false],[209,327,false],[210,323,false]]],["object",[[211,78,true],[212,323,false],[213,323,false],[45,323,false]]],["object",[[214,78,true],[215,79,false],[207,3,true],[216,78,true],[217,79,false],[45,323,false]]],["enum","Fraction","Pixels","Percent","Auto"],["object",[[94,331,true],[2,81,false]]],["object",[[218,84,false],[86,84,false],[163,84,false],[1,3,true]]],["object",[[105,84,false],[106,3,true]]],["enum","Unspecified","Auto","Manual"],["ref",88],["array",336],["ref",101],["array",338],["ref",97],["union",340,1],["ref",102,103],["union",342,1],["object",[[6,12,false],[219,335,true],[37,337,false],[68,84,false],[220,339,false],[221,3,true],[222,335,true],[223,341,false],[47,3,true],[224,248,false],[225,343,false],[179,269,false]]],["ref",79],["array",345],["ref",57,83],["union",347,1],["object",[[226,346,false],[83,348,false],[4,7,false],[227,2,false]]],["ref",107],["union",350,1],["object",[[103,240,false],[69,125,false],[228,351,false]]],["ref",108],["array",353],["object",[[229,354,false]]],["object",[[230,3,true]]],["object",[[68,84,false],[47,3,true]]],["ref",111],["union",358,1],["object",[[231,359,false],[68,84,false],[232,359,false],[233,210,false],[47,3,true],[234,3,true]]],["object",[[103,240,false],[68,84,false],[69,125,false],[228,351,false]]],["ref",248],["union",362,1],["ref",247],["union",364,1],["object",[[68,84,false],[221,2,false],[235,132,false],[47,3,true],[236,363,false],[122,365,false],[66,3,true],[141,132,false]]],["object",[[47,3,true],[141,132,false]]],["object",[[237,3,true]]],["object",[[237,3,true],[141,132,false]]],["object",[[186,84,false],[238,3,true],[187,282,false]]],["ref",56,134],["object",[[239,189,false],[240,371,true]]],["object",[[239,189,false]]],["object",[[112,3,true],[47,3,true]]],["ref",120],["array",375],["ref",121],["union",377,1],["ref",3,19,74,124],["object",[[239,189,false],[241,376,false],[240,84,false],[242,378,false],[243,379,true]]],["enum","Seconds","Minutes","Hours","Days"],["object",[[92,78,true],[94,381,true]]],["ref",127],["array",383],["object",[[189,3,true],[4,132,false],[244,384,false]]],["object",[[245,86,true],[246,84,false],[119,208,false],[247,3,true]]],["object",[[3,5,true],[72,3,true],[4,7,false]]],["ref",128],["array",388],["object",[[226,389,false],[248,3,true],[1,3,true]]],["object",[[88,0,true],[1,3,true]]],["ref",14],["array",392],["object",[[168,259,false],[6,12,false],[169,84,false],[172,263,false],[47,3,true],[249,393,false],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["array",0],["object",[[61,395,false]]],["union",3,86,1],["number",-1.7976931348623157E+308,1.7976931348623157E+308],["enum","Int32","Int64","Decimal","Single"],["string","^-?[0-9]\u002B(\\.[0-9]\u002B)?([Ee][\u002B-]?[0-9]\u002B)?$"],["object",[[250,399,true],[2,400,true]]],["const","ExactNumber"],["string","^(?:0|-?(?:[1-9][0-9]{0,28}|(?:0|[1-9][0-9]{0,28})\\.[0-9]{0,27}[1-9]))$"],["object",[[250,402,true],[2,403,true]]],["union",397,398,401,404],["object",[[2,405,false]]],["enum","And","Or"],["object",[[129,371,true],[131,407,true],[132,371,true]]],["ref",8,38,135,142,186,277],["object",[[129,409,true],[131,407,true],[132,409,true]]],["object",[[129,102,true],[131,407,true],[132,102,true]]],["ref",70],["array",412],["union",413,1],["ref",104],["array",415],["union",416,1],["ref",206],["array",418],["object",[[114,200,false],[6,12,false],[190,289,false],[191,291,false],[68,84,false],[251,414,false],[117,84,false],[11,22,false],[192,293,false],[13,26,false],[252,417,false],[193,86,true],[47,3,true],[249,393,false],[21,295,false],[253,419,false],[29,59,false],[195,299,false],[179,269,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[254,3,true]]],["object",[[3,5,true],[99,171,false],[1,3,true]]],["object",[[96,409,true]]],["enum","Info","Warning","Error","Unknown"],["object",[[107,187,false],[255,424,true],[157,3,true],[158,86,true],[108,189,false],[109,189,false],[110,189,false]]],["object",[[107,187,false],[256,3,true],[108,189,false],[109,189,false],[110,189,false]]],["ref",146],["array",427],["object",[[257,428,false]]],["object",[[47,3,true],[2,0,true]]],["object",[[103,240,false],[69,125,false]]],["object",[[68,84,false],[258,151,false],[43,79,false],[47,3,true],[20,151,false],[45,79,false],[183,79,false],[184,79,false]]],["object",[[259,3,true],[260,84,false],[43,79,false],[230,3,true],[45,79,false],[183,78,true],[184,78,true]]],["object",[[261,86,false],[262,84,false],[263,84,false],[264,3,true],[183,79,false],[184,79,false]]],["union",409,1],["object",[[103,240,false],[240,435,false],[68,84,false],[69,125,false],[47,3,true]]],["ref",156],["array",437],["object",[[265,84,false],[266,84,false],[267,84,false],[240,84,false],[268,84,false],[68,84,false],[269,84,false],[270,84,false],[47,3,true],[271,151,false],[272,84,false],[273,151,false],[274,438,false]]],["object",[[161,3,true],[275,3,true]]],["ref",80],["union",441,1],["ref",110],["union",443,1],["union",371,1],["object",[[72,3,true],[221,2,false],[276,442,false],[277,444,false],[4,132,false],[122,217,false],[73,135,false],[74,445,false]]],["object",[[3,5,true],[99,171,false],[68,84,false],[69,125,false],[83,348,false],[47,3,true],[278,84,false],[279,84,false],[25,53,false]]],["ref",158],["array",448],["object",[[99,171,false],[280,449,false],[47,3,true]]],["object",[[1,3,true],[78,0,true]]],["object",[[281,86,false],[282,86,false],[283,86,false],[284,86,false],[47,3,true],[66,119,true]]],["ref",164],["object",[[47,3,true],[78,453,true],[66,120,false]]],["object",[[78,453,true]]],["ref",165],["array",456],["object",[[220,457,false]]],["object",[[2,0,true]]],["object",[[220,132,false]]],["object",[[47,3,true],[78,2,false],[66,119,true]]],["ref",170],["union",462,1],["array",462],["ref",148],["union",465,1],["object",[[114,200,false],[105,463,false],[285,464,false],[68,84,false],[286,464,false],[287,86,false],[47,3,true],[288,466,false],[289,119,true],[136,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[243,3,true]]],["object",[[290,151,false],[42,3,true]]],["ref",55],["union",470,1],["ref",174],["union",472,1],["ref",176],["array",474],["object",[[68,84,false],[117,84,false],[86,471,false],[47,3,true],[291,473,false],[32,475,false],[292,445,false]]],["ref",265],["array",477],["ref",126],["array",479],["union",480,1],["union",208,1],["ref",125,138,187],["object",[[103,240,false],[293,478,false],[68,84,false],[69,125,false],[294,481,false],[119,482,false],[120,213,false],[78,483,true]]],["object",[[295,3,true]]],["object",[[68,84,false],[117,84,false],[69,125,false],[47,3,true],[90,210,false]]],["object",[[51,84,false],[105,84,false],[285,132,false],[278,3,true]]],["object",[[103,240,false],[68,84,false],[72,3,true],[69,125,false]]],["ref",180],["array",489],["object",[[68,84,false],[86,471,false],[47,3,true],[278,3,true],[167,490,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[106,3,true]]],["ref",57],["union",493,1],["object",[[72,3,true],[83,2,false],[227,2,false],[296,494,false]]],["enum","Error","Information","Warning"],["object",[[240,371,true],[157,84,false],[297,496,true]]],["object",[[298,3,true]]],["enum","Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],["union",499,1],["string","^([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]{1,7})?$"],["object",[[299,79,false],[300,500,false],[301,501,true]]],["enum","Item","Screen"],["union",503,1],["object",[[189,3,true],[233,187,false],[163,84,false],[164,248,false],[302,504,false]]],["ref",191],["array",506],["ref",192],["union",508,1],["object",[[241,507,false],[163,3,true],[164,248,false],[242,509,false],[302,504,false]]],["object",[[107,187,false],[189,3,true],[240,371,true]]],["enum","Hidden","Execute","Unknown"],["object",[[107,187,false],[189,84,false],[303,512,true]]],["object",[[304,11,true]]],["ref",49],["array",515],["ref",50],["array",517],["ref",161],["array",519],["ref",51],["array",521],["object",[[6,12,false],[200,3,true],[305,197,false],[172,516,false],[54,84,false],[47,3,true],[173,518,false],[165,520,false],[90,522,false],[306,84,false],[179,269,false]]],["object",[[105,84,false],[106,3,true],[66,119,true]]],["object",[[163,3,true],[1,3,true]]],["ref",189],["array",526],["object",[[105,84,false],[307,84,false],[71,527,false],[308,84,false],[254,3,true]]],["ref",198],["array",529],["object",[[220,530,false],[57,3,true]]],["ref",95],["array",532],["object",[[190,533,false],[68,84,false],[113,195,false],[69,125,false],[47,3,true]]],["ref",196],["array",535],["object",[[6,12,false],[37,536,false],[309,248,false],[57,3,true],[179,269,false]]],["ref",201],["array",538],["object",[[310,84,false],[47,3,true],[177,539,false],[311,84,false]]],["object",[[168,259,false],[6,12,false],[169,84,false],[170,261,false],[68,84,false],[171,84,false],[172,263,false],[312,84,false],[47,3,true],[173,265,false],[174,86,false],[175,151,false],[176,151,false],[177,267,false],[178,84,false],[179,269,false]]],["ref",260],["array",542],["object",[[60,111,false],[61,543,false],[47,3,true]]],["object",[[234,268,true]]],["object",[[72,3,true],[90,132,false]]],["ref",210],["array",547],["object",[[313,3,true],[226,548,false]]],["ref",211],["array",550],["object",[[314,551,false],[47,84,false],[183,79,false],[184,79,false]]],["object",[[310,84,false],[47,3,true],[311,84,false]]],["object",[[107,187,false],[108,189,false],[109,189,false],[110,189,false],[57,3,true],[2,3,true]]],["ref",27],["array",555],["ref",53],["array",557],["enum","Inbound","Outbound"],["union",559,1],["array",441],["array",443],["ref",159],["array",563],["ref",171],["array",565],["ref",175],["array",567],["ref",178],["array",569],["union",570,1],["ref",181],["array",572],["union",573,1],["ref",203],["array",575],["ref",253],["array",577],["enum","StateChange","StateView","Automation","Translate"],["object",[[315,556,false],[316,558,false],[317,302,false],[68,84,false],[318,560,false],[117,84,false],[226,561,false],[11,22,false],[69,125,false],[47,3,true],[203,562,false],[319,564,false],[21,295,false],[320,566,false],[321,568,false],[322,571,false],[323,574,false],[324,576,false],[325,578,false],[29,59,false],[66,579,true]]],["object",[[326,84,false],[47,3,true]]],["object",[[83,0,true],[47,3,true]]],["object",[[66,3,true],[2,3,true]]],["ref",222],["array",584],["object",[[327,86,true],[328,585,false],[290,151,false]]],["object",[[329,3,true],[330,132,false]]],["object",[[331,3,true]]],["object",[[189,3,true],[1,3,true],[78,0,true]]],["object",[[189,3,true],[141,132,false]]],["object",[[332,3,true],[221,2,false],[235,132,false],[333,84,false],[141,132,false]]],["ref",36],["union",592,1],["object",[[334,593,false],[47,84,false]]],["object",[[335,3,true],[221,2,false],[333,84,false],[236,363,false],[122,365,false],[141,132,false]]],["object",[[336,84,false],[337,84,false],[338,84,false],[339,84,false]]],["union",86,1],["object",[[340,84,false],[341,84,false],[47,84,false],[342,597,false]]],["ref",238],["array",599],["object",[[310,84,false],[47,3,true],[343,600,false],[311,84,false]]],["ref",241],["object",[[344,602,true],[278,3,true]]],["enum","Word","Text","Number","Flag"],["object",[[47,3,true],[42,604,true],[2,3,true]]],["enum","Text","Number","Flag","Null"],["object",[[47,3,true],[42,606,true],[2,84,false]]],["object",[[278,3,true],[345,3,true]]],["object",[[346,86,true],[47,3,true]]],["ref",245],["array",610],["object",[[347,84,false],[47,3,true],[348,611,false],[58,84,false]]],["ref",239],["array",613],["object",[[220,614,false]]],["union",602,1],["ref",237],["array",617],["ref",240],["array",619],["object",[[349,616,false],[67,618,false],[4,620,false]]],["ref",243],["array",622],["object",[[40,623,false],[345,3,true]]],["object",[[125,3,true],[122,3,true],[127,223,false],[128,132,false]]],["object",[[350,86,true],[90,132,false]]],["ref",249],["array",627],["object",[[107,132,false],[350,86,true],[106,3,true],[351,628,false]]],["object",[[350,86,true],[333,84,false],[47,3,true],[90,132,false]]],["object",[[335,3,true],[221,2,false],[236,363,false],[352,3,true],[122,365,false],[141,132,false]]],["ref",114],["array",632],["ref",232],["array",634],["ref",224],["union",636,1],["ref",223],["union",638,1],["ref",225],["array",640],["ref",226],["union",642,1],["ref",227],["array",644],["ref",115],["array",646],["ref",251],["array",648],["union",649,1],["ref",34],["union",651,1],["ref",113],["array",653],["ref",221],["array",655],["ref",117],["array",657],["ref",230],["union",659,1],["ref",231],["array",661],["ref",228],["array",663],["ref",246],["union",665,1],["ref",116],["array",667],["ref",250],["array",669],["ref",168,169],["union",671,1],["ref",229],["union",673,1],["union",634,1],["union",640,1],["ref",255],["union",677,1],["ref",252],["union",679,1],["ref",254],["union",681,1],["object",[[353,633,false],[68,84,false],[11,22,false],[69,125,false],[354,635,false],[355,637,false],[356,639,false],[357,641,false],[358,643,false],[359,645,false],[360,647,false],[361,650,false],[362,652,false],[47,3,true],[71,654,false],[25,53,false],[363,656,false],[364,658,false],[365,660,false],[366,662,false],[367,635,false],[368,86,true],[369,664,false],[370,86,false],[371,666,false],[372,668,false],[373,670,false],[374,650,false],[375,628,false],[376,672,false],[74,674,false],[377,675,false],[378,676,false],[379,643,false],[380,678,false],[381,680,false],[382,682,false]]],["object",[[243,3,true],[141,132,false]]],["object",[[107,132,false],[106,3,true]]],["object",[[83,3,true]]],["enum","Primary","Secondary","Quiet"],["union",687,1],["object",[[114,200,false],[383,84,false],[384,688,false],[54,84,false],[55,3,true],[385,84,false],[58,3,true]]],["enum","Unknown","Action","Navigate","Dialog"],["object",[[383,84,false],[54,84,false],[163,84,false],[47,3,true],[71,527,false],[165,520,false],[302,504,false],[42,690,true],[57,3,true]]],["ref",262,263],["array",692],["object",[[133,693,false]]],["object",[[386,151,false],[47,3,true]]],["object",[[293,478,false],[68,84,false],[69,125,false],[47,3,true]]],["object",[[202,86,true],[387,86,true],[47,3,true]]],["object",[[68,84,false],[69,125,false],[47,3,true],[90,210,false]]],["enum","Invalid","DataContext","QueryResult","ComponentProperty","Literal"],["enum","OneWay","TwoWay"],["union",700,1],["enum","Propagate","Clear","Preserve"],["union",702,1],["object",[[388,699,true],[389,84,false],[390,84,false],[391,84,false],[392,2,false],[48,701,false],[393,703,false],[159,3,true],[106,84,false],[394,84,false]]],["ref",234],["union",705,1],["ref",235],["union",707,1],["ref",233],["union",709,1],["ref",236],["union",711,1],["ref",244],["union",713,1],["object",[[395,706,false],[396,84,false],[397,151,false],[14,708,false],[223,84,false],[47,3,true],[398,710,false],[399,151,false],[400,151,false],[44,712,false],[401,714,false],[402,84,false]]],["object",[[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[198,151,false]]],["object",[[403,151,false],[196,302,false],[68,84,false],[72,3,true],[197,86,true],[157,84,false],[47,3,true],[1,3,true],[198,151,false]]],["object",[[57,3,true]]],["ref",16],["array",719],["object",[[107,720,false],[304,3,true]]],["enum","NotEmpty","Max","Min","GreaterThan","GreaterThanOrEqual","LessThan","LessThanOrEqual","Equal","Length","Matches","AllGreaterThan","AllGreaterThanOrEqual","Rule","NotEqual","Checksum","Contains","NotContains","StartsWith","EndsWith","DecimalPlaces"],["object",[[103,240,false],[69,125,false],[228,351,false],[157,84,false],[1,3,true],[150,722,true],[297,496,true],[2,2,false]]],["ref",151],["array",724],["object",[[43,3,true],[404,725,false],[45,3,true]]]],"contracts":[4,8,74,75,83,85,87,96,97,98,101,103,108,109,116,117,118,121,128,130,138,143,146,147,118,150,152,159,160,162,163,164,165,166,167,168,169,172,173,174,176,177,180,182,183,184,185,190,191,193,196,198,176,221,224,225,227,230,231,239,241,242,243,244,244,249,251,184,257,184,270,271,271,244,272,97,275,276,279,280,283,284,285,286,300,303,304,244,305,308,309,312,315,318,319,320,321,328,329,330,332,333,97,334,344,349,352,355,356,357,360,361,366,276,367,368,369,368,370,184,372,373,374,380,382,382,385,386,387,390,391,394,396,406,408,410,411,420,271,421,190,422,423,425,426,429,430,244,431,432,433,434,271,436,439,271,440,446,280,447,450,118,451,452,184,454,455,458,459,460,461,467,468,356,469,476,484,485,486,487,488,491,492,280,495,497,498,502,505,193,510,511,513,514,176,523,305,524,525,528,196,196,531,534,537,540,541,356,544,545,546,549,552,451,553,121,271,554,580,581,244,582,583,271,586,587,588,589,590,591,97,594,595,553,596,598,601,603,605,607,608,609,612,615,621,624,97,625,97,626,629,630,631,683,684,685,686,4,459,689,691,694,286,356,695,121,696,697,698,704,715,716,717,718,721,723,726,97]} as const; From 441d103adb1f21a6804f92954307aabd7aec61d1 Mon Sep 17 00:00:00 2001 From: woksin Date: Sun, 25 Oct 2026 22:51:36 +0100 Subject: [PATCH 8/9] Parse complete screen headers before subject clauses and verify subject repairs per occurrence (Cratis/Screenplay#1052) --- .../Parsing/ScreenParser.ActionSubjects.cs | 32 +++- .../DotNET/Screenplay/Parsing/ScreenParser.cs | 9 +- .../WorkspaceActionSubjectRepairs.cs | 1 - ...two_identical_action_subject_advisories.cs | 97 +++++++++++ ...rving_for_identifiers_in_screen_headers.cs | 155 ++++++++++++++++++ .../when_repairing_action_subjects.ts | 45 ++++- .../Compiler/Parsing/ActionSubjectClause.ts | 13 +- .../Compiler/Parsing/ScreenParser.ts | 12 +- ...rving_for_identifiers_in_screen_headers.ts | 125 ++++++++++++++ 9 files changed, 472 insertions(+), 17 deletions(-) create mode 100644 Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_one_of_two_identical_action_subject_advisories.cs create mode 100644 Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_for_identifiers_in_screen_headers.cs create mode 100644 Source/Screenplay/Compiler/for_parse/when_preserving_for_identifiers_in_screen_headers.ts diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs index 587982b4d..3159aa789 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.ActionSubjects.cs @@ -13,7 +13,8 @@ internal static partial class ScreenParser static ScreenActionSubjectKind? ParseSubjectClause(SubjectClauseRequest request, out string header, out string? label) { header = request.Line.Content; - var words = HeaderWordRegex().Matches(header).Cast().ToArray(); + var boundary = SubjectHeaderBoundary(header, request.IsHeader); + var words = HeaderWordRegex().Matches(header).Cast().Where(word => word.Index >= boundary).ToArray(); var clauses = words.Where(word => word.Value == "for").ToArray(); var labelWord = words.FirstOrDefault(word => word.Value == "label"); label = ParseSubjectLabel(ref header, labelWord); @@ -24,7 +25,7 @@ internal static partial class ScreenParser if (IsInvalidSubjectClause(request, clauses, suffix, labelWord)) { request.Context.Error(DiagnosticCodes.InvalidActionSubjectClause, "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", request.Line.Location); - header = header[..Math.Min(clause.Index, header.Length)].TrimEnd(); + header = header[..boundary].TrimEnd(); return null; } @@ -32,6 +33,31 @@ internal static partial class ScreenParser return suffix.Groups[1].Value == "item" ? ScreenActionSubjectKind.Item : ScreenActionSubjectKind.Screen; } + static int SubjectHeaderBoundary(string content, Func isHeader) + { + // A complete existing header wins, including keyword-looking required operands. + if (isHeader(content)) return content.Length; + return HeaderWordRegex().Matches(content).Cast().Reverse() + .FirstOrDefault(word => isHeader(content[..word.Index].TrimEnd()))?.Index ?? content.Length; + } + + static bool IsActionHeader(string content) => ActionRegex().IsMatch(content) || GuardedActionRegex().IsMatch(content); + + static void ValidateNonActionSubjectClause(ParserContext context, SourceLine line) + { + var grammar = LineText.FirstWord(line.Content) switch + { + "data" => DataRegex(), + "navigate" => NavigateRegex(), + "component" => ComponentRegex(), + "title" => TitleRegex(), + _ => null + }; + + // Expressions, code and open-ended template references belong to their own parsers. + if (grammar is not null) ParseSubjectClause(new(context, line, false, grammar.IsMatch), out _, out _); + } + static string? ParseSubjectLabel(ref string header, Match? labelWord) { if (labelWord is null) return null; @@ -72,5 +98,5 @@ static bool IsInvalidSubjectClause(SubjectClauseRequest request, Match[] clauses [GeneratedRegex(@"^for\s+(item|screen)$", RegexOptions.NonBacktracking)] private static partial Regex SubjectClauseRegex(); - sealed record SubjectClauseRequest(ParserContext Context, SourceLine Line, bool Action); + sealed record SubjectClauseRequest(ParserContext Context, SourceLine Line, bool Action, Func IsHeader); } diff --git a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs index 128d25205..5eeeca902 100644 --- a/Source/DotNET/Screenplay/Parsing/ScreenParser.cs +++ b/Source/DotNET/Screenplay/Parsing/ScreenParser.cs @@ -158,10 +158,7 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi static ScreenDirectiveSyntax? ParseDirective(ParserContext context, SourceLine line) { - if (LineText.FirstWord(line.Content) != "action") - { - ParseSubjectClause(new(context, line, false), out _, out _); - } + ValidateNonActionSubjectClause(context, line); switch (LineText.FirstWord(line.Content)) { @@ -221,7 +218,7 @@ internal static ScreenToolbarSyntax ParseToolbar(ParserContext context, SourceLi static ScreenDirectiveSyntax? ParseAction(ParserContext context, SourceLine line) { - var subject = ParseSubjectClause(new(context, line, true), out var header, out var inlineLabel); + var subject = ParseSubjectClause(new(context, line, true, IsActionHeader), out var header, out var inlineLabel); var guarded = GuardedActionRegex().Match(header); if (guarded.Success) { @@ -554,7 +551,7 @@ static ComponentOutletSyntax ParseComponentOutlet(ParserContext context, SourceL static ToolbarItemSyntax? ParseToolbarItem(ParserContext context, SourceLine line) { var isAction = ToolbarActionHeaderRegex().IsMatch(line.Content); - var subject = ParseSubjectClause(new(context, line, isAction), out var header, out var inlineLabel); + var subject = ParseSubjectClause(new(context, line, isAction, ToolbarItemRegex().IsMatch), out var header, out var inlineLabel); var match = ToolbarItemRegex().Match(header); if (!match.Success) { diff --git a/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs index 68db144db..1bd1f3cf7 100644 --- a/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs +++ b/Source/DotNET/Screenplay/Workspaces/WorkspaceActionSubjectRepairs.cs @@ -70,7 +70,6 @@ internal static bool Preserves(WorkspaceSyntaxIndex index, WorkspaceDiagnosticRe var subject = index.Find(repair.Subject)!; var before = index.Workspace.Compilation.Diagnostics; var after = result.Workspace!.Compilation.Diagnostics; - if (after.Any(diagnostic => diagnostic.Code == repair.DiagnosticCode && diagnostic.Message == before.First(original => original.Code == repair.DiagnosticCode && original.Location == subject.Location).Message)) return false; static bool IsSubjectDiagnostic(Diagnostic diagnostic) => diagnostic.Code == DiagnosticCodes.InferredActionSubject || diagnostic.Code == DiagnosticCodes.ChangedActionSubject; var expected = before.Where(diagnostic => diagnostic.Location != subject.Location || !IsSubjectDiagnostic(diagnostic)).Select(diagnostic => (diagnostic.Code, diagnostic.Message)).Order().ToArray(); var actual = after.Select(diagnostic => (diagnostic.Code, diagnostic.Message)).Order().ToArray(); diff --git a/Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_one_of_two_identical_action_subject_advisories.cs b/Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_one_of_two_identical_action_subject_advisories.cs new file mode 100644 index 000000000..ec19d3e4e --- /dev/null +++ b/Source/DotNET/Screenplay/Workspaces/for_WorkspaceAuthoring/when_repairing_one_of_two_identical_action_subject_advisories.cs @@ -0,0 +1,97 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Text; +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Semantics; +using Cratis.Screenplay.Semantics.Serialization; +using Cratis.Screenplay.Syntax; +using Cratis.Screenplay.Syntax.Serialization; + +namespace Cratis.Screenplay.Workspaces.for_WorkspaceAuthoring; + +public class when_repairing_one_of_two_identical_action_subject_advisories : Specification +{ + const string Source = """ + concept ItemId : Uuid + module Work + feature Items + slice StateView List + readmodel Row + itemId ItemId key + command Retry + itemId ItemId + query Rows => Row[] + screen First + data Row[] via query Rows + action Retry // first invocation + screen Second + data Row[] via query Rows + action Retry // second invocation + """; + ScreenplayWorkspace _workspace; + WorkspaceSyntaxIndex _index; + + void Establish() + { + _workspace = ScreenplayWorkspace.Create("Model", [WorkspaceDocument.Create("model", PortablePlayPath.Parse("model.play"), Encoding.UTF8.GetBytes(Source))], SemanticIdentityCatalog.Empty(ApplicationIdentity.Create("Model"))); + _index = WorkspaceSyntaxIndex.Create(_workspace); + } + + [Theory] + [InlineData("First", "Second")] + [InlineData("Second", "First")] + void should_repair_only_the_selected_occurrence(string selectedName, string untouchedName) + { + var advisories = _workspace.Compilation.Diagnostics.Where(diagnostic => diagnostic.Code == DiagnosticCodes.InferredActionSubject).ToArray(); + advisories.Length.ShouldEqual(2); + advisories[0].Message.ShouldEqual(advisories[1].Message); + (advisories[0].Location != advisories[1].Location).ShouldBeTrue(); + var selected = Action(_index, selectedName); + var untouched = Action(_index, untouchedName); + var diagnostic = _index.RepairableDiagnostics.Single(value => value.Code == DiagnosticCodes.InferredActionSubject && value.Location == selected.Location); + var repair = WorkspaceDiagnosticRepairs.Find(_index, _workspace.Revision, diagnostic).Single(); + repair.CanFixAll.ShouldBeFalse(); + _index.Find(repair.Subject)!.Location.ShouldEqual(selected.Location); + var result = WorkspaceDiagnosticRepairs.ProposeRepair(_workspace, repair, new() + { + ExpectedRevision = _workspace.Revision, + ExpectedCatalogRevision = _workspace.IdentityCatalog.Revision, + Validation = WorkspaceAuthoringValidation.Authoring, + Formatting = WorkspaceAuthoringFormatting.CanonicalizeTouchedDocuments + }); + + result.Accepted.ShouldBeTrue(); + var candidate = result.Workspace!; + var afterIndex = WorkspaceSyntaxIndex.Create(candidate); + var repaired = Action(afterIndex, selectedName); + var remaining = Action(afterIndex, untouchedName); + repaired.Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + remaining.Subject.ShouldBeNull(); + afterIndex.Entries.Select(entry => entry.Node).OfType().Count(action => action.Subject is not null).ShouldEqual(1); + SyntaxJson.StructurallyEqual(repaired, selected with { Subject = ScreenActionSubjectKind.Screen }).ShouldBeTrue(); + SyntaxJson.StructurallyEqual(remaining, untouched).ShouldBeTrue(); + var remainingAdvisory = candidate.Compilation.Diagnostics.Single(value => value.Code == DiagnosticCodes.InferredActionSubject); + remainingAdvisory.Message.ShouldEqual(diagnostic.Message); + remainingAdvisory.Location.ShouldEqual(remaining.Location); + candidate.Compilation.Diagnostics.Any(value => value.Code == DiagnosticCodes.ChangedActionSubject && value.Location == repaired.Location).ShouldBeFalse(); + + var expected = _workspace.Compilation.Diagnostics + .Where(value => value.Location != selected.Location || value.Code is not (DiagnosticCodes.InferredActionSubject or DiagnosticCodes.ChangedActionSubject)) + .Select(value => (value.Code, value.Message)).Order().ToArray(); + var actual = candidate.Compilation.Diagnostics.Select(value => (value.Code, value.Message)).Order().ToArray(); + actual.SequenceEqual(expected).ShouldBeTrue(); + SemanticModelSerializer.Serialize(candidate.Compilation.Value!.Model).SequenceEqual(SemanticModelSerializer.Serialize(_workspace.Compilation.Value!.Model)).ShouldBeTrue(); + candidate.IdentityCatalog.Revision.ShouldEqual(_workspace.IdentityCatalog.Revision); + _workspace.Documents.Single().Text.ShouldEqual(Source); + Action(_index, selectedName).Subject.ShouldBeNull(); + Action(_index, untouchedName).Subject.ShouldBeNull(); + SyntaxJson.StructurallyEqual(Action(_index, untouchedName), untouched).ShouldBeTrue(); + candidate.Documents.Single().Text.ShouldContain("// first invocation"); + candidate.Documents.Single().Text.ShouldContain("// second invocation"); + } + + static ScreenActionSyntax Action(WorkspaceSyntaxIndex index, string screen) => index.Entries + .Select(entry => entry.Node).OfType().Single(node => node.Name == screen) + .Directives.OfType().Single(); +} diff --git a/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_for_identifiers_in_screen_headers.cs b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_for_identifiers_in_screen_headers.cs new file mode 100644 index 000000000..addc0a16b --- /dev/null +++ b/Source/DotNET/Screenplay/for_ScreenplayCompiler/when_preserving_for_identifiers_in_screen_headers.cs @@ -0,0 +1,155 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Cratis.Screenplay.Diagnostics; +using Cratis.Screenplay.Syntax; + +namespace Cratis.Screenplay.for_ScreenplayCompiler; + +public class when_preserving_for_identifiers_in_screen_headers : given.a_compiler +{ + [Theory] + [InlineData("action for", "for", null, null)] + [InlineData("action for for screen", "for", ScreenActionSubjectKind.Screen, null)] + [InlineData("action Work.Items.Details.for for item", "Work.Items.Details.for", ScreenActionSubjectKind.Item, null)] + [InlineData("action label", "label", null, null)] + [InlineData("action label for screen label \"Retry for screen\"", "label", ScreenActionSubjectKind.Screen, "Retry for screen")] + [InlineData("action for label \"Retry for screen\"", "for", null, "Retry for screen")] + [InlineData("action for for item label \"Retry \\\"for\\\" screen\"", "for", ScreenActionSubjectKind.Item, "Retry \"for\" screen")] + [InlineData("action for for screen label $strings.for.label", "for", ScreenActionSubjectKind.Screen, "$strings.for.label")] + void should_preserve_the_plain_command_and_trailing_metadata(string header, string command, ScreenActionSubjectKind? subject, string? label) + { + var result = Compile(header); + var action = Screen(result).Directives.OfType().Single(); + action.Command.ShouldEqual(command); + action.Subject.ShouldEqual(subject); + action.Label.ShouldEqual(label); + result.Success.ShouldBeTrue(); + } + + [Theory] + [InlineData("action \"Retry for screen\"", "Retry for screen", null)] + [InlineData("action \"Retry \\\"for\\\" screen\" for item", "Retry \"for\" screen", ScreenActionSubjectKind.Item)] + [InlineData("action $strings.for.label for screen", "$strings.for.label", ScreenActionSubjectKind.Screen)] + void should_keep_guarded_operands_opaque(string header, string label, ScreenActionSubjectKind? subject) + { + var result = Compile(header + "\n when item.ready == true execute for"); + var action = Screen(result).Directives.OfType().Single(); + action.Label.ShouldEqual(label); + action.Subject.ShouldEqual(subject); + action.Alternatives.Single().Command.ShouldEqual("for"); + result.Success.ShouldBeTrue(); + } + + [Theory] + [InlineData("item for action Retry", "for", "Retry", null)] + [InlineData("item retry action for", "retry", "for", null)] + [InlineData("item for action for", "for", "for", null)] + [InlineData("item for action for for screen", "for", "for", ScreenActionSubjectKind.Screen)] + [InlineData("item for action Retry for item", "for", "Retry", ScreenActionSubjectKind.Item)] + [InlineData("item label action label for screen", "label", "label", ScreenActionSubjectKind.Screen)] + [InlineData("item for action to for", "for", "for", null)] + [InlineData("item for action to for for screen", "for", "for", ScreenActionSubjectKind.Screen)] + [InlineData("item for action Work.Items.Details.for for item", "for", "Work.Items.Details.for", ScreenActionSubjectKind.Item)] + void should_consume_the_complete_toolbar_action_header(string header, string name, string target, ScreenActionSubjectKind? subject) + { + var result = Compile("toolbar\n " + header); + var item = Screen(result).Directives.OfType().Single().Items.Single(); + item.Name.ShouldEqual(name); + item.Target.ShouldEqual(target); + item.Subject.ShouldEqual(subject); + result.Success.ShouldBeTrue(); + } + + [Theory] + [InlineData("item for navigate to for", "for", "for")] + [InlineData("item for navigate for", "for", "for")] + [InlineData("item for dialog for", "for", "for")] + [InlineData("item for dialog to for", "for", "for")] + [InlineData("item label navigate to label", "label", "label")] + void should_preserve_non_action_toolbar_operands(string header, string name, string target) + { + var result = Compile("toolbar\n " + header); + var item = Screen(result).Directives.OfType().Single().Items.Single(); + item.Name.ShouldEqual(name); + item.Target.ShouldEqual(target); + item.Subject.ShouldBeNull(); + result.Success.ShouldBeTrue(); + } + + [Fact] + void should_preserve_non_action_directive_fields() + { + var result = Compile("navigate to for\ndata Row via query for\ncomponent for screen\ncomponent Widget for\ntemplate for"); + var directives = Screen(result).Directives.ToArray(); + directives.OfType().Single().Screen.ShouldEqual("for"); + directives.OfType().Last().Query.ShouldEqual("for"); + directives.OfType().First().Component.ShouldEqual("for"); + directives.OfType().First().Name.ShouldEqual("screen"); + directives.OfType().Last().Name.ShouldEqual("for"); + directives.OfType().Single().Name.ShouldEqual("for"); + result.Success.ShouldBeTrue(); + } + + [Fact] + void should_preserve_inputs_and_child_labels() + { + var result = Compile("action for for item label \"Inline for screen\"\n with note from item.note\n label \"Child for screen\"\ntoolbar\n item for action for for screen label \"Toolbar for item\""); + var action = Screen(result).Directives.OfType().Single(); + action.Subject.ShouldEqual(ScreenActionSubjectKind.Item); + action.Label.ShouldEqual("Child for screen"); + action.Inputs.Single().Binding.ShouldEqual("item.note"); + Screen(result).Directives.OfType().Single().Items.Single().Label.ShouldEqual("Toolbar for item"); + result.Success.ShouldBeTrue(); + } + + [Theory] + [InlineData("for")] + [InlineData("for planet")] + [InlineData("for item for screen")] + [InlineData("label \"Try\" for screen")] + void should_reject_malformed_tails_after_keyword_named_operands(string suffix) + { + var result = Compile("action for " + suffix + "\ntoolbar\n item for action for " + suffix); + result.Diagnostics.Count(diagnostic => diagnostic.Code == DiagnosticCodes.InvalidActionSubjectClause).ShouldEqual(2); + } + + [Theory] + [InlineData("item for action for for screen label \"Retry for item\"", "Retry for item")] + [InlineData("item for action for for screen label $strings.for.label", "$strings.for.label")] + void should_preserve_toolbar_labels_and_parameters(string header, string label) + { + var result = Compile("toolbar\n " + header + "\n parameter note from data item.note"); + var item = Screen(result).Directives.OfType().Single().Items.Single(); + item.Name.ShouldEqual("for"); + item.Target.ShouldEqual("for"); + item.Subject.ShouldEqual(ScreenActionSubjectKind.Screen); + item.Label.ShouldEqual(label); + item.Parameters.Single().Binding.Path.ShouldEqual("item.note"); + result.Success.ShouldBeTrue(); + } + + [Theory] + [InlineData("toolbar\n item for navigate to for for item")] + [InlineData("toolbar\n item for dialog for for screen")] + [InlineData("navigate to for for item")] + [InlineData("data Row via query for for screen")] + [InlineData("component for screen for item")] + void should_reject_subject_tails_on_non_actions_after_complete_operands(string directive) => + Compile(directive).Diagnostics.Count(diagnostic => diagnostic.Code == DiagnosticCodes.InvalidActionSubjectClause).ShouldEqual(1); + + CompilationResult Compile(string directives) => _compiler.Compile(""" + module Work + feature Items + slice StateView Details + command for + command Retry + command label + query Rows => Row[] + query for => Row + screen Details + data Row[] via query Rows + """ + "\n" + string.Join("\n", directives.Split('\n').Select(line => " " + line))); + + static ScreenSyntax Screen(CompilationResult result) => result.Value!.Modules.Single().Features.Single().Slices.Single().Screens.Single(); +} diff --git a/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts index 8b2ffd43f..8feb00cd7 100644 --- a/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts +++ b/Source/Screenplay/Compiler/Authoring/for_QuickFixes/when_repairing_action_subjects.ts @@ -2,7 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. import { describe, expect, it } from 'vitest'; -import { parse } from '../../ScreenplayCompiler'; +import { parse, parseForAuthoring } from '../../ScreenplayCompiler'; +import { ScreenActionSyntax } from '../../Syntax/Screens'; +import { toSyntaxJson } from '../../Syntax/SyntaxJson'; import { applyQuickFixEdits, findQuickFixes, isQuickFixDiagnostic } from '../QuickFixes'; import { prepareActionSubjectQuickFixes } from '../ActionSubjectQuickFixes'; @@ -62,6 +64,47 @@ describe('when repairing action subjects', () => { expect(edited).toContain('parameter name from data item.name\r\n parameter itemId from data item.itemId\r\n'); expect(fixes(edited)).toEqual([]); }); + it.each([0, 1])('should repair only occurrence %s of two identical subject advisories', selectedIndex => { + const text = source.replace('rowId ItemId key', 'itemId ItemId key') + .replace('itemId ItemId identifier', 'itemId ItemId') + .replace('screen List', 'screen First') + + ' screen Second\n data Row[] via query Rows\n action Retry // preserve this comment\n'; + const original = parseForAuthoring(text); + expect(original.success).toBe(true); + const actions = (document: ReturnType) => document.value.modules[0].features[0].slices[0].screens + .map(screen => screen.directives.find(directive => directive.kind === 'ScreenActionSyntax') as ScreenActionSyntax); + const before = actions(original); + const selected = before[selectedIndex]; + const untouchedIndex = 1 - selectedIndex; + const advisories = original.diagnostics.filter(diagnostic => diagnostic.code === 'PLAY0818'); + expect(advisories).toHaveLength(2); + expect(advisories[0].message).toBe(advisories[1].message); + expect(advisories[0].location.line).not.toBe(advisories[1].location.line); + const proposals = findQuickFixes(text, { diagnosticCode: 'PLAY0818', line: selected.location.line }); + expect(proposals).toHaveLength(1); + expect(proposals[0].scope).toBe('occurrence'); + const edited = applyQuickFixEdits(text, proposals[0].edits)!; + const candidate = parseForAuthoring(edited); + expect(candidate.success).toBe(true); + const after = actions(candidate); + expect(after[selectedIndex].subject).toBe('Screen'); + expect(after[untouchedIndex].subject).toBeUndefined(); + expect(after.filter(action => action.subject != null)).toHaveLength(1); + const repaired: ScreenActionSyntax = { ...selected, subject: 'Screen' }; + expect(toSyntaxJson(after[selectedIndex])).toEqual(toSyntaxJson(repaired)); + expect(toSyntaxJson(after[untouchedIndex])).toEqual(toSyntaxJson(before[untouchedIndex])); + const remaining = candidate.diagnostics.filter(diagnostic => diagnostic.code === 'PLAY0818'); + expect(remaining).toHaveLength(1); + expect(remaining[0].message).toBe(advisories[0].message); + expect(remaining[0].location.line).toBe(after[untouchedIndex].location.line); + const expected = original.diagnostics.filter(diagnostic => diagnostic.location.line !== selected.location.line || !['PLAY0818', 'PLAY0819'].includes(diagnostic.code)) + .map(diagnostic => JSON.stringify([diagnostic.code, diagnostic.message])).sort(); + expect(candidate.diagnostics.map(diagnostic => JSON.stringify([diagnostic.code, diagnostic.message])).sort()).toEqual(expected); + expect(findQuickFixes(edited, { diagnosticCode: 'PLAY0818', line: after[untouchedIndex].location.line })).toHaveLength(1); + expect(before.every(action => action.subject == null)).toBe(true); + expect(text.split('action Retry // preserve this comment')).toHaveLength(3); + expect(edited.split('// preserve this comment')).toHaveLength(3); + }); it('should not propose subject repairs when the authored clause is invalid', () => { const invalid = source.replace('action Retry //', 'action Retry for unknown //'); expect(prepareActionSubjectQuickFixes(invalid, {})()).toEqual([]); diff --git a/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts b/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts index 358c9dabc..3dbe1a181 100644 --- a/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts +++ b/Source/Screenplay/Compiler/Parsing/ActionSubjectClause.ts @@ -22,8 +22,9 @@ export function parsePlainActionInput(context: ParserContext, line: SourceLine, return { kind: 'InteractionArgumentSyntax', name: input[1], binding: input[2].trim(), location: locationOf(line) }; } -export function parseSubjectClause(context: ParserContext, line: SourceLine, action: boolean): { header: string; subject?: ScreenActionSubjectKind; label?: string } { - const words = [...line.content.matchAll(word)]; +export function parseSubjectClause(context: ParserContext, line: SourceLine, action: boolean, isHeader: (content: string) => boolean): { header: string; subject?: ScreenActionSubjectKind; label?: string } { + const boundary = subjectHeaderBoundary(line.content, isHeader); + const words = [...line.content.matchAll(word)].filter(part => part.index! >= boundary); const clauses = words.filter(part => part[0] === 'for'); const labelWord = words.find(part => part[0] === 'label'); let header = line.content; @@ -41,7 +42,13 @@ export function parseSubjectClause(context: ParserContext, line: SourceLine, act header = header.substring(0, start).trimEnd(); if (!action || clauses.length !== 1 || match === null || labelWord !== undefined && labelWord.index! < start) { context.error(DiagnosticCodes.InvalidActionSubjectClause, "Invalid action subject clause - expected one 'for item' or 'for screen' before the label on an action", locationOf(line)); - return { header, label: text }; + return { header: line.content.substring(0, boundary).trimEnd(), label: text }; } return { header, subject: match[1] === 'item' ? 'Item' : 'Screen', label: text }; } + +function subjectHeaderBoundary(content: string, isHeader: (header: string) => boolean): number { + // A complete existing header wins, including keyword-looking required operands. + if (isHeader(content)) return content.length; + return [...content.matchAll(word)].reverse().find(part => isHeader(content.substring(0, part.index).trimEnd()))?.index ?? content.length; +} diff --git a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts index 56e76b1cc..f99058bc2 100644 --- a/Source/Screenplay/Compiler/Parsing/ScreenParser.ts +++ b/Source/Screenplay/Compiler/Parsing/ScreenParser.ts @@ -116,7 +116,7 @@ function parseDirectives(context: ParserContext, parent: SourceLine): ScreenDire } function parseDirective(context: ParserContext, line: SourceLine): ScreenDirectiveSyntax | undefined { - if (firstWord(line.content) !== 'action') parseSubjectClause(context, line, false); + validateNonActionSubjectClause(context, line); switch (firstWord(line.content)) { case 'data': return parseData(context, line); @@ -163,8 +163,14 @@ function parseData(context: ParserContext, line: SourceLine): ScreenDataSyntax | return { kind: 'ScreenDataSyntax', type: parseTypeRef(match[1], locationOf(line)), query: match[2], by: match[3] ?? null, location: locationOf(line) }; } +function validateNonActionSubjectClause(context: ParserContext, line: SourceLine): void { + const grammar = new Map([['data', data], ['navigate', navigate], ['component', component], ['title', title]]).get(firstWord(line.content)); + // Expressions, code and open-ended template references belong to their own parsers. + if (grammar !== undefined) parseSubjectClause(context, line, false, content => grammar.test(content)); +} + function parseAction(context: ParserContext, line: SourceLine): ScreenActionSyntax | ScreenGuardedActionSyntax | undefined { - const parsed = parseSubjectClause(context, line, true); + const parsed = parseSubjectClause(context, line, true, content => action.test(content) || guardedAction.test(content)); const result = parseActionHeader(context, line, parsed); if (result === undefined || parsed.subject === undefined) return result; return { ...result, subject: parsed.subject }; @@ -518,7 +524,7 @@ function parseToolbarButton(context: ParserContext, line: SourceLine): ToolbarBu } function parseToolbarItem(context: ParserContext, line: SourceLine): ToolbarItemSyntax | undefined { - const parsed = parseSubjectClause(context, line, /^item\s+\S+\s+action\s/u.test(line.content)); + const parsed = parseSubjectClause(context, line, /^item\s+\S+\s+action\s/u.test(line.content), content => toolbarItem.test(content)); const match = toolbarItem.exec(parsed.header); if (match === null) { context.error(DiagnosticCodes.UnknownScreenDirective, `Invalid toolbar item '${line.content}' - expected 'item action ', 'item navigate to ', 'item dialog ' or 'button title "" slice '`, locationOf(line)); diff --git a/Source/Screenplay/Compiler/for_parse/when_preserving_for_identifiers_in_screen_headers.ts b/Source/Screenplay/Compiler/for_parse/when_preserving_for_identifiers_in_screen_headers.ts new file mode 100644 index 000000000..264ef415b --- /dev/null +++ b/Source/Screenplay/Compiler/for_parse/when_preserving_for_identifiers_in_screen_headers.ts @@ -0,0 +1,125 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { describe, expect, it } from 'vitest'; +import { ScreenActionSyntax, ScreenActionSubjectKind, ScreenComponentSyntax, ScreenDataSyntax, ScreenGuardedActionSyntax, ScreenNavigateSyntax, ScreenTemplateReferenceSyntax, ScreenToolbarSyntax } from '../Syntax/Screens'; +import { a_parsed_document } from './given/a_parsed_document'; + +const parse = (directives: string) => a_parsed_document('module Work', ' feature Items', ' slice StateView Details', + ' command for', ' command Retry', ' command label', ' query Rows => Row[]', ' query for => Row', + ' screen Details', ' data Row[] via query Rows', ...directives.split('\n').map(line => ` ${line}`)); +const screen = (result: ReturnType) => result.value.modules[0].features[0].slices[0].screens[0]; + +const actions: [string, string, ScreenActionSubjectKind | undefined, string | null][] = [ + ['action for', 'for', undefined, null], + ['action for for screen', 'for', 'Screen', null], + ['action Work.Items.Details.for for item', 'Work.Items.Details.for', 'Item', null], + ['action label', 'label', undefined, null], + ['action label for screen label "Retry for screen"', 'label', 'Screen', 'Retry for screen'], + ['action for label "Retry for screen"', 'for', undefined, 'Retry for screen'], + ['action for for item label "Retry \\"for\\" screen"', 'for', 'Item', 'Retry "for" screen'], + ['action for for screen label $strings.for.label', 'for', 'Screen', '$strings.for.label'], +]; +const guarded: [string, string, ScreenActionSubjectKind | undefined][] = [ + ['action "Retry for screen"', 'Retry for screen', undefined], + ['action "Retry \\"for\\" screen" for item', 'Retry "for" screen', 'Item'], + ['action $strings.for.label for screen', '$strings.for.label', 'Screen'], +]; +const toolbarActions: [string, string, string, ScreenActionSubjectKind | undefined][] = [ + ['item for action Retry', 'for', 'Retry', undefined], + ['item retry action for', 'retry', 'for', undefined], + ['item for action for', 'for', 'for', undefined], + ['item for action for for screen', 'for', 'for', 'Screen'], + ['item for action Retry for item', 'for', 'Retry', 'Item'], + ['item label action label for screen', 'label', 'label', 'Screen'], + ['item for action to for', 'for', 'for', undefined], + ['item for action to for for screen', 'for', 'for', 'Screen'], + ['item for action Work.Items.Details.for for item', 'for', 'Work.Items.Details.for', 'Item'], +]; + +describe('when preserving for identifiers in screen headers', () => { + it.each(actions)('should preserve the plain command and trailing metadata in %s', (header, command, subject, label) => { + const result = parse(header); + const action = screen(result).directives[1] as ScreenActionSyntax; + expect(action.command).toBe(command); + expect(action.subject).toBe(subject); + expect(action.label).toBe(label); + expect(result.success).toBe(true); + }); + it.each(guarded)('should keep guarded operands opaque in %s', (header, label, subject) => { + const result = parse(`${header}\n when item.ready == true execute for`); + const action = screen(result).directives[1] as ScreenGuardedActionSyntax; + expect(action.label).toBe(label); + expect(action.subject).toBe(subject); + expect(action.alternatives[0].command).toBe('for'); + expect(result.success).toBe(true); + }); + it.each(toolbarActions)('should consume the complete toolbar action header in %s', (header, name, target, subject) => { + const result = parse(`toolbar\n ${header}`); + const item = (screen(result).directives[1] as ScreenToolbarSyntax).items[0]; + expect(item.name).toBe(name); + expect(item.target).toBe(target); + expect(item.subject).toBe(subject); + expect(result.success).toBe(true); + }); + it.each([ + ['item for navigate to for', 'for', 'for'], + ['item for navigate for', 'for', 'for'], + ['item for dialog for', 'for', 'for'], + ['item for dialog to for', 'for', 'for'], + ['item label navigate to label', 'label', 'label'], + ])('should preserve non action toolbar operands in %s', (header, name, target) => { + const result = parse(`toolbar\n ${header}`); + const item = (screen(result).directives[1] as ScreenToolbarSyntax).items[0]; + expect(item.name).toBe(name); + expect(item.target).toBe(target); + expect(item.subject).toBeUndefined(); + expect(result.success).toBe(true); + }); + it('should preserve non action directive fields', () => { + const result = parse('navigate to for\ndata Row via query for\ncomponent for screen\ncomponent Widget for\ntemplate for'); + const directives = screen(result).directives; + expect((directives[1] as ScreenNavigateSyntax).screen).toBe('for'); + expect((directives[2] as ScreenDataSyntax).query).toBe('for'); + expect((directives[3] as ScreenComponentSyntax).component).toBe('for'); + expect((directives[3] as ScreenComponentSyntax).name).toBe('screen'); + expect((directives[4] as ScreenComponentSyntax).name).toBe('for'); + expect((directives[5] as ScreenTemplateReferenceSyntax).name).toBe('for'); + expect(result.success).toBe(true); + }); + it('should preserve inputs and child labels', () => { + const result = parse('action for for item label "Inline for screen"\n with note from item.note\n label "Child for screen"\ntoolbar\n item for action for for screen label "Toolbar for item"'); + const action = screen(result).directives[1] as ScreenActionSyntax; + expect(action.subject).toBe('Item'); + expect(action.label).toBe('Child for screen'); + expect(action.inputs![0].binding).toBe('item.note'); + expect((screen(result).directives[2] as ScreenToolbarSyntax).items[0].label).toBe('Toolbar for item'); + expect(result.success).toBe(true); + }); + it.each([ + ['item for action for for screen label "Retry for item"', 'Retry for item'], + ['item for action for for screen label $strings.for.label', '$strings.for.label'], + ])('should preserve toolbar labels and parameters in %s', (header, label) => { + const result = parse(`toolbar\n ${header}\n parameter note from data item.note`); + const item = (screen(result).directives[1] as ScreenToolbarSyntax).items[0]; + expect(item.name).toBe('for'); + expect(item.target).toBe('for'); + expect(item.subject).toBe('Screen'); + expect(item.label).toBe(label); + expect(item.parameters[0].binding.path).toBe('item.note'); + expect(result.success).toBe(true); + }); + it.each([ + 'toolbar\n item for navigate to for for item', + 'toolbar\n item for dialog for for screen', + 'navigate to for for item', + 'data Row via query for for screen', + 'component for screen for item', + ])('should reject subject tails on non actions after complete operands in %s', directive => { + expect(parse(directive).diagnostics.filter(diagnostic => diagnostic.code === 'PLAY0817')).toHaveLength(1); + }); + it.each(['for', 'for planet', 'for item for screen', 'label "Try" for screen'])('should reject malformed tails after keyword named operands: %s', suffix => { + const result = parse(`action for ${suffix}\ntoolbar\n item for action for ${suffix}`); + expect(result.diagnostics.filter(diagnostic => diagnostic.code === 'PLAY0817')).toHaveLength(2); + }); +}); From e87a0cab312d9b8f801feb919c32b20ecf6bd8b1 Mon Sep 17 00:00:00 2001 From: woksin Date: Mon, 26 Oct 2026 01:11:24 +0100 Subject: [PATCH 9/9] Align action subject diagnostic filter with final allocated codes --- .../for_ReactionGrammar/when_highlighting_action_subjects.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts b/Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts index 1d6d54427..de00ddd39 100644 --- a/Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts +++ b/Source/Screenplay/VSCodeExtension/for_ReactionGrammar/when_highlighting_action_subjects.ts @@ -9,7 +9,7 @@ import { WorkspaceApplication } from '../WorkspaceApplication'; const grammar = JSON.parse(readFileSync(new URL('../syntaxes/screenplay.tmLanguage.json', import.meta.url), 'utf8')); const clauses = (grammar.repository['action-subjects'].patterns as { match: string }[]).map(rule => new RegExp(rule.match)); const source = readFileSync(new URL('../../Compiler/Conformance/action-subjects/source.play', import.meta.url), 'utf8'); -const relevant = (code: string) => /^PLAY081[5-9]$/.test(code); +const relevant = (code: string) => /^PLAY08(?:1[7-9]|2[01])$/.test(code); describe('when highlighting action subjects', () => { for (const line of ['action Retry for item', 'action "Choose" for screen', 'action $strings.choose for item', 'item retry action Work.Items.Retry for screen']) {