@cratis/screenplay-language 4.124.0 → 4.125.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -0
- package/dist/bundles/TypeReferenceSymbol.js +2 -0
- package/dist/bundles/TypeReferenceSymbol.js.map +1 -0
- package/dist/bundles/_virtual/_virtual/_rolldown/runtime.js +1 -0
- package/dist/bundles/bmp-word-characters.js +2 -0
- package/dist/bundles/bmp-word-characters.js.map +1 -0
- package/dist/bundles/case-authoring.js +3 -0
- package/dist/bundles/case-authoring.js.map +1 -0
- package/dist/bundles/code-actions.js +2 -0
- package/dist/bundles/code-actions.js.map +1 -0
- package/dist/bundles/compiler/Authoring/QuickFixes.js +5 -0
- package/dist/bundles/compiler/Authoring/QuickFixes.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/DeclaredDependencies.js +2 -0
- package/dist/bundles/compiler/Dependencies/DeclaredDependencies.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/DeclaredDependencyTargets.js +2 -0
- package/dist/bundles/compiler/Dependencies/DeclaredDependencyTargets.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/DependencyGraph.js +2 -0
- package/dist/bundles/compiler/Dependencies/DependencyGraph.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/DependencyKind.js +2 -0
- package/dist/bundles/compiler/Dependencies/DependencyKind.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/InvalidDependencyQuery.js +2 -0
- package/dist/bundles/compiler/Dependencies/InvalidDependencyQuery.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/SliceReferences.js +2 -0
- package/dist/bundles/compiler/Dependencies/SliceReferences.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/StronglyConnectedGroups.js +2 -0
- package/dist/bundles/compiler/Dependencies/StronglyConnectedGroups.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/index.js +1 -0
- package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js +2 -0
- package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js.map +1 -0
- package/dist/bundles/compiler/Diagnostics/ProductionDestinationDiagnostics.js +2 -0
- package/dist/bundles/compiler/Diagnostics/ProductionDestinationDiagnostics.js.map +1 -0
- package/dist/bundles/compiler/Diagnostics/SourceLocation.js +2 -0
- package/dist/bundles/compiler/Diagnostics/SourceLocation.js.map +1 -0
- package/dist/bundles/compiler/Files/AuthoredOrder.js +2 -0
- package/dist/bundles/compiler/Files/AuthoredOrder.js.map +1 -0
- package/dist/bundles/compiler/Files/OrderingRoot.js +1 -0
- package/dist/bundles/compiler/Files/PlayApplicationAssembly.js +2 -0
- package/dist/bundles/compiler/Files/PlayApplicationAssembly.js.map +1 -0
- package/dist/bundles/compiler/Files/PlayFolderMerge.js +2 -0
- package/dist/bundles/compiler/Files/PlayFolderMerge.js.map +1 -0
- package/dist/bundles/compiler/Files/PlayImports.js +1 -0
- package/dist/bundles/compiler/Files/PlayPlacement.js +2 -0
- package/dist/bundles/compiler/Files/PlayPlacement.js.map +1 -0
- package/dist/bundles/compiler/Files/TimelineOrder.js +2 -0
- package/dist/bundles/compiler/Files/TimelineOrder.js.map +1 -0
- package/dist/bundles/compiler/Parsing/AuthorizeParser.js +2 -0
- package/dist/bundles/compiler/Parsing/AuthorizeParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CaptureParser.js +2 -0
- package/dist/bundles/compiler/Parsing/CaptureParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CodeBlockParser.js +3 -0
- package/dist/bundles/compiler/Parsing/CodeBlockParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CommandDestinationTypes.js +2 -0
- package/dist/bundles/compiler/Parsing/CommandDestinationTypes.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CommandParser.js +2 -0
- package/dist/bundles/compiler/Parsing/CommandParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CommandReadSources.js +2 -0
- package/dist/bundles/compiler/Parsing/CommandReadSources.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CommandResponseParser.js +2 -0
- package/dist/bundles/compiler/Parsing/CommandResponseParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CommandStreamCandidates.js +2 -0
- package/dist/bundles/compiler/Parsing/CommandStreamCandidates.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CompositeStreamIdValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/CompositeStreamIdValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/CompositionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/CompositionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ConceptComplianceParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ConceptComplianceParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ConditionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ConditionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ConstraintParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ConstraintParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ConstraintPropertyValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/ConstraintPropertyValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/DeclarationParsers.js +2 -0
- package/dist/bundles/compiler/Parsing/DeclarationParsers.js.map +1 -0
- package/dist/bundles/compiler/Parsing/DependencySourceParser.js +2 -0
- package/dist/bundles/compiler/Parsing/DependencySourceParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/DependsOnParser.js +2 -0
- package/dist/bundles/compiler/Parsing/DependsOnParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/DescriptionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/DescriptionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/DocumentationParser.js +2 -0
- package/dist/bundles/compiler/Parsing/DocumentationParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/EventMetadataParser.js +2 -0
- package/dist/bundles/compiler/Parsing/EventMetadataParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/EventSourceParser.js +2 -0
- package/dist/bundles/compiler/Parsing/EventSourceParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/EventSourceValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/EventSourceValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/EventSubjectValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/EventSubjectValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ExpressionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ExpressionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/FeatureBody.js +2 -0
- package/dist/bundles/compiler/Parsing/FeatureBody.js.map +1 -0
- package/dist/bundles/compiler/Parsing/FileImportParser.js +2 -0
- package/dist/bundles/compiler/Parsing/FileImportParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/FileReferences.js +2 -0
- package/dist/bundles/compiler/Parsing/FileReferences.js.map +1 -0
- package/dist/bundles/compiler/Parsing/GuardedActionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/GuardedActionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/GuardedActionShadowing.js +2 -0
- package/dist/bundles/compiler/Parsing/GuardedActionShadowing.js.map +1 -0
- package/dist/bundles/compiler/Parsing/GuardedActionValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/GuardedActionValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/IdentifierComplianceValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/IdentifierComplianceValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/IdentityParser.js +2 -0
- package/dist/bundles/compiler/Parsing/IdentityParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/IdentityValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/IdentityValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ImplementationParser.js +3 -0
- package/dist/bundles/compiler/Parsing/ImplementationParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ImportDiscovery.js +1 -0
- package/dist/bundles/compiler/Parsing/InlineEventValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/InlineEventValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/InputUses.js +2 -0
- package/dist/bundles/compiler/Parsing/InputUses.js.map +1 -0
- package/dist/bundles/compiler/Parsing/InteractionAlternatives.js +2 -0
- package/dist/bundles/compiler/Parsing/InteractionAlternatives.js.map +1 -0
- package/dist/bundles/compiler/Parsing/LineReader.js +2 -0
- package/dist/bundles/compiler/Parsing/LineReader.js.map +1 -0
- package/dist/bundles/compiler/Parsing/LineText.js +2 -0
- package/dist/bundles/compiler/Parsing/LineText.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ModuleBody.js +2 -0
- package/dist/bundles/compiler/Parsing/ModuleBody.js.map +1 -0
- package/dist/bundles/compiler/Parsing/OperationParser.js +2 -0
- package/dist/bundles/compiler/Parsing/OperationParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/OperationValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/OperationValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ParserContext.js +2 -0
- package/dist/bundles/compiler/Parsing/ParserContext.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PersonaCallerValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/PersonaCallerValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PolicyParser.js +2 -0
- package/dist/bundles/compiler/Parsing/PolicyParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ProducesParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ProducesParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ProjectionExpressionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ProjectionExpressionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ProjectionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ProjectionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ProjectionTargetValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/ProjectionTargetValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PropertyLineParser.js +2 -0
- package/dist/bundles/compiler/Parsing/PropertyLineParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PublicEventMetadataValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/PublicEventMetadataValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PublicEventUsageCollector.js +2 -0
- package/dist/bundles/compiler/Parsing/PublicEventUsageCollector.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PublicEventUsageValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/PublicEventUsageValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PurposeParser.js +2 -0
- package/dist/bundles/compiler/Parsing/PurposeParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/PurposeValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/PurposeValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/QueryParser.js +2 -0
- package/dist/bundles/compiler/Parsing/QueryParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ReactionIdentityParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ReactionIdentityParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ReactionParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ReactionParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ReactionRefusalValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/ReactionRefusalValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/RedeliveryValues.js +2 -0
- package/dist/bundles/compiler/Parsing/RedeliveryValues.js.map +1 -0
- package/dist/bundles/compiler/Parsing/RefusalDeclarations.js +2 -0
- package/dist/bundles/compiler/Parsing/RefusalDeclarations.js.map +1 -0
- package/dist/bundles/compiler/Parsing/RefusalValueWalker.js +2 -0
- package/dist/bundles/compiler/Parsing/RefusalValueWalker.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ResponseDateValues.js +2 -0
- package/dist/bundles/compiler/Parsing/ResponseDateValues.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ResponseValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/ResponseValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ScreenParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ScreenParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/ScreenplayParser.js +2 -0
- package/dist/bundles/compiler/Parsing/ScreenplayParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SeedParser.js +2 -0
- package/dist/bundles/compiler/Parsing/SeedParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SliceParser.js +2 -0
- package/dist/bundles/compiler/Parsing/SliceParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SourceLine.js +2 -0
- package/dist/bundles/compiler/Parsing/SourceLine.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SourceLineSplitter.js +3 -0
- package/dist/bundles/compiler/Parsing/SourceLineSplitter.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SourceOptionsParser.js +2 -0
- package/dist/bundles/compiler/Parsing/SourceOptionsParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationCaseValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationCaseValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationCommandExamples.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationCommandExamples.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationParser.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationRedeliveryValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationRedeliveryValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationRouteComparison.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationRouteComparison.js.map +1 -0
- package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js +2 -0
- package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js.map +1 -0
- package/dist/bundles/compiler/Parsing/StructuredValueParser.js +3 -0
- package/dist/bundles/compiler/Parsing/StructuredValueParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/TriggerDataParser.js +2 -0
- package/dist/bundles/compiler/Parsing/TriggerDataParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/UiBindingParser.js +2 -0
- package/dist/bundles/compiler/Parsing/UiBindingParser.js.map +1 -0
- package/dist/bundles/compiler/ScreenplayCompiler.js +2 -0
- package/dist/bundles/compiler/ScreenplayCompiler.js.map +1 -0
- package/dist/bundles/compiler/Syntax/AuthoringProductionResolver.js +2 -0
- package/dist/bundles/compiler/Syntax/AuthoringProductionResolver.js.map +1 -0
- package/dist/bundles/compiler/Syntax/CaptureEventsSource.js +2 -0
- package/dist/bundles/compiler/Syntax/CaptureEventsSource.js.map +1 -0
- package/dist/bundles/compiler/Syntax/DependencySources.js +2 -0
- package/dist/bundles/compiler/Syntax/DependencySources.js.map +1 -0
- package/dist/bundles/compiler/Syntax/EventDeclarations.js +2 -0
- package/dist/bundles/compiler/Syntax/EventDeclarations.js.map +1 -0
- package/dist/bundles/compiler/Syntax/EventSourceCatalog.js +2 -0
- package/dist/bundles/compiler/Syntax/EventSourceCatalog.js.map +1 -0
- package/dist/bundles/compiler/Syntax/EventSourceReadConfidence.js +2 -0
- package/dist/bundles/compiler/Syntax/EventSourceReadConfidence.js.map +1 -0
- package/dist/bundles/compiler/Syntax/ExactMathFacts.js +2 -0
- package/dist/bundles/compiler/Syntax/ExactMathFacts.js.map +1 -0
- package/dist/bundles/compiler/Syntax/ExactNumber.js +2 -0
- package/dist/bundles/compiler/Syntax/ExactNumber.js.map +1 -0
- package/dist/bundles/compiler/Syntax/InvalidSyntaxJson.js +2 -0
- package/dist/bundles/compiler/Syntax/InvalidSyntaxJson.js.map +1 -0
- package/dist/bundles/compiler/Syntax/LegacyWireProjection.js +2 -0
- package/dist/bundles/compiler/Syntax/LegacyWireProjection.js.map +1 -0
- package/dist/bundles/compiler/Syntax/Operations.js +2 -0
- package/dist/bundles/compiler/Syntax/Operations.js.map +1 -0
- package/dist/bundles/compiler/Syntax/PersonaCallers.js +2 -0
- package/dist/bundles/compiler/Syntax/PersonaCallers.js.map +1 -0
- package/dist/bundles/compiler/Syntax/ProductionDestinations.js +2 -0
- package/dist/bundles/compiler/Syntax/ProductionDestinations.js.map +1 -0
- package/dist/bundles/compiler/Syntax/PublicEventInvariants.js +2 -0
- package/dist/bundles/compiler/Syntax/PublicEventInvariants.js.map +1 -0
- package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js +2 -0
- package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js.map +1 -0
- package/dist/bundles/compiler/Syntax/SourceOptions.js +2 -0
- package/dist/bundles/compiler/Syntax/SourceOptions.js.map +1 -0
- package/dist/bundles/compiler/Syntax/SpecificationCaseOrigin.js +2 -0
- package/dist/bundles/compiler/Syntax/SpecificationCaseOrigin.js.map +1 -0
- package/dist/bundles/compiler/Syntax/StreamIdFormatter.js +2 -0
- package/dist/bundles/compiler/Syntax/StreamIdFormatter.js.map +1 -0
- package/dist/bundles/compiler/Syntax/StrictSyntaxJson.js +1 -0
- package/dist/bundles/compiler/Syntax/Structure.js +2 -0
- package/dist/bundles/compiler/Syntax/Structure.js.map +1 -0
- package/dist/bundles/compiler/Syntax/SyntaxCollections.js +2 -0
- package/dist/bundles/compiler/Syntax/SyntaxCollections.js.map +1 -0
- package/dist/bundles/compiler/Syntax/SyntaxInvariants.js +2 -0
- package/dist/bundles/compiler/Syntax/SyntaxInvariants.js.map +1 -0
- package/dist/bundles/compiler/Syntax/SyntaxJson.js +2 -0
- package/dist/bundles/compiler/Syntax/SyntaxJson.js.map +1 -0
- package/dist/bundles/compiler/Syntax/SyntaxMemberContracts.js +2 -0
- package/dist/bundles/compiler/Syntax/SyntaxMemberContracts.js.map +1 -0
- package/dist/bundles/compiler/Syntax/index.js +1 -0
- package/dist/bundles/compiler/Text/ImplementationHintText.js +2 -0
- package/dist/bundles/compiler/Text/ImplementationHintText.js.map +1 -0
- package/dist/bundles/compiler/Text/ReservedWords.js +2 -0
- package/dist/bundles/compiler/Text/ReservedWords.js.map +1 -0
- package/dist/bundles/compiler/Text/SourceStreamNames.js +2 -0
- package/dist/bundles/compiler/Text/SourceStreamNames.js.map +1 -0
- package/dist/bundles/compiler/Text/StringLiteral.js +3 -0
- package/dist/bundles/compiler/Text/StringLiteral.js.map +1 -0
- package/dist/bundles/compiler/Text/ordinalIgnoreCaseKey.js +2 -0
- package/dist/bundles/compiler/Text/ordinalIgnoreCaseKey.js.map +1 -0
- package/dist/bundles/compiler/Text/patterns.js +2 -0
- package/dist/bundles/compiler/Text/patterns.js.map +1 -0
- package/dist/bundles/compiler/index.js +1 -0
- package/dist/bundles/completion-items.js +21 -0
- package/dist/bundles/completion-items.js.map +1 -0
- package/dist/bundles/completion-planner.js +5 -0
- package/dist/bundles/completion-planner.js.map +1 -0
- package/dist/bundles/completions.js +2 -0
- package/dist/bundles/completions.js.map +1 -0
- package/dist/bundles/dependency-completions.js +3 -0
- package/dist/bundles/dependency-completions.js.map +1 -0
- package/dist/bundles/dependency-target-analysis.js +2 -0
- package/dist/bundles/dependency-target-analysis.js.map +1 -0
- package/dist/bundles/diagnostic-codes.js +2 -0
- package/dist/bundles/diagnostic-codes.js.map +1 -0
- package/dist/bundles/diagnostics.js +2 -0
- package/dist/bundles/diagnostics.js.map +1 -0
- package/dist/bundles/document-context.js +2 -0
- package/dist/bundles/document-context.js.map +1 -0
- package/dist/bundles/documentation-item.js +2 -0
- package/dist/bundles/documentation-item.js.map +1 -0
- package/dist/bundles/event-analysis-source.js +2 -0
- package/dist/bundles/event-analysis-source.js.map +1 -0
- package/dist/bundles/event-context-catalog.js +2 -0
- package/dist/bundles/event-context-catalog.js.map +1 -0
- package/dist/bundles/event-context.js +4 -0
- package/dist/bundles/event-context.js.map +1 -0
- package/dist/bundles/event-source-authoring.js +13 -0
- package/dist/bundles/event-source-authoring.js.map +1 -0
- package/dist/bundles/example-analysis.js +3 -0
- package/dist/bundles/example-analysis.js.map +1 -0
- package/dist/bundles/example-authoring.js +3 -0
- package/dist/bundles/example-authoring.js.map +1 -0
- package/dist/bundles/example-declaration-items.js +2 -0
- package/dist/bundles/example-declaration-items.js.map +1 -0
- package/dist/bundles/example-values.js +2 -0
- package/dist/bundles/example-values.js.map +1 -0
- package/dist/bundles/file-imports.js +2 -0
- package/dist/bundles/file-imports.js.map +1 -0
- package/dist/bundles/file-references.js +2 -0
- package/dist/bundles/file-references.js.map +1 -0
- package/dist/bundles/hover-content.js +6 -0
- package/dist/bundles/hover-content.js.map +1 -0
- package/dist/bundles/hover.js +2 -0
- package/dist/bundles/hover.js.map +1 -0
- package/dist/bundles/index.js +2 -104
- package/dist/bundles/index.js.map +1 -7
- package/dist/bundles/inlay-hints.js +2 -0
- package/dist/bundles/inlay-hints.js.map +1 -0
- package/dist/bundles/inline-completions.js +2 -0
- package/dist/bundles/inline-completions.js.map +1 -0
- package/dist/bundles/inline-event-validation.js +2 -0
- package/dist/bundles/inline-event-validation.js.map +1 -0
- package/dist/bundles/keyword-docs.js +2 -0
- package/dist/bundles/keyword-docs.js.map +1 -0
- package/dist/bundles/language.js +2 -0
- package/dist/bundles/language.js.map +1 -0
- package/dist/bundles/named-rule-context.js +2 -0
- package/dist/bundles/named-rule-context.js.map +1 -0
- package/dist/bundles/operation-authoring.js +7 -0
- package/dist/bundles/operation-authoring.js.map +1 -0
- package/dist/bundles/persona-analysis.js +2 -0
- package/dist/bundles/persona-analysis.js.map +1 -0
- package/dist/bundles/production-destinations.js +2 -0
- package/dist/bundles/production-destinations.js.map +1 -0
- package/dist/bundles/purpose-items.js +2 -0
- package/dist/bundles/purpose-items.js.map +1 -0
- package/dist/bundles/reaction-authoring.js +5 -0
- package/dist/bundles/reaction-authoring.js.map +1 -0
- package/dist/bundles/refusal-context.js +2 -0
- package/dist/bundles/refusal-context.js.map +1 -0
- package/dist/bundles/response-analysis.js +7 -0
- package/dist/bundles/response-analysis.js.map +1 -0
- package/dist/bundles/response-completions.js +2 -0
- package/dist/bundles/response-completions.js.map +1 -0
- package/dist/bundles/response-tokens.js +3 -0
- package/dist/bundles/response-tokens.js.map +1 -0
- package/dist/bundles/scope-items.js +18 -0
- package/dist/bundles/scope-items.js.map +1 -0
- package/dist/bundles/structure-completions.js +7 -0
- package/dist/bundles/structure-completions.js.map +1 -0
- package/dist/bundles/sub-language-registry.js +2 -0
- package/dist/bundles/sub-language-registry.js.map +1 -0
- package/dist/bundles/sub-languages/capture/CompletionProvider.js +2 -0
- package/dist/bundles/sub-languages/capture/CompletionProvider.js.map +1 -0
- package/dist/bundles/sub-languages/capture/HoverProvider.js +60 -0
- package/dist/bundles/sub-languages/capture/HoverProvider.js.map +1 -0
- package/dist/bundles/sub-languages/capture/Validator.js +2 -0
- package/dist/bundles/sub-languages/capture/Validator.js.map +1 -0
- package/dist/bundles/sub-languages/capture/index.js +2 -40
- package/dist/bundles/sub-languages/capture/index.js.map +1 -7
- package/dist/bundles/sub-languages/capture/language.js +2 -0
- package/dist/bundles/sub-languages/capture/language.js.map +1 -0
- package/dist/bundles/sub-languages/cdl.js +2 -0
- package/dist/bundles/sub-languages/cdl.js.map +1 -0
- package/dist/bundles/sub-languages/pdl.js +2 -0
- package/dist/bundles/sub-languages/pdl.js.map +1 -0
- package/dist/bundles/sub-languages/projection/CodeActionProvider.js +2 -0
- package/dist/bundles/sub-languages/projection/CodeActionProvider.js.map +1 -0
- package/dist/bundles/sub-languages/projection/CompletionProvider.js +2 -0
- package/dist/bundles/sub-languages/projection/CompletionProvider.js.map +1 -0
- package/dist/bundles/sub-languages/projection/HoverProvider.js +43 -0
- package/dist/bundles/sub-languages/projection/HoverProvider.js.map +1 -0
- package/dist/bundles/sub-languages/projection/Validator.js +5 -0
- package/dist/bundles/sub-languages/projection/Validator.js.map +1 -0
- package/dist/bundles/sub-languages/projection/index.js +3 -75
- package/dist/bundles/sub-languages/projection/index.js.map +1 -7
- package/dist/bundles/sub-languages/projection/language.js +2 -0
- package/dist/bundles/sub-languages/projection/language.js.map +1 -0
- package/dist/bundles/symbols.js +3 -0
- package/dist/bundles/symbols.js.map +1 -0
- package/dist/bundles/themes/screenplay-dark.js +2 -0
- package/dist/bundles/themes/screenplay-dark.js.map +1 -0
- package/dist/bundles/themes/screenplay-light.js +2 -0
- package/dist/bundles/themes/screenplay-light.js.map +1 -0
- package/dist/bundles/tokens.js +2 -0
- package/dist/bundles/tokens.js.map +1 -0
- package/dist/bundles/validation.js +3 -0
- package/dist/bundles/validation.js.map +1 -0
- package/package.json +4 -3
- package/dist/bundles/chunk-7GSRLVHB.js +0 -42
- package/dist/bundles/chunk-7GSRLVHB.js.map +0 -7
- package/dist/bundles/chunk-AYDF3IFZ.js +0 -2
- package/dist/bundles/chunk-AYDF3IFZ.js.map +0 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectionTargetValidator.js","names":["resolver","AuthoringProductionResolver","application","slices","imported","entry","events","eventDeclarations","slice","event","types","uniqueByName","scalar","concept","name","rest","path","properties","matches","value","views","segments","named","qualifiers","index","depth","scope","visible","reference","imports","resolution","candidate","context","DiagnosticCodes","location","block","blocks","reported","resolved","key","element","ownsEvents","effectiveHandlers","mappings","mapping","target","projection","capture","append","child","variants","variant"],"sources":["../../../../../../Compiler/Parsing/ProjectionTargetValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { AuthoringProductionKind, AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { ProjectionBlockSyntax } from '../Syntax/Projections';\nimport { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\nimport { uniqueByName } from './ResponseValidator';\n\nexport function validateProjectionTargets(application: ApplicationSyntax, context: ParserContext): void {\n const resolver = new AuthoringProductionResolver(application);\n const slices = resolver.slices;\n const imported = new Set(application.imports.map(entry => entry.qualifiedName));\n const events = new Set([...slices.flatMap(({ slice }) => eventDeclarations(slice).map(event => event.name)), ...application.imports.map(entry => entry.qualifiedName.split('.').at(-1)!)]);\n const types = uniqueByName(application.types);\n const scalar = new Set(['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime', ...application.concepts.map(concept => concept.name)].filter(name => !types.has(name)));\n const property = (properties: readonly PropertySyntax[] | null, path: string): { value: PropertySyntax | null; missing: boolean } => {\n const [name, ...rest] = path.split('.');\n if (properties === null) return { value: null, missing: false };\n const matches = properties.filter(entry => entry.name === name);\n if (matches.length !== 1) return { value: null, missing: matches.length === 0 };\n const value = matches[0];\n if (rest.length === 0) return { value, missing: false };\n if (scalar.has(value.type.name)) return { value: null, missing: true };\n return property(types.get(value.type.name)?.properties ?? null, rest.join('.'));\n };\n const views = slices.flatMap(({ slice, scope }) => slice.readModels.map(node => ({ node, scope })));\n const viewProperties = (reference: string, scope: readonly string[]): readonly PropertySyntax[] | null => {\n const candidates = (name: string) => {\n const segments = name.split('.');\n const named = views.filter(entry => entry.node.name === segments.at(-1));\n const qualifiers = segments.slice(0, -1);\n if (qualifiers.length > 0) return named.filter(entry => qualifiers.length <= entry.scope.length && qualifiers.every((value, index) => entry.scope[entry.scope.length - qualifiers.length + index] === value));\n for (let depth = scope.length; depth >= 0; depth--) {\n const visible = named.filter(entry => depth <= entry.scope.length && scope.slice(0, depth).every((value, index) => entry.scope[index] === value));\n if (visible.length > 0) return visible;\n }\n return [];\n };\n let matches = candidates(reference);\n const imports = application.imports.filter(entry => entry.qualifiedName.split('.').at(-1) === reference);\n if (matches.length === 0 && imports.length === 1) matches = candidates(imports[0].qualifiedName);\n return matches.length === 1 ? matches[0].node.properties : null;\n };\n const unknownEvent = (name: string, location: SourceLocation, slice: SliceSyntax): void => {\n const resolution = resolver.resolve(name, slice);\n const declared = events.has(name) || imported.has(name) || resolution.declaration?.kind === AuthoringProductionKind.Event || resolution.candidates.some(candidate => candidate.kind === AuthoringProductionKind.Event);\n if (!declared) context.warning(DiagnosticCodes.UnknownEvent, `Unknown event '${name}' - declare it with 'event ${name}'`, location);\n };\n const removals = (blocks: readonly ProjectionBlockSyntax[], slice: SliceSyntax): void => {\n for (const block of blocks) {\n if (block.kind === 'RemoveWithSyntax' || block.kind === 'RemoveViaJoinSyntax') unknownEvent(block.event, block.location, slice);\n if ('blocks' in block) removals(block.blocks, slice);\n }\n };\n const reported = new Set<string>();\n const walk = (blocks: readonly ProjectionBlockSyntax[], properties: readonly PropertySyntax[] | null, element = false, effectiveHandlers = false): void => {\n const validate = (path: string, location: SourceLocation) => {\n const resolved = property(properties, path);\n const key = JSON.stringify([location.path, location.line, location.column]);\n if (resolved.missing && !reported.has(key)) {\n reported.add(key);\n context.warning(DiagnosticCodes.UnknownReadModelProperty, `Projection target '${path}' is not a declared ${element ? 'element' : 'read-model'} property`, location);\n }\n return resolved.value;\n };\n // An 'every' without local handlers only cascades into the element scopes.\n const ownsEvents = effectiveHandlers || blocks.some(block => block.kind === 'FromSyntax' || block.kind === 'JoinSyntax' || block.kind === 'AllSyntax');\n for (const block of blocks) {\n const mappings = block.kind === 'EverySyntax' && !ownsEvents ? [] : 'mappings' in block ? block.mappings : block.kind === 'JoinSyntax' ? block.events.flatMap(event => event.mappings) : [];\n for (const mapping of mappings) validate(mapping.property, mapping.location);\n if (block.kind === 'ChildrenSyntax' || block.kind === 'NestedSyntax') {\n const target = validate(block.property, block.location);\n walk(block.blocks, target === null ? null : types.get(target.type.name)?.properties ?? null, true);\n }\n }\n };\n for (const { slice } of slices) {\n for (const projection of slice.projections) removals(projection.blocks, slice);\n for (const capture of slice.captures) {\n for (const append of [...capture.appends, ...capture.children.flatMap(child => child.appends), ...capture.nested.flatMap(child => child.appends)]) unknownEvent(append.event, append.location, slice);\n }\n }\n for (const { slice, scope } of slices) {\n for (const projection of slice.projections) {\n const variants = projection.blocks.filter(block => block.kind === 'ProjectionVariantSyntax');\n if (variants.length === 0) walk(projection.blocks, viewProperties(projection.readModel ?? projection.name, scope));\n for (const variant of variants) {\n const properties = viewProperties(variant.name, scope);\n walk(projection.blocks.filter(block => block.kind === 'ChildrenSyntax' || block.kind === 'NestedSyntax'), properties);\n // Lowering combines shared handlers and turns entering events into From handlers.\n const ownsEvents = variant.entersOn.length > 0 || projection.blocks.some(block => block.kind === 'FromSyntax' || block.kind === 'JoinSyntax' || block.kind === 'AllSyntax');\n walk(variant.blocks, properties, false, ownsEvents);\n }\n }\n }\n}\n"],"mappings":"yUAaA,SAAgB,0BAA0B,EAAgC,EAA8B,CACpG,IAAMA,EAAW,IAAIC,EAA4BC,CAAW,EACtDC,EAASH,EAAS,OAClBI,EAAW,IAAI,IAAIF,EAAY,QAAQ,IAAI,GAASG,EAAM,aAAa,CAAC,EACxEC,kBAAS,IAAI,IAAI,CAAC,GAAGH,EAAO,SAAS,CAAE,WAAYI,EAAkBC,CAAK,CAAC,CAAC,IAAI,GAASC,EAAM,IAAI,CAAC,EAAG,GAAGP,EAAY,QAAQ,IAAI,GAASG,EAAM,cAAc,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,CAAE,CAAC,CAAC,EACnLK,EAAQC,EAAaT,EAAY,KAAK,EACtCU,EAAS,IAAI,IAAI,CAAC,OAAQ,SAAU,MAAO,UAAW,OAAQ,OAAQ,WAAY,GAAGV,EAAY,SAAS,IAAI,GAAWW,EAAQ,IAAI,CAAC,CAAC,CAAC,OAAO,GAAQ,CAACH,EAAM,IAAII,CAAI,CAAC,CAAC,EACxK,UAAY,EAA8C,IAAqE,CACjI,GAAM,CAACA,EAAM,GAAGC,GAAQC,EAAK,MAAM,GAAG,EACtC,GAAIC,IAAe,KAAM,MAAO,CAAE,MAAO,KAAM,QAAS,EAAM,EAC9D,IAAMC,EAAUD,EAAW,OAAO,GAASZ,EAAM,OAASS,CAAI,EAC9D,GAAII,EAAQ,SAAW,EAAG,MAAO,CAAE,MAAO,KAAM,QAASA,EAAQ,SAAW,CAAE,EAC9E,IAAMC,EAAQD,EAAQ,GAGtB,OAFIH,EAAK,SAAW,EAAU,CAAE,QAAO,QAAS,EAAM,EAClDH,EAAO,IAAIO,EAAM,KAAK,IAAI,EAAU,CAAE,MAAO,KAAM,QAAS,EAAK,EAC9D,SAAST,EAAM,IAAIS,EAAM,KAAK,IAAI,CAAC,EAAE,YAAc,KAAMJ,EAAK,KAAK,GAAG,CAAC,CAClF,EACMK,EAAQjB,EAAO,SAAS,CAAE,QAAO,WAAYK,EAAM,WAAW,IAAI,IAAS,CAAE,OAAM,OAAM,EAAE,CAAC,EAC5F,gBAAkB,EAAmB,IAA+D,CACtG,IAAM,WAAc,GAAiB,CACjC,IAAMa,EAAWP,EAAK,MAAM,GAAG,EACzBQ,EAAQF,EAAM,OAAO,GAASf,EAAM,KAAK,OAASgB,EAAS,GAAG,EAAE,CAAC,EACjEE,EAAaF,EAAS,MAAM,EAAG,EAAE,EACvC,GAAIE,EAAW,OAAS,EAAG,OAAOD,EAAM,OAAO,GAASC,EAAW,QAAUlB,EAAM,MAAM,QAAUkB,EAAW,OAAO,EAAO,IAAUlB,EAAM,MAAMA,EAAM,MAAM,OAASkB,EAAW,OAASC,KAAWL,CAAK,CAAC,EAC5M,IAAK,IAAIM,EAAQC,EAAM,OAAQD,GAAS,EAAG,IAAS,CAChD,IAAME,EAAUL,EAAM,OAAO,GAASG,GAASpB,EAAM,MAAM,QAAUqB,EAAM,MAAM,EAAGD,CAAK,CAAC,CAAC,OAAO,EAAO,IAAUpB,EAAM,MAAMmB,KAAWL,CAAK,CAAC,EAChJ,GAAIQ,EAAQ,OAAS,EAAG,OAAOA,CACnC,CACA,MAAO,CAAC,CACZ,EACIT,EAAU,WAAWU,CAAS,EAC5BC,EAAU3B,EAAY,QAAQ,OAAO,GAASG,EAAM,cAAc,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,IAAMuB,CAAS,EAEvG,OADIV,EAAQ,SAAW,GAAKW,EAAQ,SAAW,IAAG,EAAU,WAAWA,EAAQ,EAAE,CAAC,aAAa,GACxFX,EAAQ,SAAW,EAAIA,EAAQ,EAAE,CAAC,KAAK,WAAa,IAC/D,EACM,cAAgB,EAAc,EAA0B,IAA6B,CACvF,IAAMY,EAAa9B,EAAS,QAAQc,EAAMN,CAAK,EAC9BF,EAAO,IAAIQ,CAAI,GAAKV,EAAS,IAAIU,CAAI,GAAKgB,EAAW,aAAa,OAAA,SAA0CA,EAAW,WAAW,KAAK,GAAaC,EAAU,OAAA,OAAsC,GACtMC,EAAQ,QAAQC,EAAgB,aAAc,kBAAkBnB,EAAK,6BAA6BA,EAAK,GAAIoB,CAAQ,CACtI,EACM,UAAY,EAA0C,IAA6B,CACrF,IAAK,IAAMC,KAASC,GACZD,EAAM,OAAS,oBAAsBA,EAAM,OAAS,wBAAuB,aAAaA,EAAM,MAAOA,EAAM,SAAU3B,CAAK,EAC1H,WAAY2B,GAAO,SAASA,EAAM,OAAQ3B,CAAK,CAE3D,EACM6B,kBAAW,IAAI,IACf,MAAQ,EAA0C,EAA8C,EAAU,GAAO,EAAoB,KAAgB,CACvJ,IAAM,UAAY,EAAc,IAA6B,CACzD,IAAMC,EAAW,SAASrB,EAAYD,CAAI,EACpCuB,EAAM,KAAK,UAAU,CAACL,EAAS,KAAMA,EAAS,KAAMA,EAAS,MAAM,CAAC,EAK1E,OAJII,EAAS,SAAW,CAACD,EAAS,IAAIE,CAAG,IACrCF,EAAS,IAAIE,CAAG,EAChBP,EAAQ,QAAQC,EAAgB,yBAA0B,sBAAsBjB,EAAK,sBAAsBwB,EAAU,UAAY,aAAa,WAAYN,CAAQ,GAE/JI,EAAS,KACpB,EAEMG,EAAaC,GAAqBN,EAAO,KAAK,GAASD,EAAM,OAAS,cAAgBA,EAAM,OAAS,cAAgBA,EAAM,OAAS,WAAW,EACrJ,IAAK,IAAMA,KAASC,EAAQ,CACxB,IAAMO,EAAWR,EAAM,OAAS,eAAiB,CAACM,EAAa,CAAC,EAAI,aAAcN,EAAQA,EAAM,SAAWA,EAAM,OAAS,aAAeA,EAAM,OAAO,QAAQ,GAAS1B,EAAM,QAAQ,EAAI,CAAC,EAC1L,IAAK,IAAMmC,KAAWD,EAAU,SAASC,EAAQ,SAAUA,EAAQ,QAAQ,EAC3E,GAAIT,EAAM,OAAS,kBAAoBA,EAAM,OAAS,eAAgB,CAClE,IAAMU,EAAS,SAASV,EAAM,SAAUA,EAAM,QAAQ,EACtD,KAAKA,EAAM,OAAQU,IAAW,KAAO,KAAOnC,EAAM,IAAImC,EAAO,KAAK,IAAI,CAAC,EAAE,YAAc,KAAM,EAAI,CACrG,CACJ,CACJ,EACA,IAAK,GAAM,CAAE,WAAW1C,EAAQ,CAC5B,IAAK,IAAM2C,KAActC,EAAM,YAAa,SAASsC,EAAW,OAAQtC,CAAK,EAC7E,IAAK,IAAMuC,KAAWvC,EAAM,SACxB,IAAK,IAAMwC,IAAU,CAAC,GAAGD,EAAQ,QAAS,GAAGA,EAAQ,SAAS,QAAQ,GAASE,EAAM,OAAO,EAAG,GAAGF,EAAQ,OAAO,QAAQ,GAASE,EAAM,OAAO,CAAC,EAAG,aAAaD,EAAO,MAAOA,EAAO,SAAUxC,CAAK,CAE5M,CACA,IAAK,GAAM,CAAE,QAAO,WAAWL,EAC3B,IAAK,IAAM2C,KAActC,EAAM,YAAa,CACxC,IAAM0C,EAAWJ,EAAW,OAAO,OAAO,GAASX,EAAM,OAAS,yBAAyB,EACvFe,EAAS,SAAW,GAAG,KAAKJ,EAAW,OAAQ,eAAeA,EAAW,WAAaA,EAAW,KAAMpB,CAAK,CAAC,EACjH,IAAK,IAAMyB,KAAWD,EAAU,CAC5B,IAAMjC,EAAa,eAAekC,EAAQ,KAAMzB,CAAK,EACrD,KAAKoB,EAAW,OAAO,OAAO,GAASX,EAAM,OAAS,kBAAoBA,EAAM,OAAS,cAAc,EAAGlB,CAAU,EAEpH,IAAMwB,EAAaU,EAAQ,SAAS,OAAS,GAAKL,EAAW,OAAO,KAAK,GAASX,EAAM,OAAS,cAAgBA,EAAM,OAAS,cAAgBA,EAAM,OAAS,WAAW,EAC1K,KAAKgB,EAAQ,OAAQlC,EAAY,GAAOwB,CAAU,CACtD,CACJ,CAER"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{unescapeIdentifier as n}from"./LineText.js";import{locationOf as r}from"./SourceLine.js";const i=t(`^(@?[a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+(generated))?(?:\\s+(identifier))?(?:\\s+(subject))?$`),a=t(`^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\??\\s+((?:optional|generated|identifier|subject)(?:\\s+(?:optional|generated|identifier|subject))*)$`),o=t(`^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\s+identifier\\s+optional(?:\\s*=.*)?$`);function tryParseProperty(e){let t=i.exec(e.content);if(t===null)return;let a=r(e);return{kind:`PropertySyntax`,name:n(t[1]),type:parseTypeRef(t[2],{...a,column:a.column+e.content.indexOf(t[2],t[1].length)}),isGenerated:t[3]!==void 0,nameWasEscaped:t[1].startsWith(`@`),isIdentifier:t[4]!==void 0,...t[5]===void 0?{}:{isSubject:!0},location:a}}function parseTypeRef(e,t){let n=e.endsWith(`?`),r=/\soptional$/.test(e),i=n||r;i&&(e=e.substring(0,e.length-(n?1:8)).trimEnd());let a=e.endsWith(`[]`);return a&&(e=e.substring(0,e.length-2)),{kind:`TypeRefSyntax`,name:e,isCollection:a,isOptional:i,location:t}}function parseProperty(e,t){let n=tryParseProperty(t);return n===void 0?reportInvalidModifierOrder(e,t):reportLegacyOptionalSuffix(e,n.type,t),n}function reportLegacyOptionalSuffix(t,n,r){t.claimField(r);let i=n.name.length+(n.isCollection?2:0),a=n.location.column-r.indent-1+i;if(n.isOptional&&r.content[a]===`?`){let r=n.name+(n.isCollection?`[]`:``);t.information(e.LegacyOptionalSuffix,`Write '${r} optional' instead of '${r}?'.`,n.location)}}function reportInvalidModifierOrder(t,n){let i=a.exec(n.content);if(i!==null&&i[1].split(/\s+/).includes(`subject`))return t.error(e.InvalidSubjectModifierOrder,`Write each modifier once in order: '<name> <Type> optional generated identifier subject'.`,r(n)),!0;if(o.test(n.content))return t.error(e.InvalidOptionalModifierOrder,`Write 'optional' before 'identifier': '<name> <Type> optional identifier'.`,r(n)),!0;{let i=a.exec(n.content);if(i!==null&&i[1].split(/\s+/).some(e=>e===`generated`||e===`identifier`))return t.error(e.InvalidGeneratedModifierOrder,`Write each modifier once in order: '<name> <Type> optional generated identifier'.`,r(n)),!0}return!1}export{parseProperty,parseTypeRef,reportInvalidModifierOrder,reportLegacyOptionalSuffix,tryParseProperty};
|
|
2
|
+
//# sourceMappingURL=PropertyLineParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyLineParser.js","names":["propertyPattern","pattern","invalidGeneratedModifiers","reversedModifiers","match","line","location","locationOf","unescapeIdentifier","legacy","text","canonical","isOptional","isCollection","property","context","length","type","offset","name","DiagnosticCodes","subjectModifiers","modifiers","modifier"],"sources":["../../../../../../Compiler/Parsing/PropertyLineParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { PropertySyntax, TypeRefSyntax } from '../Syntax/Declarations';\nimport { pattern } from '../Text/patterns';\nimport { ParserContext } from './ParserContext';\nimport { unescapeIdentifier } from './LineText';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst propertyPattern = pattern('^(@?[a-z_]\\\\w*)\\\\s+([\\\\w.]+(?:\\\\[\\\\])?(?:\\\\?|\\\\s+optional)?)(?:\\\\s+(generated))?(?:\\\\s+(identifier))?(?:\\\\s+(subject))?$');\nconst invalidGeneratedModifiers = pattern('^@?[a-z_]\\\\w*\\\\s+[\\\\w.]+(?:\\\\[\\\\])?\\\\??\\\\s+((?:optional|generated|identifier|subject)(?:\\\\s+(?:optional|generated|identifier|subject))*)$');\nconst reversedModifiers = pattern('^@?[a-z_]\\\\w*\\\\s+[\\\\w.]+(?:\\\\[\\\\])?\\\\s+identifier\\\\s+optional(?:\\\\s*=.*)?$');\n\n// A '<name> <Type>[[]][?] [identifier]' line, or undefined when the line does not have that shape.\nexport function tryParseProperty(line: SourceLine): PropertySyntax | undefined {\n const match = propertyPattern.exec(line.content);\n if (match === null) {\n return undefined;\n }\n const location = locationOf(line);\n return {\n kind: 'PropertySyntax',\n name: unescapeIdentifier(match[1]),\n type: parseTypeRef(match[2], { ...location, column: location.column + line.content.indexOf(match[2], match[1].length) }),\n isGenerated: match[3] !== undefined,\n nameWasEscaped: match[1].startsWith('@'),\n isIdentifier: match[4] !== undefined,\n ...(match[5] !== undefined ? { isSubject: true } : {}),\n location,\n };\n}\n\nexport function parseTypeRef(text: string, location: SourceLocation): TypeRefSyntax {\n const legacy = text.endsWith('?');\n const canonical = /\\soptional$/.test(text);\n const isOptional = legacy || canonical;\n if (isOptional) {\n text = text.substring(0, text.length - (legacy ? 1 : 'optional'.length)).trimEnd();\n }\n const isCollection = text.endsWith('[]');\n if (isCollection) {\n text = text.substring(0, text.length - 2);\n }\n return { kind: 'TypeRefSyntax', name: text, isCollection, isOptional, location };\n}\n\n// Unlike tryParseProperty, this is only called once the owner commits to a property position.\nexport function parseProperty(context: ParserContext, line: SourceLine): PropertySyntax | undefined {\n const property = tryParseProperty(line);\n if (property !== undefined) {\n reportLegacyOptionalSuffix(context, property.type, line);\n } else {\n reportInvalidModifierOrder(context, line);\n }\n return property;\n}\n\nexport function reportLegacyOptionalSuffix(context: ParserContext, type: TypeRefSyntax, line: SourceLine): void {\n context.claimField(line);\n const length = type.name.length + (type.isCollection ? 2 : 0);\n const offset = type.location.column - line.indent - 1 + length;\n if (type.isOptional && line.content[offset] === '?') {\n const name = type.name + (type.isCollection ? '[]' : '');\n context.information(DiagnosticCodes.LegacyOptionalSuffix, `Write '${name} optional' instead of '${name}?'.`, type.location);\n }\n}\n\nexport function reportInvalidModifierOrder(context: ParserContext, line: SourceLine): boolean {\n const subjectModifiers = invalidGeneratedModifiers.exec(line.content);\n if (subjectModifiers !== null && subjectModifiers[1].split(/\\s+/).includes('subject')) {\n context.error(DiagnosticCodes.InvalidSubjectModifierOrder, \"Write each modifier once in order: '<name> <Type> optional generated identifier subject'.\", locationOf(line));\n return true;\n }\n if (reversedModifiers.test(line.content)) {\n context.error(DiagnosticCodes.InvalidOptionalModifierOrder, \"Write 'optional' before 'identifier': '<name> <Type> optional identifier'.\", locationOf(line));\n return true;\n } else {\n const modifiers = invalidGeneratedModifiers.exec(line.content);\n if (modifiers !== null && modifiers[1].split(/\\s+/).some(modifier => modifier === 'generated' || modifier === 'identifier')) {\n context.error(DiagnosticCodes.InvalidGeneratedModifierOrder, \"Write each modifier once in order: '<name> <Type> optional generated identifier'.\", locationOf(line));\n return true;\n }\n }\n return false;\n}\n"],"mappings":"uQAWA,MAAMA,EAAkBC,EAAQ,0HAA0H,EACpJC,EAA4BD,EAAQ,2IAA2I,EAC/KE,EAAoBF,EAAQ,4EAA4E,EAG9G,SAAgB,iBAAiB,EAA8C,CAC3E,IAAMG,EAAQJ,EAAgB,KAAKK,EAAK,OAAO,EAC/C,GAAID,IAAU,KACV,OAEJ,IAAME,EAAWC,EAAWF,CAAI,EAChC,MAAO,CACH,KAAM,iBACN,KAAMG,EAAmBJ,EAAM,EAAE,EACjC,KAAM,aAAaA,EAAM,GAAI,CAAE,GAAGE,EAAU,OAAQA,EAAS,OAASD,EAAK,QAAQ,QAAQD,EAAM,GAAIA,EAAM,EAAE,CAAC,MAAM,CAAE,CAAC,EACvH,YAAaA,EAAM,KAAO,IAAA,GAC1B,eAAgBA,EAAM,EAAE,CAAC,WAAW,GAAG,EACvC,aAAcA,EAAM,KAAO,IAAA,GAC3B,GAAIA,EAAM,KAAO,IAAA,GAAkC,CAAC,EAAvB,CAAE,UAAW,EAAK,EAC/C,UACJ,CACJ,CAEA,SAAgB,aAAa,EAAc,EAAyC,CAChF,IAAMK,EAASC,EAAK,SAAS,GAAG,EAC1BC,EAAY,cAAc,KAAKD,CAAI,EACnCE,EAAaH,GAAUE,EACzBC,IACA,EAAOF,EAAK,UAAU,EAAGA,EAAK,QAAUD,EAAS,EAAI,EAAkB,CAAC,CAAC,QAAQ,GAErF,IAAMI,EAAeH,EAAK,SAAS,IAAI,EAIvC,OAHIG,IACA,EAAOH,EAAK,UAAU,EAAGA,EAAK,OAAS,CAAC,GAErC,CAAE,KAAM,gBAAiB,KAAMA,EAAM,eAAc,aAAY,UAAS,CACnF,CAGA,SAAgB,cAAc,EAAwB,EAA8C,CAChG,IAAMI,EAAW,iBAAiBT,CAAI,EAMtC,OALIS,IAAa,IAAA,GAGb,2BAA2BC,EAASV,CAAI,EAFxC,2BAA2BU,EAASD,EAAS,KAAMT,CAAI,EAIpDS,CACX,CAEA,SAAgB,2BAA2B,EAAwB,EAAqB,EAAwB,CAC5GC,EAAQ,WAAWV,CAAI,EACvB,IAAMW,EAASC,EAAK,KAAK,QAAUA,EAAK,aAAe,EAAI,GACrDC,EAASD,EAAK,SAAS,OAASZ,EAAK,OAAS,EAAIW,EACxD,GAAIC,EAAK,YAAcZ,EAAK,QAAQa,KAAY,IAAK,CACjD,IAAMC,EAAOF,EAAK,MAAQA,EAAK,aAAe,KAAO,IACrDF,EAAQ,YAAYK,EAAgB,qBAAsB,UAAUD,EAAK,yBAAyBA,EAAK,KAAMF,EAAK,QAAQ,CAC9H,CACJ,CAEA,SAAgB,2BAA2B,EAAwB,EAA2B,CAC1F,IAAMI,EAAmBnB,EAA0B,KAAKG,EAAK,OAAO,EACpE,GAAIgB,IAAqB,MAAQA,EAAiB,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,SAAS,SAAS,EAEhF,OADAN,EAAQ,MAAMK,EAAgB,4BAA6B,4FAA6Fb,EAAWF,CAAI,CAAC,EACjK,GAEX,GAAIF,EAAkB,KAAKE,EAAK,OAAO,EAEnC,OADAU,EAAQ,MAAMK,EAAgB,6BAA8B,6EAA8Eb,EAAWF,CAAI,CAAC,EACnJ,GACJ,CACH,IAAMiB,EAAYpB,EAA0B,KAAKG,EAAK,OAAO,EAC7D,GAAIiB,IAAc,MAAQA,EAAU,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,GAAYC,IAAa,aAAeA,IAAa,YAAY,EAEtH,OADAR,EAAQ,MAAMK,EAAgB,8BAA+B,oFAAqFb,EAAWF,CAAI,CAAC,EAC3J,EAEf,CACA,MAAO,EACX"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{ScreenplaySyntaxWalker as t}from"../Syntax/ScreenplaySyntaxWalker.js";import{publicEventMetadataError as n}from"../Syntax/PublicEventInvariants.js";var PublicEventMetadataValidator=class extends t{context;constructor(e){super(),this.context=e}visitNode(t){let r=n(t);if(r===void 0)return;let i=t.kind===`EventSyntax`?e.InvalidEventDeclaration:t.kind===`ImportSyntax`?e.InvalidImportDeclaration:e.InvalidSliceDeclaration;this.context.error(i,r,t.location)}};function validatePublicEventMetadata(e,t){new PublicEventMetadataValidator(t).visitApplication(e)}export{validatePublicEventMetadata};
|
|
2
|
+
//# sourceMappingURL=PublicEventMetadataValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicEventMetadataValidator.js","names":["ScreenplaySyntaxWalker","context","error","publicEventMetadataError","node","code","DiagnosticCodes","application"],"sources":["../../../../../../Compiler/Parsing/PublicEventMetadataValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { publicEventMetadataError } from '../Syntax/PublicEventInvariants';\nimport { ScreenplaySyntaxWalker } from '../Syntax/ScreenplaySyntaxWalker';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\nimport { ParserContext } from './ParserContext';\n\nclass PublicEventMetadataValidator extends ScreenplaySyntaxWalker {\n constructor(private readonly context: ParserContext) { super(); }\n\n override visitNode(node: SyntaxNode): void {\n const error = publicEventMetadataError(node);\n if (error === undefined) return;\n const code = node.kind === 'EventSyntax' ? DiagnosticCodes.InvalidEventDeclaration\n : node.kind === 'ImportSyntax' ? DiagnosticCodes.InvalidImportDeclaration : DiagnosticCodes.InvalidSliceDeclaration;\n this.context.error(code, error, node.location);\n }\n}\n\nexport function validatePublicEventMetadata(application: ApplicationSyntax, context: ParserContext): void {\n new PublicEventMetadataValidator(context).visitApplication(application);\n}\n"],"mappings":"oRAUA,IAAM,6BAAN,cAA2CA,CAAuB,CACjC,QAA7B,YAAY,EAAyC,CAAE,MAAM,EAAhC,KAAA,QAAAC,CAAmC,CAEhE,UAAmB,EAAwB,CACvC,IAAMC,EAAQC,EAAyBC,CAAI,EAC3C,GAAIF,IAAU,IAAA,GAAW,OACzB,IAAMG,EAAOD,EAAK,OAAS,cAAgBE,EAAgB,wBACrDF,EAAK,OAAS,eAAiBE,EAAgB,yBAA2BA,EAAgB,wBAChG,KAAK,QAAQ,MAAMD,EAAMH,EAAOE,EAAK,QAAQ,CACjD,CACJ,EAEA,SAAgB,4BAA4B,EAAgC,EAA8B,CACtG,IAAI,6BAA6BH,CAAO,CAAC,CAAC,iBAAiBM,CAAW,CAC1E"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{dependencySourcesOf as e}from"../Syntax/DependencySources.js";import{ScreenplaySyntaxWalker as t}from"../Syntax/ScreenplaySyntaxWalker.js";import{consumedEvents as n,isEventsSource as r}from"../Syntax/CaptureEventsSource.js";var PublicEventUsageCollector=class extends t{command=!1;uses=[];allEvents=[];projectionTargets=[];eventSources=[];visitProjection(e){e.readModel!=null&&this.projectionTargets.push({target:e.readModel,node:e}),super.visitProjection(e)}visitReducer(e){this.projectionTargets.push({target:e.readModel,node:e}),super.visitReducer(e)}visitCaptureSource(e){r(e)&&(this.eventSources.push(e),n(e).forEach(e=>this.uses.push({name:e.value,node:e,output:!1,command:!1}))),super.visitCaptureSource(e)}visitSlice(t){super.visitSlice(t),e(t).reducers?.forEach(e=>this.visitReducer(e))}visitCommand(e){this.command=!0,super.visitCommand(e),this.command=!1}visitProduces(e){e.inlineOperation??this.uses.push({name:e.event,node:e,output:!0,command:this.command})}visitCaptureAppend(e){this.inputOrOutput(e.event,e,!0)}visitJoinEvent(e){this.inputOrOutput(e.event,e)}visitReducerRule(e){this.inputOrOutput(e.event,e)}visitConstraint(e){e.releasedBy.forEach(t=>this.inputOrOutput(t,e)),e.kind!==`FileConstraintSyntax`&&this.inputOrOutput(e.event,e),super.visitConstraint(e)}visitProjectionBlock(e){switch(e.kind){case`FromSyntax`:e.events.forEach(e=>this.inputOrOutput(e.event,e));break;case`ClearWithSyntax`:case`RemoveWithSyntax`:case`RemoveViaJoinSyntax`:this.inputOrOutput(e.event,e);break;case`AllSyntax`:this.allEvents.push(e)}super.visitProjectionBlock(e)}visitReactionTrigger(e){e.source.kind===`NamedTriggerSourceSyntax`&&this.inputOrOutput(e.source.name,e.source),super.visitReactionTrigger(e)}visitSpecification(e){}inputOrOutput(e,t,n=!1){this.uses.push({name:e,node:t,output:n,command:!1})}};export{PublicEventUsageCollector};
|
|
2
|
+
//# sourceMappingURL=PublicEventUsageCollector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicEventUsageCollector.js","names":["ScreenplaySyntaxWalker","syntax","isEventsSource","consumedEvents","setting","dependencySourcesOf","reducer","name","event"],"sources":["../../../../../../Compiler/Parsing/PublicEventUsageCollector.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { CommandSyntax } from '../Syntax/Commands';\nimport { CaptureAppendSyntax, CaptureSourceSyntax } from '../Syntax/Captures';\nimport { ConstraintSyntax } from '../Syntax/Constraints';\nimport { dependencySourcesOf, ReducerRuleSyntax } from '../Syntax/DependencySources';\nimport { ReducerSyntax } from '../Syntax/ReducerSyntax';\nimport { consumedEvents, isEventsSource } from '../Syntax/CaptureEventsSource';\nimport { AllSyntax, JoinEventSyntax, ProjectionBlockSyntax, ProjectionSyntax } from '../Syntax/Projections';\nimport { ProducesSyntax, ReactionTriggerSyntax } from '../Syntax/Reactions';\nimport { ScreenplaySyntaxWalker } from '../Syntax/ScreenplaySyntaxWalker';\nimport { SpecificationSyntax } from '../Syntax/Specifications';\nimport { SliceSyntax } from '../Syntax/Structure';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\n\n/** Operational event edges only: fixtures and assertions are not subscriptions or appends. */\nexport class PublicEventUsageCollector extends ScreenplaySyntaxWalker {\n private command = false;\n readonly uses: { name: string; node: SyntaxNode; output: boolean; command: boolean }[] = [];\n readonly allEvents: AllSyntax[] = [];\n /** The '=> Name' of each projection and reducer: a read model, or an event in an outbound translation. */\n readonly projectionTargets: { target: string; node: SyntaxNode }[] = [];\n readonly eventSources: CaptureSourceSyntax[] = [];\n\n override visitProjection(syntax: ProjectionSyntax): void {\n if (syntax.readModel != null) this.projectionTargets.push({ target: syntax.readModel, node: syntax });\n super.visitProjection(syntax);\n }\n override visitReducer(syntax: ReducerSyntax): void {\n this.projectionTargets.push({ target: syntax.readModel, node: syntax });\n super.visitReducer(syntax);\n }\n override visitCaptureSource(syntax: CaptureSourceSyntax): void {\n if (isEventsSource(syntax)) {\n this.eventSources.push(syntax);\n consumedEvents(syntax).forEach(setting => this.uses.push({ name: setting.value, node: setting, output: false, command: false }));\n }\n super.visitCaptureSource(syntax);\n }\n\n override visitSlice(syntax: SliceSyntax): void {\n super.visitSlice(syntax);\n dependencySourcesOf(syntax).reducers?.forEach(reducer => this.visitReducer(reducer));\n }\n override visitCommand(syntax: CommandSyntax): void {\n this.command = true;\n super.visitCommand(syntax);\n this.command = false;\n }\n override visitProduces(syntax: ProducesSyntax): void {\n if (syntax.inlineOperation == null) this.uses.push({ name: syntax.event, node: syntax, output: true, command: this.command });\n }\n override visitCaptureAppend(syntax: CaptureAppendSyntax): void { this.inputOrOutput(syntax.event, syntax, true); }\n override visitJoinEvent(syntax: JoinEventSyntax): void { this.inputOrOutput(syntax.event, syntax); }\n override visitReducerRule(syntax: ReducerRuleSyntax): void { this.inputOrOutput(syntax.event, syntax); }\n override visitConstraint(syntax: ConstraintSyntax): void {\n syntax.releasedBy.forEach(name => this.inputOrOutput(name, syntax));\n if (syntax.kind !== 'FileConstraintSyntax') this.inputOrOutput(syntax.event, syntax);\n super.visitConstraint(syntax);\n }\n override visitProjectionBlock(syntax: ProjectionBlockSyntax): void {\n switch (syntax.kind) {\n case 'FromSyntax': syntax.events.forEach(event => this.inputOrOutput(event.event, event)); break;\n case 'ClearWithSyntax':\n case 'RemoveWithSyntax':\n case 'RemoveViaJoinSyntax': this.inputOrOutput(syntax.event, syntax); break;\n case 'AllSyntax': this.allEvents.push(syntax); break;\n }\n super.visitProjectionBlock(syntax);\n }\n override visitReactionTrigger(syntax: ReactionTriggerSyntax): void {\n if (syntax.source.kind === 'NamedTriggerSourceSyntax') this.inputOrOutput(syntax.source.name, syntax.source);\n super.visitReactionTrigger(syntax);\n }\n override visitSpecification(_syntax: SpecificationSyntax): void {}\n\n private inputOrOutput(name: string, node: SyntaxNode, output = false): void {\n this.uses.push({ name, node, output, command: false });\n }\n}\n"],"mappings":"6RAiBA,IAAa,0BAAb,cAA+CA,CAAuB,CAClE,QAAkB,GAClB,KAAyF,CAAC,EAC1F,UAAkC,CAAC,EAEnC,kBAAqE,CAAC,EACtE,aAA+C,CAAC,EAEhD,gBAAyB,EAAgC,CACjDC,EAAO,WAAa,MAAM,KAAK,kBAAkB,KAAK,CAAE,OAAQA,EAAO,UAAW,KAAMA,CAAO,CAAC,EACpG,MAAM,gBAAgBA,CAAM,CAChC,CACA,aAAsB,EAA6B,CAC/C,KAAK,kBAAkB,KAAK,CAAE,OAAQA,EAAO,UAAW,KAAMA,CAAO,CAAC,EACtE,MAAM,aAAaA,CAAM,CAC7B,CACA,mBAA4B,EAAmC,CACvDC,EAAeD,CAAM,IACrB,KAAK,aAAa,KAAKA,CAAM,EAC7BE,EAAeF,CAAM,CAAC,CAAC,QAAQ,GAAW,KAAK,KAAK,KAAK,CAAE,KAAMG,EAAQ,MAAO,KAAMA,EAAS,OAAQ,GAAO,QAAS,EAAM,CAAC,CAAC,GAEnI,MAAM,mBAAmBH,CAAM,CACnC,CAEA,WAAoB,EAA2B,CAC3C,MAAM,WAAWA,CAAM,EACvBI,EAAoBJ,CAAM,CAAC,CAAC,UAAU,QAAQ,GAAW,KAAK,aAAaK,CAAO,CAAC,CACvF,CACA,aAAsB,EAA6B,CAC/C,KAAK,QAAU,GACf,MAAM,aAAaL,CAAM,EACzB,KAAK,QAAU,EACnB,CACA,cAAuB,EAA8B,CAC7CA,EAAO,iBAAyB,KAAK,KAAK,KAAK,CAAE,KAAMA,EAAO,MAAO,KAAMA,EAAQ,OAAQ,GAAM,QAAS,KAAK,OAAQ,CAAC,CAChI,CACA,mBAA4B,EAAmC,CAAE,KAAK,cAAcA,EAAO,MAAOA,EAAQ,EAAI,CAAG,CACjH,eAAwB,EAA+B,CAAE,KAAK,cAAcA,EAAO,MAAOA,CAAM,CAAG,CACnG,iBAA0B,EAAiC,CAAE,KAAK,cAAcA,EAAO,MAAOA,CAAM,CAAG,CACvG,gBAAyB,EAAgC,CACrDA,EAAO,WAAW,QAAQ,GAAQ,KAAK,cAAcM,EAAMN,CAAM,CAAC,EAC9DA,EAAO,OAAS,wBAAwB,KAAK,cAAcA,EAAO,MAAOA,CAAM,EACnF,MAAM,gBAAgBA,CAAM,CAChC,CACA,qBAA8B,EAAqC,CAC/D,OAAQA,EAAO,KAAf,CACI,IAAK,aAAcA,EAAO,OAAO,QAAQ,GAAS,KAAK,cAAcO,EAAM,MAAOA,CAAK,CAAC,EAAG,MAC3F,IAAK,kBACL,IAAK,mBACL,IAAK,sBAAuB,KAAK,cAAcP,EAAO,MAAOA,CAAM,EAAG,MACtE,IAAK,YAAa,KAAK,UAAU,KAAKA,CAAM,CAChD,CACA,MAAM,qBAAqBA,CAAM,CACrC,CACA,qBAA8B,EAAqC,CAC3DA,EAAO,OAAO,OAAS,4BAA4B,KAAK,cAAcA,EAAO,OAAO,KAAMA,EAAO,MAAM,EAC3G,MAAM,qBAAqBA,CAAM,CACrC,CACA,mBAA4B,EAAoC,CAAC,CAEjE,cAAsB,EAAc,EAAkB,EAAS,GAAa,CACxE,KAAK,KAAK,KAAK,CAAE,OAAM,OAAM,SAAQ,QAAS,EAAM,CAAC,CACzD,CACJ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{eventDeclarations as t}from"../Syntax/EventDeclarations.js";import{AuthoringProductionResolver as n}from"../Syntax/AuthoringProductionResolver.js";import{dependencySourcesOf as r}from"../Syntax/DependencySources.js";import{isEventsSource as i}from"../Syntax/CaptureEventsSource.js";import{PublicEventUsageCollector as a}from"./PublicEventUsageCollector.js";import{validatePublicEventMetadata as o}from"./PublicEventMetadataValidator.js";function validatePublicEventUsage(t,r){o(t,r);let i=new n(t);if(!i.declarations.some(e=>e.node.kind===`EventSyntax`&&(e.node.visibility===`Public`||e.node.origin!=null))&&!t.imports.some(e=>e.visibility===`Public`||e.origin!=null)&&!i.slices.some(({slice:e})=>e.direction!=null||usesEventSource(e)||targetsEvent(e,i)))return;let a=new n(t,i.declarations.filter(e=>e.kind===`event`));for(let{slice:e,scope:n}of i.slices)validateSlice(t,e,n,i,a,r);for(let n of t.seeds?.flatMap(e=>e.groups.flatMap(e=>e.events))??[]){let i=resolve(t,a,[],n.event,n,!0,r);if(i?.visibility!==`Public`)continue;let o=i.origin==null?e.PublicEventRequiresOutboundTranslation:e.ForeignPublicEventProduced;r.error(o,`Seed cannot append public event '${n.event}'; public production belongs to outbound translation, and foreign contracts cannot be produced locally.`,n.location)}}function validateSlice(n,r,i,o,s,c){let l=new a;l.visitSlice(r);let u=[],d=r.type===`Translate`&&r.direction===`Outbound`,f=new Set(r.readModels.map(e=>e.name));for(let{target:t,node:a}of l.projectionTargets){let o=f.has(t)?void 0:resolve(n,s,i,t,a,!1,c);o!==void 0&&(d?(u.push({node:o,output:!0}),validateUse(r,t,a,!0,!1,o,c)):c.error(e.EventTargetOutsideOutboundTranslation,`'${t}' is an event: a projection or reducer may only target an event in an explicitly outbound Translate slice.`,a.location))}if((r.type!==`Translate`||r.direction!==`Inbound`)&&!d)for(let t of l.eventSources)c.error(e.EventsSourceOutsideInboundTranslation,`'source events' reads another application's public events and belongs to a Translate slice with 'direction inbound', not '${r.name}'.`,t.location);for(let e of l.uses){let t=resolve(n,e.node.kind===`ProducesSyntax`?o:s,i,e.name,e.node,e.output,c);t!==void 0&&(u.push({node:t,output:e.output}),validateUse(r,e.name,e.node,e.output,e.command,t,c))}for(let e of l.allEvents){let t=o.declarations.filter(e=>e.kind===`event`).map(e=>e.node);for(let i of[...t,...n.imports.filter(e=>e.visibility===`Public`)])u.push({node:i,output:!1}),validateUse(r,i.kind===`ImportSyntax`?i.qualifiedName:i.name,e,!1,!1,i,c)}if(r.type!==`Translate`||(r.direction==null&&(t(r).some(e=>e.visibility===`Public`)||u.some(e=>e.node.visibility===`Public`))&&c.error(e.PublicTranslationRequiresDirection,`A Translate slice using public events requires an explicit 'direction inbound' or 'direction outbound'. Legacy translations without public metadata remain inbound.`,r.location),r.direction!==`Outbound`))return;let p=new Set(u.filter(e=>e.output&&e.node.visibility===`Public`&&e.node.origin==null).map(e=>e.node)).size;p!==1&&c.error(e.OutboundPublicEventCount,`Outbound Translate slice '${r.name}' must produce exactly one local public event type; found ${p}.`,r.location);for(let t of r.captures)c.error(e.TranslationConstructDirection,`An outbound translation consumes private local events, not an external-data capture. Capture belongs to inbound translation.`,t.location)}function validateUse(t,n,r,i,a,o,s){let c=o.origin!=null,l=o.visibility===`Public`,error=(e,t)=>s.error(e,t,r.location);i?(a&&l&&error(e.CommandProducesPublicEvent,`Command cannot produce public event '${n}'; publish through an outbound Translate slice.`),t.type===`Translate`&&t.direction===`Outbound`&&!l&&error(e.OutboundTranslationOutput,`Outbound translation must produce its one local public event, not private event '${n}'.`),c&&error(e.ForeignPublicEventProduced,`Foreign public event '${n}' cannot be produced locally; translate it into a private local event.`),l&&!c&&(t.type!==`Translate`||t.direction!==`Outbound`)&&error(e.PublicEventRequiresOutboundTranslation,`Local public event '${n}' may only be produced by an explicitly outbound Translate slice.`),t.type===`Translate`&&(t.direction??`Inbound`)===`Inbound`&&(l||c)&&error(e.InboundTranslationOutput,`Inbound translation must produce private local events, not '${n}'.`)):(c&&(t.type!==`Translate`||t.direction!==`Inbound`)&&error(e.ForeignPublicEventConsumer,`Foreign public event '${n}' may only be consumed by an explicitly inbound Translate slice.`),t.type===`Translate`&&t.direction===`Outbound`&&(l||c)&&error(e.OutboundTranslationInput,`Outbound translation must consume private local events, not '${n}'.`),t.type===`Translate`&&t.direction===`Inbound`&&(!l||!c)&&error(e.InboundTranslationInput,`Explicitly inbound translation must consume foreign public events, not '${n}'.`))}function resolve(t,n,r,i,a,o,s){let c=n.resolveFromScope(i,r);if(c.declaration?.node.kind===`EventSyntax`)return c.declaration.node;if(c.kind===`operation`)return;if(c.kind===`ambiguous`){s.warning(e.AmbiguousReference,`Ambiguous event reference '${i}'; qualify it with its owning module, feature and slice.`,a.location);return}let l=t.imports.filter(e=>e.qualifiedName.split(`.`).at(-1)===i||e.qualifiedName===i);if(l.length===1){let t=l[0],o=n.resolveFromScope(t.qualifiedName,r);if(o.declaration?.node.kind===`EventSyntax`)return o.declaration.node;if(o.kind===`ambiguous`){s.warning(e.AmbiguousReference,`Ambiguous imported event reference '${i}'; qualify its declaration.`,a.location);return}return t.visibility===`Public`?t:void 0}l.length>1?s.warning(e.AmbiguousReference,`Ambiguous imported event reference '${i}'; use its qualified name.`,a.location):(o&&a.kind!==`CaptureAppendSyntax`||a.kind===`CaptureSourceSettingSyntax`)&&!s.diagnostics.some(t=>t.code===e.UnknownEvent&&t.location.path===a.location.path&&t.location.line===a.location.line&&t.location.column===a.location.column)&&s.warning(e.UnknownEvent,`Unknown event '${i}' - declare its contract before classifying its usage.`,a.location)}function usesEventSource(e){return e.captures.some(e=>e.source!=null&&i(e.source))}function targetsEvent(e,t){return[...e.projections.map(e=>e.readModel),...(r(e).reducers??[]).map(e=>e.readModel)].some(e=>e!=null&&t.declarations.some(t=>t.kind===`event`&&t.name===e))}export{validatePublicEventUsage};
|
|
2
|
+
//# sourceMappingURL=PublicEventUsageValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PublicEventUsageValidator.js","names":["validatePublicEventMetadata","application","context","resolver","AuthoringProductionResolver","declaration","imported","slice","events","scope","seed","group","contract","code","DiagnosticCodes","collector","PublicEventUsageCollector","contracts","explicitOutbound","readModels","readModel","target","node","source","use","all","declarations","eventDeclarations","event","outputs","capture","foreign","publicEvent","message","output","command","name","resolution","imports","local","diagnostic","isEventsSource","projection","dependencySourcesOf","reducer"],"sources":["../../../../../../Compiler/Parsing/PublicEventUsageValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { AuthoringProductionKind, AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { EventSyntax, ImportSyntax } from '../Syntax/Declarations';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isEventsSource } from '../Syntax/CaptureEventsSource';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\nimport { TranslationDirection } from '../Syntax/TranslationDirection';\nimport { ParserContext } from './ParserContext';\nimport { PublicEventUsageCollector } from './PublicEventUsageCollector';\nimport { validatePublicEventMetadata } from './PublicEventMetadataValidator';\n\n/** Validates public contract boundaries against the complete assembled declaration inventory. */\nexport function validatePublicEventUsage(application: ApplicationSyntax, context: ParserContext): void {\n validatePublicEventMetadata(application, context);\n const resolver = new AuthoringProductionResolver(application);\n if (!resolver.declarations.some(declaration => declaration.node.kind === 'EventSyntax' && ((declaration.node as EventSyntax).visibility === EventVisibility.Public || (declaration.node as EventSyntax).origin != null)) &&\n !application.imports.some(imported => imported.visibility === EventVisibility.Public || imported.origin != null) &&\n !resolver.slices.some(({ slice }) => slice.direction != null || usesEventSource(slice) || targetsEvent(slice, resolver))) return;\n const events = new AuthoringProductionResolver(application, resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event));\n for (const { slice, scope } of resolver.slices) validateSlice(application, slice, scope, resolver, events, context);\n for (const seed of application.seeds?.flatMap(seed => seed.groups.flatMap(group => group.events)) ?? []) {\n const contract = resolve(application, events, [], seed.event, seed, true, context);\n if (contract?.visibility !== EventVisibility.Public) continue;\n const code = contract.origin == null ? DiagnosticCodes.PublicEventRequiresOutboundTranslation : DiagnosticCodes.ForeignPublicEventProduced;\n context.error(code, `Seed cannot append public event '${seed.event}'; public production belongs to outbound translation, and foreign contracts cannot be produced locally.`, seed.location);\n }\n}\n\nfunction validateSlice(application: ApplicationSyntax, slice: SliceSyntax, scope: readonly string[], resolver: AuthoringProductionResolver, events: AuthoringProductionResolver, context: ParserContext): void {\n const collector = new PublicEventUsageCollector();\n collector.visitSlice(slice);\n const contracts: { node: EventSyntax | ImportSyntax; output: boolean }[] = [];\n const explicitOutbound = slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound;\n const readModels = new Set(slice.readModels.map(readModel => readModel.name));\n for (const { target, node } of collector.projectionTargets) {\n // '=> Name' names a read model unless it resolves to an event: then the projection or reducer publishes that event.\n const contract = readModels.has(target) ? undefined : resolve(application, events, scope, target, node, false, context);\n if (contract === undefined) continue;\n if (!explicitOutbound) {\n context.error(DiagnosticCodes.EventTargetOutsideOutboundTranslation, `'${target}' is an event: a projection or reducer may only target an event in an explicitly outbound Translate slice.`, node.location);\n continue;\n }\n contracts.push({ node: contract, output: true });\n validateUse(slice, target, node, true, false, contract, context);\n }\n // An outbound slice with a capture is already refused as a whole by the translation-direction check below.\n if (!(slice.type === 'Translate' && slice.direction === TranslationDirection.Inbound) && !explicitOutbound) {\n for (const source of collector.eventSources) context.error(DiagnosticCodes.EventsSourceOutsideInboundTranslation, `'source events' reads another application's public events and belongs to a Translate slice with 'direction inbound', not '${slice.name}'.`, source.location);\n }\n for (const use of collector.uses) {\n const contract = resolve(application, use.node.kind === 'ProducesSyntax' ? resolver : events, scope, use.name, use.node, use.output, context);\n if (contract === undefined) continue;\n contracts.push({ node: contract, output: use.output });\n validateUse(slice, use.name, use.node, use.output, use.command, contract, context);\n }\n // 'all' subscribes to every event type; 'every' maps only the projection's existing inputs.\n for (const all of collector.allEvents) {\n const declarations = resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event).map(declaration => declaration.node as EventSyntax);\n for (const contract of [...declarations, ...application.imports.filter(imported => imported.visibility === EventVisibility.Public)]) {\n contracts.push({ node: contract, output: false });\n validateUse(slice, contract.kind === 'ImportSyntax' ? contract.qualifiedName : contract.name, all, false, false, contract, context);\n }\n }\n if (slice.type !== 'Translate') return;\n if (slice.direction == null && (eventDeclarations(slice).some(event => event.visibility === EventVisibility.Public) || contracts.some(contract => contract.node.visibility === EventVisibility.Public))) {\n context.error(DiagnosticCodes.PublicTranslationRequiresDirection, \"A Translate slice using public events requires an explicit 'direction inbound' or 'direction outbound'. Legacy translations without public metadata remain inbound.\", slice.location);\n }\n if (slice.direction !== TranslationDirection.Outbound) return;\n const outputs = new Set(contracts.filter(contract => contract.output && contract.node.visibility === EventVisibility.Public && contract.node.origin == null).map(contract => contract.node)).size;\n if (outputs !== 1) context.error(DiagnosticCodes.OutboundPublicEventCount, `Outbound Translate slice '${slice.name}' must produce exactly one local public event type; found ${outputs}.`, slice.location);\n for (const capture of slice.captures) context.error(DiagnosticCodes.TranslationConstructDirection, 'An outbound translation consumes private local events, not an external-data capture. Capture belongs to inbound translation.', capture.location);\n}\n\nfunction validateUse(slice: SliceSyntax, name: string, node: SyntaxNode, output: boolean, command: boolean, contract: EventSyntax | ImportSyntax, context: ParserContext): void {\n const foreign = contract.origin != null;\n const publicEvent = contract.visibility === EventVisibility.Public;\n const error = (code: string, message: string) => context.error(code, message, node.location);\n if (output) {\n if (command && publicEvent) error(DiagnosticCodes.CommandProducesPublicEvent, `Command cannot produce public event '${name}'; publish through an outbound Translate slice.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound && !publicEvent) error(DiagnosticCodes.OutboundTranslationOutput, `Outbound translation must produce its one local public event, not private event '${name}'.`);\n if (foreign) error(DiagnosticCodes.ForeignPublicEventProduced, `Foreign public event '${name}' cannot be produced locally; translate it into a private local event.`);\n if (publicEvent && !foreign && (slice.type !== 'Translate' || slice.direction !== TranslationDirection.Outbound)) error(DiagnosticCodes.PublicEventRequiresOutboundTranslation, `Local public event '${name}' may only be produced by an explicitly outbound Translate slice.`);\n if (slice.type === 'Translate' && (slice.direction ?? TranslationDirection.Inbound) === TranslationDirection.Inbound && (publicEvent || foreign)) error(DiagnosticCodes.InboundTranslationOutput, `Inbound translation must produce private local events, not '${name}'.`);\n } else {\n if (foreign && (slice.type !== 'Translate' || slice.direction !== TranslationDirection.Inbound)) error(DiagnosticCodes.ForeignPublicEventConsumer, `Foreign public event '${name}' may only be consumed by an explicitly inbound Translate slice.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound && (publicEvent || foreign)) error(DiagnosticCodes.OutboundTranslationInput, `Outbound translation must consume private local events, not '${name}'.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Inbound && (!publicEvent || !foreign)) error(DiagnosticCodes.InboundTranslationInput, `Explicitly inbound translation must consume foreign public events, not '${name}'.`);\n }\n}\n\nfunction resolve(application: ApplicationSyntax, resolver: AuthoringProductionResolver, scope: readonly string[], name: string, use: SyntaxNode, output: boolean, context: ParserContext): EventSyntax | ImportSyntax | undefined {\n const resolution = resolver.resolveFromScope(name, scope);\n if (resolution.declaration?.node.kind === 'EventSyntax') return resolution.declaration.node as EventSyntax;\n if (resolution.kind === AuthoringProductionKind.Operation) return undefined;\n if (resolution.kind === AuthoringProductionKind.Ambiguous) {\n context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous event reference '${name}'; qualify it with its owning module, feature and slice.`, use.location);\n return undefined;\n }\n const imports = application.imports.filter(imported => imported.qualifiedName.split('.').at(-1) === name || imported.qualifiedName === name);\n if (imports.length === 1) {\n const imported = imports[0];\n const local = resolver.resolveFromScope(imported.qualifiedName, scope);\n if (local.declaration?.node.kind === 'EventSyntax') return local.declaration.node as EventSyntax;\n if (local.kind === AuthoringProductionKind.Ambiguous) {\n context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous imported event reference '${name}'; qualify its declaration.`, use.location);\n return undefined;\n }\n return imported.visibility === EventVisibility.Public ? imported : undefined;\n }\n if (imports.length > 1) context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous imported event reference '${name}'; use its qualified name.`, use.location);\n else if (((output && use.kind !== 'CaptureAppendSyntax') || use.kind === 'CaptureSourceSettingSyntax') && !context.diagnostics.some(diagnostic => diagnostic.code === DiagnosticCodes.UnknownEvent && diagnostic.location.path === use.location.path && diagnostic.location.line === use.location.line && diagnostic.location.column === use.location.column)) {\n context.warning(DiagnosticCodes.UnknownEvent, `Unknown event '${name}' - declare its contract before classifying its usage.`, use.location);\n }\n return undefined;\n}\n\nfunction usesEventSource(slice: SliceSyntax): boolean {\n return slice.captures.some(capture => capture.source != null && isEventsSource(capture.source));\n}\n\nfunction targetsEvent(slice: SliceSyntax, resolver: AuthoringProductionResolver): boolean {\n const targets = [...slice.projections.map(projection => projection.readModel), ...(dependencySourcesOf(slice).reducers ?? []).map(reducer => reducer.readModel)];\n return targets.some(target => target != null && resolver.declarations.some(declaration => declaration.kind === AuthoringProductionKind.Event && declaration.name === target));\n}\n"],"mappings":"qjBAkBA,SAAgB,yBAAyB,EAAgC,EAA8B,CACnGA,EAA4BC,EAAaC,CAAO,EAChD,IAAMC,EAAW,IAAIC,EAA4BH,CAAW,EAC5D,GAAI,CAACE,EAAS,aAAa,KAAK,GAAeE,EAAY,KAAK,OAAS,gBAAmBA,EAAY,KAAqB,aAAA,UAA0CA,EAAY,KAAqB,QAAU,KAAK,GACnN,CAACJ,EAAY,QAAQ,KAAK,GAAYK,EAAS,aAAA,UAAyCA,EAAS,QAAU,IAAI,GAC/G,CAACH,EAAS,OAAO,MAAM,CAAE,WAAYI,EAAM,WAAa,MAAQ,gBAAgBA,CAAK,GAAK,aAAaA,EAAOJ,CAAQ,CAAC,EAAG,OAC9H,IAAMK,EAAS,IAAIJ,EAA4BH,EAAaE,EAAS,aAAa,OAAO,GAAeE,EAAY,OAAA,OAAsC,CAAC,EAC3J,IAAK,GAAM,CAAE,QAAO,WAAWF,EAAS,OAAQ,cAAcF,EAAaM,EAAOE,EAAON,EAAUK,EAAQN,CAAO,EAClH,IAAK,IAAMQ,KAAQT,EAAY,OAAO,QAAQ,GAAQS,EAAK,OAAO,QAAQ,GAASC,EAAM,MAAM,CAAC,GAAK,CAAC,EAAG,CACrG,IAAMC,EAAW,QAAQX,EAAaO,EAAQ,CAAC,EAAGE,EAAK,MAAOA,EAAM,GAAMR,CAAO,EACjF,GAAIU,GAAU,aAAA,SAAuC,SACrD,IAAMC,EAAOD,EAAS,QAAU,KAAOE,EAAgB,uCAAyCA,EAAgB,2BAChHZ,EAAQ,MAAMW,EAAM,oCAAoCH,EAAK,MAAM,yGAA0GA,EAAK,QAAQ,CAC9L,CACJ,CAEA,SAAS,cAAc,EAAgC,EAAoB,EAA0B,EAAuC,EAAqC,EAA8B,CAC3M,IAAMK,EAAY,IAAIC,EACtBD,EAAU,WAAWR,CAAK,EAC1B,IAAMU,EAAqE,CAAC,EACtEC,EAAmBX,EAAM,OAAS,aAAeA,EAAM,YAAA,WACvDY,EAAa,IAAI,IAAIZ,EAAM,WAAW,IAAI,GAAaa,EAAU,IAAI,CAAC,EAC5E,IAAK,GAAM,CAAE,SAAQ,UAAUL,EAAU,kBAAmB,CAExD,IAAMH,EAAWO,EAAW,IAAIE,CAAM,EAAI,IAAA,GAAY,QAAQpB,EAAaO,EAAQC,EAAOY,EAAQC,EAAM,GAAOpB,CAAO,EAClHU,IAAa,IAAA,KACZM,GAILD,EAAU,KAAK,CAAE,KAAML,EAAU,OAAQ,EAAK,CAAC,EAC/C,YAAYL,EAAOc,EAAQC,EAAM,GAAM,GAAOV,EAAUV,CAAO,GAJ3DA,EAAQ,MAAMY,EAAgB,sCAAuC,IAAIO,EAAO,4GAA6GC,EAAK,QAAQ,EAKlN,CAEA,IAAMf,EAAM,OAAS,aAAeA,EAAM,YAAA,YAA+C,CAACW,EACtF,IAAK,IAAMK,KAAUR,EAAU,aAAcb,EAAQ,MAAMY,EAAgB,sCAAuC,6HAA6HP,EAAM,KAAK,IAAKgB,EAAO,QAAQ,EAElR,IAAK,IAAMC,KAAOT,EAAU,KAAM,CAC9B,IAAMH,EAAW,QAAQX,EAAauB,EAAI,KAAK,OAAS,iBAAmBrB,EAAWK,EAAQC,EAAOe,EAAI,KAAMA,EAAI,KAAMA,EAAI,OAAQtB,CAAO,EACxIU,IAAa,IAAA,KACjBK,EAAU,KAAK,CAAE,KAAML,EAAU,OAAQY,EAAI,MAAO,CAAC,EACrD,YAAYjB,EAAOiB,EAAI,KAAMA,EAAI,KAAMA,EAAI,OAAQA,EAAI,QAASZ,EAAUV,CAAO,EACrF,CAEA,IAAK,IAAMuB,KAAOV,EAAU,UAAW,CACnC,IAAMW,EAAevB,EAAS,aAAa,OAAO,GAAeE,EAAY,OAAA,OAAsC,CAAC,CAAC,IAAI,GAAeA,EAAY,IAAmB,EACvK,IAAK,IAAMO,IAAY,CAAC,GAAGc,EAAc,GAAGzB,EAAY,QAAQ,OAAO,GAAYK,EAAS,aAAA,QAAqC,CAAC,EAC9HW,EAAU,KAAK,CAAE,KAAML,EAAU,OAAQ,EAAM,CAAC,EAChD,YAAYL,EAAOK,EAAS,OAAS,eAAiBA,EAAS,cAAgBA,EAAS,KAAMa,EAAK,GAAO,GAAOb,EAAUV,CAAO,CAE1I,CAKA,GAJIK,EAAM,OAAS,cACfA,EAAM,WAAa,OAASoB,EAAkBpB,CAAK,CAAC,CAAC,KAAK,GAASqB,EAAM,aAAA,QAAqC,GAAKX,EAAU,KAAK,GAAYL,EAAS,KAAK,aAAA,QAAqC,IACjMV,EAAQ,MAAMY,EAAgB,mCAAoC,sKAAuKP,EAAM,QAAQ,EAEvPA,EAAM,YAAA,YAA6C,OACvD,IAAMsB,EAAU,IAAI,IAAIZ,EAAU,OAAO,GAAYL,EAAS,QAAUA,EAAS,KAAK,aAAA,UAAyCA,EAAS,KAAK,QAAU,IAAI,CAAC,CAAC,IAAI,GAAYA,EAAS,IAAI,CAAC,CAAC,CAAC,KACzLiB,IAAY,GAAG3B,EAAQ,MAAMY,EAAgB,yBAA0B,6BAA6BP,EAAM,KAAK,4DAA4DsB,EAAQ,GAAItB,EAAM,QAAQ,EACzM,IAAK,IAAMuB,KAAWvB,EAAM,SAAUL,EAAQ,MAAMY,EAAgB,8BAA+B,+HAAgIgB,EAAQ,QAAQ,CACvP,CAEA,SAAS,YAAY,EAAoB,EAAc,EAAkB,EAAiB,EAAkB,EAAsC,EAA8B,CAC5K,IAAMC,EAAUnB,EAAS,QAAU,KAC7BoB,EAAcpB,EAAS,aAAA,SACvB,OAAS,EAAc,IAAoBV,EAAQ,MAAMW,EAAMoB,EAASX,EAAK,QAAQ,EACvFY,GACIC,GAAWH,GAAa,MAAMlB,EAAgB,2BAA4B,wCAAwCsB,EAAK,gDAAgD,EACvK7B,EAAM,OAAS,aAAeA,EAAM,YAAA,YAA+C,CAACyB,GAAa,MAAMlB,EAAgB,0BAA2B,oFAAoFsB,EAAK,GAAG,EAC9OL,GAAS,MAAMjB,EAAgB,2BAA4B,yBAAyBsB,EAAK,uEAAuE,EAChKJ,GAAe,CAACD,IAAYxB,EAAM,OAAS,aAAeA,EAAM,YAAA,aAA8C,MAAMO,EAAgB,uCAAwC,uBAAuBsB,EAAK,kEAAkE,EAC1Q7B,EAAM,OAAS,cAAgBA,EAAM,WAAA,aAAA,YAAgFyB,GAAeD,IAAU,MAAMjB,EAAgB,yBAA0B,+DAA+DsB,EAAK,GAAG,IAErQL,IAAYxB,EAAM,OAAS,aAAeA,EAAM,YAAA,YAA6C,MAAMO,EAAgB,2BAA4B,yBAAyBsB,EAAK,iEAAiE,EAC9O7B,EAAM,OAAS,aAAeA,EAAM,YAAA,aAAgDyB,GAAeD,IAAU,MAAMjB,EAAgB,yBAA0B,gEAAgEsB,EAAK,GAAG,EACrO7B,EAAM,OAAS,aAAeA,EAAM,YAAA,YAA+C,CAACyB,GAAe,CAACD,IAAU,MAAMjB,EAAgB,wBAAyB,2EAA2EsB,EAAK,GAAG,EAE5P,CAEA,SAAS,QAAQ,EAAgC,EAAuC,EAA0B,EAAc,EAAiB,EAAiB,EAAgE,CAC9N,IAAMC,EAAalC,EAAS,iBAAiBiC,EAAM3B,CAAK,EACxD,GAAI4B,EAAW,aAAa,KAAK,OAAS,cAAe,OAAOA,EAAW,YAAY,KACvF,GAAIA,EAAW,OAAA,YAA4C,OAC3D,GAAIA,EAAW,OAAA,YAA4C,CACvDnC,EAAQ,QAAQY,EAAgB,mBAAoB,8BAA8BsB,EAAK,0DAA2DZ,EAAI,QAAQ,EAC9J,MACJ,CACA,IAAMc,EAAUrC,EAAY,QAAQ,OAAO,GAAYK,EAAS,cAAc,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,IAAM8B,GAAQ9B,EAAS,gBAAkB8B,CAAI,EAC3I,GAAIE,EAAQ,SAAW,EAAG,CACtB,IAAMhC,EAAWgC,EAAQ,GACnBC,EAAQpC,EAAS,iBAAiBG,EAAS,cAAeG,CAAK,EACrE,GAAI8B,EAAM,aAAa,KAAK,OAAS,cAAe,OAAOA,EAAM,YAAY,KAC7E,GAAIA,EAAM,OAAA,YAA4C,CAClDrC,EAAQ,QAAQY,EAAgB,mBAAoB,uCAAuCsB,EAAK,6BAA8BZ,EAAI,QAAQ,EAC1I,MACJ,CACA,OAAOlB,EAAS,aAAA,SAAwCA,EAAW,IAAA,EACvE,CACIgC,EAAQ,OAAS,EAAGpC,EAAQ,QAAQY,EAAgB,mBAAoB,uCAAuCsB,EAAK,4BAA6BZ,EAAI,QAAQ,GACtJU,GAAUV,EAAI,OAAS,uBAA0BA,EAAI,OAAS,+BAAiC,CAACtB,EAAQ,YAAY,KAAK,GAAcsC,EAAW,OAAS1B,EAAgB,cAAgB0B,EAAW,SAAS,OAAShB,EAAI,SAAS,MAAQgB,EAAW,SAAS,OAAShB,EAAI,SAAS,MAAQgB,EAAW,SAAS,SAAWhB,EAAI,SAAS,MAAM,GACxVtB,EAAQ,QAAQY,EAAgB,aAAc,kBAAkBsB,EAAK,wDAAyDZ,EAAI,QAAQ,CAGlJ,CAEA,SAAS,gBAAgB,EAA6B,CAClD,OAAOjB,EAAM,SAAS,KAAK,GAAWuB,EAAQ,QAAU,MAAQW,EAAeX,EAAQ,MAAM,CAAC,CAClG,CAEA,SAAS,aAAa,EAAoB,EAAgD,CAEtF,MAAO,CADU,GAAGvB,EAAM,YAAY,IAAI,GAAcmC,EAAW,SAAS,EAAG,IAAIC,EAAoBpC,CAAK,CAAC,CAAC,UAAY,CAAC,EAAA,CAAG,IAAI,GAAWqC,EAAQ,SAAS,CACjJ,CAAC,CAAC,KAAK,GAAUvB,GAAU,MAAQlB,EAAS,aAAa,KAAK,GAAeE,EAAY,OAAA,SAA0CA,EAAY,OAASgB,CAAM,CAAC,CAChL"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{stringBodyPattern as n,unescapeString as r}from"../Text/StringLiteral.js";import{firstWord as i}from"./LineText.js";import{locationOf as a}from"./SourceLine.js";import{parseDescription as o}from"./DescriptionParser.js";const s=t(`^purpose\\s+([A-Za-z_]\\w*)$`),c=t(`^(basis|condition)\\s+(\\w+)(?:\\s+"(${n})")?$`),l=t(`^(interest|authorization|retention|recipient)\\s+"(${n})"$`),u=t(`^transfer\\s+"(${n})"\\s+safeguard\\s+"(${n})"$`),d=t(`^[A-Za-z_]\\w*$`),f=t(`^erasure\\s+exception\\s+(\\w+)$`),p=[`consent`,`contract`,`legalObligation`,`vitalInterests`,`publicTask`,`legitimateInterests`],m=[`explicitConsent`,`employmentLaw`,`vitalInterests`,`notForProfit`,`madePublic`,`legalClaims`,`substantialPublicInterest`,`healthCare`,`publicHealth`,`research`],h=[`expression`,`legalObligation`,`publicTask`,`publicHealth`,`archiving`,`legalClaims`];function parsePurpose(t,n){let s=purposeName(t,n),g={kind:`PurposeSyntax`,name:s,description:null,basis:null,basisReference:null,interest:null,condition:null,conditionReference:null,authorization:null,subjects:[],retention:null,recipients:[],transfers:[],erasureException:null,location:a(n)},_=/* @__PURE__ */ new Set,v=[],y=[];for(let b=t.peekChild(n.indent);b!==void 0;b=t.peekChild(n.indent)){t.reader.takeSignificant();let n=i(b.content);if(n!==`recipient`&&n!==`transfer`&&_.has(n))t.error(e.DuplicatePurposeField,`Purpose '${s}' already declares '${n}' - at most one is allowed`,a(b)),t.skipBlock(b.indent);else if(_.add(n),n===`description`)g={...g,description:o(t,b,g.description,`Purpose '${s}'`)};else if(n===`basis`||n===`condition`){let i=c.exec(b.content),o=n===`basis`?p:m;if(i===null||!o.includes(i[2]))t.error(e.InvalidPurposeVocabulary,`Invalid ${n} in purpose '${s}' - expected ${o.join(`, `)} with an optional quoted reference`,a(b));else{let e=i[3]===void 0?null:r(i[3]);g=n===`basis`?{...g,basis:i[2],basisReference:e}:{...g,condition:i[2],conditionReference:e}}}else if(n===`interest`||n===`authorization`||n===`retention`||n===`recipient`){let i=l.exec(b.content);i===null?t.error(e.InvalidPurposeDeclaration,`Invalid purpose field '${b.content}' - expected '${n} "<text>"'`,a(b)):n===`recipient`?v.push(r(i[2])):g={...g,[n]:r(i[2])}}else if(n===`subjects`){let n=b.content.slice(8).split(`,`).map(e=>e.trim());n.every(e=>d.test(e))?g={...g,subjects:[...new Set(n)]}:t.error(e.InvalidPurposeDeclaration,`Invalid purpose subjects '${b.content}' - expected comma-separated identifiers`,a(b))}else if(n===`erasure`){let n=f.exec(b.content);n!==null&&h.includes(n[1])?g={...g,erasureException:n[1]}:t.error(e.InvalidPurposeVocabulary,`Invalid erasure exception '${b.content}' - expected 'erasure exception ${h.join(`|`)}'`,a(b))}else if(n===`transfer`){let n=u.exec(b.content);n===null?t.error(e.InvalidPurposeDeclaration,`Invalid transfer '${b.content}' - expected 'transfer "<destination>" safeguard "<text>"'`,a(b)):y.push({kind:`PurposeTransferSyntax`,destination:r(n[1]),safeguard:r(n[2]),location:a(b)})}else t.error(e.InvalidPurposeDeclaration,`Unexpected '${b.content}' in purpose '${s}'`,a(b)),t.skipBlock(b.indent)}return{...g,recipients:v,transfers:y}}function parsePurposeReference(e,t,n){let r=purposeName(e,t);r.length>0&&!n.some(e=>e.name===r)&&n.push({kind:`PurposeReferenceSyntax`,name:r,location:a(t)})}function purposeName(t,n){let r=s.exec(n.content);return r===null?(t.error(e.InvalidPurposeDeclaration,`Invalid purpose declaration '${n.content}' - expected 'purpose <Name>'`,a(n)),``):r[1]}export{parsePurpose,parsePurposeReference};
|
|
2
|
+
//# sourceMappingURL=PurposeParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PurposeParser.js","names":["header","pattern","vocabulary","stringBodyPattern","textField","transfer","identifier","erasure","bases","conditions","exceptions","name","context","line","purpose","locationOf","seen","recipients","transfers","child","keyword","firstWord","DiagnosticCodes","parseDescription","match","values","reference","unescapeString","subjects","value","references"],"sources":["../../../../../../Compiler/Parsing/PurposeParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { PurposeReferenceSyntax, PurposeSyntax, PurposeTransferSyntax } from '../Syntax/Purposes';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { pattern } from '../Text/patterns';\nimport { parseDescription } from './DescriptionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^purpose\\\\s+([A-Za-z_]\\\\w*)$');\nconst vocabulary = pattern(`^(basis|condition)\\\\s+(\\\\w+)(?:\\\\s+\"(${stringBodyPattern})\")?$`);\nconst textField = pattern(`^(interest|authorization|retention|recipient)\\\\s+\"(${stringBodyPattern})\"$`);\nconst transfer = pattern(`^transfer\\\\s+\"(${stringBodyPattern})\"\\\\s+safeguard\\\\s+\"(${stringBodyPattern})\"$`);\nconst identifier = pattern('^[A-Za-z_]\\\\w*$');\nconst erasure = pattern('^erasure\\\\s+exception\\\\s+(\\\\w+)$');\nconst bases = ['consent', 'contract', 'legalObligation', 'vitalInterests', 'publicTask', 'legitimateInterests'];\nconst conditions = ['explicitConsent', 'employmentLaw', 'vitalInterests', 'notForProfit', 'madePublic', 'legalClaims', 'substantialPublicInterest', 'healthCare', 'publicHealth', 'research'];\nconst exceptions = ['expression', 'legalObligation', 'publicTask', 'publicHealth', 'archiving', 'legalClaims'];\n\nexport function parsePurpose(context: ParserContext, line: SourceLine): PurposeSyntax {\n const name = purposeName(context, line);\n let purpose: PurposeSyntax = { kind: 'PurposeSyntax', name, description: null, basis: null, basisReference: null, interest: null, condition: null, conditionReference: null, authorization: null, subjects: [], retention: null, recipients: [], transfers: [], erasureException: null, location: locationOf(line) };\n const seen = new Set<string>();\n const recipients: string[] = [];\n const transfers: PurposeTransferSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword !== 'recipient' && keyword !== 'transfer' && seen.has(keyword)) {\n context.error(DiagnosticCodes.DuplicatePurposeField, `Purpose '${name}' already declares '${keyword}' - at most one is allowed`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n seen.add(keyword);\n if (keyword === 'description') purpose = { ...purpose, description: parseDescription(context, child, purpose.description, `Purpose '${name}'`) };\n else if (keyword === 'basis' || keyword === 'condition') {\n const match = vocabulary.exec(child.content);\n const values = keyword === 'basis' ? bases : conditions;\n if (match === null || !values.includes(match[2])) {\n context.error(DiagnosticCodes.InvalidPurposeVocabulary, `Invalid ${keyword} in purpose '${name}' - expected ${values.join(', ')} with an optional quoted reference`, locationOf(child));\n } else {\n const reference = match[3] === undefined ? null : unescapeString(match[3]);\n purpose = keyword === 'basis' ? { ...purpose, basis: match[2], basisReference: reference } : { ...purpose, condition: match[2], conditionReference: reference };\n }\n } else if (keyword === 'interest' || keyword === 'authorization' || keyword === 'retention' || keyword === 'recipient') {\n const match = textField.exec(child.content);\n if (match === null) context.error(DiagnosticCodes.InvalidPurposeDeclaration, `Invalid purpose field '${child.content}' - expected '${keyword} \"<text>\"'`, locationOf(child));\n else if (keyword === 'recipient') recipients.push(unescapeString(match[2]));\n else purpose = { ...purpose, [keyword]: unescapeString(match[2]) };\n } else if (keyword === 'subjects') {\n const subjects = child.content.slice('subjects'.length).split(',').map(value => value.trim());\n if (subjects.every(value => identifier.test(value))) purpose = { ...purpose, subjects: [...new Set(subjects)] };\n else context.error(DiagnosticCodes.InvalidPurposeDeclaration, `Invalid purpose subjects '${child.content}' - expected comma-separated identifiers`, locationOf(child));\n } else if (keyword === 'erasure') {\n const match = erasure.exec(child.content);\n if (match !== null && exceptions.includes(match[1])) purpose = { ...purpose, erasureException: match[1] };\n else context.error(DiagnosticCodes.InvalidPurposeVocabulary, `Invalid erasure exception '${child.content}' - expected 'erasure exception ${exceptions.join('|')}'`, locationOf(child));\n } else if (keyword === 'transfer') {\n const match = transfer.exec(child.content);\n if (match === null) context.error(DiagnosticCodes.InvalidPurposeDeclaration, `Invalid transfer '${child.content}' - expected 'transfer \"<destination>\" safeguard \"<text>\"'`, locationOf(child));\n else transfers.push({ kind: 'PurposeTransferSyntax', destination: unescapeString(match[1]), safeguard: unescapeString(match[2]), location: locationOf(child) });\n } else {\n context.error(DiagnosticCodes.InvalidPurposeDeclaration, `Unexpected '${child.content}' in purpose '${name}'`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return { ...purpose, recipients, transfers };\n}\n\nexport function parsePurposeReference(context: ParserContext, line: SourceLine, references: PurposeReferenceSyntax[]): void {\n const name = purposeName(context, line);\n if (name.length > 0 && !references.some(reference => reference.name === name)) references.push({ kind: 'PurposeReferenceSyntax', name, location: locationOf(line) });\n}\n\nfunction purposeName(context: ParserContext, line: SourceLine): string {\n const match = header.exec(line.content);\n if (match !== null) return match[1];\n context.error(DiagnosticCodes.InvalidPurposeDeclaration, `Invalid purpose declaration '${line.content}' - expected 'purpose <Name>'`, locationOf(line));\n return '';\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";function validatePurposes(t,n){let r=/* @__PURE__ */ new Set;for(let i of t.purposes??[])r.has(i.name)&&n.error(e.DuplicatePurposeDeclaration,`Duplicate purpose '${i.name}' - a purpose is declared once`,i.location),r.add(i.name);for(let r of t.purposes??[])r.interest!==null&&r.basis!==`legitimateInterests`?n.warning(e.PurposeInterestMismatch,`Purpose '${r.name}' declares an interest without basis legitimateInterests`,r.location):r.basis===`legitimateInterests`&&!r.interest?.trim()&&n.warning(e.PurposeInterestMismatch,`Purpose '${r.name}' with basis legitimateInterests has no interest statement (Art. 13(1)(d))`,r.location);let i=[],collect=e=>{i.push(...e.purposes??[],...e.slices.flatMap(e=>e.purposes??[])),e.features.forEach(collect)};for(let e of t.modules)i.push(...e.purposes??[]),e.features.forEach(collect);for(let t of i)r.has(t.name)||n.warning(e.UnknownPurpose,`Unknown purpose '${t.name}' - declare it with 'purpose ${t.name}'`,t.location)}export{validatePurposes};
|
|
2
|
+
//# sourceMappingURL=PurposeValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PurposeValidator.js","names":["known","purpose","application","context","DiagnosticCodes","references","feature","slice","module","reference"],"sources":["../../../../../../Compiler/Parsing/PurposeValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { PurposeReferenceSyntax } from '../Syntax/Purposes';\nimport { ApplicationSyntax, FeatureSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\n\nexport function validatePurposes(application: ApplicationSyntax, context: ParserContext): void {\n const known = new Set<string>();\n for (const purpose of application.purposes ?? []) {\n if (known.has(purpose.name)) context.error(DiagnosticCodes.DuplicatePurposeDeclaration, `Duplicate purpose '${purpose.name}' - a purpose is declared once`, purpose.location);\n known.add(purpose.name);\n }\n for (const purpose of application.purposes ?? []) {\n if (purpose.interest !== null && purpose.basis !== 'legitimateInterests') context.warning(DiagnosticCodes.PurposeInterestMismatch, `Purpose '${purpose.name}' declares an interest without basis legitimateInterests`, purpose.location);\n else if (purpose.basis === 'legitimateInterests' && !purpose.interest?.trim()) context.warning(DiagnosticCodes.PurposeInterestMismatch, `Purpose '${purpose.name}' with basis legitimateInterests has no interest statement (Art. 13(1)(d))`, purpose.location);\n }\n const references: PurposeReferenceSyntax[] = [];\n const collect = (feature: FeatureSyntax): void => {\n references.push(...feature.purposes ?? [], ...feature.slices.flatMap(slice => slice.purposes ?? []));\n feature.features.forEach(collect);\n };\n for (const module of application.modules) {\n references.push(...module.purposes ?? []);\n module.features.forEach(collect);\n }\n for (const reference of references) {\n if (!known.has(reference.name)) context.warning(DiagnosticCodes.UnknownPurpose, `Unknown purpose '${reference.name}' - declare it with 'purpose ${reference.name}'`, reference.location);\n }\n}\n"],"mappings":"yHAQA,SAAgB,iBAAiB,EAAgC,EAA8B,CAC3F,IAAMA,kBAAQ,IAAI,IAClB,IAAK,IAAMC,KAAWC,EAAY,UAAY,CAAC,EACvCF,EAAM,IAAIC,EAAQ,IAAI,GAAGE,EAAQ,MAAMC,EAAgB,4BAA6B,sBAAsBH,EAAQ,KAAK,gCAAiCA,EAAQ,QAAQ,EAC5KD,EAAM,IAAIC,EAAQ,IAAI,EAE1B,IAAK,IAAMA,KAAWC,EAAY,UAAY,CAAC,EACvCD,EAAQ,WAAa,MAAQA,EAAQ,QAAU,sBAAuBE,EAAQ,QAAQC,EAAgB,wBAAyB,YAAYH,EAAQ,KAAK,0DAA2DA,EAAQ,QAAQ,EAC9NA,EAAQ,QAAU,uBAAyB,CAACA,EAAQ,UAAU,KAAK,GAAGE,EAAQ,QAAQC,EAAgB,wBAAyB,YAAYH,EAAQ,KAAK,4EAA6EA,EAAQ,QAAQ,EAElQ,IAAMI,EAAuC,CAAC,EACxC,QAAW,GAAiC,CAC9CA,EAAW,KAAK,GAAGC,EAAQ,UAAY,CAAC,EAAG,GAAGA,EAAQ,OAAO,QAAQ,GAASC,EAAM,UAAY,CAAC,CAAC,CAAC,EACnGD,EAAQ,SAAS,QAAQ,OAAO,CACpC,EACA,IAAK,IAAME,KAAUN,EAAY,QAC7BG,EAAW,KAAK,GAAGG,EAAO,UAAY,CAAC,CAAC,EACxCA,EAAO,SAAS,QAAQ,OAAO,EAEnC,IAAK,IAAMC,KAAaJ,EACfL,EAAM,IAAIS,EAAU,IAAI,GAAGN,EAAQ,QAAQC,EAAgB,eAAgB,oBAAoBK,EAAU,KAAK,+BAA+BA,EAAU,KAAK,GAAIA,EAAU,QAAQ,CAE/L"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{parseMappingSource as n}from"./ExpressionParser.js";import{firstWord as r}from"./LineText.js";import{locationOf as i}from"./SourceLine.js";import{parseTypeRef as a,reportLegacyOptionalSuffix as o}from"./PropertyLineParser.js";import{combineAuthorize as s,parseAuthorize as c}from"./AuthorizeParser.js";import{parseDescription as l}from"./DescriptionParser.js";const u=t(`^query\\s+([A-Za-z_]\\w*)\\s*=>\\s*(observable\\s+)?([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)$`),d=t(`^([a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+from\\s+(.+))?$`),f=t(`^scoped\\s+to\\s+([a-z_]\\w*)$`),p=/* @__PURE__ */ new Set([`performer`]);function parseQuery(t,n){let d=u.exec(n.content);if(d===null)return t.error(e.InvalidQueryDeclaration,`Invalid query declaration '${n.content}' - expected 'query <Name> => [observable] <ReadModel>'`,i(n)),t.skipBlock(n.indent),{kind:`QuerySyntax`,name:r(n.content),returnType:a(``,i(n)),by:null,filters:[],description:null,isObservable:!1,scope:null,authorize:null,location:i(n)};let f=d[1],m=a(d[3],{...i(n),column:n.indent+1+d[0].length-d[3].length});(d[2]!==void 0||m.name!==`observable`||!m.isOptional||m.isCollection)&&o(t,m,n);let h=null,g=[],_=null,v=null,y=null;for(let a=t.peekChild(n.indent);a!==void 0;a=t.peekChild(n.indent)){t.reader.takeSignificant();let n=r(a.content);if(n===`description`)_=l(t,a,_,`Query '${f}'`);else if(n===`by`){let n=parseParameter(t,a,`by`);n!==void 0&&(h!==null&&t.error(e.InvalidQueryParameter,`Query '${f}' already declares 'by' - a query can have at most one key parameter`,i(a)),h=n)}else if(n===`filter`){let e=parseParameter(t,a,`filter`);e!==void 0&&g.push(e)}else n===`authorize`?y=s(y,c(t,a)):n===`scoped`?v=parseScope(t,a,v,f)??v:p.has(n)?t.skipOpaqueBlock(a.indent):(t.error(e.UnknownQueryDirective,`Unexpected '${a.content}' in query body - expected description, by, filter, authorize, scoped or performer`,i(a)),t.skipBlock(a.indent))}return{kind:`QuerySyntax`,name:f,returnType:m,by:h,filters:g,description:_,isObservable:d[2]!==void 0,scope:v,authorize:y,location:i(n)}}function parseParameter(t,r,s){let c=d.exec(r.content.substring(s.length).trim());if(c===null){t.error(e.InvalidQueryParameter,`Invalid '${s}' parameter '${r.content}' - expected '${s} <name> <Type> [from <source>]'`,i(r));return}let l=r.content.indexOf(c[1],s.length),u=a(c[2],{...i(r),column:r.indent+1+r.content.indexOf(c[2],l+c[1].length)});return o(t,u,r),{kind:`QueryParameterSyntax`,name:c[1],type:u,source:c[3]===void 0?null:n(c[3],i(r),t.valueContext),location:i(r)}}function parseScope(t,n,r,a){let o=f.exec(n.content);if(o===null)t.error(e.InvalidScopeDeclaration,`Invalid scope declaration '${n.content}' - expected 'scoped to <scope>'`,i(n));else if(r!==null)t.error(e.DuplicateScope,`Query '${a}' already declares a scope - results are narrowed one way`,i(n));else return o[1]}export{parseQuery};
|
|
2
|
+
//# sourceMappingURL=QueryParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryParser.js","names":["header","pattern","parameterPattern","scopePattern","opaqueDirectives","match","line","context","DiagnosticCodes","locationOf","firstWord","parseTypeRef","name","returnType","reportLegacyOptionalSuffix","by","filters","description","scope","authorize","child","keyword","parseDescription","parameter","filter","combineAuthorize","parseAuthorize","nameOffset","type","parseMappingSource","existing","queryName"],"sources":["../../../../../../Compiler/Parsing/QueryParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { AuthorizeSyntax } from '../Syntax/Authorization';\nimport { QueryParameterSyntax, QuerySyntax } from '../Syntax/Queries';\nimport { pattern } from '../Text/patterns';\nimport { combineAuthorize, parseAuthorize } from './AuthorizeParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseMappingSource } from './ExpressionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseTypeRef, reportLegacyOptionalSuffix } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^query\\\\s+([A-Za-z_]\\\\w*)\\\\s*=>\\\\s*(observable\\\\s+)?([\\\\w.]+(?:\\\\[\\\\])?(?:\\\\?|\\\\s+optional)?)$');\nconst parameterPattern = pattern('^([a-z_]\\\\w*)\\\\s+([\\\\w.]+(?:\\\\[\\\\])?(?:\\\\?|\\\\s+optional)?)(?:\\\\s+from\\\\s+(.+))?$');\nconst scopePattern = pattern('^scoped\\\\s+to\\\\s+([a-z_]\\\\w*)$');\n\n// Query directives this compiler does not model. They are skipped whole.\nconst opaqueDirectives = new Set(['performer']);\n\nexport function parseQuery(context: ParserContext, line: SourceLine): QuerySyntax {\n const match = header.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidQueryDeclaration, `Invalid query declaration '${line.content}' - expected 'query <Name> => [observable] <ReadModel>'`, locationOf(line));\n context.skipBlock(line.indent);\n return {\n kind: 'QuerySyntax', name: firstWord(line.content), returnType: parseTypeRef('', locationOf(line)), by: null, filters: [],\n description: null, isObservable: false, scope: null, authorize: null, location: locationOf(line),\n };\n }\n const name = match[1];\n const returnType = parseTypeRef(match[3], { ...locationOf(line), column: line.indent + 1 + match[0].length - match[3].length });\n // This one '?' has no equivalent keyword spelling: 'observable optional' is a live query\n // returning the type named 'optional'. It is neither deprecated nor a migration occurrence.\n if (!(match[2] === undefined && returnType.name === 'observable' && returnType.isOptional && !returnType.isCollection)) {\n reportLegacyOptionalSuffix(context, returnType, line);\n }\n let by: QueryParameterSyntax | null = null;\n const filters: QueryParameterSyntax[] = [];\n let description: string | null = null;\n let scope: string | null = null;\n let authorize: AuthorizeSyntax | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Query '${name}'`);\n } else if (keyword === 'by') {\n const parameter = parseParameter(context, child, 'by');\n if (parameter !== undefined) {\n if (by !== null) {\n context.error(DiagnosticCodes.InvalidQueryParameter, `Query '${name}' already declares 'by' - a query can have at most one key parameter`, locationOf(child));\n }\n by = parameter;\n }\n } else if (keyword === 'filter') {\n const filter = parseParameter(context, child, 'filter');\n if (filter !== undefined) {\n filters.push(filter);\n }\n } else if (keyword === 'authorize') {\n authorize = combineAuthorize(authorize, parseAuthorize(context, child));\n } else if (keyword === 'scoped') {\n scope = parseScope(context, child, scope, name) ?? scope;\n } else if (opaqueDirectives.has(keyword)) {\n context.skipOpaqueBlock(child.indent);\n } else {\n context.error(DiagnosticCodes.UnknownQueryDirective, `Unexpected '${child.content}' in query body - expected description, by, filter, authorize, scoped or performer`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return {\n kind: 'QuerySyntax',\n name,\n returnType,\n by,\n filters,\n description,\n isObservable: match[2] !== undefined,\n scope,\n authorize,\n location: locationOf(line),\n };\n}\n\nfunction parseParameter(context: ParserContext, line: SourceLine, keyword: string): QueryParameterSyntax | undefined {\n const match = parameterPattern.exec(line.content.substring(keyword.length).trim());\n if (match === null) {\n context.error(DiagnosticCodes.InvalidQueryParameter, `Invalid '${keyword}' parameter '${line.content}' - expected '${keyword} <name> <Type> [from <source>]'`, locationOf(line));\n return undefined;\n }\n const nameOffset = line.content.indexOf(match[1], keyword.length);\n const type = parseTypeRef(match[2], { ...locationOf(line), column: line.indent + 1 + line.content.indexOf(match[2], nameOffset + match[1].length) });\n reportLegacyOptionalSuffix(context, type, line);\n return { kind: 'QueryParameterSyntax', name: match[1], type, source: match[3] === undefined ? null : parseMappingSource(match[3], locationOf(line), context.valueContext), location: locationOf(line) };\n}\n\nfunction parseScope(context: ParserContext, line: SourceLine, existing: string | null, queryName: string): string | undefined {\n const match = scopePattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidScopeDeclaration, `Invalid scope declaration '${line.content}' - expected 'scoped to <scope>'`, locationOf(line));\n return undefined;\n }\n if (existing !== null) {\n context.error(DiagnosticCodes.DuplicateScope, `Query '${queryName}' already declares a scope - results are narrowed one way`, locationOf(line));\n return undefined;\n }\n return match[1];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{dotNetWhitespace as t}from"../Text/patterns.js";import{stringBodyPattern as n,unescapeString as r}from"../Text/StringLiteral.js";import{locationOf as i}from"./SourceLine.js";const a=RegExp(`^runs${t}+as${t}+system(?:${t}+role${t}+"${n}"(?:${t}+and${t}+role${t}+"${n}")*)?$`,`u`),o=RegExp(`"(${n})"`,`gu`),s=RegExp(`^runs${t}+as\\b`,`u`),isReactionIdentityLine=e=>s.test(e.content);function parseReactionIdentity(t,n,s){if(s)return t.error(e.InvalidReactionIdentity,`A reaction may declare 'runs as' only once.`,i(n)),t.skipBlock(n.indent),null;if(!a.test(n.content)||t.peekChild(n.indent)!==void 0)return t.error(e.InvalidReactionIdentity,`Expected one reaction-level line: 'runs as system [role "<Role>" and role "<Role>"]'.`,i(n)),t.skipBlock(n.indent),null;let c=[...n.content.matchAll(o)].map(e=>r(e[1]));return c.some(e=>e.length===0)||new Set(c).size!==c.length?(t.error(e.InvalidReactionIdentity,`Reaction identity roles must be nonempty and distinct quoted literals.`,i(n)),null):{kind:`ReactionIdentitySyntax`,syntaxKind:`system`,roles:c,location:i(n)}}function misplacedReactionIdentity(t,n){t.error(e.InvalidReactionIdentity,`'runs as' belongs directly in a reaction body, not under a trigger or invocation.`,i(n)),t.skipBlock(n.indent)}export{isReactionIdentityLine,misplacedReactionIdentity,parseReactionIdentity};
|
|
2
|
+
//# sourceMappingURL=ReactionIdentityParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactionIdentityParser.js","names":["identityPattern","dotNetWhitespace","stringBodyPattern","rolePattern","identityPrefix","line","repeated","context","DiagnosticCodes","locationOf","roles","unescapeString","match","role"],"sources":["../../../../../../Compiler/Parsing/ReactionIdentityParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { ReactionIdentitySyntax } from '../Syntax/ReactionIdentitySyntax';\nimport { dotNetWhitespace } from '../Text/patterns';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst identityPattern = new RegExp(`^runs${dotNetWhitespace}+as${dotNetWhitespace}+system(?:${dotNetWhitespace}+role${dotNetWhitespace}+\"${stringBodyPattern}\"(?:${dotNetWhitespace}+and${dotNetWhitespace}+role${dotNetWhitespace}+\"${stringBodyPattern}\")*)?$`, 'u');\nconst rolePattern = new RegExp(`\"(${stringBodyPattern})\"`, 'gu');\n\nconst identityPrefix = new RegExp(`^runs${dotNetWhitespace}+as\\\\b`, 'u');\nexport const isReactionIdentityLine = (line: SourceLine): boolean => identityPrefix.test(line.content);\n\nexport function parseReactionIdentity(context: ParserContext, line: SourceLine, repeated: boolean): ReactionIdentitySyntax | null {\n if (repeated) {\n context.error(DiagnosticCodes.InvalidReactionIdentity, \"A reaction may declare 'runs as' only once.\", locationOf(line));\n context.skipBlock(line.indent);\n return null;\n }\n if (!identityPattern.test(line.content) || context.peekChild(line.indent) !== undefined) {\n context.error(DiagnosticCodes.InvalidReactionIdentity, 'Expected one reaction-level line: \\'runs as system [role \"<Role>\" and role \"<Role>\"]\\'.', locationOf(line));\n context.skipBlock(line.indent);\n return null;\n }\n const roles = [...line.content.matchAll(rolePattern)].map(match => unescapeString(match[1]));\n if (roles.some(role => role.length === 0) || new Set(roles).size !== roles.length) {\n context.error(DiagnosticCodes.InvalidReactionIdentity, 'Reaction identity roles must be nonempty and distinct quoted literals.', locationOf(line));\n return null;\n }\n return { kind: 'ReactionIdentitySyntax', syntaxKind: 'system', roles, location: locationOf(line) };\n}\n\nexport function misplacedReactionIdentity(context: ParserContext, line: SourceLine): void {\n context.error(DiagnosticCodes.InvalidReactionIdentity, \"'runs as' belongs directly in a reaction body, not under a trigger or invocation.\", locationOf(line));\n context.skipBlock(line.indent);\n}\n"],"mappings":"8SAUA,MAAMA,EAAsB,OAAO,QAAQC,EAAiB,KAAKA,EAAiB,YAAYA,EAAiB,OAAOA,EAAiB,IAAIC,EAAkB,MAAMD,EAAiB,MAAMA,EAAiB,OAAOA,EAAiB,IAAIC,EAAkB,QAAS,GAAG,EAC/PC,EAAkB,OAAO,KAAKD,EAAkB,IAAK,IAAI,EAEzDE,EAAqB,OAAO,QAAQH,EAAiB,QAAS,GAAG,EAC1D,uBAA0B,GAA8BG,EAAe,KAAKC,EAAK,OAAO,EAErG,SAAgB,sBAAsB,EAAwB,EAAkB,EAAkD,CAC9H,GAAIC,EAGA,OAFAC,EAAQ,MAAMC,EAAgB,wBAAyB,8CAA+CC,EAAWJ,CAAI,CAAC,EACtHE,EAAQ,UAAUF,EAAK,MAAM,EACtB,KAEX,GAAI,CAACL,EAAgB,KAAKK,EAAK,OAAO,GAAKE,EAAQ,UAAUF,EAAK,MAAM,IAAM,IAAA,GAG1E,OAFAE,EAAQ,MAAMC,EAAgB,wBAAyB,wFAA2FC,EAAWJ,CAAI,CAAC,EAClKE,EAAQ,UAAUF,EAAK,MAAM,EACtB,KAEX,IAAMK,EAAQ,CAAC,GAAGL,EAAK,QAAQ,SAASF,CAAW,CAAC,CAAC,CAAC,IAAI,GAASQ,EAAeC,EAAM,EAAE,CAAC,EAK3F,OAJIF,EAAM,KAAK,GAAQG,EAAK,SAAW,CAAC,GAAK,IAAI,IAAIH,CAAK,CAAC,CAAC,OAASA,EAAM,QACvEH,EAAQ,MAAMC,EAAgB,wBAAyB,yEAA0EC,EAAWJ,CAAI,CAAC,EAC1I,MAEJ,CAAE,KAAM,yBAA0B,WAAY,SAAU,QAAO,SAAUI,EAAWJ,CAAI,CAAE,CACrG,CAEA,SAAgB,0BAA0B,EAAwB,EAAwB,CACtFE,EAAQ,MAAMC,EAAgB,wBAAyB,oFAAqFC,EAAWJ,CAAI,CAAC,EAC5JE,EAAQ,UAAUF,EAAK,MAAM,CACjC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{nativePattern as t,pattern as n}from"../Text/patterns.js";import{dependencySources as r}from"../Syntax/DependencySources.js";import{parseModeledMappingSource as i}from"./ExpressionParser.js";import{firstWord as a}from"./LineText.js";import{locationOf as o}from"./SourceLine.js";import{parseDescription as s}from"./DescriptionParser.js";import{parseDocumentation as c}from"./DocumentationParser.js";import{parseCondition as l}from"./ConditionParser.js";import{ParserContext as u}from"./ParserContext.js";import{collectInputUses as d}from"./InputUses.js";import{isReactionIdentityLine as f,misplacedReactionIdentity as p,parseReactionIdentity as m}from"./ReactionIdentityParser.js";import{captureReads as h}from"./DependencySourceParser.js";import{parseProduces as g}from"./ProducesParser.js";import{parseTriggerData as _}from"./TriggerDataParser.js";const v=n(`^reaction\\s+([A-Za-z_]\\w*)$`),y=n(`^when\\s+([A-Za-z_]\\w*)$`),b=n(`^every\\s+(\\d+)\\s+(seconds?|minutes?|hours?|days?)$`),x=n(`^at\\s+(\\d{2}:\\d{2})(?:\\s+on\\s+(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)|day\\s+(\\d{1,2})))?$`),S=/* @__PURE__ */ new Set([`when`,`every`,`at`]),C=n(`^invokes\\s+([A-Z]\\w*)$`),w=t(`^(@?[\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),T=t(`^on\\s+refused\\b(?=$|\\s+by\\b)`),E=t(`^on\\s+refused(?:\\s+by\\s+(validation|constraint|authorization)(?:\\s+([A-Za-z_]\\w*(?:\\.\\w+)*))?)?$`),D=n(`^reads\\s+[A-Z]\\w*\\s+optional(?:\\s|$)`);function parseReaction(t,n){let r=v.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidReactionDeclaration,`Invalid reaction declaration '${n.content}' - expected 'reaction <Name>'`,o(n));let i=null,u=null,d=null,f=null,p=!1,h=[],g=/* @__PURE__ */ new Set,_=!1;for(let v=t.peekChild(n.indent);v!==void 0;v=t.peekChild(n.indent)){t.reader.takeSignificant();let n=a(v.content);if(n===`description`){i=s(t,v,i,`Reaction '${r}'`);continue}if(n===`documentation`){u=c(t,v,u,`Reaction '${r}'`);continue}if(n===`runs`){f=m(t,v,p)??f,p=!0;continue}if(n===`where`){d=l(t,v.content.substring(5).trim(),o(v));continue}if(T.test(v.content)){t.error(e.InvalidRefusalBranch,`A refusal branch belongs inside 'invokes <Command>'.`,o(v)),t.skipBlock(v.indent),_=!0;continue}if(!S.has(n)){t.error(e.InvalidReactionTrigger,`Expected a trigger in reaction body, got '${v.content}' - a reaction is set off by 'when <Name>', 'every <n> <unit>' or 'at <HH:mm>'`,o(v)),t.skipBlock(v.indent),_=!0;continue}let y=parseTriggerSource(t,v);if(y===void 0){_=!0;continue}let b=sourceKey(y);g.has(b)?(t.error(e.DuplicateReactionTrigger,`Reaction '${r}' already declares '${v.content}' - a second says nothing the first did not`,o(v)),t.skipBlock(v.indent)):(g.add(b),h.push(parseTrigger(t,v,y)))}return h.length===0&&!_&&t.error(e.ReactionWithoutTrigger,`Reaction '${r}' must declare at least one trigger - nothing sets it off`,o(n)),{kind:`ReactionSyntax`,name:r,description:i,documentation:u,runsAs:f,where:d,triggers:h,location:o(n)}}function parseTrigger(t,n,c){let l=null,m=[],v=[],y=[],b=[],x=!1;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=a(r.content);if(n===`runs`&&f(r))p(t,r);else if(n===`description`)l=s(t,r,l,`Trigger '${r.content}'`);else if(n===`produces`){let e=g(t,r);e!==void 0&&m.push(e)}else if(n===`invokes`){let n=C.exec(r.content);if(n===null)t.error(e.InvalidInvokesDeclaration,`Invalid invokes declaration '${r.content}' - expected 'invokes <Command>'`,o(r)),t.skipBlock(r.indent);else{let a=new u(t.reader.fork(),t.path,t.languages);a.scope=t.scope,a.sourceOptions=t.sourceOptions,d(a,r),t.inputUses.push(...a.inputUses);let s=[],c=[];for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent)){if(t.reader.takeSignificant(),f(n)){p(t,n);continue}if(T.test(n.content)){let e=parseRefusal(t,n);e!==void 0&&c.push(e);continue}let r=w.exec(n.content);r===null?t.error(e.InvalidPropertyMapping,`Invalid property mapping '${n.content}' - expected '<property> = <source>'`,o(n)):s.push({kind:`PropertyMappingSyntax`,property:r[1].replaceAll(`@`,``),source:i(r[2],o(n),t.valueContext),location:o(n)})}v.push({kind:`InvokesSyntax`,command:n[1],mappings:s,onRefused:c,location:o(r)})}}else if(T.test(r.content))t.error(e.InvalidRefusalBranch,`A refusal branch belongs inside 'invokes <Command>'.`,o(r)),t.skipBlock(r.indent);else if(n===`reads`||n===`file`||r.content===`csharp`||r.content.startsWith("```")){x||=n===`file`||r.content===`csharp`||r.content.startsWith("```");let i=h(r);i!==void 0&&y.push(i),D.test(r.content)&&t.error(e.OptionalReadsNotSupported,`Optional reads are not yet supported (see #308).`,o(r)),r.content.startsWith("```")&&t.skipFencedBody(),t.skipOpaqueBlock(r.indent)}else{let e=t.triggerData.length;_(t,r);for(let n of t.triggerData.slice(e))b.push({kind:`TriggerDataSyntax`,name:n.name,type:n.type,location:n.location})}}let S={kind:`ReactionTriggerSyntax`,source:c,description:l,produces:m,invokes:v,location:o(n)};return r.set(S,{reads:y,data:b,implementation:x}),S}function parseRefusal(t,n){let r=E.exec(n.content);if(r===null||r[2]!==void 0&&r[1]!==`constraint`){t.error(e.InvalidRefusalBranch,`Expected 'on refused [by validation | by constraint [<Name>] | by authorization]'.`,o(n)),t.skipBlock(n.indent);return}let i=[],s=!1,c=!1;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent))if(t.reader.takeSignificant(),f(r))p(t,r),c=!0;else if(r.content===`acknowledge`)(s||i.length>0||t.peekChild(r.indent)!==void 0)&&(t.error(e.InvalidRefusalBranchBody,`A refusal branch contains 'acknowledge' alone or one or more 'produces' blocks.`,o(r)),c=!0),s=!0,t.skipBlock(r.indent);else if(a(r.content)===`produces`){s&&(t.error(e.InvalidRefusalBranchBody,`A refusal branch cannot combine 'acknowledge' and 'produces'.`,o(r)),c=!0);let n=g(t,r);n===void 0?c=!0:i.push(n)}else t.error(e.InvalidRefusalBranchBody,`Expected 'acknowledge' or 'produces <Event>' in a refusal branch.`,o(r)),t.skipBlock(r.indent),c=!0;return!s&&i.length===0&&!c&&t.error(e.InvalidRefusalBranchBody,`A refusal branch must acknowledge or produce an event.`,o(n)),{kind:`InvocationRefusalSyntax`,selector:r[1]??`any`,constraint:r[2]??null,acknowledge:s,produces:i,location:o(n)}}function sourceKey(e){switch(e.kind){case`NamedTriggerSourceSyntax`:return JSON.stringify([e.kind,e.name]);case`IntervalTriggerSourceSyntax`:return JSON.stringify([e.kind,e.amount,e.unit]);case`ScheduleTriggerSourceSyntax`:return JSON.stringify([e.kind,e.time,e.dayOfWeek,e.dayOfMonth])}}function parseTriggerSource(t,n){let r=o(n);switch(a(n.content)){case`when`:{let i=y.exec(n.content);if(i===null){t.error(e.InvalidReactionTrigger,`Invalid trigger '${n.content}' - expected 'when <Name>'`,r),t.skipBlock(n.indent);return}return{kind:`NamedTriggerSourceSyntax`,name:i[1],location:r}}case`every`:{let i=b.exec(n.content),a=i===null?NaN:Number(i[1]);if(i===null||!Number.isInteger(a)||a<1||a>2147483647){t.error(e.InvalidIntervalTrigger,`Invalid interval '${n.content}' - expected 'every <n> <seconds|minutes|hours|days>'`,r),t.skipBlock(n.indent);return}return{kind:`IntervalTriggerSourceSyntax`,amount:a,unit:unitOf(i[2]),location:r}}default:return parseSchedule(t,n)}}function parseSchedule(t,n){let r=o(n),i=x.exec(n.content),a=i===null?void 0:timeOf(i[1]);if(i===null||a===void 0)t.error(e.InvalidScheduleTrigger,`Invalid schedule '${n.content}' - expected 'at <HH:mm>', optionally followed by 'on <Weekday>' or 'on day <n>'`,r),t.skipBlock(n.indent);else{if(i[3]!==void 0){let o=Number(i[3]);if(o<1||o>31){t.error(e.InvalidScheduleTrigger,`Invalid day of month '${o}' in '${n.content}' - a day of the month is between 1 and 31`,r),t.skipBlock(n.indent);return}return{kind:`ScheduleTriggerSourceSyntax`,time:a,dayOfWeek:null,dayOfMonth:o,location:r}}return{kind:`ScheduleTriggerSourceSyntax`,time:a,dayOfWeek:i[2]??null,dayOfMonth:null,location:r}}}function timeOf(e){let[t,n]=e.split(`:`).map(Number);if(t>=0&&t<=23&&n>=0&&n<=59)return`${e}:00.0000000`}function unitOf(e){switch(e.replace(/s+$/,``)){case`second`:return`Seconds`;case`minute`:return`Minutes`;case`hour`:return`Hours`;default:return`Days`}}export{parseReaction,parseTriggerSource};
|
|
2
|
+
//# sourceMappingURL=ReactionParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactionParser.js","names":["parseMappingSource","header","pattern","whenPattern","everyPattern","atPattern","clauseKeywords","invokesPattern","mappingPattern","nativePattern","refusalPrefix","refusalHeader","optionalReads","name","line","context","DiagnosticCodes","locationOf","description","documentation","where","runsAs","identityDeclared","triggers","sources","reported","child","keyword","firstWord","parseDescription","parseDocumentation","parseReactionIdentity","parseCondition","source","key","produces","invokes","reads","data","implementation","isReactionIdentityLine","misplacedReactionIdentity","produced","parseProduces","match","uses","ParserContext","collectInputUses","mappings","onRefused","value","refusal","mapped","parseModeledMappingSource","read","captureReads","start","parseTriggerData","property","syntax","dependencySources","acknowledge","location","amount","time","day","hours","minutes","text"],"sources":["../../../../../../Compiler/Parsing/ReactionParser.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { ConditionSyntax } from '../Syntax/Conditions';\nimport { PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { InvocationRefusalSyntax } from '../Syntax/InvocationRefusalSyntax';\nimport { parseCondition } from './ConditionParser';\nimport { parseModeledMappingSource as parseMappingSource } from './ExpressionParser';\nimport { DayOfWeek, IntervalUnit, InvokesSyntax, ProducesSyntax, ReactionSyntax, ReactionTriggerSyntax, TriggerSourceSyntax } from '../Syntax/Reactions';\nimport { nativePattern, pattern } from '../Text/patterns';\nimport { ReactionIdentitySyntax } from '../Syntax/ReactionIdentitySyntax';\nimport { isReactionIdentityLine, misplacedReactionIdentity, parseReactionIdentity } from './ReactionIdentityParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { collectInputUses } from './InputUses';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseTriggerData } from './TriggerDataParser';\nimport { dependencySources, ReadsSyntax, TriggerDataSyntax } from '../Syntax/DependencySources';\nimport { captureReads } from './DependencySourceParser';\nimport { parseProduces } from './ProducesParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^reaction\\\\s+([A-Za-z_]\\\\w*)$');\nconst whenPattern = pattern('^when\\\\s+([A-Za-z_]\\\\w*)$');\nconst everyPattern = pattern('^every\\\\s+(\\\\d+)\\\\s+(seconds?|minutes?|hours?|days?)$');\nconst atPattern = pattern('^at\\\\s+(\\\\d{2}:\\\\d{2})(?:\\\\s+on\\\\s+(?:(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday)|day\\\\s+(\\\\d{1,2})))?$');\nconst clauseKeywords = new Set(['when', 'every', 'at']);\nconst invokesPattern = pattern('^invokes\\\\s+([A-Z]\\\\w*)$');\nconst mappingPattern = nativePattern('^(@?[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst refusalPrefix = nativePattern('^on\\\\s+refused\\\\b(?=$|\\\\s+by\\\\b)');\nconst refusalHeader = nativePattern('^on\\\\s+refused(?:\\\\s+by\\\\s+(validation|constraint|authorization)(?:\\\\s+([A-Za-z_]\\\\w*(?:\\\\.\\\\w+)*))?)?$');\nconst optionalReads = pattern('^reads\\\\s+[A-Z]\\\\w*\\\\s+optional(?:\\\\s|$)');\n\nexport function parseReaction(context: ParserContext, line: SourceLine): ReactionSyntax {\n const name = header.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidReactionDeclaration, `Invalid reaction declaration '${line.content}' - expected 'reaction <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n let documentation: string | null = null;\n let where: ConditionSyntax | null = null;\n let runsAs: ReactionIdentitySyntax | null = null;\n let identityDeclared = false;\n const triggers: ReactionTriggerSyntax[] = [];\n const sources = new Set<string>();\n // A reaction whose only trigger is misspelled has no trigger, but saying so as well turns one mistake\n // into two diagnostics.\n let reported = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Reaction '${name}'`);\n continue;\n }\n if (keyword === 'documentation') {\n documentation = parseDocumentation(context, child, documentation, `Reaction '${name}'`);\n continue;\n }\n if (keyword === 'runs') {\n runsAs = parseReactionIdentity(context, child, identityDeclared) ?? runsAs;\n identityDeclared = true;\n continue;\n }\n if (keyword === 'where') {\n where = parseCondition(context, child.content.substring('where'.length).trim(), locationOf(child));\n continue;\n }\n if (refusalPrefix.test(child.content)) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"A refusal branch belongs inside 'invokes <Command>'.\", locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n continue;\n }\n if (!clauseKeywords.has(keyword)) {\n context.error(DiagnosticCodes.InvalidReactionTrigger, `Expected a trigger in reaction body, got '${child.content}' - a reaction is set off by 'when <Name>', 'every <n> <unit>' or 'at <HH:mm>'`, locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n continue;\n }\n const source = parseTriggerSource(context, child);\n if (source === undefined) {\n reported = true;\n continue;\n }\n const key = sourceKey(source);\n if (sources.has(key)) {\n context.error(DiagnosticCodes.DuplicateReactionTrigger, `Reaction '${name}' already declares '${child.content}' - a second says nothing the first did not`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n sources.add(key);\n triggers.push(parseTrigger(context, child, source));\n }\n if (triggers.length === 0 && !reported) {\n context.error(DiagnosticCodes.ReactionWithoutTrigger, `Reaction '${name}' must declare at least one trigger - nothing sets it off`, locationOf(line));\n }\n return { kind: 'ReactionSyntax', name, description, documentation, runsAs, where, triggers, location: locationOf(line) };\n}\n\n// What a trigger does - the events it produces and the commands it invokes - is read by name; its reads,\n// values and code are not modeled. The C# compiler remains the authority on whether what is skipped is valid.\nfunction parseTrigger(context: ParserContext, line: SourceLine, source: TriggerSourceSyntax): ReactionTriggerSyntax {\n let description: string | null = null;\n const produces: ProducesSyntax[] = [];\n const invokes: InvokesSyntax[] = [];\n const reads: ReadsSyntax[] = [];\n const data: TriggerDataSyntax[] = [];\n let implementation = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'runs' && isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n } else if (keyword === 'description') {\n description = parseDescription(context, child, description, `Trigger '${child.content}'`);\n } else if (keyword === 'produces') {\n const produced = parseProduces(context, child);\n if (produced !== undefined) {\n produces.push(produced);\n }\n } else if (keyword === 'invokes') {\n const match = invokesPattern.exec(child.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidInvokesDeclaration, `Invalid invokes declaration '${child.content}' - expected 'invokes <Command>'`, locationOf(child));\n context.skipBlock(child.indent);\n } else {\n const uses = new ParserContext(context.reader.fork(), context.path, context.languages);\n uses.scope = context.scope;\n uses.sourceOptions = context.sourceOptions;\n collectInputUses(uses, child);\n context.inputUses.push(...uses.inputUses);\n const mappings: PropertyMappingSyntax[] = [];\n const onRefused: InvocationRefusalSyntax[] = [];\n for (let value = context.peekChild(child.indent); value !== undefined; value = context.peekChild(child.indent)) {\n context.reader.takeSignificant();\n if (isReactionIdentityLine(value)) {\n misplacedReactionIdentity(context, value);\n continue;\n }\n if (refusalPrefix.test(value.content)) {\n const refusal = parseRefusal(context, value);\n if (refusal !== undefined) onRefused.push(refusal);\n continue;\n }\n const mapped = mappingPattern.exec(value.content);\n if (mapped !== null) mappings.push({ kind: 'PropertyMappingSyntax', property: mapped[1].replaceAll('@', ''), source: parseMappingSource(mapped[2], locationOf(value), context.valueContext), location: locationOf(value) });\n else context.error(DiagnosticCodes.InvalidPropertyMapping, `Invalid property mapping '${value.content}' - expected '<property> = <source>'`, locationOf(value));\n }\n invokes.push({ kind: 'InvokesSyntax', command: match[1], mappings, onRefused, location: locationOf(child) });\n }\n } else if (refusalPrefix.test(child.content)) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"A refusal branch belongs inside 'invokes <Command>'.\", locationOf(child));\n context.skipBlock(child.indent);\n } else if (keyword === 'reads' || keyword === 'file' || child.content === 'csharp' || child.content.startsWith('```')) {\n implementation ||= keyword === 'file' || child.content === 'csharp' || child.content.startsWith('```');\n const read = captureReads(child);\n if (read !== undefined) reads.push(read);\n if (optionalReads.test(child.content)) {\n context.error(DiagnosticCodes.OptionalReadsNotSupported, 'Optional reads are not yet supported (see #308).', locationOf(child));\n }\n if (child.content.startsWith('```')) {\n context.skipFencedBody();\n }\n context.skipOpaqueBlock(child.indent);\n } else {\n const start = context.triggerData.length;\n parseTriggerData(context, child);\n for (const property of context.triggerData.slice(start)) data.push({ kind: 'TriggerDataSyntax', name: property.name, type: property.type, location: property.location });\n }\n }\n const syntax: ReactionTriggerSyntax = { kind: 'ReactionTriggerSyntax', source, description, produces, invokes, location: locationOf(line) };\n dependencySources.set(syntax, { reads, data, implementation });\n return syntax;\n}\n\nfunction parseRefusal(context: ParserContext, line: SourceLine): InvocationRefusalSyntax | undefined {\n const match = refusalHeader.exec(line.content);\n if (match === null || (match[2] !== undefined && match[1] !== 'constraint')) {\n context.error(DiagnosticCodes.InvalidRefusalBranch, \"Expected 'on refused [by validation | by constraint [<Name>] | by authorization]'.\", locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n }\n const produces: ProducesSyntax[] = [];\n let acknowledge = false;\n let reported = false;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n reported = true;\n } else if (child.content === 'acknowledge') {\n if (acknowledge || produces.length > 0 || context.peekChild(child.indent) !== undefined) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"A refusal branch contains 'acknowledge' alone or one or more 'produces' blocks.\", locationOf(child));\n reported = true;\n }\n acknowledge = true;\n context.skipBlock(child.indent);\n } else if (firstWord(child.content) === 'produces') {\n if (acknowledge) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"A refusal branch cannot combine 'acknowledge' and 'produces'.\", locationOf(child));\n reported = true;\n }\n const produced = parseProduces(context, child);\n if (produced !== undefined) produces.push(produced);\n else reported = true;\n } else {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, \"Expected 'acknowledge' or 'produces <Event>' in a refusal branch.\", locationOf(child));\n context.skipBlock(child.indent);\n reported = true;\n }\n }\n if (!acknowledge && produces.length === 0 && !reported) {\n context.error(DiagnosticCodes.InvalidRefusalBranchBody, 'A refusal branch must acknowledge or produce an event.', locationOf(line));\n }\n return { kind: 'InvocationRefusalSyntax', selector: match[1] ?? 'any', constraint: match[2] ?? null, acknowledge, produces, location: locationOf(line) };\n}\n\nfunction sourceKey(source: TriggerSourceSyntax): string {\n switch (source.kind) {\n case 'NamedTriggerSourceSyntax': return JSON.stringify([source.kind, source.name]);\n case 'IntervalTriggerSourceSyntax': return JSON.stringify([source.kind, source.amount, source.unit]);\n case 'ScheduleTriggerSourceSyntax': return JSON.stringify([source.kind, source.time, source.dayOfWeek, source.dayOfMonth]);\n }\n}\n\n// Reads a 'when', 'every' or 'at' clause - the port of the C# TriggerParser.ParseSource. The caller only\n// hands it a line starting with one of the three, so anything that is not 'when' or 'every' is 'at'.\nexport function parseTriggerSource(context: ParserContext, line: SourceLine): TriggerSourceSyntax | undefined {\n const location = locationOf(line);\n switch (firstWord(line.content)) {\n case 'when': {\n const match = whenPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidReactionTrigger, `Invalid trigger '${line.content}' - expected 'when <Name>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'NamedTriggerSourceSyntax', name: match[1], location };\n }\n case 'every': {\n const match = everyPattern.exec(line.content);\n const amount = match === null ? NaN : Number(match[1]);\n if (match === null || !Number.isInteger(amount) || amount < 1 || amount > 2147483647) {\n context.error(DiagnosticCodes.InvalidIntervalTrigger, `Invalid interval '${line.content}' - expected 'every <n> <seconds|minutes|hours|days>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'IntervalTriggerSourceSyntax', amount, unit: unitOf(match[2]), location };\n }\n default:\n return parseSchedule(context, line);\n }\n}\n\nfunction parseSchedule(context: ParserContext, line: SourceLine): TriggerSourceSyntax | undefined {\n const location = locationOf(line);\n const match = atPattern.exec(line.content);\n const time = match === null ? undefined : timeOf(match[1]);\n if (match === null || time === undefined) {\n context.error(DiagnosticCodes.InvalidScheduleTrigger, `Invalid schedule '${line.content}' - expected 'at <HH:mm>', optionally followed by 'on <Weekday>' or 'on day <n>'`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n if (match[3] !== undefined) {\n const day = Number(match[3]);\n if (day < 1 || day > 31) {\n context.error(DiagnosticCodes.InvalidScheduleTrigger, `Invalid day of month '${day}' in '${line.content}' - a day of the month is between 1 and 31`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n return { kind: 'ScheduleTriggerSourceSyntax', time, dayOfWeek: null, dayOfMonth: day, location };\n }\n return { kind: 'ScheduleTriggerSourceSyntax', time, dayOfWeek: (match[2] as DayOfWeek | undefined) ?? null, dayOfMonth: null, location };\n}\n\n// 'HH:mm' as SyntaxJson writes a TimeOnly, or undefined when it is not a time of day.\nfunction timeOf(text: string): string | undefined {\n const [hours, minutes] = text.split(':').map(Number);\n if (!(hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59)) {\n return undefined;\n }\n return `${text}:00.0000000`;\n}\n\nfunction unitOf(text: string): IntervalUnit {\n switch (text.replace(/s+$/, '')) {\n case 'second':\n return 'Seconds';\n case 'minute':\n return 'Minutes';\n case 'hour':\n return 'Hours';\n default:\n return 'Days';\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{dependencySourcesOf as t}from"../Syntax/DependencySources.js";import{expandSpecificationExamples as n}from"./SpecificationCommandExamples.js";import{RefusalDeclarations as r}from"./RefusalDeclarations.js";import{RefusalValueWalker as i}from"./RefusalValueWalker.js";function authorizationGatedSlices(e){let t=/* @__PURE__ */ new Set,collect=(e,n)=>{let r=n||e.authorize!==null;r&&e.slices.forEach(e=>t.add(e)),e.features.forEach(e=>collect(e,r))};return e.modules.forEach(e=>e.features.forEach(t=>collect(t,e.authorize!==null))),t}function validateReactionRefusals(a,o){let s=new r(n(a));new i(s,o).visitApplication(s.application);let c=authorizationGatedSlices(s.application);for(let{slice:n}of s.slices){let constraintOf=e=>s.resolve(e,n,e=>e.constraints),sameConstraint=(e,t)=>e===t||constraintOf(e)!==null&&constraintOf(e)?.node===constraintOf(t)?.node,covers=(e,t)=>e.selector===`any`&&[`any`,`validation`,`constraint`].includes(t.selector)||e.selector===t.selector&&(e.selector!==`constraint`||e.constraint===null||t.constraint!==null&&sameConstraint(e.constraint,t.constraint));for(let r of n.reactions)r.runsAs!=null&&!r.triggers.some(e=>e.invokes.length>0||t(e).implementation)&&o.warning(e.UnusedReactionIdentity,`Reaction '${r.name}' declares an identity but has no invocations or implementation body.`,r.runsAs.location);for(let{reaction:t,invocation:r}of n.reactions.flatMap(e=>e.triggers.flatMap(e=>e.invokes).map(t=>({reaction:e,invocation:t})))){let i=s.resolve(r.command,n,e=>e.commands),a=i!==null&&(i.node.authorize!==null||c.has(i.slice)),l=r.onRefused?.find(e=>e.selector===`authorization`);t.runsAs==null&&a&&l===void 0&&o.warning(e.GatedInvocationWithoutIdentity,`Command '${r.command}' is authorization-gated, but reaction '${t.name}' has no declared identity. Declare 'runs as system role "<Role>"'.`,r.location);let u=[];for(let n of r.onRefused??[]){if(u.some(e=>covers(e,n))&&o.warning(e.UnreachableRefusalBranch,`This refusal selector is covered by an earlier branch; the first matching branch wins.`,n.location),u.push(n),n===l&&t.runsAs==null&&a&&o.warning(e.AuthorizationRefusalWithoutIdentity,`Command '${r.command}' is authorization-gated, but this invocation has no declared identity. This authorization refusal branch always fires in the reference runner because there is no caller. Declare 'runs as system role "<Role>"'; Arc runs commands as the system only for a reactor carrying [ExecuteCommandsAsSystem].`,n.location),n.constraint===null)continue;let c=constraintOf(n.constraint);if(c===null){o.error(e.UnknownRefusalConstraint,`Unknown or ambiguous refusal constraint '${n.constraint}'.`,n.location);continue}if(i===null||i.node.handler!==null)continue;let d=[c.node,...c.node.additionalRules];if(d.some(e=>e.kind===`FileConstraintSyntax`))continue;let f=d.map(e=>e.kind===`FileConstraintSyntax`?null:s.event(e.event,c.slice)),p=i.node.produces.map(e=>s.event(e.event,i.slice));f.every(e=>e!==null)&&p.every(e=>e!==null)&&!f.some(e=>p.includes(e))&&o.warning(e.UnreachableRefusalBranch,`Constraint '${n.constraint}' targets none of the events produced by '${r.command}'.`,n.location)}}}}export{validateReactionRefusals};
|
|
2
|
+
//# sourceMappingURL=ReactionRefusalValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactionRefusalValidator.js","names":["slices","gated","inherited","feature","slice","child","application","module","declarations","RefusalDeclarations","expandSpecificationExamples","RefusalValueWalker","context","gatedSlices","name","owner","left","right","previous","branch","reaction","trigger","dependencySourcesOf","DiagnosticCodes","invoked","invocation","authorizationGated","authorizationBranch","earlier","constraint","rules","rule","targets","productions","produced","target"],"sources":["../../../../../../Compiler/Parsing/ReactionRefusalValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { InvocationRefusalSyntax } from '../Syntax/InvocationRefusalSyntax';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { ApplicationSyntax, FeatureSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\nimport { RefusalDeclarations } from './RefusalDeclarations';\nimport { RefusalValueWalker } from './RefusalValueWalker';\nimport { expandSpecificationExamples } from './SpecificationCommandExamples';\n\nfunction authorizationGatedSlices(application: ApplicationSyntax): Set<SliceSyntax> {\n const slices = new Set<SliceSyntax>();\n const collect = (feature: FeatureSyntax, inherited: boolean): void => {\n const gated = inherited || feature.authorize !== null;\n if (gated) feature.slices.forEach(slice => slices.add(slice));\n feature.features.forEach(child => collect(child, gated));\n };\n application.modules.forEach(module => module.features.forEach(feature => collect(feature, module.authorize !== null)));\n return slices;\n}\n\nexport function validateReactionRefusals(application: ApplicationSyntax, context: ParserContext): void {\n const declarations = new RefusalDeclarations(expandSpecificationExamples(application));\n new RefusalValueWalker(declarations, context).visitApplication(declarations.application);\n const gatedSlices = authorizationGatedSlices(declarations.application);\n for (const { slice } of declarations.slices) {\n const constraintOf = (name: string) => declarations.resolve(name, slice, owner => owner.constraints);\n const sameConstraint = (left: string, right: string) => left === right || constraintOf(left) !== null && constraintOf(left)?.node === constraintOf(right)?.node;\n const covers = (previous: InvocationRefusalSyntax, branch: InvocationRefusalSyntax) =>\n previous.selector === 'any' && ['any', 'validation', 'constraint'].includes(branch.selector) ||\n previous.selector === branch.selector && (previous.selector !== 'constraint' || previous.constraint === null || branch.constraint !== null && sameConstraint(previous.constraint, branch.constraint));\n for (const reaction of slice.reactions) {\n if (reaction.runsAs != null && !reaction.triggers.some(trigger => trigger.invokes.length > 0 || dependencySourcesOf(trigger).implementation)) {\n context.warning(DiagnosticCodes.UnusedReactionIdentity, `Reaction '${reaction.name}' declares an identity but has no invocations or implementation body.`, reaction.runsAs.location);\n }\n }\n for (const { reaction, invocation } of slice.reactions.flatMap(reaction => reaction.triggers.flatMap(trigger => trigger.invokes).map(invocation => ({ reaction, invocation })))) {\n const invoked = declarations.resolve(invocation.command, slice, owner => owner.commands);\n const authorizationGated = invoked !== null && (invoked.node.authorize !== null || gatedSlices.has(invoked.slice));\n const authorizationBranch = invocation.onRefused?.find(branch => branch.selector === 'authorization');\n if (reaction.runsAs == null && authorizationGated && authorizationBranch === undefined) {\n context.warning(DiagnosticCodes.GatedInvocationWithoutIdentity, `Command '${invocation.command}' is authorization-gated, but reaction '${reaction.name}' has no declared identity. Declare 'runs as system role \"<Role>\"'.`, invocation.location);\n }\n const earlier: InvocationRefusalSyntax[] = [];\n for (const branch of invocation.onRefused ?? []) {\n if (earlier.some(previous => covers(previous, branch))) context.warning(DiagnosticCodes.UnreachableRefusalBranch, 'This refusal selector is covered by an earlier branch; the first matching branch wins.', branch.location);\n earlier.push(branch);\n if (branch === authorizationBranch && reaction.runsAs == null && authorizationGated) {\n context.warning(DiagnosticCodes.AuthorizationRefusalWithoutIdentity,\n `Command '${invocation.command}' is authorization-gated, but this invocation has no declared identity. This authorization refusal branch always fires in the reference runner because there is no caller. Declare 'runs as system role \"<Role>\"'; Arc runs commands as the system only for a reactor carrying [ExecuteCommandsAsSystem].`,\n branch.location);\n }\n if (branch.constraint === null) continue;\n const constraint = constraintOf(branch.constraint);\n if (constraint === null) {\n context.error(DiagnosticCodes.UnknownRefusalConstraint, `Unknown or ambiguous refusal constraint '${branch.constraint}'.`, branch.location);\n continue;\n }\n if (invoked === null || invoked.node.handler !== null) continue;\n const rules = [constraint.node, ...constraint.node.additionalRules];\n if (rules.some(rule => rule.kind === 'FileConstraintSyntax')) continue;\n const targets = rules.map(rule => rule.kind === 'FileConstraintSyntax' ? null : declarations.event(rule.event, constraint.slice));\n const productions = invoked.node.produces.map(produced => declarations.event(produced.event, invoked.slice));\n if (targets.every(target => target !== null) && productions.every(produced => produced !== null) && !targets.some(target => productions.includes(target)))\n context.warning(DiagnosticCodes.UnreachableRefusalBranch, `Constraint '${branch.constraint}' targets none of the events produced by '${invocation.command}'.`, branch.location);\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{canonicalExactText as e}from"../Syntax/ExactMathFacts.js";function redeliveryValue(e,t,n){let r=t===null||t.isCollection?void 0:n.concepts.get(t.name),i=r!==void 0&&r.type===`Enum`?r:null,member=e=>i!==null&&e.startsWith(`${i.name}.`)?e.substring(i.name.length+1):e;if(t?.isCollection&&e.kind===`ListExpressionSyntax`&&n.compatible({...t,isCollection:!1},{...t,isCollection:!1})===!0){let r=e.items.map(e=>redeliveryValue(e,{...t,isCollection:!1,isOptional:!1},n));return r.some(e=>e===void 0)?void 0:{canonical:`[${r.map(canonical).join(`,`)}]`}}let a=t===null?void 0:n.types.get(t.name)?.properties;if(t!==null&&!t.isCollection&&e.kind===`ObjectExpressionSyntax`&&a!==void 0){let t=e.members.map(e=>{let t=n.property(a,e.name);return{name:e.name,value:t===null?void 0:redeliveryValue(e.value,t.type,n)}});return t.some(e=>e.value===void 0)?void 0:{canonical:`{${t.sort((e,t)=>e.name<t.name?-1:+(e.name>t.name)).map(e=>`${JSON.stringify(e.name)}:${canonical(e.value)}`).join(`,`)}}`}}if(e.kind===`LiteralExpressionSyntax`)return i!==null&&typeof e.value==`string`?member(e.value):e.value;if(e.kind===`PathExpressionSyntax`&&i!==null)return member(e.path)}function canonical(t){return typeof t==`object`&&t?`canonical`in t?t.canonical:e(t):JSON.stringify(t)}function sameRedeliveryValue(e,t,n,r){let i=redeliveryValue(e,n,r),a=redeliveryValue(t,n,r);return i===void 0||a===void 0?null:canonical(i)===canonical(a)}export{redeliveryValue,sameRedeliveryValue};
|
|
2
|
+
//# sourceMappingURL=RedeliveryValues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RedeliveryValues.js","names":["concept","type","declarations","enumeration","text","expression","items","item","properties","members","property","left","right","value","canonicalExactText","first","second"],"sources":["../../../../../../Compiler/Parsing/RedeliveryValues.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { TypeRefSyntax } from '../Syntax/Declarations';\nimport { canonicalExactText } from '../Syntax/ExactMathFacts';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { RefusalDeclarations } from './RefusalDeclarations';\nimport { RedeliveryValue } from './RedeliveryValue';\n\n// Undefined means undecidable, not the authored null literal. Mirror TryValue in the C#\n// specification consistency validator, including nominal enums and structured fixture values.\nexport function redeliveryValue(expression: ExpressionSyntax, type: TypeRefSyntax | null, declarations: RefusalDeclarations): RedeliveryValue | undefined {\n const concept = type === null || type.isCollection ? undefined : declarations.concepts.get(type.name);\n const enumeration = concept !== undefined && concept.type === 'Enum' ? concept : null;\n const member = (text: string) => enumeration !== null && text.startsWith(`${enumeration.name}.`) ? text.substring(enumeration.name.length + 1) : text;\n if (type?.isCollection && expression.kind === 'ListExpressionSyntax' && declarations.compatible({ ...type, isCollection: false }, { ...type, isCollection: false }) === true) {\n const items = expression.items.map(item => redeliveryValue(item, { ...type, isCollection: false, isOptional: false }, declarations));\n return items.some(item => item === undefined) ? undefined : { canonical: `[${items.map(canonical).join(',')}]` };\n }\n const properties = type === null ? undefined : declarations.types.get(type.name)?.properties;\n if (type !== null && !type.isCollection && expression.kind === 'ObjectExpressionSyntax' && properties !== undefined) {\n const members = expression.members.map(item => {\n const property = declarations.property(properties, item.name);\n return { name: item.name, value: property === null ? undefined : redeliveryValue(item.value, property.type, declarations) };\n });\n return members.some(item => item.value === undefined) ? undefined : { canonical: `{${members.sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0).map(item => `${JSON.stringify(item.name)}:${canonical(item.value)}`).join(',')}}` };\n }\n if (expression.kind === 'LiteralExpressionSyntax') return enumeration !== null && typeof expression.value === 'string' ? member(expression.value) : expression.value;\n if (expression.kind === 'PathExpressionSyntax' && enumeration !== null) return member(expression.path);\n return undefined;\n}\n\nfunction canonical(value: RedeliveryValue | undefined): string {\n if (typeof value === 'object' && value !== null) return 'canonical' in value ? value.canonical : canonicalExactText(value);\n return JSON.stringify(value)!;\n}\n\nexport function sameRedeliveryValue(left: ExpressionSyntax, right: ExpressionSyntax, type: TypeRefSyntax | null, declarations: RefusalDeclarations): boolean | null {\n const first = redeliveryValue(left, type, declarations);\n const second = redeliveryValue(right, type, declarations);\n if (first === undefined || second === undefined) return null;\n return canonical(first) === canonical(second);\n}\n"],"mappings":"sHAWA,SAAgB,gBAAgB,EAA8B,EAA4B,EAAgE,CACtJ,IAAMA,EAAUC,IAAS,MAAQA,EAAK,aAAe,IAAA,GAAYC,EAAa,SAAS,IAAID,EAAK,IAAI,EAC9FE,EAAcH,IAAY,IAAA,IAAaA,EAAQ,OAAS,OAASA,EAAU,KAC3E,OAAU,GAAiBG,IAAgB,MAAQC,EAAK,WAAW,GAAGD,EAAY,KAAK,EAAE,EAAIC,EAAK,UAAUD,EAAY,KAAK,OAAS,CAAC,EAAIC,EACjJ,GAAIH,GAAM,cAAgBI,EAAW,OAAS,wBAA0BH,EAAa,WAAW,CAAE,GAAGD,EAAM,aAAc,EAAM,EAAG,CAAE,GAAGA,EAAM,aAAc,EAAM,CAAC,IAAM,GAAM,CAC1K,IAAMK,EAAQD,EAAW,MAAM,IAAI,GAAQ,gBAAgBE,EAAM,CAAE,GAAGN,EAAM,aAAc,GAAO,WAAY,EAAM,EAAGC,CAAY,CAAC,EACnI,OAAOI,EAAM,KAAK,GAAQC,IAAS,IAAA,EAAS,EAAI,IAAA,GAAY,CAAE,UAAW,IAAID,EAAM,IAAI,SAAS,CAAC,CAAC,KAAK,GAAG,EAAE,EAAG,CACnH,CACA,IAAME,EAAaP,IAAS,KAAO,IAAA,GAAYC,EAAa,MAAM,IAAID,EAAK,IAAI,CAAC,EAAE,WAClF,GAAIA,IAAS,MAAQ,CAACA,EAAK,cAAgBI,EAAW,OAAS,0BAA4BG,IAAe,IAAA,GAAW,CACjH,IAAMC,EAAUJ,EAAW,QAAQ,IAAI,GAAQ,CAC3C,IAAMK,EAAWR,EAAa,SAASM,EAAYD,EAAK,IAAI,EAC5D,MAAO,CAAE,KAAMA,EAAK,KAAM,MAAOG,IAAa,KAAO,IAAA,GAAY,gBAAgBH,EAAK,MAAOG,EAAS,KAAMR,CAAY,CAAE,CAC9H,CAAC,EACD,OAAOO,EAAQ,KAAK,GAAQF,EAAK,QAAU,IAAA,EAAS,EAAI,IAAA,GAAY,CAAE,UAAW,IAAIE,EAAQ,MAAM,EAAM,IAAUE,EAAK,KAAOC,EAAM,KAAO,GAAK,IAAK,KAAOA,EAAM,KAAY,CAAC,CAAC,IAAI,GAAQ,GAAG,KAAK,UAAUL,EAAK,IAAI,EAAE,GAAG,UAAUA,EAAK,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,EAAG,CACvQ,CACA,GAAIF,EAAW,OAAS,0BAA2B,OAAOF,IAAgB,MAAQ,OAAOE,EAAW,OAAU,SAAW,OAAOA,EAAW,KAAK,EAAIA,EAAW,MAC/J,GAAIA,EAAW,OAAS,wBAA0BF,IAAgB,KAAM,OAAO,OAAOE,EAAW,IAAI,CAEzG,CAEA,SAAS,UAAU,EAA4C,CAE3D,OADI,OAAOQ,GAAU,UAAYA,EAAuB,cAAeA,EAAQA,EAAM,UAAYC,EAAmBD,CAAK,EAClH,KAAK,UAAUA,CAAK,CAC/B,CAEA,SAAgB,oBAAoB,EAAwB,EAAyB,EAA4B,EAAmD,CAChK,IAAME,EAAQ,gBAAgBJ,EAAMV,EAAMC,CAAY,EAChDc,EAAS,gBAAgBJ,EAAOX,EAAMC,CAAY,EAExD,OADIa,IAAU,IAAA,IAAaC,IAAW,IAAA,GAAkB,KACjD,UAAUD,CAAK,IAAM,UAAUC,CAAM,CAChD"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{eventDeclarations as e}from"../Syntax/EventDeclarations.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{uniqueByName as n}from"./ResponseValidator.js";const r=/* @__PURE__ */ new Set([`String`,`Uuid`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`]);var RefusalDeclarations=class{application;slices;types;concepts;events;knownTypes;constructor(i){this.application=i,this.slices=new t(i).slices,this.types=n(i.types),this.concepts=n(i.concepts),this.knownTypes=/* @__PURE__ */ new Set([...r,...i.types.map(e=>e.name),...i.concepts.map(e=>e.name)]),this.events=new Map(this.slices.map(({slice:t})=>{let n=/* @__PURE__ */ new Map;for(let r of e(t))(!n.has(r.name)||n.get(r.name).generation<r.generation)&&n.set(r.name,r);return[t,[...n.values()]]}))}resolve(e,t,n){let r=this.slices.flatMap(({slice:e,scope:t})=>n(e).map(n=>({node:n,slice:e,scope:t}))),i=this.slices.find(e=>e.slice===t)?.scope??[],candidates=e=>{let t=e.split(`.`),n=r.filter(e=>e.node.name===t.at(-1)),a=t.slice(0,-1);if(a.length>0)return n.filter(e=>a.length<=e.scope.length&&a.every((t,n)=>e.scope[e.scope.length-a.length+n]===t));for(let e=i.length;e>=0;e--){let t=n.filter(t=>e<=t.scope.length&&i.slice(0,e).every((e,n)=>t.scope[n]===e));if(t.length>0)return t}return[]},a=candidates(e);if(a.length===0){let t=this.application.imports.filter(t=>t.qualifiedName.split(`.`).at(-1)===e);t.length===1&&(a=candidates(t[0].qualifiedName))}return a.length===1?a[0]:null}event(e,t){return this.resolve(e,t,e=>this.events.get(e)??[])?.node??null}property(e,t){let n=t.split(`.`);for(let[t,i]of n.entries()){let a=e?.filter(e=>e.name===i)??[];if(a.length!==1)return null;let o=a[0];if(t===n.length-1)return o;if(r.has(o.type.name)||this.concepts.has(o.type.name)&&!this.application.types.some(e=>e.name===o.type.name))return null;e=this.types.get(o.type.name)?.properties??null}return null}compatible(e,t){return this.knownTypes.has(e.name)&&this.knownTypes.has(t.name)?e.name===t.name&&e.isCollection===t.isCollection&&(!e.isOptional||t.isOptional):null}};export{RefusalDeclarations};
|
|
2
|
+
//# sourceMappingURL=RefusalDeclarations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RefusalDeclarations.js","names":["primitives","application","AuthoringProductionResolver","uniqueByName","type","concept","latest","event","eventDeclarations","slice","entries","select","scope","entry","from","parts","reference","named","qualifiers","index","part","depth","visible","matches","name","imports","imported","path","properties","property","source","target"],"sources":["../../../../../../Compiler/Parsing/RefusalDeclarations.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax, TypeRefSyntax } from '../Syntax/Declarations';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { uniqueByName } from './ResponseValidator';\n\nconst primitives = new Set(['String', 'Uuid', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime']);\n\n// The scoped declaration facts used by the C# refusal and redelivery consistency validators.\nexport class RefusalDeclarations {\n readonly slices: AuthoringProductionResolver['slices'];\n readonly types;\n readonly concepts;\n private readonly events;\n private readonly knownTypes: Set<string>;\n\n constructor(readonly application: ApplicationSyntax) {\n this.slices = new AuthoringProductionResolver(application).slices;\n this.types = uniqueByName(application.types);\n this.concepts = uniqueByName(application.concepts);\n this.knownTypes = new Set([...primitives, ...application.types.map(type => type.name), ...application.concepts.map(concept => concept.name)]);\n this.events = new Map(this.slices.map(({ slice }) => {\n const latest = new Map<string, ReturnType<typeof eventDeclarations>[number]>();\n for (const event of eventDeclarations(slice)) {\n if (!latest.has(event.name) || latest.get(event.name)!.generation < event.generation) latest.set(event.name, event);\n }\n return [slice, [...latest.values()]];\n }));\n }\n\n resolve<T extends { readonly name: string }>(name: string, from: SliceSyntax, select: (slice: SliceSyntax) => readonly T[]): { node: T; slice: SliceSyntax } | null {\n const entries = this.slices.flatMap(({ slice, scope }) => select(slice).map(node => ({ node, slice, scope })));\n const scope = this.slices.find(entry => entry.slice === from)?.scope ?? [];\n const candidates = (reference: string) => {\n const parts = reference.split('.');\n const named = entries.filter(entry => entry.node.name === parts.at(-1));\n const qualifiers = parts.slice(0, -1);\n if (qualifiers.length > 0) return named.filter(entry => qualifiers.length <= entry.scope.length && qualifiers.every((part, index) => entry.scope[entry.scope.length - qualifiers.length + index] === part));\n for (let depth = scope.length; depth >= 0; depth--) {\n const visible = named.filter(entry => depth <= entry.scope.length && scope.slice(0, depth).every((part, index) => entry.scope[index] === part));\n if (visible.length > 0) return visible;\n }\n return [];\n };\n let matches = candidates(name);\n if (matches.length === 0) {\n const imports = this.application.imports.filter(imported => imported.qualifiedName.split('.').at(-1) === name);\n if (imports.length === 1) matches = candidates(imports[0].qualifiedName);\n }\n return matches.length === 1 ? matches[0] : null;\n }\n\n event(name: string, from: SliceSyntax) {\n return this.resolve(name, from, slice => this.events.get(slice) ?? [])?.node ?? null;\n }\n\n property(properties: readonly PropertySyntax[] | null, path: string): PropertySyntax | null {\n const parts = path.split('.');\n for (const [index, part] of parts.entries()) {\n const matches: readonly PropertySyntax[] = properties?.filter(property => property.name === part) ?? [];\n if (matches.length !== 1) return null;\n const property = matches[0];\n if (index === parts.length - 1) return property;\n if (primitives.has(property.type.name) || this.concepts.has(property.type.name) && !this.application.types.some(type => type.name === property.type.name)) return null;\n properties = this.types.get(property.type.name)?.properties ?? null;\n }\n return null;\n }\n\n compatible(source: TypeRefSyntax, target: TypeRefSyntax): boolean | null {\n return this.knownTypes.has(source.name) && this.knownTypes.has(target.name)\n ? source.name === target.name && source.isCollection === target.isCollection && (!source.isOptional || target.isOptional) : null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{ScreenplaySyntaxWalker as t}from"../Syntax/ScreenplaySyntaxWalker.js";var RefusalValueWalker=class extends t{declarations;context;slice=null;branch=null;properties=null;target=null;mapping=!1;constructor(e,t){super(),this.declarations=e,this.context=t}visitSlice(e){this.slice=e,super.visitSlice(e),this.slice=null}visitInvocationRefusal(e){this.branch=e,super.visitInvocationRefusal(e),this.branch=null}visitProduces(e){this.branch===null||this.slice===null?super.visitProduces(e):(this.visitNode(e),e.for!==null&&this.visitExpression(e.for),e.when!=null&&this.visitCondition(e.when),e.tags.forEach(e=>this.visitTag(e)),this.properties=this.declarations.event(e.event,this.slice)?.properties??null,e.mappings.forEach(e=>this.visitPropertyMapping(e)),this.properties=null)}visitPropertyMapping(e){this.mapping=this.branch!==null,this.target=this.declarations.property(this.properties,e.property)?.type??null,super.visitPropertyMapping(e),this.target=null,this.mapping=!1}visitObjectMember(e){let t=this.target;this.target=this.declarations.property(t===null?null:this.declarations.types.get(t.name)?.properties??null,e.name)?.type??null,super.visitObjectMember(e),this.target=t}visitExpression(t){t.kind===`RefusalExpressionSyntax`&&(!this.mapping||this.branch===null||![`reason`,`constraint`,`message`].includes(t.member)||t.member===`constraint`&&this.branch.selector!==`constraint`?this.context.error(e.InvalidRefusalValue,`'$refusal.${t.member}' is only available in a refusal branch's event mapping; constraint requires 'by constraint'.`,t.location):this.target!==null&&(this.target.isCollection||this.declarations.compatible({...this.target,name:`String`,isOptional:!1,isCollection:!1},this.target)===!1&&!this.declarations.application.concepts.some(e=>e.name===this.target.name&&e.type===`String`))&&this.context.error(e.InvalidRefusalValue,`'$refusal.${t.member}' is a String value, incompatible with '${this.target.name}'.`,t.location));let n=this.target;t.kind===`ListExpressionSyntax`&&n!==null&&(this.target={...n,isCollection:!1}),super.visitExpression(t),this.target=n}};export{RefusalValueWalker};
|
|
2
|
+
//# sourceMappingURL=RefusalValueWalker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RefusalValueWalker.js","names":["ScreenplaySyntaxWalker","declarations","context","syntax","tag","mapping","parent","DiagnosticCodes","concept"],"sources":["../../../../../../Compiler/Parsing/RefusalValueWalker.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { PropertySyntax, TypeRefSyntax } from '../Syntax/Declarations';\nimport { ExpressionSyntax, ObjectMemberSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { InvocationRefusalSyntax } from '../Syntax/InvocationRefusalSyntax';\nimport { ProducesSyntax } from '../Syntax/Reactions';\nimport { ScreenplaySyntaxWalker } from '../Syntax/ScreenplaySyntaxWalker';\nimport { SliceSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\nimport { RefusalDeclarations } from './RefusalDeclarations';\n\nexport class RefusalValueWalker extends ScreenplaySyntaxWalker {\n private slice: SliceSyntax | null = null;\n private branch: InvocationRefusalSyntax | null = null;\n private properties: readonly PropertySyntax[] | null = null;\n private target: TypeRefSyntax | null = null;\n private mapping = false;\n\n constructor(private readonly declarations: RefusalDeclarations, private readonly context: ParserContext) { super(); }\n\n visitSlice(syntax: SliceSyntax): void {\n this.slice = syntax;\n super.visitSlice(syntax);\n this.slice = null;\n }\n\n visitInvocationRefusal(syntax: InvocationRefusalSyntax): void {\n this.branch = syntax;\n super.visitInvocationRefusal(syntax);\n this.branch = null;\n }\n\n visitProduces(syntax: ProducesSyntax): void {\n if (this.branch === null || this.slice === null) { super.visitProduces(syntax); return; }\n this.visitNode(syntax);\n if (syntax.for !== null) this.visitExpression(syntax.for);\n if (syntax.when != null) this.visitCondition(syntax.when);\n syntax.tags.forEach(tag => this.visitTag(tag));\n this.properties = this.declarations.event(syntax.event, this.slice)?.properties ?? null;\n syntax.mappings.forEach(mapping => this.visitPropertyMapping(mapping));\n this.properties = null;\n }\n\n visitPropertyMapping(syntax: PropertyMappingSyntax): void {\n this.mapping = this.branch !== null;\n this.target = this.declarations.property(this.properties, syntax.property)?.type ?? null;\n super.visitPropertyMapping(syntax);\n this.target = null;\n this.mapping = false;\n }\n\n visitObjectMember(syntax: ObjectMemberSyntax): void {\n const parent = this.target;\n this.target = this.declarations.property(parent === null ? null : this.declarations.types.get(parent.name)?.properties ?? null, syntax.name)?.type ?? null;\n super.visitObjectMember(syntax);\n this.target = parent;\n }\n\n visitExpression(syntax: ExpressionSyntax): void {\n if (syntax.kind === 'RefusalExpressionSyntax') {\n if (!this.mapping || this.branch === null || !['reason', 'constraint', 'message'].includes(syntax.member) || syntax.member === 'constraint' && this.branch.selector !== 'constraint') {\n this.context.error(DiagnosticCodes.InvalidRefusalValue, `'$refusal.${syntax.member}' is only available in a refusal branch's event mapping; constraint requires 'by constraint'.`, syntax.location);\n } else if (this.target !== null && (this.target.isCollection || this.declarations.compatible({ ...this.target, name: 'String', isOptional: false, isCollection: false }, this.target) === false && !this.declarations.application.concepts.some(concept => concept.name === this.target!.name && concept.type === 'String'))) {\n this.context.error(DiagnosticCodes.InvalidRefusalValue, `'$refusal.${syntax.member}' is a String value, incompatible with '${this.target.name}'.`, syntax.location);\n }\n }\n const parent = this.target;\n if (syntax.kind === 'ListExpressionSyntax' && parent !== null) this.target = { ...parent, isCollection: false };\n super.visitExpression(syntax);\n this.target = parent;\n }\n}\n"],"mappings":"sMAaA,IAAa,mBAAb,cAAwCA,CAAuB,CAO9B,aAAoD,QANjF,MAAoC,KACpC,OAAiD,KACjD,WAAuD,KACvD,OAAuC,KACvC,QAAkB,GAElB,YAAY,EAAoD,EAAyC,CAAE,MAAM,EAApF,KAAA,aAAAC,EAAoD,KAAA,QAAAC,CAAmC,CAEpH,WAAW,EAA2B,CAClC,KAAK,MAAQC,EACb,MAAM,WAAWA,CAAM,EACvB,KAAK,MAAQ,IACjB,CAEA,uBAAuB,EAAuC,CAC1D,KAAK,OAASA,EACd,MAAM,uBAAuBA,CAAM,EACnC,KAAK,OAAS,IAClB,CAEA,cAAc,EAA8B,CACpC,KAAK,SAAW,MAAQ,KAAK,QAAU,KAAQ,MAAM,cAAcA,CAAM,GAC7E,KAAK,UAAUA,CAAM,EACjBA,EAAO,MAAQ,MAAM,KAAK,gBAAgBA,EAAO,GAAG,EACpDA,EAAO,MAAQ,MAAM,KAAK,eAAeA,EAAO,IAAI,EACxDA,EAAO,KAAK,QAAQ,GAAO,KAAK,SAASC,CAAG,CAAC,EAC7C,KAAK,WAAa,KAAK,aAAa,MAAMD,EAAO,MAAO,KAAK,KAAK,CAAC,EAAE,YAAc,KACnFA,EAAO,SAAS,QAAQ,GAAW,KAAK,qBAAqBE,CAAO,CAAC,EACrE,KAAK,WAAa,KACtB,CAEA,qBAAqB,EAAqC,CACtD,KAAK,QAAU,KAAK,SAAW,KAC/B,KAAK,OAAS,KAAK,aAAa,SAAS,KAAK,WAAYF,EAAO,QAAQ,CAAC,EAAE,MAAQ,KACpF,MAAM,qBAAqBA,CAAM,EACjC,KAAK,OAAS,KACd,KAAK,QAAU,EACnB,CAEA,kBAAkB,EAAkC,CAChD,IAAMG,EAAS,KAAK,OACpB,KAAK,OAAS,KAAK,aAAa,SAASA,IAAW,KAAO,KAAO,KAAK,aAAa,MAAM,IAAIA,EAAO,IAAI,CAAC,EAAE,YAAc,KAAMH,EAAO,IAAI,CAAC,EAAE,MAAQ,KACtJ,MAAM,kBAAkBA,CAAM,EAC9B,KAAK,OAASG,CAClB,CAEA,gBAAgB,EAAgC,CACxCH,EAAO,OAAS,4BACZ,CAAC,KAAK,SAAW,KAAK,SAAW,MAAQ,CAAC,CAAC,SAAU,aAAc,SAAS,CAAC,CAAC,SAASA,EAAO,MAAM,GAAKA,EAAO,SAAW,cAAgB,KAAK,OAAO,WAAa,aACpK,KAAK,QAAQ,MAAMI,EAAgB,oBAAqB,aAAaJ,EAAO,OAAO,+FAAgGA,EAAO,QAAQ,EAC3L,KAAK,SAAW,OAAS,KAAK,OAAO,cAAgB,KAAK,aAAa,WAAW,CAAE,GAAG,KAAK,OAAQ,KAAM,SAAU,WAAY,GAAO,aAAc,EAAM,EAAG,KAAK,MAAM,IAAM,IAAS,CAAC,KAAK,aAAa,YAAY,SAAS,KAAK,GAAWK,EAAQ,OAAS,KAAK,OAAQ,MAAQA,EAAQ,OAAS,QAAQ,IACtT,KAAK,QAAQ,MAAMD,EAAgB,oBAAqB,aAAaJ,EAAO,OAAO,0CAA0C,KAAK,OAAO,KAAK,IAAKA,EAAO,QAAQ,GAG1K,IAAMG,EAAS,KAAK,OAChBH,EAAO,OAAS,wBAA0BG,IAAW,OAAM,KAAK,OAAS,CAAE,GAAGA,EAAQ,aAAc,EAAM,GAC9G,MAAM,gBAAgBH,CAAM,EAC5B,KAAK,OAASG,CAClB,CACJ"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";const e=/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/,t=/^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\.[0-9]{1,7})?(?:Z|[+-]([0-9]{2}):([0-9]{2}))$/;function responseDateValue(n,r){let i=(r?t:e).exec(n);if(i===null||i[0].length!==n.length)return!1;let a=Number(i[1]),o=Number(i[2]),s=Number(i[3]),c=[31,a%4==0&&(a%100!=0||a%400==0)?29:28,31,30,31,30,31,31,30,31,30,31];if(a<1||o<1||o>12||s<1||s>c[o-1])return!1;if(!r)return!0;if(Number(i[4])>23||Number(i[5])>59||Number(i[6])>59)return!1;if(i[7]===void 0)return!0;let l=Number(i[7]),u=Number(i[8]);return l<=14&&u<=59&&(l!==14||u===0)}export{responseDateValue};
|
|
2
|
+
//# sourceMappingURL=ResponseDateValues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResponseDateValues.js","names":["date","dateTime","match","includeTime","text","year","month","day","days","hours","minutes"],"sources":["../../../../../../Compiler/Parsing/ResponseDateValues.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nconst date = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/;\nconst dateTime = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\\.[0-9]{1,7})?(?:Z|[+-]([0-9]{2}):([0-9]{2}))$/;\n\n// Only response/fixture compatibility uses this grammar; general literal parsing stays unchanged.\nexport function responseDateValue(text: string, includeTime: boolean): boolean {\n const match = (includeTime ? dateTime : date).exec(text);\n if (match === null || match[0].length !== text.length) return false;\n const year = Number(match[1]);\n const month = Number(match[2]);\n const day = Number(match[3]);\n const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);\n const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n if (year < 1 || month < 1 || month > 12 || day < 1 || day > days[month - 1]) return false;\n if (!includeTime) return true;\n if (Number(match[4]) > 23 || Number(match[5]) > 59 || Number(match[6]) > 59) return false;\n if (match[7] === undefined) return true;\n const hours = Number(match[7]);\n const minutes = Number(match[8]);\n return hours <= 14 && minutes <= 59 && (hours !== 14 || minutes === 0);\n}\n"],"mappings":"qDAGA,MAAMA,EAAO,qCACPC,EAAW,sHAGjB,SAAgB,kBAAkB,EAAc,EAA+B,CAC3E,IAAMC,GAASC,EAAcF,EAAWD,EAAA,CAAM,KAAKI,CAAI,EACvD,GAAIF,IAAU,MAAQA,EAAM,EAAE,CAAC,SAAWE,EAAK,OAAQ,MAAO,GAC9D,IAAMC,EAAO,OAAOH,EAAM,EAAE,EACtBI,EAAQ,OAAOJ,EAAM,EAAE,EACvBK,EAAM,OAAOL,EAAM,EAAE,EAErBM,EAAO,CAAC,GADDH,EAAO,GAAM,IAAMA,EAAO,KAAQ,GAAKA,EAAO,KAAQ,GAC1C,GAAK,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,EAAE,EACxE,GAAIA,EAAO,GAAKC,EAAQ,GAAKA,EAAQ,IAAMC,EAAM,GAAKA,EAAMC,EAAKF,EAAQ,GAAI,MAAO,GACpF,GAAI,CAACH,EAAa,MAAO,GACzB,GAAI,OAAOD,EAAM,EAAE,EAAI,IAAM,OAAOA,EAAM,EAAE,EAAI,IAAM,OAAOA,EAAM,EAAE,EAAI,GAAI,MAAO,GACpF,GAAIA,EAAM,KAAO,IAAA,GAAW,MAAO,GACnC,IAAMO,EAAQ,OAAOP,EAAM,EAAE,EACvBQ,EAAU,OAAOR,EAAM,EAAE,EAC/B,OAAOO,GAAS,IAAMC,GAAW,KAAOD,IAAU,IAAMC,IAAY,EACxE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{exactIsIntegral as t}from"../Syntax/ExactMathFacts.js";import{responseDateValue as n}from"./ResponseDateValues.js";import{specificationCommandExamples as r}from"./SpecificationCommandExamples.js";const i=/* @__PURE__ */ new Set([`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`]);function validateResponses(t,n,a=n.inputUses){let o=r(t),s=[],collect=(e,t)=>{let n=[...t,e.name];e.slices.forEach(e=>s.push({slice:e,scope:[...n,e.name]})),e.features.forEach(e=>collect(e,n))};t.modules.forEach(e=>e.features.forEach(t=>collect(t,[e.name])));let c=/* @__PURE__ */ new Map,l=/* @__PURE__ */ new Map,u=/* @__PURE__ */ new Map;for(let{slice:e,scope:t}of s)for(let n of e.commands){let e=c.get(n.name)??[];e.push({command:n,scope:t}),c.set(n.name,e),l.set(n,uniqueByName(n.properties)),n.response?.kind===`RecordCommandResponseSyntax`&&u.set(n,uniqueByName(n.response.fields))}let d=/* @__PURE__ */ new Map;for(let e of t.imports){let t=e.qualifiedName.split(`.`).at(-1);d.set(t,[...d.get(t)??[],e.qualifiedName])}let f=/* @__PURE__ */ new Map,resolve=(e,t)=>{let n=`${t.join(`.`)}|${e}`;if(f.has(n))return f.get(n);let r=d.get(e)??[],i=((c.get(e.split(`.`).at(-1))??[]).length===0&&r.length===1?r[0]:e).split(`.`),a=c.get(i.at(-1))??[];if(i.length>1){let e=i.slice(0,-1);a=a.filter(t=>e.length<=t.scope.length&&e.every((n,r)=>t.scope[t.scope.length-e.length+r]===n))}else for(let e=t.length;e>=0;e--){let n=a.filter(n=>e<=n.scope.length&&t.slice(0,e).every((e,t)=>n.scope[t]===e));if(n.length>0){a=n;break}}let o=a.length===1?a[0].command:null;return f.set(n,o),o},p=uniqueByName(t.concepts),m=new Set(t.concepts.map(e=>e.name)),h=new Map([...uniqueByName(t.types)].map(([e,t])=>[e,uniqueByName(t.properties)])),g=new Set(s.flatMap(e=>e.slice.readModels.map(e=>e.name))),_=new Set([...l.keys()].flatMap(e=>[...e.properties])),checkDeclarations=t=>{for(let r of t)r.isGenerated&&!_.has(r)&&n.error(e.GeneratedPropertyOutsideCommand,`Generated properties can only be declared on commands.`,r.location)},checkFeature=e=>{e.features.forEach(checkFeature);for(let t of e.slices){for(let e of t.commands)for(let t of e.produces)t.inlineEvent!==null&&checkDeclarations(t.inlineEvent.properties);t.events.forEach(e=>checkDeclarations(e.properties)),t.readModels.forEach(e=>checkDeclarations(e.properties));for(let e of t.reactions)for(let t of e.triggers)for(let e of t.produces)e.inlineEvent!==null&&checkDeclarations(e.inlineEvent.properties)}};t.types.forEach(e=>checkDeclarations(e.properties)),t.modules.forEach(e=>e.features.forEach(checkFeature));let validateSource=(t,r,i)=>{let a=l.get(i).get(t.property);if(a===void 0){n.error(e.InvalidResponseSource,`Response source '${t.property}' must reference one direct command property.`,t.location);return}let o=a.type;(o.isCollection||g.has(o.name))&&n.error(e.InvalidResponseShape,`Collection and whole-read-model responses are not supported.`,t.location),r!==null&&(r.name!==o.name||r.isCollection!==o.isCollection||r.isOptional!==o.isOptional)&&n.error(e.InvalidResponseShape,`An explicit response field type must match its source's declared type, collection shape and optionality.`,r.location)};for(let t of l.keys()){for(let r of t.properties){if(!r.isGenerated)continue;let t=p.get(r.type.name);(r.type.isOptional||r.type.isCollection||(t===void 0?i.has(r.type.name)||h.has(r.type.name)||m.has(r.type.name)||g.has(r.type.name):t.type!==`Uuid`))&&n.error(e.InvalidGeneratedType,`A generated property must be a required, noncollection concept backed by Uuid.`,r.location)}let r=t.response;if(r?.kind===`ScalarCommandResponseSyntax`)validateSource(r.source,null,t);else if(r?.kind===`RecordCommandResponseSyntax`){r.fields.length===0&&n.error(e.InvalidCommandResponse,`A response block requires at least one field.`,r.location);let i=/* @__PURE__ */ new Set;for(let a of r.fields)i.has(a.name)&&n.error(e.DuplicateResponseField,`Duplicate response field '${a.name}'.`,a.location),i.add(a.name),validateSource(a.source,a.type,t)}}let validateSpecification=(t,r)=>{let a=o(t.when,r),s=a===null?null:resolve(a.commandType,r);if(a!==null&&s!==null){let t=l.get(s);for(let r of a.values)t.get(r.property.split(`.`)[0])?.isGenerated&&n.error(e.GeneratedPropertySuppliedAsInput,`Generated property '${r.property}' cannot be supplied as request or form input.`,r.location);let r=[...t.values()].filter(e=>e.isIdentifier);if(a.for!==null&&r.length===1&&r[0].isGenerated){let t=r[0].type;(i.has(t.name)||p.has(t.name)||h.has(t.name))&&(t.isOptional||t.isCollection||p.get(t.name)?.type!==`Uuid`||a.for.kind!==`LiteralExpressionSyntax`||typeof a.for.value!=`string`||!uuidValue(a.for.value))&&n.error(e.InvalidGeneratedFixture,`A generated identifier fixture must supply one compatible concrete UUID value through 'for'.`,a.for.location)}let o=/* @__PURE__ */ new Set;for(let r of a.generatedValues??[]){let i=t.get(r.property);(o.has(r.property)||i===void 0||!i.isGenerated||i.isIdentifier||!compatibleValue(r.source,i.type,p,h))&&n.error(e.InvalidGeneratedFixture,`A generated fixture must uniquely supply a compatible value for a nonidentifier generated command property.`,r.location),o.add(r.property)}}let c=t.thenReturns;if(c==null||((a===null||t.thenErrors.length>0||t.thenDenied!=null)&&n.error(e.InvalidReturnExpectation,`A return expectation requires a command action and cannot accompany an error or denial.`,c.location),s===null))return;let d=s.response,f=l.get(s);if(c.kind===`ScalarSpecificationReturnSyntax`&&d?.kind===`ScalarCommandResponseSyntax`&&f.has(d.source.property))compatibleValue(c.value,f.get(d.source.property).type,p,h)||n.error(e.InvalidReturnExpectation,`The expected return value must match the response source's type.`,c.location);else if(c.kind===`RecordSpecificationReturnSyntax`&&d?.kind===`RecordCommandResponseSyntax`){c.fields.length===0&&n.error(e.InvalidReturnExpectation,`A record return expectation requires at least one field.`,c.location);let t=u.get(s),r=/* @__PURE__ */ new Set;for(let i of c.fields){let a=t.get(i.property),o=a===void 0?void 0:f.get(a.source.property);(r.has(i.property)||o===void 0||!compatibleValue(i.source,o.type,p,h))&&n.error(e.InvalidReturnExpectation,`A return assertion must uniquely name a response field and supply a compatible concrete value.`,i.location),r.add(i.property)}}else n.error(e.InvalidReturnExpectation,`The return expectation must match the command's scalar or record response shape.`,c.location)};for(let{slice:e,scope:t}of s)e.specifications.forEach(e=>validateSpecification(e,t));for(let t of a){if(t.isParameter===!0)continue;let r=resolve(t.command,t.scope);r!==null&&l.get(r).get(t.property.split(`.`)[0])?.isGenerated&&n.error(e.GeneratedPropertySuppliedAsInput,`Generated property '${t.property}' cannot be supplied as request or form input.`,t.location)}}function uniqueByName(e){let t=/* @__PURE__ */ new Map,n=/* @__PURE__ */ new Set;for(let r of e)t.has(r.name)&&n.add(r.name),t.set(r.name,r);return n.forEach(e=>t.delete(e)),t}function compatibleValue(e,r,a,o){if(e.kind===`LiteralExpressionSyntax`&&e.value===null)return r.isOptional;if(r.isCollection)return e.kind===`ListExpressionSyntax`&&e.items.every(e=>compatibleValue(e,{...r,isCollection:!1,isOptional:!1},a,o));let s=o.get(r.name);if(s!==void 0)return e.kind===`ObjectExpressionSyntax`&&e.members.every(e=>{let t=s.get(e.name);return t!==void 0&&compatibleValue(e.value,t.type,a,o)});let c=a.get(r.name),l=c?.type??r.name;if(c?.type===`Enum`)return e.kind===`LiteralExpressionSyntax`&&typeof e.value==`string`&&c.values.includes(e.value);if(e.kind===`LiteralExpressionSyntax`)switch(l){case`Uuid`:return typeof e.value==`string`&&uuidValue(e.value);case`String`:return typeof e.value==`string`;case`Bool`:return typeof e.value==`boolean`;case`Int`:return typeof e.value==`number`?Number.isFinite(e.value)&&Number.isInteger(e.value):typeof e.value==`object`&&e.value!==null&&t(e.value);case`Decimal`:return typeof e.value==`number`?Number.isFinite(e.value):typeof e.value==`object`&&e.value!==null&&e.value.literalType===`ExactNumber`;case`Date`:return typeof e.value==`string`&&n(e.value,!1);case`DateTime`:return typeof e.value==`string`&&n(e.value,!0);default:return!i.has(l)}return!i.has(l)&&c===void 0}const a=/^(?:[0-9a-f]{32}|[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}|\{[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\}|\([0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}\))(?![\s\S])/i;function uuidValue(e){return a.test(e)}export{compatibleValue,uniqueByName,validateResponses};
|
|
2
|
+
//# sourceMappingURL=ResponseValidator.js.map
|