@cratis/screenplay-language 4.241.0 → 4.243.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.
Files changed (53) hide show
  1. package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js +1 -1
  2. package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js.map +1 -1
  3. package/dist/bundles/compiler/Files/PlayFolderMerge.js +1 -1
  4. package/dist/bundles/compiler/Files/PlayFolderMerge.js.map +1 -1
  5. package/dist/bundles/compiler/Parsing/CaptureEventFixturesValidator.js +1 -1
  6. package/dist/bundles/compiler/Parsing/CaptureEventFixturesValidator.js.map +1 -1
  7. package/dist/bundles/compiler/Parsing/CaptureParser.js +1 -1
  8. package/dist/bundles/compiler/Parsing/CaptureParser.js.map +1 -1
  9. package/dist/bundles/compiler/Parsing/ClockOperandParser.js +2 -0
  10. package/dist/bundles/compiler/Parsing/ClockOperandParser.js.map +1 -0
  11. package/dist/bundles/compiler/Parsing/CommandParser.js +1 -1
  12. package/dist/bundles/compiler/Parsing/CommandParser.js.map +1 -1
  13. package/dist/bundles/compiler/Parsing/ConditionParser.js +1 -1
  14. package/dist/bundles/compiler/Parsing/ConditionParser.js.map +1 -1
  15. package/dist/bundles/compiler/Parsing/PublicEventUsageValidator.js +1 -1
  16. package/dist/bundles/compiler/Parsing/PublicEventUsageValidator.js.map +1 -1
  17. package/dist/bundles/compiler/Parsing/ScreenplayParser.js +1 -1
  18. package/dist/bundles/compiler/Parsing/ScreenplayParser.js.map +1 -1
  19. package/dist/bundles/compiler/Parsing/SpecificationParser.js +1 -1
  20. package/dist/bundles/compiler/Parsing/SpecificationParser.js.map +1 -1
  21. package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js +1 -1
  22. package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js.map +1 -1
  23. package/dist/bundles/compiler/Syntax/Structure.js.map +1 -1
  24. package/dist/bundles/compiler/Syntax/SyntaxCollections.js +1 -1
  25. package/dist/bundles/compiler/Syntax/SyntaxCollections.js.map +1 -1
  26. package/dist/bundles/compiler/Syntax/SyntaxJson.js +1 -1
  27. package/dist/bundles/compiler/Syntax/SyntaxJson.js.map +1 -1
  28. package/dist/bundles/completion-items.js +3 -3
  29. package/dist/bundles/completion-items.js.map +1 -1
  30. package/dist/bundles/diagnostic-codes.js +1 -1
  31. package/dist/bundles/diagnostic-codes.js.map +1 -1
  32. package/dist/bundles/example-analysis.js +1 -1
  33. package/dist/bundles/example-analysis.js.map +1 -1
  34. package/dist/bundles/keyword-docs.js +1 -1
  35. package/dist/bundles/keyword-docs.js.map +1 -1
  36. package/dist/bundles/language.js +1 -1
  37. package/dist/bundles/language.js.map +1 -1
  38. package/dist/bundles/response-analysis.js +2 -2
  39. package/dist/bundles/response-analysis.js.map +1 -1
  40. package/dist/bundles/sub-languages/cdl.js +1 -1
  41. package/dist/bundles/sub-languages/cdl.js.map +1 -1
  42. package/dist/bundles/tokens.js +1 -1
  43. package/dist/bundles/tokens.js.map +1 -1
  44. package/dist/bundles/validation.js +1 -1
  45. package/dist/bundles/validation.js.map +1 -1
  46. package/dist/completion-items.d.ts.map +1 -1
  47. package/dist/diagnostic-codes.d.ts +4 -0
  48. package/dist/diagnostic-codes.d.ts.map +1 -1
  49. package/dist/keyword-docs.d.ts.map +1 -1
  50. package/dist/language.d.ts.map +1 -1
  51. package/dist/sub-languages/cdl.d.ts.map +1 -1
  52. package/dist/tokens.d.ts.map +1 -1
  53. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PublicEventUsageValidator.js","names":["validatePublicEventMetadata","application","context","resolver","AuthoringProductionResolver","events","declaration","slice","scope","imported","seed","group","contract","code","DiagnosticCodes","collector","PublicEventUsageCollector","contracts","explicitOutbound","readModels","readModel","target","node","source","captureOrigins","use","validateCaptureEventFixtures","all","declarations","eventDeclarations","event","outputs","capture","resolutionContext","ParserContext","appended","reaction","matching","trigger","origin","isEventsSource","origins","consumedEvents","setting","foreign","publicEvent","message","output","command","name","resolution","imports","local","diagnostic","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 { consumedEvents, 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';\nimport { validateCaptureEventFixtures } from './CaptureEventFixturesValidator';\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 const events = new AuthoringProductionResolver(application, resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event));\n for (const { slice, scope } of resolver.slices) validateOwnCaptureReactions(application, slice, scope, events, context);\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 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 const captureOrigins = new Map<SyntaxNode, string>();\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 recordCaptureOrigin(use.node, contract, captureOrigins);\n }\n validateCaptureOrigins(slice, captureOrigins, context);\n validateCaptureEventFixtures(slice, scope, events, context);\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 validateOwnCaptureReactions(application: ApplicationSyntax, slice: SliceSyntax, scope: readonly string[], events: AuthoringProductionResolver, context: ParserContext): void {\n if (slice.type !== 'Translate' || slice.direction != null) return;\n const collector = new PublicEventUsageCollector();\n collector.visitSlice(slice);\n // Resolution diagnostics belong to the existing reference validators, not this co-location warning.\n const resolutionContext = new ParserContext(context.reader, context.path);\n const appended = new Set(collector.uses.filter(use => use.node.kind === 'CaptureAppendSyntax')\n .map(use => resolve(application, events, scope, use.name, use.node, true, resolutionContext)).filter(node => node !== undefined));\n for (const reaction of slice.reactions.filter(reaction => reaction.from == null)) {\n const matching = new Map<EventSyntax | ImportSyntax, string>();\n for (const trigger of reaction.triggers) {\n if (trigger.source.kind !== 'NamedTriggerSourceSyntax') continue;\n const source = trigger.source;\n const node = resolve(application, events, scope, source.name, source, false, resolutionContext);\n if (node !== undefined && appended.has(node) && !matching.has(node)) matching.set(node, source.name);\n }\n if (matching.size === 0) continue;\n context.warning(DiagnosticCodes.DirectionlessTranslationReactsToOwnCapture,\n `Reaction '${reaction.name}' reacts to events appended by a capture in the same directionless Translate slice (${[...matching.values()].join(', ')}); keep the capture in this Translate slice and move the reaction to an Automation slice.`, reaction.location);\n }\n}\n\nfunction recordCaptureOrigin(node: SyntaxNode, contract: EventSyntax | ImportSyntax, captureOrigins: Map<SyntaxNode, string>): void {\n if (node.kind !== 'CaptureSourceSettingSyntax') return;\n const origin = publicOrigin(contract);\n if (origin !== undefined) captureOrigins.set(node, origin);\n}\n\nfunction publicOrigin(contract: EventSyntax | ImportSyntax): string | undefined {\n if (contract.visibility !== EventVisibility.Public) return undefined;\n const origin = contract.origin ?? '';\n return origin.trim().length > 0 ? origin : undefined;\n}\n\nfunction validateCaptureOrigins(slice: SliceSyntax, captureOrigins: Map<SyntaxNode, string>, context: ParserContext): void {\n for (const capture of slice.captures) {\n const source = capture.source;\n if (source == null || !isEventsSource(source)) continue;\n const origins = [...new Set(consumedEvents(source).flatMap(setting => {\n const origin = captureOrigins.get(setting);\n return origin == null ? [] : [origin];\n }))].sort();\n if (origins.length < 2) continue;\n context.error(DiagnosticCodes.CaptureEventsFromSeveralOrigins, `The 'from' events of capture '${capture.name}' originate from several event stores (${origins.join(', ')}); a capture reads one event store - split it into one capture per origin.`, source.location);\n }\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":"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"}
1
+ {"version":3,"file":"PublicEventUsageValidator.js","names":["validatePublicEventMetadata","application","context","resolver","AuthoringProductionResolver","events","declaration","slice","scope","validateEventSourceKeys","imported","seed","group","contract","code","DiagnosticCodes","collector","PublicEventUsageCollector","contracts","explicitOutbound","readModels","readModel","target","node","source","captureOrigins","use","validateCaptureEventFixtures","all","declarations","eventDeclarations","event","outputs","capture","resolutionContext","ParserContext","appended","reaction","matching","trigger","origin","isEventsSource","origins","consumedEvents","setting","foreign","publicEvent","message","output","command","name","resolution","imports","local","diagnostic","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 { consumedEvents, 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';\nimport { validateCaptureEventFixtures, validateEventSourceKeys } from './CaptureEventFixturesValidator';\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 const events = new AuthoringProductionResolver(application, resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event));\n for (const { slice, scope } of resolver.slices) {\n validateOwnCaptureReactions(application, slice, scope, events, context);\n validateEventSourceKeys(slice, context);\n }\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 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 const captureOrigins = new Map<SyntaxNode, string>();\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 recordCaptureOrigin(use.node, contract, captureOrigins);\n }\n validateCaptureOrigins(slice, captureOrigins, context);\n validateCaptureEventFixtures(slice, scope, events, context);\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 validateOwnCaptureReactions(application: ApplicationSyntax, slice: SliceSyntax, scope: readonly string[], events: AuthoringProductionResolver, context: ParserContext): void {\n if (slice.type !== 'Translate' || slice.direction != null) return;\n const collector = new PublicEventUsageCollector();\n collector.visitSlice(slice);\n // Resolution diagnostics belong to the existing reference validators, not this co-location warning.\n const resolutionContext = new ParserContext(context.reader, context.path);\n const appended = new Set(collector.uses.filter(use => use.node.kind === 'CaptureAppendSyntax')\n .map(use => resolve(application, events, scope, use.name, use.node, true, resolutionContext)).filter(node => node !== undefined));\n for (const reaction of slice.reactions.filter(reaction => reaction.from == null)) {\n const matching = new Map<EventSyntax | ImportSyntax, string>();\n for (const trigger of reaction.triggers) {\n if (trigger.source.kind !== 'NamedTriggerSourceSyntax') continue;\n const source = trigger.source;\n const node = resolve(application, events, scope, source.name, source, false, resolutionContext);\n if (node !== undefined && appended.has(node) && !matching.has(node)) matching.set(node, source.name);\n }\n if (matching.size === 0) continue;\n context.warning(DiagnosticCodes.DirectionlessTranslationReactsToOwnCapture,\n `Reaction '${reaction.name}' reacts to events appended by a capture in the same directionless Translate slice (${[...matching.values()].join(', ')}); keep the capture in this Translate slice and move the reaction to an Automation slice.`, reaction.location);\n }\n}\n\nfunction recordCaptureOrigin(node: SyntaxNode, contract: EventSyntax | ImportSyntax, captureOrigins: Map<SyntaxNode, string>): void {\n if (node.kind !== 'CaptureSourceSettingSyntax') return;\n const origin = publicOrigin(contract);\n if (origin !== undefined) captureOrigins.set(node, origin);\n}\n\nfunction publicOrigin(contract: EventSyntax | ImportSyntax): string | undefined {\n if (contract.visibility !== EventVisibility.Public) return undefined;\n const origin = contract.origin ?? '';\n return origin.trim().length > 0 ? origin : undefined;\n}\n\nfunction validateCaptureOrigins(slice: SliceSyntax, captureOrigins: Map<SyntaxNode, string>, context: ParserContext): void {\n for (const capture of slice.captures) {\n const source = capture.source;\n if (source == null || !isEventsSource(source)) continue;\n const origins = [...new Set(consumedEvents(source).flatMap(setting => {\n const origin = captureOrigins.get(setting);\n return origin == null ? [] : [origin];\n }))].sort();\n if (origins.length < 2) continue;\n context.error(DiagnosticCodes.CaptureEventsFromSeveralOrigins, `The 'from' events of capture '${capture.name}' originate from several event stores (${origins.join(', ')}); a capture reads one event store - split it into one capture per origin.`, source.location);\n }\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":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i,startOf as a}from"./SourceLine.js";import{parseComplianceDirective as o,parseComplianceMarkers as s}from"./ConceptComplianceParser.js";import{firstWord as c,unescapeIdentifier as l}from"./LineText.js";import{describePlacement as u,documentPlacement as d,isDocumentPlacement as f}from"../Files/PlayPlacement.js";import{parseDescription as p}from"./DescriptionParser.js";import{parsePurpose as m}from"./PurposeParser.js";import{isFileImport as h,parseFileImport as g}from"./FileImportParser.js";import{recordAuthoredDocument as _}from"../Syntax/SourceOptions.js";import{collectInputUses as v}from"./InputUses.js";import{misplacedReactionIdentity as y}from"./ReactionIdentityParser.js";import{parseCanvasPair as b}from"./CanvasPlacement.js";import{parseEventSource as x}from"./EventSourceParser.js";import{isFileDirective as S}from"./FileReferences.js";import{parseSystem as C}from"./OperationParser.js";import{parseExample as w}from"./SpecificationExampleParser.js";import{isBlankPublicEventOrigin as ee}from"../Syntax/PublicEventInvariants.js";import{parseType as te}from"./DeclarationParsers.js";import{parseValidate as T}from"./CommandParser.js";import{parseTriggerDeclaration as E}from"./TriggerDataParser.js";import{FeatureBody as D,featureBodyExpected as O}from"./FeatureBody.js";import{ModuleBody as k,moduleBodyExpected as A,modulePattern as j,parseModule as M}from"./ModuleBody.js";import{EnumerationMembers as N}from"./EnumerationMembers.js";import{parseGeneration as P}from"./GenerationParser.js";import{parseIdentity as F}from"./IdentityParser.js";import{parsePolicy as ne}from"./PolicyParser.js";import{parseSeed as re}from"./SeedParser.js";import{parseExposure as ie,parseInstance as I}from"./CompositionParser.js";import{parseUiProfile as L}from"./UiProfileLegacyLayout.js";const R=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),z=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),B=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),V=r(`^@?[a-z_]\\w*$`),H=r(`^persona\\s+([A-Za-z_]\\w*)$`),U=r(`^policy\\s+([A-Za-z_]\\w*)$`),W=r(`^goal\\s+"(${t})"$`),G=r(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),K=r(`^colour\\s+(yellow|pink|green|blue)$`),q=/^[ ]*\t/,J=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],Y=/* @__PURE__ */ new Set([`policy`,`authentication`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),X=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(t,r,a=d){t.deferIdentityValidation=!0,warnOnTabIndentation(t,r);let o=a.length===1?new k(a[0]):void 0,s=a.length>1?new D(a[a.length-1]):void 0,l=o??s,u=null,p=null,b=!1,S=null,T=!1,O=null,A=[],j=[],N=[],P=[],R=[],B=[],V=[],H=[],U=[],W=[],G=[],K=[],q=[],J=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(r.content))T||!f(a)||!/^command\s+reads\s+protected$/.test(r.content)?t.error(e.InvalidCommandReadsDeclaration,`Declare 'command reads protected' once at the application root.`,i(r)):S=`Protected`,T=!0;else if(s===`reaction`)b||!f(a)||!/^reaction\s+batches\s+atomic$/.test(r.content)?t.error(e.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,i(r)):p=`Atomic`,b=!0;else if(s===`runs`)y(t,r);else if(s===`domain`)t.authoredDeclarations=!0,O=parseDomain(t,r,O,Q);else if(Q||=declaresConstruct(s,r,a),t.authoredDeclarations||=s!==`import`&&declaresConstruct(s,r,a),s===`import`&&h(r.content))l===void 0?g(t,r,j):l.tryParse(t,r);else if(s===`import`){let a=z.exec(r.content);if(a===null)t.error(e.InvalidImportDeclaration,`Invalid import '${r.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,i(r));else{let o=a.groups?.origin===void 0?null:n(a.groups.origin);o!==null&&ee(o)&&t.error(e.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,i(r)),A.push({kind:`ImportSyntax`,qualifiedName:a[1],origin:o,visibility:o===null?`Private`:`Public`,location:i(r)})}}else if(s===`example`)l===void 0?q.push(w(t,r)):l.tryParse(t,r);else if(s===`eventsource`)B.push(x(t,r));else if(s===`system`)R.push(C(t,r));else if(s===`concept`)N.push(parseConcept(t,r));else if(s===`type`)P.push(te(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)V.push(M(t,r));else if(s===`persona`)H.push(parsePersona(t,r));else if(s===`sticky`){let e=parseStickyNote(t,r);e!==null&&U.push(e)}else if(s===`seed`)K.push(re(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)G.push(m(t,r));else if(s===`identity`)u=F(t,r,u);else if(s===`policy`){let n=ne(t,r);W.some(e=>e.name===n.name)&&t.error(e.DuplicateDeclaration,`Duplicate declaration of policy '${n.name}' - policy names must be unique`,n.location),W.push(n)}else if(s===`exposure`)X.push(ie(t,r));else if(s===`instance`)Z.push(I(t,r));else if(s===`trigger`){let e=E(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&J.push({name:n,data:e})}else Y.has(s)?s===`behavior`||s===`layout`?v(t,r):s===`ui`?L(t,r):t.skipOpaqueBlock(r.indent):l?.tryParse(t,r)!==!0&&reportUnexpectedTopLevel(t,r,a)}o===void 0?s!==void 0&&V.unshift(place(a,s.build(t.start,!0),t.start)):V.unshift(o.build(t.start,!0));let $={kind:`ApplicationSyntax`,...S===null?{}:{commandReadMode:S},...p===null?{}:{reactionProductionMode:p},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:O,imports:A,concepts:N,types:P,systems:R,eventSources:B,examples:q,modules:V,personas:H,policies:W,purposes:G,seeds:K,declaredTriggers:J,fileImports:j,...X.length>0?{exposures:X}:{},...U.length>0?{stickyNotes:U}:{},...Z.length>0?{instanceContributions:Z}:{},location:t.start};return t.authoredDeclarations&&_($),$}function declaresConstruct(e,t,n){return e===`import`?z.test(t.content):e===`module`?f(n):e===`identity`?t.content===`identity`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||Y.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=j.exec(n.content)?.[1]??``;a!==void 0&&o===r[0]?(t.authoredDeclarations=!0,a.parseChildren(t,n)):(t.error(e.ModuleInPlacedFile,`This file is imported into ${u(r)}, so it cannot declare module '${o}' - import it at the top level of a document instead`,i(n)),t.skipBlock(n.indent))}function reportUnexpectedTopLevel(t,n,r){let a=c(n.content);if(f(r)){let r=X.has(a)?` - '${a}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, sticky note, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;t.error(e.UnknownTopLevelConstruct,`Unexpected '${a}' at the top level${r}`,i(n))}else{let o=r.length===1?A:O;t.error(e.UnexpectedInPlacedFile,`Unexpected '${a}' in a file imported into ${u(r)} - expected an application declaration or ${o}`,i(n))}t.skipBlock(n.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(t,n,r,a){let o=R.exec(n.content);return o===null?(t.error(e.InvalidDomainDeclaration,`Invalid domain declaration '${n.content}' - expected 'domain <Qualified.Name>'`,i(n)),r):r===null?(a&&t.error(e.DomainNotFirst,`'domain' must be declared before any other construct`,i(n)),{kind:`DomainSyntax`,name:o[1],location:i(n)}):(t.error(e.DuplicateDomain,`The document already declares a domain - a document can have at most one`,i(n)),r)}function warnOnTabIndentation(t,n){let r=!1;for(let i of n)i.raw.trimStart().startsWith("```")?r=!r:!r&&q.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=B.exec(n.content);if(r===null)return t.error(e.InvalidConceptDeclaration,`Invalid concept declaration '${n.content}' - expected 'concept <Name> : <Type>'`,i(n)),t.skipBlock(n.indent),{kind:`ConceptSyntax`,name:c(n.content),type:``,attributes:[],values:[],location:i(n)};let[,a,u,d]=r,f=s(t,n,a,d);u!==`Enum`&&!J.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${J.join(`, `)} or Enum`,i(n));let m=[],h=new N,g=null,_=!1,v=null,y=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=u===`Enum`?h.tryNumbered(t,r):void 0;if(n!==void 0)m.push(n);else if(c(r.content)===`description`&&(u!==`Enum`||r.content!==`description`||t.peekChild(r.indent)?.content.startsWith("```")===!0))v=p(t,r,v,`Concept '${a}'`);else if(S(r))continue;else if(c(r.content)===`validate`){u===`Enum`&&r.content===`validate`&&t.peekChild(r.indent)===void 0&&t.warning(e.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${a}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,i(r));let n=T(t,r,`concept`,a);n!==void 0&&y.push(n)}else if(c(r.content)===`generate`&&(u!==`Enum`||r.content!==`generate`)){_&&t.error(e.DuplicateGeneration,`Concept '${a}' declares generation more than once.`,i(r));let n=P(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&V.test(r.content)?m.push(l(r.content)):u===`Enum`?t.error(e.InvalidEnumerationValue,`Invalid enum value '${r.content}' - expected an identifier`,i(r)):(t.error(e.UnknownConceptDirective,`Unexpected '${r.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'`,i(r)),t.skipBlock(r.indent)))}let b=h.finish(t,n,m.length);return{kind:`ConceptSyntax`,name:a,type:u,attributes:f,values:m,validations:y,description:v,...g===null?{}:{generation:g},...b===void 0?{}:{valueNumbers:b},location:i(n)}}function parsePersona(t,r){let a=H.exec(r.content)?.[1]??``;a===``&&t.error(e.InvalidPersonaDeclaration,`Invalid persona declaration '${r.content}' - expected 'persona <Name>'`,i(r));let o=null,s=[],l=[],u=null,d=null;for(let f=t.peekChild(r.indent);f!==void 0;f=t.peekChild(r.indent)){t.reader.takeSignificant();let r=c(f.content);if(r===`description`)o=p(t,f,o,`Persona '${a}'`);else if(r===`goal`){let r=W.exec(f.content);r===null?t.error(e.InvalidPersonaDeclaration,`Invalid goal '${f.content}' - expected 'goal "<text>"'`,i(f)):l.push(n(r[1]))}else if(r===`position`)u=b(t,f,`position`,`x`,`y`,u,!0)??u;else if(r===`size`)d=b(t,f,`size`,`width`,`height`,d,!1)??d;else if(r===`policy`){let n=U.exec(f.content);n===null?t.error(e.InvalidPersonaPolicyReference,`Invalid policy reference '${f.content}' - expected 'policy <Name>'`,i(f)):s.push(n[1])}else t.error(e.UnknownPersonaDirective,`Unexpected '${r}' in persona body - expected description, goal, policy, position or size`,i(f)),t.skipBlock(f.indent)}return{kind:`PersonaSyntax`,name:a,description:o,policies:s,...l.length>0?{goals:l}:{},...u===null?{}:{x:u[0],y:u[1]},...d===null?{}:{width:d[0],height:d[1]},location:i(r)}}function parseStickyNote(t,n){let r=G.exec(n.content);if(r===null)return t.error(e.InvalidPersonaDeclaration,`Invalid sticky note declaration '${n.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`,i(n)),t.skipBlock(n.indent),null;let a=null,o=null,s=null,l=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=c(r.content);if(n===`description`)a=p(t,r,a,`A sticky note`);else if(n===`colour`){let n=K.exec(r.content);n===null?t.error(e.InvalidPersonaDeclaration,`Invalid colour '${r.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`,i(r)):o=n[1]}else n===`position`?s=b(t,r,`position`,`x`,`y`,s,!0)??s:n===`size`?l=b(t,r,`size`,`width`,`height`,l,!1)??l:(t.error(e.UnknownPersonaDirective,`Unexpected '${n}' in sticky note body - expected description, colour, position or size`,i(r)),t.skipBlock(r.indent))}return a===null||s===null?(t.error(e.InvalidPersonaDeclaration,`A sticky note needs a description (the text on it) and a position`,i(n)),null):{kind:`StickyNoteSyntax`,canvas:r[1],text:a,colour:o,x:s[0],y:s[1],width:l===null?null:l[0],height:l===null?null:l[1],location:i(n)}}export{parseApplication};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i,startOf as a}from"./SourceLine.js";import{parseComplianceDirective as o,parseComplianceMarkers as s}from"./ConceptComplianceParser.js";import{firstWord as c,unescapeIdentifier as l}from"./LineText.js";import{describePlacement as u,documentPlacement as d,isDocumentPlacement as f}from"../Files/PlayPlacement.js";import{parseDescription as p}from"./DescriptionParser.js";import{parsePurpose as m}from"./PurposeParser.js";import{isFileImport as h,parseFileImport as g}from"./FileImportParser.js";import{recordAuthoredDocument as _}from"../Syntax/SourceOptions.js";import{collectInputUses as v}from"./InputUses.js";import{misplacedReactionIdentity as y}from"./ReactionIdentityParser.js";import{parseCanvasPair as b}from"./CanvasPlacement.js";import{parseEventSource as ee}from"./EventSourceParser.js";import{isFileDirective as x}from"./FileReferences.js";import{parseSystem as S}from"./OperationParser.js";import{parseExample as te}from"./SpecificationExampleParser.js";import{isBlankPublicEventOrigin as ne}from"../Syntax/PublicEventInvariants.js";import{parseType as re}from"./DeclarationParsers.js";import{parseValidate as C}from"./CommandParser.js";import{parseTriggerDeclaration as w}from"./TriggerDataParser.js";import{FeatureBody as T,featureBodyExpected as E}from"./FeatureBody.js";import{ModuleBody as D,moduleBodyExpected as O,modulePattern as k,parseModule as A}from"./ModuleBody.js";import{EnumerationMembers as j}from"./EnumerationMembers.js";import{parseGeneration as M}from"./GenerationParser.js";import{parseIdentity as N}from"./IdentityParser.js";import{parsePolicy as ie}from"./PolicyParser.js";import{parseSeed as ae}from"./SeedParser.js";import{parseExposure as oe,parseInstance as se}from"./CompositionParser.js";import{parseUiProfile as P}from"./UiProfileLegacyLayout.js";const F=r(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),I=r(`^time\\s+zone\\s+(configurable\\s+default\\s+)?"(${t})"$`),L=r(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${t})")?$`),R=r(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),z=r(`^@?[a-z_]\\w*$`),B=r(`^persona\\s+([A-Za-z_]\\w*)$`),V=r(`^policy\\s+([A-Za-z_]\\w*)$`),H=r(`^goal\\s+"(${t})"$`),U=r(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),W=r(`^colour\\s+(yellow|pink|green|blue)$`),G=/^[ ]*\t/,K=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],q=/* @__PURE__ */ new Set([`policy`,`authentication`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),J=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(t,r,a=d){t.deferIdentityValidation=!0,warnOnTabIndentation(t,r);let o=a.length===1?new D(a[0]):void 0,s=a.length>1?new T(a[a.length-1]):void 0,l=o??s,u=null,p=null,b=!1,x=null,C=null,E=!1,O=!1,k=null,j=[],M=[],F=[],R=[],z=[],B=[],V=[],H=[],U=[],W=[],G=[],K=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let r=t.reader.peekSignificant();r!==void 0;r=t.reader.peekSignificant()){t.reader.takeSignificant();let s=c(r.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(r.content))O||!f(a)||!/^command\s+reads\s+protected$/.test(r.content)?t.error(e.InvalidCommandReadsDeclaration,`Declare 'command reads protected' once at the application root.`,i(r)):x=`Protected`,O=!0;else if(s===`time`&&/^time\s+zone(?:\s|$)/.test(r.content)){let o=I.exec(r.content);t.skipBlock(r.indent),E||!f(a)||o===null?t.error(e.InvalidTimeZoneDeclaration,`Declare 'time zone "<id>"' or 'time zone configurable default "<id>"' once at the application root.`,i(r)):C={kind:`TimeZoneSyntax`,id:n(o[2]),configurable:o[1]!==void 0,location:i(r)},E=!0}else if(s===`reaction`)b||!f(a)||!/^reaction\s+batches\s+atomic$/.test(r.content)?t.error(e.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,i(r)):p=`Atomic`,b=!0;else if(s===`runs`)y(t,r);else if(s===`domain`)t.authoredDeclarations=!0,k=parseDomain(t,r,k,Q);else if(Q||=declaresConstruct(s,r,a),t.authoredDeclarations||=s!==`import`&&declaresConstruct(s,r,a),s===`import`&&h(r.content))l===void 0?g(t,r,M):l.tryParse(t,r);else if(s===`import`){let a=L.exec(r.content);if(a===null)t.error(e.InvalidImportDeclaration,`Invalid import '${r.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,i(r));else{let o=a.groups?.origin===void 0?null:n(a.groups.origin);o!==null&&ne(o)&&t.error(e.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,i(r)),j.push({kind:`ImportSyntax`,qualifiedName:a[1],origin:o,visibility:o===null?`Private`:`Public`,location:i(r)})}}else if(s===`example`)l===void 0?J.push(te(t,r)):l.tryParse(t,r);else if(s===`eventsource`)B.push(ee(t,r));else if(s===`system`)z.push(S(t,r));else if(s===`concept`)F.push(parseConcept(t,r));else if(s===`type`)R.push(re(t,r));else if(s===`module`&&!f(a))parseModuleInPlacedFile(t,r,a,o);else if(s===`module`)V.push(A(t,r));else if(s===`persona`)H.push(parsePersona(t,r));else if(s===`sticky`){let e=parseStickyNote(t,r);e!==null&&U.push(e)}else if(s===`seed`)K.push(ae(t.valueContext,r));else if(s===`purpose`&&l!==void 0)l.tryParse(t,r);else if(s===`purpose`)G.push(m(t,r));else if(s===`identity`)u=N(t,r,u);else if(s===`policy`){let n=ie(t,r);W.some(e=>e.name===n.name)&&t.error(e.DuplicateDeclaration,`Duplicate declaration of policy '${n.name}' - policy names must be unique`,n.location),W.push(n)}else if(s===`exposure`)X.push(oe(t,r));else if(s===`instance`)Z.push(se(t,r));else if(s===`trigger`){let e=w(t,r),n=/^trigger\s+([A-Za-z_]\w*)$/.exec(r.content)?.[1];n!==void 0&&Y.push({name:n,data:e})}else q.has(s)?s===`behavior`||s===`layout`?v(t,r):s===`ui`?P(t,r):t.skipOpaqueBlock(r.indent):l?.tryParse(t,r)!==!0&&reportUnexpectedTopLevel(t,r,a)}o===void 0?s!==void 0&&V.unshift(place(a,s.build(t.start,!0),t.start)):V.unshift(o.build(t.start,!0));let $={kind:`ApplicationSyntax`,...x===null?{}:{commandReadMode:x},...C===null?{}:{timeZone:C},...p===null?{}:{reactionProductionMode:p},...u===null?{}:{identity:u},sourceOptions:t.sourceOptions,domain:k,imports:j,concepts:F,types:R,systems:z,eventSources:B,examples:J,modules:V,personas:H,policies:W,purposes:G,seeds:K,declaredTriggers:Y,fileImports:M,...X.length>0?{exposures:X}:{},...U.length>0?{stickyNotes:U}:{},...Z.length>0?{instanceContributions:Z}:{},location:t.start};return t.authoredDeclarations&&_($),$}function declaresConstruct(e,t,n){return e===`import`?L.test(t.content):e===`module`?f(n):e===`identity`?t.content===`identity`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||q.has(e)}function parseModuleInPlacedFile(t,n,r,a){let o=k.exec(n.content)?.[1]??``;a!==void 0&&o===r[0]?(t.authoredDeclarations=!0,a.parseChildren(t,n)):(t.error(e.ModuleInPlacedFile,`This file is imported into ${u(r)}, so it cannot declare module '${o}' - import it at the top level of a document instead`,i(n)),t.skipBlock(n.indent))}function reportUnexpectedTopLevel(t,n,r){let a=c(n.content);if(f(r)){let r=J.has(a)?` - '${a}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, sticky note, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;t.error(e.UnknownTopLevelConstruct,`Unexpected '${a}' at the top level${r}`,i(n))}else{let o=r.length===1?O:E;t.error(e.UnexpectedInPlacedFile,`Unexpected '${a}' in a file imported into ${u(r)} - expected an application declaration or ${o}`,i(n))}t.skipBlock(n.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(t,n,r,a){let o=F.exec(n.content);return o===null?(t.error(e.InvalidDomainDeclaration,`Invalid domain declaration '${n.content}' - expected 'domain <Qualified.Name>'`,i(n)),r):r===null?(a&&t.error(e.DomainNotFirst,`'domain' must be declared before any other construct`,i(n)),{kind:`DomainSyntax`,name:o[1],location:i(n)}):(t.error(e.DuplicateDomain,`The document already declares a domain - a document can have at most one`,i(n)),r)}function warnOnTabIndentation(t,n){let r=!1;for(let i of n)i.raw.trimStart().startsWith("```")?r=!r:!r&&G.test(i.raw)&&t.warning(e.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,a(i))}function parseConcept(t,n){let r=R.exec(n.content);if(r===null)return t.error(e.InvalidConceptDeclaration,`Invalid concept declaration '${n.content}' - expected 'concept <Name> : <Type>'`,i(n)),t.skipBlock(n.indent),{kind:`ConceptSyntax`,name:c(n.content),type:``,attributes:[],values:[],location:i(n)};let[,a,u,d]=r,f=s(t,n,a,d);u!==`Enum`&&!K.includes(u)&&t.error(e.UnknownPrimitiveType,`Unknown primitive type '${u}' - expected ${K.join(`, `)} or Enum`,i(n));let m=[],h=new j,g=null,_=!1,v=null,y=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=u===`Enum`?h.tryNumbered(t,r):void 0;if(n!==void 0)m.push(n);else if(c(r.content)===`description`&&(u!==`Enum`||r.content!==`description`||t.peekChild(r.indent)?.content.startsWith("```")===!0))v=p(t,r,v,`Concept '${a}'`);else if(x(r))continue;else if(c(r.content)===`validate`){u===`Enum`&&r.content===`validate`&&t.peekChild(r.indent)===void 0&&t.warning(e.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${a}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,i(r));let n=C(t,r,`concept`,a);n!==void 0&&y.push(n)}else if(c(r.content)===`generate`&&(u!==`Enum`||r.content!==`generate`)){_&&t.error(e.DuplicateGeneration,`Concept '${a}' declares generation more than once.`,i(r));let n=M(t,r,u);_||(g=n),_=!0}else o(t,r,a,f)||(u===`Enum`&&z.test(r.content)?m.push(l(r.content)):u===`Enum`?t.error(e.InvalidEnumerationValue,`Invalid enum value '${r.content}' - expected an identifier`,i(r)):(t.error(e.UnknownConceptDirective,`Unexpected '${r.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'`,i(r)),t.skipBlock(r.indent)))}let b=h.finish(t,n,m.length);return{kind:`ConceptSyntax`,name:a,type:u,attributes:f,values:m,validations:y,description:v,...g===null?{}:{generation:g},...b===void 0?{}:{valueNumbers:b},location:i(n)}}function parsePersona(t,r){let a=B.exec(r.content)?.[1]??``;a===``&&t.error(e.InvalidPersonaDeclaration,`Invalid persona declaration '${r.content}' - expected 'persona <Name>'`,i(r));let o=null,s=[],l=[],u=null,d=null;for(let f=t.peekChild(r.indent);f!==void 0;f=t.peekChild(r.indent)){t.reader.takeSignificant();let r=c(f.content);if(r===`description`)o=p(t,f,o,`Persona '${a}'`);else if(r===`goal`){let r=H.exec(f.content);r===null?t.error(e.InvalidPersonaDeclaration,`Invalid goal '${f.content}' - expected 'goal "<text>"'`,i(f)):l.push(n(r[1]))}else if(r===`position`)u=b(t,f,`position`,`x`,`y`,u,!0)??u;else if(r===`size`)d=b(t,f,`size`,`width`,`height`,d,!1)??d;else if(r===`policy`){let n=V.exec(f.content);n===null?t.error(e.InvalidPersonaPolicyReference,`Invalid policy reference '${f.content}' - expected 'policy <Name>'`,i(f)):s.push(n[1])}else t.error(e.UnknownPersonaDirective,`Unexpected '${r}' in persona body - expected description, goal, policy, position or size`,i(f)),t.skipBlock(f.indent)}return{kind:`PersonaSyntax`,name:a,description:o,policies:s,...l.length>0?{goals:l}:{},...u===null?{}:{x:u[0],y:u[1]},...d===null?{}:{width:d[0],height:d[1]},location:i(r)}}function parseStickyNote(t,n){let r=U.exec(n.content);if(r===null)return t.error(e.InvalidPersonaDeclaration,`Invalid sticky note declaration '${n.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`,i(n)),t.skipBlock(n.indent),null;let a=null,o=null,s=null,l=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=c(r.content);if(n===`description`)a=p(t,r,a,`A sticky note`);else if(n===`colour`){let n=W.exec(r.content);n===null?t.error(e.InvalidPersonaDeclaration,`Invalid colour '${r.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`,i(r)):o=n[1]}else n===`position`?s=b(t,r,`position`,`x`,`y`,s,!0)??s:n===`size`?l=b(t,r,`size`,`width`,`height`,l,!1)??l:(t.error(e.UnknownPersonaDirective,`Unexpected '${n}' in sticky note body - expected description, colour, position or size`,i(r)),t.skipBlock(r.indent))}return a===null||s===null?(t.error(e.InvalidPersonaDeclaration,`A sticky note needs a description (the text on it) and a position`,i(n)),null):{kind:`StickyNoteSyntax`,canvas:r[1],text:a,colour:o,x:s[0],y:s[1],width:l===null?null:l[0],height:l===null?null:l[1],location:i(n)}}export{parseApplication};
2
2
  //# sourceMappingURL=ScreenplayParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScreenplayParser.js","names":["domainPattern","pattern","importPattern","stringBodyPattern","conceptPattern","enumValuePattern","personaPattern","personaPolicyPattern","personaGoalPattern","stickyNotePattern","stickyNoteColourPattern","tabIndentPattern","primitiveTypes","opaqueTopLevel","bodyKeywords","documentPlacement","context","lines","moduleBody","placement","ModuleBody","featureBody","FeatureBody","placedBody","identity","reactionProductionMode","sawReactionBatches","commandReadMode","sawCommandReads","domain","imports","fileImports","concepts","types","systems","eventSources","modules","personas","stickyNotes","policies","purposes","seeds","examples","declaredTriggers","exposures","instanceContributions","sawOtherConstruct","line","keyword","firstWord","isDocumentPlacement","DiagnosticCodes","locationOf","misplacedReactionIdentity","isFileImport","parseFileImport","match","origin","unescapeString","isBlankPublicEventOrigin","parseExample","parseEventSource","parseSystem","parseType","parseModule","stickyNote","parseSeed","parsePurpose","parseIdentity","policy","parsePolicy","previous","parseExposure","parseInstance","data","parseTriggerDeclaration","name","collectInputUses","parseUiProfile","root","recordAuthoredDocument","modulePattern","describePlacement","word","hint","expected","moduleBodyExpected","featureBodyExpected","feature","innermost","index","start","existing","inFence","startOf","type","attributeText","attributes","parseComplianceMarkers","values","members","EnumerationMembers","generation","declaredGeneration","description","validations","child","memberName","parseDescription","isFileDirective","parsed","parseValidate","parseGeneration","parseComplianceDirective","unescapeIdentifier","valueNumbers","goals","position","size","goal","parseCanvasPair","canvasMatch","text","colour"],"sources":["../../../../../../Compiler/Parsing/ScreenplayParser.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 { CommandReadMode } from '../Syntax/CommandReadMode';\nimport { ReactionProductionMode } from '../Syntax/ReactionProductionMode';\nimport { EnumerationMembers } from './EnumerationMembers';\nimport { GenerationSyntax } from '../Syntax/GenerationSyntax';\nimport { parseGeneration } from './GenerationParser';\nimport { IdentitySyntax } from '../Syntax/IdentitySyntax';\nimport { parseIdentity } from './IdentityParser';\nimport { misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { recordAuthoredDocument } from '../Syntax/SourceOptions';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { describePlacement, documentPlacement, isDocumentPlacement, PlayPlacement } from '../Files/PlayPlacement';\nimport { PersonaSyntax, StickyNoteSyntax } from '../Syntax/Authorization';\nimport { ConceptSyntax, DomainSyntax, ImportSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { ApplicationSyntax, FeatureSyntax, FileImportSyntax, ModuleSyntax } from '../Syntax/Structure';\nimport { parseTriggerDeclaration } from './TriggerDataParser';\nimport { pattern } from '../Text/patterns';\nimport { parseComplianceDirective, parseComplianceMarkers } from './ConceptComplianceParser';\nimport { parseType } from './DeclarationParsers';\nimport { ValidateSyntax } from '../Syntax/Commands';\nimport { parseValidate } from './CommandParser';\nimport { parseDescription } from './DescriptionParser';\nimport { FeatureBody, featureBodyExpected } from './FeatureBody';\nimport { isFileImport, parseFileImport } from './FileImportParser';\nimport { isFileDirective } from './FileReferences';\nimport { collectInputUses } from './InputUses';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ModuleBody, moduleBodyExpected, modulePattern, parseModule } from './ModuleBody';\nimport { ParserContext } from './ParserContext';\nimport { PolicySyntax } from '../Syntax/Policies';\nimport { parsePolicy } from './PolicyParser';\nimport { PurposeSyntax } from '../Syntax/Purposes';\nimport { parsePurpose } from './PurposeParser';\nimport { SeedSyntax } from '../Syntax/Seeds';\nimport { parseSeed } from './SeedParser';\nimport { parseSystem } from './OperationParser';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { SystemSyntax } from '../Syntax/Operations';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { parseCanvasPair } from './CanvasPlacement';\nimport { parseEventSource } from './EventSourceParser';\nimport { parseExposure, parseInstance } from './CompositionParser';\nimport { ExposureSyntax, InstanceContributionsSyntax } from '../Syntax/CompositionSyntax';\nimport { parseExample } from './SpecificationExampleParser';\nimport { parseUiProfile } from './UiProfileLegacyLayout';\nimport { locationOf, SourceLine, startOf } from './SourceLine';\n\nconst domainPattern = pattern('^domain\\\\s+([A-Za-z_]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst importPattern = pattern(`^import\\\\s+([\\\\w.]+)(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst conceptPattern = pattern('^concept\\\\s+(\\\\w+)\\\\s*:\\\\s*(\\\\w+)((?:\\\\s+@?\\\\w+)*)$');\nconst enumValuePattern = pattern('^@?[a-z_]\\\\w*$');\nconst personaPattern = pattern('^persona\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaPolicyPattern = pattern('^policy\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaGoalPattern = pattern(`^goal\\\\s+\"(${stringBodyPattern})\"$`);\nconst stickyNotePattern = pattern('^sticky\\\\s+note\\\\s+on\\\\s+(personas|eventsources|givencontexts|seeddata)$');\nconst stickyNoteColourPattern = pattern('^colour\\\\s+(yellow|pink|green|blue)$');\nconst tabIndentPattern = /^[ ]*\\t/;\nconst primitiveTypes = ['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime'];\n\n// Top-level, module and feature constructs the C# compiler knows that this compiler does not model. They\n// are skipped whole, not reported.\nconst opaqueTopLevel = new Set(['policy', 'authentication', 'seed', 'ui', 'theme', 'trigger', 'layout', 'behavior', 'sample']);\n\n// What belongs in a module or feature body; at the top level of a whole document it gets a hint saying so.\nconst bodyKeywords = new Set(['slice', 'feature', 'description', 'documentation', 'authorize', 'screen', 'dialog', 'form', 'contribute', 'on', 'uses']);\n\n// Parses one document into its application syntax - the port of the C# ScreenplayParser. The placement says\n// where the document's top level belongs: the application, unless an import placed it in a module or feature.\nexport function parseApplication(context: ParserContext, lines: readonly SourceLine[], placement: PlayPlacement = documentPlacement): ApplicationSyntax {\n context.deferIdentityValidation = true;\n warnOnTabIndentation(context, lines);\n const moduleBody = placement.length === 1 ? new ModuleBody(placement[0]) : undefined;\n const featureBody = placement.length > 1 ? new FeatureBody(placement[placement.length - 1]) : undefined;\n const placedBody = moduleBody ?? featureBody;\n let identity: IdentitySyntax | null = null;\n let reactionProductionMode: ReactionProductionMode | null = null;\n let sawReactionBatches = false;\n let commandReadMode: CommandReadMode | null = null;\n let sawCommandReads = false;\n let domain: DomainSyntax | null = null;\n const imports: ImportSyntax[] = [];\n const fileImports: FileImportSyntax[] = [];\n const concepts: ConceptSyntax[] = [];\n const types: TypeSyntax[] = [];\n const systems: SystemSyntax[] = [];\n const eventSources: EventSourceSyntax[] = [];\n const modules: ModuleSyntax[] = [];\n const personas: PersonaSyntax[] = [];\n const stickyNotes: StickyNoteSyntax[] = [];\n const policies: PolicySyntax[] = [];\n const purposes: PurposeSyntax[] = [];\n const seeds: SeedSyntax[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n const declaredTriggers: NonNullable<ApplicationSyntax['declaredTriggers']>[number][] = [];\n const exposures: ExposureSyntax[] = [];\n const instanceContributions: InstanceContributionsSyntax[] = [];\n let sawOtherConstruct = false;\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n if (keyword === 'command' && /^command\\s+reads(?:\\s|$)/.test(line.content)) {\n if (sawCommandReads || !isDocumentPlacement(placement) || !/^command\\s+reads\\s+protected$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidCommandReadsDeclaration, \"Declare 'command reads protected' once at the application root.\", locationOf(line));\n } else {\n commandReadMode = CommandReadMode.Protected;\n }\n sawCommandReads = true;\n continue;\n }\n if (keyword === 'reaction') {\n if (sawReactionBatches || !isDocumentPlacement(placement) || !/^reaction\\s+batches\\s+atomic$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidReactionBatchesDeclaration, \"Declare 'reaction batches atomic' once at the application root.\", locationOf(line));\n } else {\n reactionProductionMode = ReactionProductionMode.Atomic;\n }\n sawReactionBatches = true;\n continue;\n }\n if (keyword === 'runs') {\n misplacedReactionIdentity(context, line);\n continue;\n }\n if (keyword === 'domain') {\n context.authoredDeclarations = true;\n domain = parseDomain(context, line, domain, sawOtherConstruct);\n continue;\n }\n // The C# parser asks whether anything was declared before the domain, so an import it rejected,\n // a file import and an unknown construct do not count.\n sawOtherConstruct ||= declaresConstruct(keyword, line, placement);\n context.authoredDeclarations ||= keyword !== 'import' && declaresConstruct(keyword, line, placement);\n if (keyword === 'import' && isFileImport(line.content)) {\n // A top level import belongs to whatever the document's top level is - the application, or the\n // module or feature the document was itself imported into.\n if (placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else {\n parseFileImport(context, line, fileImports);\n }\n } else if (keyword === 'import') {\n const match = importPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, `Invalid import '${line.content}' - expected 'import <Qualified.Name> [from \"<origin>\"]'`, locationOf(line));\n } else {\n const origin = match.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, 'An import origin must be a nonblank quoted string', locationOf(line));\n }\n imports.push({ kind: 'ImportSyntax', qualifiedName: match[1], origin, visibility: origin === null ? EventVisibility.Private : EventVisibility.Public, location: locationOf(line) });\n }\n } else if (keyword === 'example') {\n if (placedBody !== undefined) placedBody.tryParse(context, line);\n else examples.push(parseExample(context, line));\n } else if (keyword === 'eventsource') {\n eventSources.push(parseEventSource(context, line));\n } else if (keyword === 'system') {\n systems.push(parseSystem(context, line));\n } else if (keyword === 'concept') {\n concepts.push(parseConcept(context, line));\n } else if (keyword === 'type') {\n types.push(parseType(context, line));\n } else if (keyword === 'module' && !isDocumentPlacement(placement)) {\n parseModuleInPlacedFile(context, line, placement, moduleBody);\n } else if (keyword === 'module') {\n modules.push(parseModule(context, line));\n } else if (keyword === 'persona') {\n personas.push(parsePersona(context, line));\n } else if (keyword === 'sticky') {\n const stickyNote = parseStickyNote(context, line);\n if (stickyNote !== null) stickyNotes.push(stickyNote);\n } else if (keyword === 'seed') {\n seeds.push(parseSeed(context.valueContext, line));\n } else if (keyword === 'purpose' && placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else if (keyword === 'purpose') {\n purposes.push(parsePurpose(context, line));\n } else if (keyword === 'identity') {\n identity = parseIdentity(context, line, identity);\n } else if (keyword === 'policy') {\n const policy = parsePolicy(context, line);\n if (policies.some(previous => previous.name === policy.name)) {\n context.error(DiagnosticCodes.DuplicateDeclaration, `Duplicate declaration of policy '${policy.name}' - policy names must be unique`, policy.location);\n }\n policies.push(policy);\n } else if (keyword === 'exposure') {\n exposures.push(parseExposure(context, line));\n } else if (keyword === 'instance') {\n instanceContributions.push(parseInstance(context, line));\n } else if (keyword === 'trigger') {\n const data = parseTriggerDeclaration(context, line);\n const name = /^trigger\\s+([A-Za-z_]\\w*)$/.exec(line.content)?.[1];\n if (name !== undefined) declaredTriggers.push({ name, data });\n } else if (opaqueTopLevel.has(keyword)) {\n if (keyword === 'behavior' || keyword === 'layout') collectInputUses(context, line);\n else if (keyword === 'ui') parseUiProfile(context, line);\n else context.skipOpaqueBlock(line.indent);\n } else if (placedBody?.tryParse(context, line) !== true) {\n reportUnexpectedTopLevel(context, line, placement);\n }\n }\n if (moduleBody !== undefined) {\n modules.unshift(moduleBody.build(context.start, true));\n } else if (featureBody !== undefined) {\n modules.unshift(place(placement, featureBody.build(context.start, true), context.start));\n }\n const root: ApplicationSyntax = { kind: 'ApplicationSyntax', ...(commandReadMode === null ? {} : { commandReadMode }), ...(reactionProductionMode === null ? {} : { reactionProductionMode }), ...(identity === null ? {} : { identity }), sourceOptions: context.sourceOptions, domain, imports, concepts, types, systems, eventSources, examples, modules, personas, policies, purposes, seeds, declaredTriggers, fileImports, ...(exposures.length > 0 ? { exposures } : {}), ...(stickyNotes.length > 0 ? { stickyNotes } : {}), ...(instanceContributions.length > 0 ? { instanceContributions } : {}), location: context.start };\n if (context.authoredDeclarations) recordAuthoredDocument(root);\n return root;\n}\n\nfunction declaresConstruct(keyword: string, line: SourceLine, placement: PlayPlacement): boolean {\n if (keyword === 'import') {\n return importPattern.test(line.content);\n }\n if (keyword === 'module') {\n return isDocumentPlacement(placement);\n }\n if (keyword === 'identity') return line.content === 'identity';\n return keyword === 'purpose' || keyword === 'example' || keyword === 'exposure' || keyword === 'instance' || keyword === 'eventsource' || keyword === 'system' || keyword === 'concept' || keyword === 'type' || keyword === 'persona' || keyword === 'sticky' || opaqueTopLevel.has(keyword);\n}\n\nfunction parseModuleInPlacedFile(context: ParserContext, line: SourceLine, placement: PlayPlacement, moduleBody: ModuleBody | undefined): void {\n const name = modulePattern.exec(line.content)?.[1] ?? '';\n\n // Restating the module a file is placed in says nothing new, so its body simply joins the placement.\n if (moduleBody !== undefined && name === placement[0]) {\n context.authoredDeclarations = true;\n moduleBody.parseChildren(context, line);\n return;\n }\n context.error(DiagnosticCodes.ModuleInPlacedFile,\n `This file is imported into ${describePlacement(placement)}, so it cannot declare module '${name}' - import it at the top level of a document instead`, locationOf(line));\n context.skipBlock(line.indent);\n}\n\nfunction reportUnexpectedTopLevel(context: ParserContext, line: SourceLine, placement: PlayPlacement): void {\n const word = firstWord(line.content);\n if (!isDocumentPlacement(placement)) {\n const expected = placement.length === 1 ? moduleBodyExpected : featureBodyExpected;\n context.error(DiagnosticCodes.UnexpectedInPlacedFile,\n `Unexpected '${word}' in a file imported into ${describePlacement(placement)} - expected an application declaration or ${expected}`, locationOf(line));\n } else {\n const hint = bodyKeywords.has(word)\n ? ` - '${word}' belongs in a module or feature; wrap it in one, or import this file from inside one`\n : ' - expected domain, import, concept, type, policy, persona, sticky note, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout';\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Unexpected '${word}' at the top level${hint}`, locationOf(line));\n }\n context.skipBlock(line.indent);\n}\n\n// Wraps the feature a file is placed in in the features and module around it, each marked as a placement.\nfunction place(placement: PlayPlacement, innermost: FeatureSyntax, start: SourceLocation): ModuleSyntax {\n let feature = innermost;\n for (let index = placement.length - 2; index >= 1; index--) {\n feature = {\n kind: 'FeatureSyntax', name: placement[index], description: null, authorize: null,\n features: [feature], slices: [], fileImports: [], isPlacement: true, location: start,\n };\n }\n return {\n kind: 'ModuleSyntax', name: placement[0], description: null, authorize: null,\n features: [feature], fileImports: [], isPlacement: true, location: start,\n };\n}\n\nfunction parseDomain(context: ParserContext, line: SourceLine, existing: DomainSyntax | null, sawOtherConstruct: boolean): DomainSyntax | null {\n const match = domainPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidDomainDeclaration, `Invalid domain declaration '${line.content}' - expected 'domain <Qualified.Name>'`, locationOf(line));\n return existing;\n }\n if (existing !== null) {\n context.error(DiagnosticCodes.DuplicateDomain, 'The document already declares a domain - a document can have at most one', locationOf(line));\n return existing;\n }\n if (sawOtherConstruct) {\n context.error(DiagnosticCodes.DomainNotFirst, '\\'domain\\' must be declared before any other construct', locationOf(line));\n }\n return { kind: 'DomainSyntax', name: match[1], location: locationOf(line) };\n}\n\nfunction warnOnTabIndentation(context: ParserContext, lines: readonly SourceLine[]): void {\n let inFence = false;\n for (const line of lines) {\n if (line.raw.trimStart().startsWith('```')) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && tabIndentPattern.test(line.raw)) {\n context.warning(DiagnosticCodes.TabIndentation, 'Screenplay is indentation based - use spaces, not tabs', startOf(line));\n }\n }\n}\n\nfunction parseConcept(context: ParserContext, line: SourceLine): ConceptSyntax {\n const match = conceptPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidConceptDeclaration, `Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ConceptSyntax', name: firstWord(line.content), type: '', attributes: [], values: [], location: locationOf(line) };\n }\n const [, name, type, attributeText] = match;\n const attributes = parseComplianceMarkers(context, line, name, attributeText);\n if (type !== 'Enum' && !primitiveTypes.includes(type)) {\n context.error(DiagnosticCodes.UnknownPrimitiveType, `Unknown primitive type '${type}' - expected ${primitiveTypes.join(', ')} or Enum`, locationOf(line));\n }\n const values: string[] = [];\n const members = new EnumerationMembers();\n let generation: GenerationSyntax | null = null;\n let declaredGeneration = false;\n let description: string | null = null;\n const validations: ValidateSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const memberName = type === 'Enum' ? members.tryNumbered(context, child) : undefined;\n if (memberName !== undefined) {\n values.push(memberName);\n } else if (firstWord(child.content) === 'description' && (type !== 'Enum' || child.content !== 'description' || context.peekChild(child.indent)?.content.startsWith('```') === true)) {\n description = parseDescription(context, child, description, `Concept '${name}'`);\n } else if (isFileDirective(child)) {\n continue;\n } else if (firstWord(child.content) === 'validate') {\n if (type === 'Enum' && child.content === 'validate' && context.peekChild(child.indent) === undefined) {\n context.warning(DiagnosticCodes.ValidateReadAsEnumerationBlock,\n `'validate' in enumeration concept '${name}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,\n locationOf(child));\n }\n const parsed = parseValidate(context, child, 'concept', name);\n if (parsed !== undefined) validations.push(parsed);\n } else if (firstWord(child.content) === 'generate' && !(type === 'Enum' && child.content === 'generate')) {\n if (declaredGeneration) context.error(DiagnosticCodes.DuplicateGeneration, `Concept '${name}' declares generation more than once.`, locationOf(child));\n const parsed = parseGeneration(context, child, type);\n if (!declaredGeneration) generation = parsed;\n declaredGeneration = true;\n } else if (parseComplianceDirective(context, child, name, attributes)) {\n // Compliance directives are modeled by their original concept marker.\n } else if (type === 'Enum' && enumValuePattern.test(child.content)) {\n values.push(unescapeIdentifier(child.content));\n } else if (type === 'Enum') {\n context.error(DiagnosticCodes.InvalidEnumerationValue, `Invalid enum value '${child.content}' - expected an identifier`, locationOf(child));\n } else {\n context.error(DiagnosticCodes.UnknownConceptDirective, `Unexpected '${child.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason \"<text>\"'`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const valueNumbers = members.finish(context, line, values.length);\n return { kind: 'ConceptSyntax', name, type, attributes, values, validations, description, ...(generation === null ? {} : { generation }), ...(valueNumbers === undefined ? {} : { valueNumbers }), location: locationOf(line) };\n}\n\n// 'persona <Name>' with an optional description and the policies it holds - the port of the C# ParsePersona.\nfunction parsePersona(context: ParserContext, line: SourceLine): PersonaSyntax {\n const name = personaPattern.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid persona declaration '${line.content}' - expected 'persona <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n const policies: string[] = [];\n const goals: string[] = [];\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | 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, `Persona '${name}'`);\n } else if (keyword === 'goal') {\n const goal = personaGoalPattern.exec(child.content);\n if (goal === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid goal '${child.content}' - expected 'goal \"<text>\"'`, locationOf(child));\n } else {\n goals.push(unescapeString(goal[1]));\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else if (keyword === 'policy') {\n const policy = personaPolicyPattern.exec(child.content);\n if (policy === null) {\n context.error(DiagnosticCodes.InvalidPersonaPolicyReference, `Invalid policy reference '${child.content}' - expected 'policy <Name>'`, locationOf(child));\n } else {\n policies.push(policy[1]);\n }\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in persona body - expected description, goal, policy, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return {\n kind: 'PersonaSyntax', name, description, policies,\n ...(goals.length > 0 ? { goals } : {}),\n ...(position === null ? {} : { x: position[0], y: position[1] }),\n ...(size === null ? {} : { width: size[0], height: size[1] }),\n location: locationOf(line),\n };\n}\n\n// 'sticky note on <canvas>' with the text it carries, an optional colour and where it sits on that canvas - the port of the C# ParseStickyNote.\nfunction parseStickyNote(context: ParserContext, line: SourceLine): StickyNoteSyntax | null {\n const canvasMatch = stickyNotePattern.exec(line.content);\n if (canvasMatch === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid sticky note declaration '${line.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`, locationOf(line));\n context.skipBlock(line.indent);\n return null;\n }\n let text: string | null = null;\n let colour: string | null = null;\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | 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 text = parseDescription(context, child, text, 'A sticky note');\n } else if (keyword === 'colour') {\n const match = stickyNoteColourPattern.exec(child.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid colour '${child.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`, locationOf(child));\n } else {\n colour = match[1];\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in sticky note body - expected description, colour, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n if (text === null || position === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, 'A sticky note needs a description (the text on it) and a position', locationOf(line));\n return null;\n }\n return { kind: 'StickyNoteSyntax', canvas: canvasMatch[1] as StickyNoteSyntax['canvas'], text, colour, x: position[0], y: position[1], width: size === null ? null : size[0], height: size === null ? null : size[1], location: locationOf(line) };\n}\n\n"],"mappings":"0gEAqDA,MAAMA,EAAgBC,EAAQ,kDAAkD,EAC1EC,EAAgBD,EAAQ,iDAAiDE,EAAkB,MAAM,EACjGC,EAAiBH,EAAQ,qDAAqD,EAC9EI,EAAmBJ,EAAQ,gBAAgB,EAC3CK,EAAiBL,EAAQ,8BAA8B,EACvDM,EAAuBN,EAAQ,6BAA6B,EAC5DO,EAAqBP,EAAQ,cAAcE,EAAkB,IAAI,EACjEM,EAAoBR,EAAQ,0EAA0E,EACtGS,EAA0BT,EAAQ,sCAAsC,EACxEU,EAAmB,UACnBC,EAAiB,CAAC,OAAQ,SAAU,MAAO,UAAW,OAAQ,OAAQ,UAAU,EAIhFC,kBAAiB,IAAI,IAAI,CAAC,SAAU,iBAAkB,OAAQ,KAAM,QAAS,UAAW,SAAU,WAAY,QAAQ,CAAC,EAGvHC,kBAAe,IAAI,IAAI,CAAC,QAAS,UAAW,cAAe,gBAAiB,YAAa,SAAU,SAAU,OAAQ,aAAc,KAAM,MAAM,CAAC,EAItJ,SAAgB,iBAAiB,EAAwB,EAA8B,EAA2BC,EAAsC,CACpJ,EAAQ,wBAA0B,GAClC,qBAAqBC,EAASC,CAAK,EACnC,IAAMC,EAAaC,EAAU,SAAW,EAAI,IAAIC,EAAWD,EAAU,EAAE,EAAI,IAAA,GACrEE,EAAcF,EAAU,OAAS,EAAI,IAAIG,EAAYH,EAAUA,EAAU,OAAS,EAAE,EAAI,IAAA,GACxFI,EAAaL,GAAcG,EAC7BG,EAAkC,KAClCC,EAAwD,KACxDC,EAAqB,GACrBC,EAA0C,KAC1CC,EAAkB,GAClBC,EAA8B,KAC5BC,EAA0B,CAAC,EAC3BC,EAAkC,CAAC,EACnCC,EAA4B,CAAC,EAC7BC,EAAsB,CAAC,EACvBC,EAA0B,CAAC,EAC3BC,EAAoC,CAAC,EACrCC,EAA0B,CAAC,EAC3BC,EAA4B,CAAC,EAC7BC,EAAkC,CAAC,EACnCC,EAA2B,CAAC,EAC5BC,EAA4B,CAAC,EAC7BC,EAAsB,CAAC,EACvBC,EAAyC,CAAC,EAC1CC,EAAiF,CAAC,EAClFC,EAA8B,CAAC,EAC/BC,EAAuD,CAAC,EAC1DC,EAAoB,GACxB,IAAK,IAAIC,EAAO/B,EAAQ,OAAO,gBAAgB,EAAG+B,IAAS,IAAA,GAAW,EAAO/B,EAAQ,OAAO,gBAAgB,EAAG,CAC3GA,EAAQ,OAAO,gBAAgB,EAC/B,IAAMgC,EAAUC,EAAUF,EAAK,OAAO,EACtC,GAAIC,IAAY,WAAa,2BAA2B,KAAKD,EAAK,OAAO,EACjEnB,GAAmB,CAACsB,EAAoB/B,CAAS,GAAK,CAAC,gCAAgC,KAAK4B,EAAK,OAAO,EACxG/B,EAAQ,MAAMmC,EAAgB,+BAAgC,kEAAmEC,EAAWL,CAAI,CAAC,EAEjJ,EAAA,YAEJ,EAAkB,QAGtB,GAAIC,IAAY,WACRtB,GAAsB,CAACwB,EAAoB/B,CAAS,GAAK,CAAC,gCAAgC,KAAK4B,EAAK,OAAO,EAC3G/B,EAAQ,MAAMmC,EAAgB,kCAAmC,kEAAmEC,EAAWL,CAAI,CAAC,EAEpJ,EAAA,SAEJ,EAAqB,QAGzB,GAAIC,IAAY,OACZK,EAA0BrC,EAAS+B,CAAI,OAG3C,GAAIC,IAAY,SACZ,EAAQ,qBAAuB,GAC/B,EAAS,YAAYhC,EAAS+B,EAAMlB,EAAQiB,CAAiB,OAOjE,GAFA,IAAsB,kBAAkBE,EAASD,EAAM5B,CAAS,EAChE,EAAQ,uBAAyB6B,IAAY,UAAY,kBAAkBA,EAASD,EAAM5B,CAAS,EAC/F6B,IAAY,UAAYM,EAAaP,EAAK,OAAO,EAG7CxB,IAAe,IAAA,GAGfgC,EAAgBvC,EAAS+B,EAAMhB,CAAW,EAF1CR,EAAW,SAASP,EAAS+B,CAAI,OAIlC,GAAIC,IAAY,SAAU,CAC7B,IAAMQ,EAAQtD,EAAc,KAAK6C,EAAK,OAAO,EAC7C,GAAIS,IAAU,KACVxC,EAAQ,MAAMmC,EAAgB,yBAA0B,mBAAmBJ,EAAK,QAAQ,0DAA2DK,EAAWL,CAAI,CAAC,MAChK,CACH,IAAMU,EAASD,EAAM,QAAQ,SAAW,IAAA,GAAY,KAAOE,EAAeF,EAAM,OAAO,MAAM,EACzFC,IAAW,MAAQE,GAAyBF,CAAM,GAClDzC,EAAQ,MAAMmC,EAAgB,yBAA0B,oDAAqDC,EAAWL,CAAI,CAAC,EAEjIjB,EAAQ,KAAK,CAAE,KAAM,eAAgB,cAAe0B,EAAM,GAAI,SAAQ,WAAYC,IAAW,KAAA,UAAA,SAAyD,SAAUL,EAAWL,CAAI,CAAE,CAAC,CACtL,CACJ,MAAO,GAAIC,IAAY,UACfzB,IAAe,IAAA,GACdmB,EAAS,KAAKkB,EAAa5C,EAAS+B,CAAI,CAAC,EADhBxB,EAAW,SAASP,EAAS+B,CAAI,OAE5D,GAAIC,IAAY,cACnBb,EAAa,KAAK0B,EAAiB7C,EAAS+B,CAAI,CAAC,OAC9C,GAAIC,IAAY,SACnBd,EAAQ,KAAK4B,EAAY9C,EAAS+B,CAAI,CAAC,OACpC,GAAIC,IAAY,UACnBhB,EAAS,KAAK,aAAahB,EAAS+B,CAAI,CAAC,OACtC,GAAIC,IAAY,OACnBf,EAAM,KAAK8B,GAAU/C,EAAS+B,CAAI,CAAC,OAChC,GAAIC,IAAY,UAAY,CAACE,EAAoB/B,CAAS,EAC7D,wBAAwBH,EAAS+B,EAAM5B,EAAWD,CAAU,OACzD,GAAI8B,IAAY,SACnBZ,EAAQ,KAAK4B,EAAYhD,EAAS+B,CAAI,CAAC,OACpC,GAAIC,IAAY,UACnBX,EAAS,KAAK,aAAarB,EAAS+B,CAAI,CAAC,OACtC,GAAIC,IAAY,SAAU,CAC7B,IAAMiB,EAAa,gBAAgBjD,EAAS+B,CAAI,EAC5CkB,IAAe,MAAM3B,EAAY,KAAK2B,CAAU,CACxD,MAAO,GAAIjB,IAAY,OACnBP,EAAM,KAAKyB,GAAUlD,EAAQ,aAAc+B,CAAI,CAAC,OAC7C,GAAIC,IAAY,WAAazB,IAAe,IAAA,GAC/CA,EAAW,SAASP,EAAS+B,CAAI,OAC9B,GAAIC,IAAY,UACnBR,EAAS,KAAK2B,EAAanD,EAAS+B,CAAI,CAAC,OACtC,GAAIC,IAAY,WACnB,EAAWoB,EAAcpD,EAAS+B,EAAMvB,CAAQ,OAC7C,GAAIwB,IAAY,SAAU,CAC7B,IAAMqB,EAASC,GAAYtD,EAAS+B,CAAI,EACpCR,EAAS,KAAK,GAAYgC,EAAS,OAASF,EAAO,IAAI,GACvDrD,EAAQ,MAAMmC,EAAgB,qBAAsB,oCAAoCkB,EAAO,KAAK,iCAAkCA,EAAO,QAAQ,EAEzJ9B,EAAS,KAAK8B,CAAM,CACxB,MAAO,GAAIrB,IAAY,WACnBJ,EAAU,KAAK4B,GAAcxD,EAAS+B,CAAI,CAAC,OACxC,GAAIC,IAAY,WACnBH,EAAsB,KAAK4B,EAAczD,EAAS+B,CAAI,CAAC,OACpD,GAAIC,IAAY,UAAW,CAC9B,IAAM0B,EAAOC,EAAwB3D,EAAS+B,CAAI,EAC5C6B,EAAO,6BAA6B,KAAK7B,EAAK,OAAO,CAAC,GAAG,GAC3D6B,IAAS,IAAA,IAAWjC,EAAiB,KAAK,CAAE,OAAM,MAAK,CAAC,CAChE,MAAW9B,EAAe,IAAImC,CAAO,EAC7BA,IAAY,YAAcA,IAAY,SAAU6B,EAAiB7D,EAAS+B,CAAI,EACzEC,IAAY,KAAM8B,EAAe9D,EAAS+B,CAAI,EAClD/B,EAAQ,gBAAgB+B,EAAK,MAAM,EACjCxB,GAAY,SAASP,EAAS+B,CAAI,IAAM,IAC/C,yBAAyB/B,EAAS+B,EAAM5B,CAAS,CAEzD,CACID,IAAe,IAAA,GAERG,IAAgB,IAAA,IACvBe,EAAQ,QAAQ,MAAMjB,EAAWE,EAAY,MAAML,EAAQ,MAAO,EAAI,EAAGA,EAAQ,KAAK,CAAC,EAFvFoB,EAAQ,QAAQlB,EAAW,MAAMF,EAAQ,MAAO,EAAI,CAAC,EAIzD,IAAM+D,EAA0B,CAAE,KAAM,oBAAqB,GAAIpD,IAAoB,KAAO,CAAC,EAAI,CAAE,iBAAgB,EAAI,GAAIF,IAA2B,KAAO,CAAC,EAAI,CAAE,wBAAuB,EAAI,GAAID,IAAa,KAAO,CAAC,EAAI,CAAE,UAAS,EAAI,cAAeR,EAAQ,cAAe,SAAQ,UAAS,WAAU,QAAO,UAAS,eAAc,WAAU,UAAS,WAAU,WAAU,WAAU,QAAO,mBAAkB,cAAa,GAAI4B,EAAU,OAAS,EAAI,CAAE,WAAU,EAAI,CAAC,EAAI,GAAIN,EAAY,OAAS,EAAI,CAAE,aAAY,EAAI,CAAC,EAAI,GAAIO,EAAsB,OAAS,EAAI,CAAE,uBAAsB,EAAI,CAAC,EAAI,SAAU7B,EAAQ,KAAM,EAErmB,OADIA,EAAQ,sBAAsBgE,EAAuBD,CAAI,EACtDA,CACX,CAEA,SAAS,kBAAkB,EAAiB,EAAkB,EAAmC,CAQ7F,OAPI/B,IAAY,SACL9C,EAAc,KAAK6C,EAAK,OAAO,EAEtCC,IAAY,SACLE,EAAoB/B,CAAS,EAEpC6B,IAAY,WAAmBD,EAAK,UAAY,WAC7CC,IAAY,WAAaA,IAAY,WAAaA,IAAY,YAAcA,IAAY,YAAcA,IAAY,eAAiBA,IAAY,UAAYA,IAAY,WAAaA,IAAY,QAAUA,IAAY,WAAaA,IAAY,UAAYnC,EAAe,IAAImC,CAAO,CAChS,CAEA,SAAS,wBAAwB,EAAwB,EAAkB,EAA0B,EAA0C,CAC3I,IAAM4B,EAAOK,EAAc,KAAKlC,EAAK,OAAO,CAAC,GAAG,IAAM,GAGlD7B,IAAe,IAAA,IAAa0D,IAASzD,EAAU,IAC/C,EAAQ,qBAAuB,GAC/BD,EAAW,cAAcF,EAAS+B,CAAI,IAG1C/B,EAAQ,MAAMmC,EAAgB,mBAC1B,8BAA8B+B,EAAkB/D,CAAS,EAAE,iCAAiCyD,EAAK,sDAAuDxB,EAAWL,CAAI,CAAC,EAC5K/B,EAAQ,UAAU+B,EAAK,MAAM,EACjC,CAEA,SAAS,yBAAyB,EAAwB,EAAkB,EAAgC,CACxG,IAAMoC,EAAOlC,EAAUF,EAAK,OAAO,EACnC,GAAKG,EAAoB/B,CAAS,EAI3B,CACH,IAAMiE,EAAOtE,EAAa,IAAIqE,CAAI,EAC5B,OAAOA,EAAK,uFACZ,+KACNnE,EAAQ,MAAMmC,EAAgB,yBAA0B,eAAegC,EAAK,oBAAoBC,IAAQhC,EAAWL,CAAI,CAAC,CAC5H,KATqC,CACjC,IAAMsC,EAAWlE,EAAU,SAAW,EAAImE,EAAqBC,EAC/DvE,EAAQ,MAAMmC,EAAgB,uBAC1B,eAAegC,EAAK,4BAA4BD,EAAkB/D,CAAS,EAAE,4CAA4CkE,IAAYjC,EAAWL,CAAI,CAAC,CAC7J,CAMA/B,EAAQ,UAAU+B,EAAK,MAAM,CACjC,CAGA,SAAS,MAAM,EAA0B,EAA0B,EAAqC,CACpG,IAAIyC,EAAUC,EACd,IAAK,IAAIC,EAAQvE,EAAU,OAAS,EAAGuE,GAAS,EAAG,IAC/C,EAAU,CACN,KAAM,gBAAiB,KAAMvE,EAAUuE,GAAQ,YAAa,KAAM,UAAW,KAC7E,SAAU,CAACF,CAAO,EAAG,OAAQ,CAAC,EAAG,YAAa,CAAC,EAAG,YAAa,GAAM,SAAUG,CACnF,EAEJ,MAAO,CACH,KAAM,eAAgB,KAAMxE,EAAU,GAAI,YAAa,KAAM,UAAW,KACxE,SAAU,CAACqE,CAAO,EAAG,YAAa,CAAC,EAAG,YAAa,GAAM,SAAUG,CACvE,CACJ,CAEA,SAAS,YAAY,EAAwB,EAAkB,EAA+B,EAAiD,CAC3I,IAAMnC,EAAQxD,EAAc,KAAK+C,EAAK,OAAO,EAY7C,OAXIS,IAAU,MACVxC,EAAQ,MAAMmC,EAAgB,yBAA0B,+BAA+BJ,EAAK,QAAQ,wCAAyCK,EAAWL,CAAI,CAAC,EACtJ6C,GAEPA,IAAa,MAIb9C,GACA9B,EAAQ,MAAMmC,EAAgB,eAAgB,uDAA0DC,EAAWL,CAAI,CAAC,EAErH,CAAE,KAAM,eAAgB,KAAMS,EAAM,GAAI,SAAUJ,EAAWL,CAAI,CAAE,IANtE/B,EAAQ,MAAMmC,EAAgB,gBAAiB,2EAA4EC,EAAWL,CAAI,CAAC,EACpI6C,EAMf,CAEA,SAAS,qBAAqB,EAAwB,EAAoC,CACtF,IAAIC,EAAU,GACd,IAAK,IAAM9C,KAAQ9B,EACX8B,EAAK,IAAI,UAAU,CAAC,CAAC,WAAW,KAAK,EACrC,EAAU,CAAC8C,EAGX,CAACA,GAAWlF,EAAiB,KAAKoC,EAAK,GAAG,GAC1C/B,EAAQ,QAAQmC,EAAgB,eAAgB,yDAA0D2C,EAAQ/C,CAAI,CAAC,CAGnI,CAEA,SAAS,aAAa,EAAwB,EAAiC,CAC3E,IAAMS,EAAQpD,EAAe,KAAK2C,EAAK,OAAO,EAC9C,GAAIS,IAAU,KAGV,OAFAxC,EAAQ,MAAMmC,EAAgB,0BAA2B,gCAAgCJ,EAAK,QAAQ,wCAAyCK,EAAWL,CAAI,CAAC,EAC/J/B,EAAQ,UAAU+B,EAAK,MAAM,EACtB,CAAE,KAAM,gBAAiB,KAAME,EAAUF,EAAK,OAAO,EAAG,KAAM,GAAI,WAAY,CAAC,EAAG,OAAQ,CAAC,EAAG,SAAUK,EAAWL,CAAI,CAAE,EAEpI,GAAM,EAAG6B,EAAMmB,EAAMC,GAAiBxC,EAChCyC,EAAaC,EAAuBlF,EAAS+B,EAAM6B,EAAMoB,CAAa,EACxED,IAAS,QAAU,CAACnF,EAAe,SAASmF,CAAI,GAChD/E,EAAQ,MAAMmC,EAAgB,qBAAsB,2BAA2B4C,EAAK,eAAenF,EAAe,KAAK,IAAI,EAAE,UAAWwC,EAAWL,CAAI,CAAC,EAE5J,IAAMoD,EAAmB,CAAC,EACpBC,EAAU,IAAIC,EAChBC,EAAsC,KACtCC,EAAqB,GACrBC,EAA6B,KAC3BC,EAAgC,CAAC,EACvC,IAAK,IAAIC,EAAQ1F,EAAQ,UAAU+B,EAAK,MAAM,EAAG2D,IAAU,IAAA,GAAW,EAAQ1F,EAAQ,UAAU+B,EAAK,MAAM,EAAG,CAC1G/B,EAAQ,OAAO,gBAAgB,EAC/B,IAAM2F,EAAaZ,IAAS,OAASK,EAAQ,YAAYpF,EAAS0F,CAAK,EAAI,IAAA,GAC3E,GAAIC,IAAe,IAAA,GACfR,EAAO,KAAKQ,CAAU,OACnB,GAAI1D,EAAUyD,EAAM,OAAO,IAAM,gBAAkBX,IAAS,QAAUW,EAAM,UAAY,eAAiB1F,EAAQ,UAAU0F,EAAM,MAAM,CAAC,EAAE,QAAQ,WAAW,KAAK,IAAM,IAC3K,EAAcE,EAAiB5F,EAAS0F,EAAOF,EAAa,YAAY5B,EAAK,EAAE,OAC5E,GAAIiC,EAAgBH,CAAK,EAC5B,cACG,GAAIzD,EAAUyD,EAAM,OAAO,IAAM,WAAY,CAC5CX,IAAS,QAAUW,EAAM,UAAY,YAAc1F,EAAQ,UAAU0F,EAAM,MAAM,IAAM,IAAA,IACvF1F,EAAQ,QAAQmC,EAAgB,+BAC5B,sCAAsCyB,EAAK,oGAC3CxB,EAAWsD,CAAK,CAAC,EAEzB,IAAMI,EAASC,EAAc/F,EAAS0F,EAAO,UAAW9B,CAAI,EACxDkC,IAAW,IAAA,IAAWL,EAAY,KAAKK,CAAM,CACrD,MAAO,GAAI7D,EAAUyD,EAAM,OAAO,IAAM,aAAgBX,IAAS,QAAUW,EAAM,UAAY,YAAa,CAClGH,GAAoBvF,EAAQ,MAAMmC,EAAgB,oBAAqB,YAAYyB,EAAK,uCAAwCxB,EAAWsD,CAAK,CAAC,EACrJ,IAAMI,EAASE,EAAgBhG,EAAS0F,EAAOX,CAAI,EAC9CQ,IAAoB,EAAaO,GACtC,EAAqB,EACzB,MAAWG,EAAyBjG,EAAS0F,EAAO9B,EAAMqB,CAAU,IAEzDF,IAAS,QAAU1F,EAAiB,KAAKqG,EAAM,OAAO,EAC7DP,EAAO,KAAKe,EAAmBR,EAAM,OAAO,CAAC,EACtCX,IAAS,OAChB/E,EAAQ,MAAMmC,EAAgB,wBAAyB,uBAAuBuD,EAAM,QAAQ,4BAA6BtD,EAAWsD,CAAK,CAAC,GAE1I1F,EAAQ,MAAMmC,EAAgB,wBAAyB,eAAeuD,EAAM,QAAQ,iGAAkGtD,EAAWsD,CAAK,CAAC,EACvM1F,EAAQ,UAAU0F,EAAM,MAAM,GAEtC,CACA,IAAMS,EAAef,EAAQ,OAAOpF,EAAS+B,EAAMoD,EAAO,MAAM,EAChE,MAAO,CAAE,KAAM,gBAAiB,OAAM,OAAM,aAAY,SAAQ,cAAa,cAAa,GAAIG,IAAe,KAAO,CAAC,EAAI,CAAE,YAAW,EAAI,GAAIa,IAAiB,IAAA,GAAY,CAAC,EAAI,CAAE,cAAa,EAAI,SAAU/D,EAAWL,CAAI,CAAE,CAClO,CAGA,SAAS,aAAa,EAAwB,EAAiC,CAC3E,IAAM6B,EAAOtE,EAAe,KAAKyC,EAAK,OAAO,CAAC,GAAG,IAAM,GACnD6B,IAAS,IACT5D,EAAQ,MAAMmC,EAAgB,0BAA2B,gCAAgCJ,EAAK,QAAQ,+BAAgCK,EAAWL,CAAI,CAAC,EAE1J,IAAIyD,EAA6B,KAC3BjE,EAAqB,CAAC,EACtB6E,EAAkB,CAAC,EACrBC,EAA6C,KAC7CC,EAAyC,KAC7C,IAAK,IAAIZ,EAAQ1F,EAAQ,UAAU+B,EAAK,MAAM,EAAG2D,IAAU,IAAA,GAAW,EAAQ1F,EAAQ,UAAU+B,EAAK,MAAM,EAAG,CAC1G/B,EAAQ,OAAO,gBAAgB,EAC/B,IAAMgC,EAAUC,EAAUyD,EAAM,OAAO,EACvC,GAAI1D,IAAY,cACZ,EAAc4D,EAAiB5F,EAAS0F,EAAOF,EAAa,YAAY5B,EAAK,EAAE,OAC5E,GAAI5B,IAAY,OAAQ,CAC3B,IAAMuE,EAAO/G,EAAmB,KAAKkG,EAAM,OAAO,EAC9Ca,IAAS,KACTvG,EAAQ,MAAMmC,EAAgB,0BAA2B,iBAAiBuD,EAAM,QAAQ,8BAA+BtD,EAAWsD,CAAK,CAAC,EAExIU,EAAM,KAAK1D,EAAe6D,EAAK,EAAE,CAAC,CAE1C,MAAO,GAAIvE,IAAY,WACnB,EAAWwE,EAAgBxG,EAAS0F,EAAO,WAAY,IAAK,IAAKW,EAAU,EAAI,GAAKA,OACjF,GAAIrE,IAAY,OACnB,EAAOwE,EAAgBxG,EAAS0F,EAAO,OAAQ,QAAS,SAAUY,EAAM,EAAK,GAAKA,OAC/E,GAAItE,IAAY,SAAU,CAC7B,IAAMqB,EAAS9D,EAAqB,KAAKmG,EAAM,OAAO,EAClDrC,IAAW,KACXrD,EAAQ,MAAMmC,EAAgB,8BAA+B,6BAA6BuD,EAAM,QAAQ,8BAA+BtD,EAAWsD,CAAK,CAAC,EAExJnE,EAAS,KAAK8B,EAAO,EAAE,CAE/B,MACIrD,EAAQ,MAAMmC,EAAgB,wBAAyB,eAAeH,EAAQ,0EAA2EI,EAAWsD,CAAK,CAAC,EAC1K1F,EAAQ,UAAU0F,EAAM,MAAM,CAEtC,CACA,MAAO,CACH,KAAM,gBAAiB,OAAM,cAAa,WAC1C,GAAIU,EAAM,OAAS,EAAI,CAAE,OAAM,EAAI,CAAC,EACpC,GAAIC,IAAa,KAAO,CAAC,EAAI,CAAE,EAAGA,EAAS,GAAI,EAAGA,EAAS,EAAG,EAC9D,GAAIC,IAAS,KAAO,CAAC,EAAI,CAAE,MAAOA,EAAK,GAAI,OAAQA,EAAK,EAAG,EAC3D,SAAUlE,EAAWL,CAAI,CAC7B,CACJ,CAGA,SAAS,gBAAgB,EAAwB,EAA2C,CACxF,IAAM0E,EAAchH,EAAkB,KAAKsC,EAAK,OAAO,EACvD,GAAI0E,IAAgB,KAGhB,OAFAzG,EAAQ,MAAMmC,EAAgB,0BAA2B,oCAAoCJ,EAAK,QAAQ,oIAAqIK,EAAWL,CAAI,CAAC,EAC/P/B,EAAQ,UAAU+B,EAAK,MAAM,EACtB,KAEX,IAAI2E,EAAsB,KACtBC,EAAwB,KACxBN,EAA6C,KAC7CC,EAAyC,KAC7C,IAAK,IAAIZ,EAAQ1F,EAAQ,UAAU+B,EAAK,MAAM,EAAG2D,IAAU,IAAA,GAAW,EAAQ1F,EAAQ,UAAU+B,EAAK,MAAM,EAAG,CAC1G/B,EAAQ,OAAO,gBAAgB,EAC/B,IAAMgC,EAAUC,EAAUyD,EAAM,OAAO,EACvC,GAAI1D,IAAY,cACZ,EAAO4D,EAAiB5F,EAAS0F,EAAOgB,EAAM,eAAe,OAC1D,GAAI1E,IAAY,SAAU,CAC7B,IAAMQ,EAAQ9C,EAAwB,KAAKgG,EAAM,OAAO,EACpDlD,IAAU,KACVxC,EAAQ,MAAMmC,EAAgB,0BAA2B,mBAAmBuD,EAAM,QAAQ,8EAA+EtD,EAAWsD,CAAK,CAAC,EAE1L,EAASlD,EAAM,EAEvB,MAAWR,IAAY,WACnB,EAAWwE,EAAgBxG,EAAS0F,EAAO,WAAY,IAAK,IAAKW,EAAU,EAAI,GAAKA,EAC7ErE,IAAY,OACnB,EAAOwE,EAAgBxG,EAAS0F,EAAO,OAAQ,QAAS,SAAUY,EAAM,EAAK,GAAKA,GAElFtG,EAAQ,MAAMmC,EAAgB,wBAAyB,eAAeH,EAAQ,wEAAyEI,EAAWsD,CAAK,CAAC,EACxK1F,EAAQ,UAAU0F,EAAM,MAAM,EAEtC,CAKA,OAJIgB,IAAS,MAAQL,IAAa,MAC9BrG,EAAQ,MAAMmC,EAAgB,0BAA2B,oEAAqEC,EAAWL,CAAI,CAAC,EACvI,MAEJ,CAAE,KAAM,mBAAoB,OAAQ0E,EAAY,GAAkC,OAAM,SAAQ,EAAGJ,EAAS,GAAI,EAAGA,EAAS,GAAI,MAAOC,IAAS,KAAO,KAAOA,EAAK,GAAI,OAAQA,IAAS,KAAO,KAAOA,EAAK,GAAI,SAAUlE,EAAWL,CAAI,CAAE,CACrP"}
1
+ {"version":3,"file":"ScreenplayParser.js","names":["domainPattern","pattern","timeZonePattern","stringBodyPattern","importPattern","conceptPattern","enumValuePattern","personaPattern","personaPolicyPattern","personaGoalPattern","stickyNotePattern","stickyNoteColourPattern","tabIndentPattern","primitiveTypes","opaqueTopLevel","bodyKeywords","documentPlacement","context","lines","moduleBody","placement","ModuleBody","featureBody","FeatureBody","placedBody","identity","reactionProductionMode","sawReactionBatches","commandReadMode","timeZone","sawTimeZone","sawCommandReads","domain","imports","fileImports","concepts","types","systems","eventSources","modules","personas","stickyNotes","policies","purposes","seeds","examples","declaredTriggers","exposures","instanceContributions","sawOtherConstruct","line","keyword","firstWord","isDocumentPlacement","DiagnosticCodes","locationOf","match","unescapeString","misplacedReactionIdentity","isFileImport","parseFileImport","origin","isBlankPublicEventOrigin","parseExample","parseEventSource","parseSystem","parseType","parseModule","stickyNote","parseSeed","parsePurpose","parseIdentity","policy","parsePolicy","previous","parseExposure","parseInstance","data","parseTriggerDeclaration","name","collectInputUses","parseUiProfile","root","recordAuthoredDocument","modulePattern","describePlacement","word","hint","expected","moduleBodyExpected","featureBodyExpected","feature","innermost","index","start","existing","inFence","startOf","type","attributeText","attributes","parseComplianceMarkers","values","members","EnumerationMembers","generation","declaredGeneration","description","validations","child","memberName","parseDescription","isFileDirective","parsed","parseValidate","parseGeneration","parseComplianceDirective","unescapeIdentifier","valueNumbers","goals","position","size","goal","parseCanvasPair","canvasMatch","text","colour"],"sources":["../../../../../../Compiler/Parsing/ScreenplayParser.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 { CommandReadMode } from '../Syntax/CommandReadMode';\nimport { ReactionProductionMode } from '../Syntax/ReactionProductionMode';\nimport { EnumerationMembers } from './EnumerationMembers';\nimport { GenerationSyntax } from '../Syntax/GenerationSyntax';\nimport { parseGeneration } from './GenerationParser';\nimport { IdentitySyntax } from '../Syntax/IdentitySyntax';\nimport { parseIdentity } from './IdentityParser';\nimport { misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { recordAuthoredDocument } from '../Syntax/SourceOptions';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { describePlacement, documentPlacement, isDocumentPlacement, PlayPlacement } from '../Files/PlayPlacement';\nimport { PersonaSyntax, StickyNoteSyntax } from '../Syntax/Authorization';\nimport { ConceptSyntax, DomainSyntax, ImportSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { TimeZoneSyntax } from '../Syntax/Calendar';\nimport { ApplicationSyntax, FeatureSyntax, FileImportSyntax, ModuleSyntax } from '../Syntax/Structure';\nimport { parseTriggerDeclaration } from './TriggerDataParser';\nimport { pattern } from '../Text/patterns';\nimport { parseComplianceDirective, parseComplianceMarkers } from './ConceptComplianceParser';\nimport { parseType } from './DeclarationParsers';\nimport { ValidateSyntax } from '../Syntax/Commands';\nimport { parseValidate } from './CommandParser';\nimport { parseDescription } from './DescriptionParser';\nimport { FeatureBody, featureBodyExpected } from './FeatureBody';\nimport { isFileImport, parseFileImport } from './FileImportParser';\nimport { isFileDirective } from './FileReferences';\nimport { collectInputUses } from './InputUses';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ModuleBody, moduleBodyExpected, modulePattern, parseModule } from './ModuleBody';\nimport { ParserContext } from './ParserContext';\nimport { PolicySyntax } from '../Syntax/Policies';\nimport { parsePolicy } from './PolicyParser';\nimport { PurposeSyntax } from '../Syntax/Purposes';\nimport { parsePurpose } from './PurposeParser';\nimport { SeedSyntax } from '../Syntax/Seeds';\nimport { parseSeed } from './SeedParser';\nimport { parseSystem } from './OperationParser';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { SystemSyntax } from '../Syntax/Operations';\nimport { EventSourceSyntax } from '../Syntax/EventSources';\nimport { parseCanvasPair } from './CanvasPlacement';\nimport { parseEventSource } from './EventSourceParser';\nimport { parseExposure, parseInstance } from './CompositionParser';\nimport { ExposureSyntax, InstanceContributionsSyntax } from '../Syntax/CompositionSyntax';\nimport { parseExample } from './SpecificationExampleParser';\nimport { parseUiProfile } from './UiProfileLegacyLayout';\nimport { locationOf, SourceLine, startOf } from './SourceLine';\n\nconst domainPattern = pattern('^domain\\\\s+([A-Za-z_]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst timeZonePattern = pattern(`^time\\\\s+zone\\\\s+(configurable\\\\s+default\\\\s+)?\"(${stringBodyPattern})\"$`);\nconst importPattern = pattern(`^import\\\\s+([\\\\w.]+)(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst conceptPattern = pattern('^concept\\\\s+(\\\\w+)\\\\s*:\\\\s*(\\\\w+)((?:\\\\s+@?\\\\w+)*)$');\nconst enumValuePattern = pattern('^@?[a-z_]\\\\w*$');\nconst personaPattern = pattern('^persona\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaPolicyPattern = pattern('^policy\\\\s+([A-Za-z_]\\\\w*)$');\nconst personaGoalPattern = pattern(`^goal\\\\s+\"(${stringBodyPattern})\"$`);\nconst stickyNotePattern = pattern('^sticky\\\\s+note\\\\s+on\\\\s+(personas|eventsources|givencontexts|seeddata)$');\nconst stickyNoteColourPattern = pattern('^colour\\\\s+(yellow|pink|green|blue)$');\nconst tabIndentPattern = /^[ ]*\\t/;\nconst primitiveTypes = ['Uuid', 'String', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime'];\n\n// Top-level, module and feature constructs the C# compiler knows that this compiler does not model. They\n// are skipped whole, not reported.\nconst opaqueTopLevel = new Set(['policy', 'authentication', 'seed', 'ui', 'theme', 'trigger', 'layout', 'behavior', 'sample']);\n\n// What belongs in a module or feature body; at the top level of a whole document it gets a hint saying so.\nconst bodyKeywords = new Set(['slice', 'feature', 'description', 'documentation', 'authorize', 'screen', 'dialog', 'form', 'contribute', 'on', 'uses']);\n\n// Parses one document into its application syntax - the port of the C# ScreenplayParser. The placement says\n// where the document's top level belongs: the application, unless an import placed it in a module or feature.\nexport function parseApplication(context: ParserContext, lines: readonly SourceLine[], placement: PlayPlacement = documentPlacement): ApplicationSyntax {\n context.deferIdentityValidation = true;\n warnOnTabIndentation(context, lines);\n const moduleBody = placement.length === 1 ? new ModuleBody(placement[0]) : undefined;\n const featureBody = placement.length > 1 ? new FeatureBody(placement[placement.length - 1]) : undefined;\n const placedBody = moduleBody ?? featureBody;\n let identity: IdentitySyntax | null = null;\n let reactionProductionMode: ReactionProductionMode | null = null;\n let sawReactionBatches = false;\n let commandReadMode: CommandReadMode | null = null;\n let timeZone: TimeZoneSyntax | null = null;\n let sawTimeZone = false;\n let sawCommandReads = false;\n let domain: DomainSyntax | null = null;\n const imports: ImportSyntax[] = [];\n const fileImports: FileImportSyntax[] = [];\n const concepts: ConceptSyntax[] = [];\n const types: TypeSyntax[] = [];\n const systems: SystemSyntax[] = [];\n const eventSources: EventSourceSyntax[] = [];\n const modules: ModuleSyntax[] = [];\n const personas: PersonaSyntax[] = [];\n const stickyNotes: StickyNoteSyntax[] = [];\n const policies: PolicySyntax[] = [];\n const purposes: PurposeSyntax[] = [];\n const seeds: SeedSyntax[] = [];\n const examples: SpecificationExampleSyntax[] = [];\n const declaredTriggers: NonNullable<ApplicationSyntax['declaredTriggers']>[number][] = [];\n const exposures: ExposureSyntax[] = [];\n const instanceContributions: InstanceContributionsSyntax[] = [];\n let sawOtherConstruct = false;\n for (let line = context.reader.peekSignificant(); line !== undefined; line = context.reader.peekSignificant()) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n if (keyword === 'command' && /^command\\s+reads(?:\\s|$)/.test(line.content)) {\n if (sawCommandReads || !isDocumentPlacement(placement) || !/^command\\s+reads\\s+protected$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidCommandReadsDeclaration, \"Declare 'command reads protected' once at the application root.\", locationOf(line));\n } else {\n commandReadMode = CommandReadMode.Protected;\n }\n sawCommandReads = true;\n continue;\n }\n if (keyword === 'time' && /^time\\s+zone(?:\\s|$)/.test(line.content)) {\n const match = timeZonePattern.exec(line.content);\n context.skipBlock(line.indent);\n if (sawTimeZone || !isDocumentPlacement(placement) || match === null) {\n context.error(DiagnosticCodes.InvalidTimeZoneDeclaration, \"Declare 'time zone \\\"<id>\\\"' or 'time zone configurable default \\\"<id>\\\"' once at the application root.\", locationOf(line));\n } else {\n timeZone = { kind: 'TimeZoneSyntax', id: unescapeString(match[2]), configurable: match[1] !== undefined, location: locationOf(line) };\n }\n sawTimeZone = true;\n continue;\n }\n if (keyword === 'reaction') {\n if (sawReactionBatches || !isDocumentPlacement(placement) || !/^reaction\\s+batches\\s+atomic$/.test(line.content)) {\n context.error(DiagnosticCodes.InvalidReactionBatchesDeclaration, \"Declare 'reaction batches atomic' once at the application root.\", locationOf(line));\n } else {\n reactionProductionMode = ReactionProductionMode.Atomic;\n }\n sawReactionBatches = true;\n continue;\n }\n if (keyword === 'runs') {\n misplacedReactionIdentity(context, line);\n continue;\n }\n if (keyword === 'domain') {\n context.authoredDeclarations = true;\n domain = parseDomain(context, line, domain, sawOtherConstruct);\n continue;\n }\n // The C# parser asks whether anything was declared before the domain, so an import it rejected,\n // a file import and an unknown construct do not count.\n sawOtherConstruct ||= declaresConstruct(keyword, line, placement);\n context.authoredDeclarations ||= keyword !== 'import' && declaresConstruct(keyword, line, placement);\n if (keyword === 'import' && isFileImport(line.content)) {\n // A top level import belongs to whatever the document's top level is - the application, or the\n // module or feature the document was itself imported into.\n if (placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else {\n parseFileImport(context, line, fileImports);\n }\n } else if (keyword === 'import') {\n const match = importPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, `Invalid import '${line.content}' - expected 'import <Qualified.Name> [from \"<origin>\"]'`, locationOf(line));\n } else {\n const origin = match.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidImportDeclaration, 'An import origin must be a nonblank quoted string', locationOf(line));\n }\n imports.push({ kind: 'ImportSyntax', qualifiedName: match[1], origin, visibility: origin === null ? EventVisibility.Private : EventVisibility.Public, location: locationOf(line) });\n }\n } else if (keyword === 'example') {\n if (placedBody !== undefined) placedBody.tryParse(context, line);\n else examples.push(parseExample(context, line));\n } else if (keyword === 'eventsource') {\n eventSources.push(parseEventSource(context, line));\n } else if (keyword === 'system') {\n systems.push(parseSystem(context, line));\n } else if (keyword === 'concept') {\n concepts.push(parseConcept(context, line));\n } else if (keyword === 'type') {\n types.push(parseType(context, line));\n } else if (keyword === 'module' && !isDocumentPlacement(placement)) {\n parseModuleInPlacedFile(context, line, placement, moduleBody);\n } else if (keyword === 'module') {\n modules.push(parseModule(context, line));\n } else if (keyword === 'persona') {\n personas.push(parsePersona(context, line));\n } else if (keyword === 'sticky') {\n const stickyNote = parseStickyNote(context, line);\n if (stickyNote !== null) stickyNotes.push(stickyNote);\n } else if (keyword === 'seed') {\n seeds.push(parseSeed(context.valueContext, line));\n } else if (keyword === 'purpose' && placedBody !== undefined) {\n placedBody.tryParse(context, line);\n } else if (keyword === 'purpose') {\n purposes.push(parsePurpose(context, line));\n } else if (keyword === 'identity') {\n identity = parseIdentity(context, line, identity);\n } else if (keyword === 'policy') {\n const policy = parsePolicy(context, line);\n if (policies.some(previous => previous.name === policy.name)) {\n context.error(DiagnosticCodes.DuplicateDeclaration, `Duplicate declaration of policy '${policy.name}' - policy names must be unique`, policy.location);\n }\n policies.push(policy);\n } else if (keyword === 'exposure') {\n exposures.push(parseExposure(context, line));\n } else if (keyword === 'instance') {\n instanceContributions.push(parseInstance(context, line));\n } else if (keyword === 'trigger') {\n const data = parseTriggerDeclaration(context, line);\n const name = /^trigger\\s+([A-Za-z_]\\w*)$/.exec(line.content)?.[1];\n if (name !== undefined) declaredTriggers.push({ name, data });\n } else if (opaqueTopLevel.has(keyword)) {\n if (keyword === 'behavior' || keyword === 'layout') collectInputUses(context, line);\n else if (keyword === 'ui') parseUiProfile(context, line);\n else context.skipOpaqueBlock(line.indent);\n } else if (placedBody?.tryParse(context, line) !== true) {\n reportUnexpectedTopLevel(context, line, placement);\n }\n }\n if (moduleBody !== undefined) {\n modules.unshift(moduleBody.build(context.start, true));\n } else if (featureBody !== undefined) {\n modules.unshift(place(placement, featureBody.build(context.start, true), context.start));\n }\n const root: ApplicationSyntax = { kind: 'ApplicationSyntax', ...(commandReadMode === null ? {} : { commandReadMode }), ...(timeZone === null ? {} : { timeZone }), ...(reactionProductionMode === null ? {} : { reactionProductionMode }), ...(identity === null ? {} : { identity }), sourceOptions: context.sourceOptions, domain, imports, concepts, types, systems, eventSources, examples, modules, personas, policies, purposes, seeds, declaredTriggers, fileImports, ...(exposures.length > 0 ? { exposures } : {}), ...(stickyNotes.length > 0 ? { stickyNotes } : {}), ...(instanceContributions.length > 0 ? { instanceContributions } : {}), location: context.start };\n if (context.authoredDeclarations) recordAuthoredDocument(root);\n return root;\n}\n\nfunction declaresConstruct(keyword: string, line: SourceLine, placement: PlayPlacement): boolean {\n if (keyword === 'import') {\n return importPattern.test(line.content);\n }\n if (keyword === 'module') {\n return isDocumentPlacement(placement);\n }\n if (keyword === 'identity') return line.content === 'identity';\n return keyword === 'purpose' || keyword === 'example' || keyword === 'exposure' || keyword === 'instance' || keyword === 'eventsource' || keyword === 'system' || keyword === 'concept' || keyword === 'type' || keyword === 'persona' || keyword === 'sticky' || opaqueTopLevel.has(keyword);\n}\n\nfunction parseModuleInPlacedFile(context: ParserContext, line: SourceLine, placement: PlayPlacement, moduleBody: ModuleBody | undefined): void {\n const name = modulePattern.exec(line.content)?.[1] ?? '';\n\n // Restating the module a file is placed in says nothing new, so its body simply joins the placement.\n if (moduleBody !== undefined && name === placement[0]) {\n context.authoredDeclarations = true;\n moduleBody.parseChildren(context, line);\n return;\n }\n context.error(DiagnosticCodes.ModuleInPlacedFile,\n `This file is imported into ${describePlacement(placement)}, so it cannot declare module '${name}' - import it at the top level of a document instead`, locationOf(line));\n context.skipBlock(line.indent);\n}\n\nfunction reportUnexpectedTopLevel(context: ParserContext, line: SourceLine, placement: PlayPlacement): void {\n const word = firstWord(line.content);\n if (!isDocumentPlacement(placement)) {\n const expected = placement.length === 1 ? moduleBodyExpected : featureBodyExpected;\n context.error(DiagnosticCodes.UnexpectedInPlacedFile,\n `Unexpected '${word}' in a file imported into ${describePlacement(placement)} - expected an application declaration or ${expected}`, locationOf(line));\n } else {\n const hint = bodyKeywords.has(word)\n ? ` - '${word}' belongs in a module or feature; wrap it in one, or import this file from inside one`\n : ' - expected domain, import, concept, type, policy, persona, sticky note, authentication, identity, module, seed, trigger, behavior, ui profile, theme, sample data or layout';\n context.error(DiagnosticCodes.UnknownTopLevelConstruct, `Unexpected '${word}' at the top level${hint}`, locationOf(line));\n }\n context.skipBlock(line.indent);\n}\n\n// Wraps the feature a file is placed in in the features and module around it, each marked as a placement.\nfunction place(placement: PlayPlacement, innermost: FeatureSyntax, start: SourceLocation): ModuleSyntax {\n let feature = innermost;\n for (let index = placement.length - 2; index >= 1; index--) {\n feature = {\n kind: 'FeatureSyntax', name: placement[index], description: null, authorize: null,\n features: [feature], slices: [], fileImports: [], isPlacement: true, location: start,\n };\n }\n return {\n kind: 'ModuleSyntax', name: placement[0], description: null, authorize: null,\n features: [feature], fileImports: [], isPlacement: true, location: start,\n };\n}\n\nfunction parseDomain(context: ParserContext, line: SourceLine, existing: DomainSyntax | null, sawOtherConstruct: boolean): DomainSyntax | null {\n const match = domainPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidDomainDeclaration, `Invalid domain declaration '${line.content}' - expected 'domain <Qualified.Name>'`, locationOf(line));\n return existing;\n }\n if (existing !== null) {\n context.error(DiagnosticCodes.DuplicateDomain, 'The document already declares a domain - a document can have at most one', locationOf(line));\n return existing;\n }\n if (sawOtherConstruct) {\n context.error(DiagnosticCodes.DomainNotFirst, '\\'domain\\' must be declared before any other construct', locationOf(line));\n }\n return { kind: 'DomainSyntax', name: match[1], location: locationOf(line) };\n}\n\nfunction warnOnTabIndentation(context: ParserContext, lines: readonly SourceLine[]): void {\n let inFence = false;\n for (const line of lines) {\n if (line.raw.trimStart().startsWith('```')) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && tabIndentPattern.test(line.raw)) {\n context.warning(DiagnosticCodes.TabIndentation, 'Screenplay is indentation based - use spaces, not tabs', startOf(line));\n }\n }\n}\n\nfunction parseConcept(context: ParserContext, line: SourceLine): ConceptSyntax {\n const match = conceptPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidConceptDeclaration, `Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ConceptSyntax', name: firstWord(line.content), type: '', attributes: [], values: [], location: locationOf(line) };\n }\n const [, name, type, attributeText] = match;\n const attributes = parseComplianceMarkers(context, line, name, attributeText);\n if (type !== 'Enum' && !primitiveTypes.includes(type)) {\n context.error(DiagnosticCodes.UnknownPrimitiveType, `Unknown primitive type '${type}' - expected ${primitiveTypes.join(', ')} or Enum`, locationOf(line));\n }\n const values: string[] = [];\n const members = new EnumerationMembers();\n let generation: GenerationSyntax | null = null;\n let declaredGeneration = false;\n let description: string | null = null;\n const validations: ValidateSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const memberName = type === 'Enum' ? members.tryNumbered(context, child) : undefined;\n if (memberName !== undefined) {\n values.push(memberName);\n } else if (firstWord(child.content) === 'description' && (type !== 'Enum' || child.content !== 'description' || context.peekChild(child.indent)?.content.startsWith('```') === true)) {\n description = parseDescription(context, child, description, `Concept '${name}'`);\n } else if (isFileDirective(child)) {\n continue;\n } else if (firstWord(child.content) === 'validate') {\n if (type === 'Enum' && child.content === 'validate' && context.peekChild(child.indent) === undefined) {\n context.warning(DiagnosticCodes.ValidateReadAsEnumerationBlock,\n `'validate' in enumeration concept '${name}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,\n locationOf(child));\n }\n const parsed = parseValidate(context, child, 'concept', name);\n if (parsed !== undefined) validations.push(parsed);\n } else if (firstWord(child.content) === 'generate' && !(type === 'Enum' && child.content === 'generate')) {\n if (declaredGeneration) context.error(DiagnosticCodes.DuplicateGeneration, `Concept '${name}' declares generation more than once.`, locationOf(child));\n const parsed = parseGeneration(context, child, type);\n if (!declaredGeneration) generation = parsed;\n declaredGeneration = true;\n } else if (parseComplianceDirective(context, child, name, attributes)) {\n // Compliance directives are modeled by their original concept marker.\n } else if (type === 'Enum' && enumValuePattern.test(child.content)) {\n values.push(unescapeIdentifier(child.content));\n } else if (type === 'Enum') {\n context.error(DiagnosticCodes.InvalidEnumerationValue, `Invalid enum value '${child.content}' - expected an identifier`, locationOf(child));\n } else {\n context.error(DiagnosticCodes.UnknownConceptDirective, `Unexpected '${child.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason \"<text>\"'`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const valueNumbers = members.finish(context, line, values.length);\n return { kind: 'ConceptSyntax', name, type, attributes, values, validations, description, ...(generation === null ? {} : { generation }), ...(valueNumbers === undefined ? {} : { valueNumbers }), location: locationOf(line) };\n}\n\n// 'persona <Name>' with an optional description and the policies it holds - the port of the C# ParsePersona.\nfunction parsePersona(context: ParserContext, line: SourceLine): PersonaSyntax {\n const name = personaPattern.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid persona declaration '${line.content}' - expected 'persona <Name>'`, locationOf(line));\n }\n let description: string | null = null;\n const policies: string[] = [];\n const goals: string[] = [];\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | 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, `Persona '${name}'`);\n } else if (keyword === 'goal') {\n const goal = personaGoalPattern.exec(child.content);\n if (goal === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid goal '${child.content}' - expected 'goal \"<text>\"'`, locationOf(child));\n } else {\n goals.push(unescapeString(goal[1]));\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else if (keyword === 'policy') {\n const policy = personaPolicyPattern.exec(child.content);\n if (policy === null) {\n context.error(DiagnosticCodes.InvalidPersonaPolicyReference, `Invalid policy reference '${child.content}' - expected 'policy <Name>'`, locationOf(child));\n } else {\n policies.push(policy[1]);\n }\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in persona body - expected description, goal, policy, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n return {\n kind: 'PersonaSyntax', name, description, policies,\n ...(goals.length > 0 ? { goals } : {}),\n ...(position === null ? {} : { x: position[0], y: position[1] }),\n ...(size === null ? {} : { width: size[0], height: size[1] }),\n location: locationOf(line),\n };\n}\n\n// 'sticky note on <canvas>' with the text it carries, an optional colour and where it sits on that canvas - the port of the C# ParseStickyNote.\nfunction parseStickyNote(context: ParserContext, line: SourceLine): StickyNoteSyntax | null {\n const canvasMatch = stickyNotePattern.exec(line.content);\n if (canvasMatch === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid sticky note declaration '${line.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`, locationOf(line));\n context.skipBlock(line.indent);\n return null;\n }\n let text: string | null = null;\n let colour: string | null = null;\n let position: readonly [number, number] | null = null;\n let size: readonly [number, number] | 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 text = parseDescription(context, child, text, 'A sticky note');\n } else if (keyword === 'colour') {\n const match = stickyNoteColourPattern.exec(child.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, `Invalid colour '${child.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`, locationOf(child));\n } else {\n colour = match[1];\n }\n } else if (keyword === 'position') {\n position = parseCanvasPair(context, child, 'position', 'x', 'y', position, true) ?? position;\n } else if (keyword === 'size') {\n size = parseCanvasPair(context, child, 'size', 'width', 'height', size, false) ?? size;\n } else {\n context.error(DiagnosticCodes.UnknownPersonaDirective, `Unexpected '${keyword}' in sticky note body - expected description, colour, position or size`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n if (text === null || position === null) {\n context.error(DiagnosticCodes.InvalidPersonaDeclaration, 'A sticky note needs a description (the text on it) and a position', locationOf(line));\n return null;\n }\n return { kind: 'StickyNoteSyntax', canvas: canvasMatch[1] as StickyNoteSyntax['canvas'], text, colour, x: position[0], y: position[1], width: size === null ? null : size[0], height: size === null ? null : size[1], location: locationOf(line) };\n}\n\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{dotNetWhitespace as r,nativePattern as i,pattern as a}from"../Text/patterns.js";import{locationOf as o}from"./SourceLine.js";import{diagnosticText as s}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as c}from"./LineText.js";import{generatedFixturePattern as l,generatedFixturePrefix as u,parseConcrete as d,parseConcreteMapping as f,parseReturn as p,thenReturnsPrefix as m}from"./SpecificationResponseParser.js";import{containsCaseReference as h,parseCase as g,parseParameter as _,parseSpecificationValue as v,validateTable as y}from"./SpecificationCaseParser.js";import{parseDescription as b}from"./DescriptionParser.js";import{sourceStreamPattern as x}from"../Text/SourceStreamNames.js";import{parseRouteParts as ee}from"./EventSourceParser.js";import{isFileDirective as te}from"./FileReferences.js";import{rejectOperationChildren as S}from"./OperationParser.js";import{addFixtureValue as C,addInlineValue as w}from"./SpecificationExampleParser.js";const T=a(`^(?:given\\s+operation|then\\s+(?:operation|compensated))(?:\\s|$)`),E=a(`^(given operation|then operation|then compensated)\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)(\\s+fails)?$`),D=a(`^specification\\s+([A-Za-z_]\\w*)$`),O=a(`^given caller as ([A-Za-z_]\\w*)$`),stepPattern=(e,t=``)=>i(`^${e}\\s+([A-Z]\\w*(?:\\.\\w+)*)${t}(?:\\s+(?<property>[\\w.]+)\\s*=(?!=|>)\\s*(?<value>.+))?$`.replaceAll(`\\s`,r)),k=stepPattern(`given`),A=stepPattern(`when\\s+append`),j=stepPattern(`when`),M=stepPattern(`then`),N=a(`^then\\s+query\\b`),P=a(`^(?:given|then)\\s+readmodel\\b`),F=stepPattern(`given\\s+readmodel`),I=stepPattern(`then\\s+readmodel`,`(?<exactly>\\s+exactly)?`),L=a(`^then\\s+no\\b`),R=a(`^then\\s+error\\s+"(${t})"$`),z=a(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),B=i(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),V=a(`^given\\s+clock\\b`),H=a(`^given\\s+capture\\b`),U=a(`^given\\s+generated\\b`),ne=a(`^given\\s+generated\\s+([A-Z]\\w*)\\.([a-z_]\\w*)\\s*=(?!=|>)\\s*(.+)$`),W=a(`^when\\s+clock\\b`),G=a(`^when\\s+trigger\\b`),K=a(`^when\\s+capture\\b`),q=a(`^when\\s+query\\b`),J=a(`^then\\s+result\\b`),Y=a(`^then\\s+no\\s+result\\b`),X=i(`^when\\s+redelivered\\b`),Z=i(`^when\\s+redelivered\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)\\s+to\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),re=a(`^then\\s+no\\s+events\\b`),ie=a(`^(given|when)\\s+clock\\s+"(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:\\d{2}))"$`),ae=a(`^when\\s+trigger\\s+([A-Za-z_]\\w*)$`),oe=a(`^(?:given|when)\\s+capture\\s+([A-Za-z_]\\w*)$`),se=a(`^when\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),ce=a(`^then\\s+result(\\s+exactly)?$`),Q=i(`^then\\s+no\\s+readmodel\\s+([A-Z]\\w*)\\s+for\\s+(.+)$`),le=i(`^(?:"${t}"|'(?:[^'\\\\]|\\\\.)*')$`),ue=i(`^then\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)(\\s+exactly)?$`);function parseSpecification(t,n){let r=D.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidSpecificationDeclaration,`Invalid specification declaration '${n.content}' - expected 'specification <Name>'`,o(n));let i=null,a=[],s=[],l={givenOperationFailures:[],thenOperations:[],thenCompensated:[],thenAbsentReadModels:[],thenQueries:[],given:[],givenReadModels:[],when:null,whenAppended:null,whenRedelivered:null,whenDeclared:!1,thenEvents:[],thenEventsInAnyOrder:!1,thenNoEvents:!1,thenReadModels:[],thenErrors:[],givenClock:null,givenCaptures:[],whenClock:null,whenTrigger:null,whenCapture:null,whenQuery:null,thenResults:[],thenNoResult:null,thenDenied:null,givenCaller:null,thenReturns:null};for(let u=t.peekChild(n.indent);u!==void 0;u=t.peekChild(n.indent)){if(t.reader.takeSignificant(),te(u)||parseOperationStep(t,u,l))continue;let n=L.test(u.content)?`then`:c(u.content);if(n===`parameter`){let e=_(t,u);e!==null&&a.push(e)}else if(n===`case`){let e=g(t,u);e!==null&&s.push(e)}else n===`description`?i=b(t,u,i,`Specification '${r}'`):n===`given`?parseGiven(t,u,l):n===`when`?parseWhen(t,u,l,r):n===`then`?parseThen(t,u,l):(t.error(e.UnknownSpecificationDirective,`Unexpected '${c(u.content)}' in specification body`,o(u)),t.skipBlock(u.indent))}l.noEventsLine!==void 0&&(l.thenEvents.length>0||l.thenEventsInAnyOrder||l.thenErrors.length>0||l.thenDenied!==null)&&t.error(e.InvalidNoEventsExpectation,`'then no events' cannot accompany event, event-order, error or denial expectations.`,o(l.noEventsLine)),validateQueryRejection(t,n,l);let{whenDeclared:u,noEventsLine:d,...f}=l,p={kind:`SpecificationSyntax`,sourceOptions:t.sourceOptions,name:r,description:i,...f,...a.length===0?{}:{parameters:a},...s.length===0?{}:{cases:s},location:o(n)};return y(p,t),p}function validateQueryRejection(t,n,r){isQueryRejectionCandidate(r)&&!isWellFormedQueryRejection(r)&&t.error(e.MismatchedSpecificationQueryResult,`A query rejection requires exactly one query and one 'then error', no action, and no other outcomes`,o(n))}function isQueryRejectionCandidate(e){return e.thenErrors.length>0&&queriedCallCount(e)>0&&(e.whenQuery!==null||!hasAction(e))}function isWellFormedQueryRejection(e){return!hasAction(e)&&hasOneQueryAndOneError(e)&&!hasOtherOutcome(e)}function hasOneQueryAndOneError(e){return queriedCallCount(e)===1&&e.thenErrors.length===1}function hasAction(e){return[e.when,e.whenAppended,e.whenClock,e.whenTrigger,e.whenCapture,e.whenRedelivered].some(e=>e!==null)}function queriedCallCount(e){return e.thenQueries.length+(e.whenQuery===null?0:1)}function hasOtherOutcome(e){return[e.thenResults.length>0,e.thenNoResult!==null,e.thenDenied!==null,e.thenEvents.length>0,e.thenNoEvents,e.thenEventsInAnyOrder,e.thenReadModels.length>0,e.thenAbsentReadModels.length>0,e.thenReturns!==null,e.thenQueries.some(e=>e.results.length>0)].some(e=>e)}function parseOperationStep(t,n,r){if(!T.test(n.content))return!1;let i=E.exec(n.content);if(i===null||i[1]===`given operation`!=(i[3]!==void 0))t.error(e.InvalidOperationSpecification,`Expected 'given operation <Name> fails', 'then operation <Name>' or 'then compensated <Name>'.`,o(n)),skipBody(t,n.indent);else if(i[1]===`then operation`){let a=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=f(t,r,z,e.InvalidOperationSpecification);n!==null&&a.push(n)}r.thenOperations.push({kind:`SpecificationOperationSyntax`,operation:i[2],values:a,location:o(n)})}else S(t,n,e.InvalidOperationSpecification,`Failure and compensation assertions cannot have children.`),i[1]===`given operation`?r.givenOperationFailures.push({kind:`SpecificationOperationFailureSyntax`,operation:i[2],location:o(n)}):r.thenCompensated.push({kind:`SpecificationCompensatedSyntax`,operation:i[2],location:o(n)});return!0}function parseGiven(t,n,r){if(V.test(n.content))r.givenClock===null?r.givenClock=parseClock(t,n,`given`):(t.error(e.InvalidSpecificationClock,`A specification states its clock at most once.`,o(n)),skipBody(t,n.indent));else if(U.test(n.content)){let e=parseGivenGenerated(t,n);e!==null&&(r.givenGenerated??=[]).push(e)}else if(H.test(n.content)){let e=parseCapture(t,n,`given`);e!==null&&r.givenCaptures.push(e)}else if(n.content.startsWith(`given caller`)){if(r.givenCaller!==null||r.givenCallerPersona!==void 0)t.error(e.DuplicateSpecificationCallerOrDenied,`A specification has at most one 'given caller' block.`,o(n)),t.skipBlock(n.indent);else if(n.content.startsWith(`given caller as`)){let i=O.exec(n.content);i===null&&t.error(e.InvalidSpecificationCallerPersona,`Expected 'given caller as <Persona>'.`,o(n));let a=t.peekChild(n.indent);a!==void 0&&t.error(e.InvalidSpecificationCallerPersona,`'given caller as <Persona>' has no body; use an explicit 'given caller' for refinements.`,o(a)),skipBody(t,n.indent),i!==null&&(r.givenCallerPersona={kind:`SpecificationCallerPersonaSyntax`,name:i[1],location:o(n)})}else r.givenCaller=parseCaller(t,n)}else if(P.test(n.content)){let e=parseReadModelStep(t,n,F,`given`);e!==void 0&&r.givenReadModels.push(e)}else{let e=parseEventStep(t,n,k,`given`);e!==void 0&&r.given.push(e)}}const de=a(`^role${r}+"(${t})"$`),fe=a(`^claim${r}+"(${t})"${r}*=${r}*"(${t})"$`);function parseCaller(t,r){if(r.content!==`given caller`)return t.error(e.InvalidSpecificationCaller,`Expected exactly 'given caller'.`,o(r)),t.skipBlock(r.indent),null;let i=!1,a=[],s=[];for(let c=t.peekChild(r.indent);c!==void 0;c=t.peekChild(r.indent)){t.reader.takeSignificant();let r=de.exec(c.content),l=fe.exec(c.content);c.content===`authenticated`&&!i?i=!0:r===null?l===null?t.error(h(c.content)?e.InvalidSpecificationCaseReference:e.InvalidSpecificationCaller,`Invalid caller fixture '${c.content}' - expected authenticated, role "...", or claim "..." = "...".`,o(c)):s.push({kind:`SpecificationCallerClaimSyntax`,type:n(l[1]),value:n(l[2]),location:o(c)}):a.push(n(r[1]))}return{kind:`SpecificationCallerSyntax`,authenticated:i,roles:a,claims:s,location:o(r)}}function parseWhen(t,n,r,i){let a=n.content.startsWith(`when append`);if(r.whenDeclared){let s=r.whenAppended!==null||a?e.ConflictingSpecificationActions:e.DuplicateSpecificationWhen;t.error(s,`Specification '${i}' already declares a 'when' - a specification can have at most one`,o(n)),skipBody(t,n.indent);return}if(r.whenDeclared=!0,a){r.whenAppended=parseEventStep(t,n,A,`when append`)??null;return}if(X.test(n.content)){let i=Z.exec(n.content);i===null?(t.error(e.UnmatchedRedeliveredOccurrence,`Expected 'when redelivered <Event> to <Reaction>'.`,o(n)),skipBody(t,n.indent)):r.whenRedelivered={kind:`SpecificationRedeliverySyntax`,eventType:i[1],reaction:i[2],...parseValuesWithEventSource(t,n,void 0,void 0,`when redelivered`),location:o(n)};return}if(W.test(n.content)){r.whenClock=parseClock(t,n,`when`);return}if(G.test(n.content)){r.whenTrigger=parseNamedStep(t,n,ae,e.InvalidSpecificationTrigger,`when trigger`,`when trigger <Trigger>`,(e,t)=>({kind:`SpecificationTriggerSyntax`,trigger:e,values:t,location:o(n)}));return}if(K.test(n.content)){r.whenCapture=parseCapture(t,n,`when`);return}if(q.test(n.content)){r.whenQuery=parseNamedStep(t,n,se,e.InvalidSpecificationQueryAction,`when query`,`when query <Query>`,(e,t)=>({kind:`SpecificationWhenQuerySyntax`,query:e,arguments:t,location:o(n)}),!0);return}let s=j.exec(n.content);if(s===null){t.error(e.InvalidSpecificationWhen,`Invalid 'when' declaration '${n.content}' - expected 'when <CommandType>' or 'when append <EventType>'`,o(n)),skipBody(t,n.indent);return}let c=[],l=parseValuesWithEventSource(t,n,c,s);r.when={kind:`SpecificationCommandSyntax`,commandType:s[1],...l,generatedValues:c,inlineProperty:s.groups?.property??null,location:o(n)}}function parseThen(t,r,i){if(re.test(r.content)){r.content!==`then no events`||i.thenNoEvents?t.error(e.InvalidNoEventsExpectation,`Expected one 'then no events' directive.`,o(r)):(i.thenNoEvents=!0,i.noEventsLine=r);let n=t.peekChild(r.indent);n!==void 0&&t.error(e.InvalidNoEventsExpectation,`'then no events' cannot have child mappings.`,o(n)),skipBody(t,r.indent);return}if(m.test(r.content)){let n=p(t,r);i.thenReturns===null?i.thenReturns=n:t.error(e.InvalidReturnExpectation,`A specification declares at most one return expectation.`,o(r));return}if(r.content.startsWith(`then events`)){r.content!==`then events in any order`||i.thenEventsInAnyOrder?t.error(e.InvalidSpecificationEventOrder,`Expected one 'then events in any order' directive.`,o(r)):i.thenEventsInAnyOrder=!0,skipBody(t,r.indent);return}if(J.test(r.content)){parseResult(t,r,i);return}if(Y.test(r.content)){r.content!==`then no result`||i.thenNoResult!==null?t.error(e.InvalidSpecificationQueryAction,`Expected one 'then no result' directive.`,o(r)):i.thenNoResult={kind:`SpecificationNoResultSyntax`,location:o(r)},skipBody(t,r.indent);return}if(r.content.startsWith(`then denied`)){r.content===`then denied`?i.thenDenied===null?i.thenDenied={kind:`SpecificationDeniedSyntax`,location:o(r)}:t.error(e.DuplicateSpecificationCallerOrDenied,`A specification has at most one 'then denied' outcome.`,o(r)):(t.error(e.InvalidSpecificationDenied,`Expected exactly 'then denied'.`,o(r)),skipBody(t,r.indent));return}if(r.content===`then error`){i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:null,location:o(r)});return}if(r.content.startsWith(`then error case.`)){let e=v(r.content.substring(11),{...o(r),column:o(r).column+11},t);e.kind===`CaseValueExpressionSyntax`&&i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:null,caseValue:e,location:o(r)});return}let a=R.exec(r.content);if(a!==null){i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:n(a[1]),location:o(r)});return}if(c(r.content.substring(4).trim())===`error`){t.error(e.InvalidThenError,`Invalid 'then error' declaration '${r.content}' - expected 'then error' or 'then error "<reason>"'`,o(r)),skipBody(t,r.indent);return}if(L.test(r.content)){if(t.sourceOptions.numericMode===`exact`){let e=parseAbsentReadModel(t,r);e!==null&&i.thenAbsentReadModels.push(e);return}let e=Q.exec(r.content);if(e!==null&&!e[2].endsWith(` exactly`)){let n=v(e[2].trim(),o(r),t.valueContext);(n.kind===`LiteralExpressionSyntax`||n.kind===`ObjectExpressionSyntax`||n.kind===`CaseValueExpressionSyntax`)&&i.thenAbsentReadModels.push({kind:`SpecificationAbsentReadModelSyntax`,name:e[1],key:n,location:o(r)})}t.skipOpaqueBlock(r.indent);return}if(N.test(r.content)){let n=t.sourceOptions.numericMode===`exact`,reject=(e,r,i)=>{if(!n)return t.skipOpaqueBlock(i.indent);t.error(e,r,o(i)),t.skipBlock(i.indent)},a=ue.exec(r.content);if(a===null)return reject(e.InvalidSpecificationQuery,`Invalid 'then query' declaration '${r.content}' - expected 'then query <Query> [exactly]'`,r);let s=[],l=[],u=!1;for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent))t.reader.takeSignificant(),n.content===`arguments`&&!u?s.push(...parseValues(t.valueContext,n,!0,void 0,t)):n.content===`arguments`?reject(e.DuplicateSpecificationQueryArguments,`Query assertion '${a[1]}' already declares arguments`,n):n.content===`result`?l.push({kind:`SpecificationQueryResultSyntax`,properties:parseValues(t.valueContext,n,!0),exactly:!1,location:o(n)}):reject(e.UnknownSpecificationQueryDirective,`Unexpected '${c(n.content)}' in 'then query' body - expected arguments or result`,n),u||=n.content===`arguments`;i.thenQueries.push({kind:`SpecificationQuerySyntax`,query:a[1],arguments:s,results:l,exactly:a[2]!==void 0,location:o(r)});return}if(P.test(r.content)){let e=parseReadModelStep(t,r,I,`then`);e!==void 0&&i.thenReadModels.push(e);return}let s=parseEventStep(t,r,M,`then`);s!==void 0&&i.thenEvents.push(s)}function parseAbsentReadModel(t,n){let r=Q.exec(n.content);if(r===null||r[2].endsWith(` exactly`))return t.error(e.InvalidAbsentReadModelStep,`Invalid absence assertion '${n.content}' - expected 'then no readmodel <ReadModelType> for <key>'`,o(n)),skipBody(t,n.indent),null;let i=r[2].trim(),a=!(i.startsWith(`"`)||i.startsWith(`'`))||le.test(i)?v(i,o(n),t.valueContext):null,s=a!==null&&(a.kind===`LiteralExpressionSyntax`||a.kind===`ObjectExpressionSyntax`||a.kind===`CaseValueExpressionSyntax`);s||t.error(e.InvalidAbsentReadModelStep,`Invalid absence key '${i}' - expected exactly one concrete value.`,o(n));let c=!1;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent))t.reader.takeSignificant(),t.error(e.InvalidAbsentReadModelStep,`An absent read model assertion cannot have child mappings.`,o(r)),c=!0;return c||!s?null:{kind:`SpecificationAbsentReadModelSyntax`,name:r[1],key:a,location:o(n)}}function skipBody(e,t){if(e.sourceOptions.numericMode!==`exact`)return e.skipBlock(t);e.skipOpaqueBlock(t)}function parseClock(t,n,r){let i=ie.exec(n.content);return skipBody(t,n.indent),i===null||i[1]!==r?(t.error(h(n.content)?e.InvalidSpecificationCaseReference:e.InvalidSpecificationClock,`Invalid '${r} clock' - expected '${r} clock "<ISO 8601 instant>"', such as '${r} clock "2026-10-05T08:00:00Z"'`,o(n)),null):{kind:`SpecificationClockSyntax`,instant:i[2],location:o(n)}}function parseGivenGenerated(t,n){let r=ne.exec(n.content);if(r===null)return t.error(e.InvalidGeneratedFixture,`Expected 'given generated <Command>.<property> = <value>' with exactly one concrete value.`,o(n)),t.skipBlock(n.indent),null;let i=o(n),a=d(t,r[3],{...i,column:i.column+n.content.indexOf(r[3],n.content.indexOf(`=`)+1)},e.InvalidGeneratedFixture),s=t.peekChild(n.indent);return s!==void 0&&(t.error(e.InvalidGeneratedFixture,`A pinned generated value cannot have child directives.`,o(s)),t.skipBlock(n.indent)),a===null?null:{kind:`SpecificationGeneratedValueSyntax`,command:r[1],property:r[2],source:a,location:i}}function parseCapture(t,n,r){return parseNamedStep(t,n,oe,e.InvalidSpecificationCapture,`${r} capture`,`${r} capture <Capture>`,(e,t)=>({kind:`SpecificationCaptureSyntax`,capture:e,record:t,location:o(n)}))}function parseNamedStep(e,t,n,r,i,a,s,c=!1){let l=n.exec(t.content);return l===null?(e.error(r,`Invalid '${i}' declaration '${t.content}' - expected '${a}'`,o(t)),skipBody(e,t.indent),null):s(l[1],parseValues(e,t,!1,void 0,c?e:void 0))}function parseResult(t,n,r){let i=ce.exec(n.content);i===null?(t.error(e.InvalidSpecificationQueryAction,`Invalid 'then result' declaration '${n.content}' - expected 'then result [exactly]'`,o(n)),skipBody(t,n.indent)):r.thenResults.push({kind:`SpecificationQueryResultSyntax`,properties:parseValues(t,n),exactly:i[1]!==void 0,location:o(n)})}function parseReadModelStep(t,n,r,i){let a=r.exec(n.content);if(a===null)t.error(e.InvalidReadModelStep,`Invalid '${i} readmodel' declaration '${n.content}' - expected '${i} readmodel <ReadModelType>'`,o(n)),skipBody(t,n.indent);else return{kind:`SpecificationReadModelSyntax`,name:a[1],properties:parseValues(t,n,!1,a),exactly:i===`then`&&a.groups?.exactly!==void 0,inlineProperty:a.groups?.property??null,location:o(n)}}function parseEventStep(t,n,r,i){let a=r.exec(n.content);if(a===null)t.error(e.InvalidEventStep,`Invalid '${i}' declaration '${n.content}' - expected '${i} <EventType>'`,o(n)),skipBody(t,n.indent);else return{kind:`SpecificationEventSyntax`,eventType:a[1],...parseValuesWithEventSource(t,n,void 0,a,i),inlineProperty:a.groups?.property??null,location:o(n)}}const $=x(`^stream\\s+([A-Za-z_]\\w*)\\.([A-Za-z_]\\w*)$`),pe=a(`^streamId\\s*=(?!=|>)\\s*(.+)$`);function parseValuesWithEventSource(t,n,r,i,a){let d=[];w(t,n,i,d);let p=null,m,h,g=!1;for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent)){if(t.reader.takeSignificant(),r!==void 0&&u.test(i.content)){let n=f(t,i,l,e.InvalidGeneratedFixture);n!==null&&r.push(n);continue}let n=z.exec(i.content);if(n!==null)C(t,d,mappingOf(t,i,n));else if(c(i.content)===`stream`||i.content.startsWith(`no stream`)){if(a===void 0){t.error(e.SpecificationStreamOnCommand,`A command occurrence cannot declare a route; assert it on a then event.`,o(i)),t.skipBlock(i.indent);continue}if(g){t.error(e.InvalidSpecificationStream,`An event occurrence declares at most one stream or no stream directive.`,o(i)),t.skipBlock(i.indent);continue}let n=$.exec(i.content);i.content===`no stream`&&(a===`then`||a===`when redelivered`)?(h={kind:`SpecificationNoStreamSyntax`,location:o(i)},g=!0,rejectSpecificationRouteChildren(t,i)):n===null?(t.error(e.InvalidSpecificationStream,`Expected 'stream Source.Stream', or 'no stream' on a then event.`,o(i)),t.skipBlock(i.indent)):(m=parseSpecificationStream(t,i,n),g=!0)}else if(c(i.content)===`for`){let n=i.content.substring(3).trim();n.length===0?t.error(e.InvalidSpecificationEventSource,`Invalid event-source assertion 'for' - expected 'for <value>'`,o(i)):p===null?p=v(n,o(i),t):t.error(e.DuplicateSpecificationEventSource,`A specification step can declare its event-source assertion only once`,o(i))}else t.error(e.InvalidSpecificationValue,`Invalid property mapping '${i.content}' - expected '<property> = <value>'`,o(i),s(`text`,i.content))}return{values:d,for:p,...m===void 0?{}:{stream:m},...h===void 0?{}:{noStream:h}}}function parseSpecificationStream(t,n,r){let i=null,a=[],s=!1,c={};for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){if(t.reader.takeSignificant(),r.content===`streamId`){i!==null||s?(t.error(e.InvalidSpecificationStream,`Declare either one 'streamId = <literal>' mapping or one streamId part block.`,o(r)),t.skipBlock(r.indent)):(s=!0,c.streamId=o(r),a=ee(t,r,e.InvalidSpecificationStream).map(e=>e.source.kind===`PathExpressionSyntax`&&e.source.path.startsWith(`case.`)?{...e,source:v(e.source.path,e.source.location,t)}:e));continue}let n=pe.exec(r.content);if(n===null||i!==null||s){t.error(e.InvalidSpecificationStream,`Declare either one 'streamId = <literal>' mapping or one streamId part block.`,o(r)),t.skipBlock(r.indent);continue}let l={...o(r),column:r.indent+1+r.content.indexOf(n[1],r.content.indexOf(`=`)+1)};i={kind:`PropertyMappingSyntax`,property:`streamId`,source:v(n[1],l,t),location:o(r)},rejectSpecificationRouteChildren(t,r)}return{kind:`SpecificationStreamSyntax`,eventSource:r[1],stream:r[2],streamId:i,streamIdParts:a,directiveLocations:c,referenceLocation:{...o(n),column:n.indent+1+n.content.indexOf(r[1],6)},referenceLength:r[1].length+1+r[2].length,location:o(n)}}function rejectSpecificationRouteChildren(t,n){let r=t.peekChild(n.indent);r!==void 0&&(t.error(e.InvalidSpecificationStream,`This directive cannot have children.`,o(r)),t.skipBlock(n.indent))}function parseValues(t,n,r=!1,i,a){let c=[];w(t,n,i,c);for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent)){t.reader.takeSignificant();let n=(r||t.sourceOptions.numericMode===`exact`?B:z).exec(i.content);if(n===null){t.error(e.InvalidSpecificationValue,`Invalid property mapping '${i.content}' - expected '<property> = <value>'`,o(i),s(`text`,i.content));continue}let l=mappingOf(t,i,n,r);a===void 0?C(t,c,l):(c.some(e=>e.property===l.property)&&a.error(e.UnknownSpecificationQueryArgument,`Query argument '${l.property}' is repeated.`,l.location,s(`argument`,l.property)),c.push(l))}return c}function mappingOf(e,t,n,r=!1){return{kind:`PropertyMappingSyntax`,property:n[1],source:v(n[2],o(t),e,r),location:o(t)}}export{parseSpecification,parseSpecificationStream,rejectSpecificationRouteChildren,$ as specificationStream};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{dotNetWhitespace as r,nativePattern as i,pattern as a}from"../Text/patterns.js";import{locationOf as o}from"./SourceLine.js";import{diagnosticText as s}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as c}from"./LineText.js";import{generatedFixturePattern as l,generatedFixturePrefix as u,parseConcrete as d,parseConcreteMapping as f,parseReturn as p,thenReturnsPrefix as m}from"./SpecificationResponseParser.js";import{containsCaseReference as h,parseCase as g,parseParameter as _,parseSpecificationValue as v,validateTable as y}from"./SpecificationCaseParser.js";import{parseDescription as b}from"./DescriptionParser.js";import{sourceStreamPattern as x}from"../Text/SourceStreamNames.js";import{parseRouteParts as ee}from"./EventSourceParser.js";import{isFileDirective as te}from"./FileReferences.js";import{rejectOperationChildren as S}from"./OperationParser.js";import{addFixtureValue as C,addInlineValue as w}from"./SpecificationExampleParser.js";const T=a(`^(?:given\\s+operation|then\\s+(?:operation|compensated))(?:\\s|$)`),E=a(`^(given operation|then operation|then compensated)\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)(\\s+fails)?$`),D=a(`^specification\\s+([A-Za-z_]\\w*)$`),O=a(`^given caller as ([A-Za-z_]\\w*)$`),stepPattern=(e,t=``)=>i(`^${e}\\s+([A-Z]\\w*(?:\\.\\w+)*)${t}(?:\\s+(?<property>[\\w.]+)\\s*=(?!=|>)\\s*(?<value>.+))?$`.replaceAll(`\\s`,r)),k=stepPattern(`given`),A=stepPattern(`when\\s+append`),j=stepPattern(`when`),M=stepPattern(`then`),N=a(`^then\\s+query\\b`),P=a(`^(?:given|then)\\s+readmodel\\b`),F=stepPattern(`given\\s+readmodel`),I=stepPattern(`then\\s+readmodel`,`(?<exactly>\\s+exactly)?`),L=a(`^then\\s+no\\b`),R=a(`^then\\s+error\\s+"(${t})"$`),z=a(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),B=i(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),V=a(`^given\\s+time\\s+zone\\b`),H=a(`^given\\s+time\\s+zone\\s+"(${t})"$`),U=a(`^given\\s+clock\\b`),ne=a(`^given\\s+capture\\b`),W=a(`^given\\s+generated\\b`),G=a(`^given\\s+generated\\s+([A-Z]\\w*)\\.([a-z_]\\w*)\\s*=(?!=|>)\\s*(.+)$`),K=a(`^when\\s+clock\\b`),q=a(`^when\\s+trigger\\b`),J=a(`^when\\s+capture\\b`),Y=a(`^when\\s+query\\b`),X=a(`^then\\s+result\\b`),Z=a(`^then\\s+no\\s+result\\b`),re=i(`^when\\s+redelivered\\b`),ie=i(`^when\\s+redelivered\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)\\s+to\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),ae=a(`^then\\s+no\\s+events\\b`),oe=a(`^(given|when)\\s+clock\\s+"(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d+)?)?(?:Z|[+-]\\d{2}:\\d{2}))"$`),se=a(`^when\\s+trigger\\s+([A-Za-z_]\\w*)$`),ce=a(`^(?:given|when)\\s+capture\\s+([A-Za-z_]\\w*)$`),le=a(`^when\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),ue=a(`^then\\s+result(\\s+exactly)?$`),Q=i(`^then\\s+no\\s+readmodel\\s+([A-Z]\\w*)\\s+for\\s+(.+)$`),de=i(`^(?:"${t}"|'(?:[^'\\\\]|\\\\.)*')$`),fe=i(`^then\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)(\\s+exactly)?$`);function parseSpecification(t,n){let r=D.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidSpecificationDeclaration,`Invalid specification declaration '${n.content}' - expected 'specification <Name>'`,o(n));let i=null,a=[],s=[],l={givenOperationFailures:[],thenOperations:[],thenCompensated:[],thenAbsentReadModels:[],thenQueries:[],given:[],givenReadModels:[],when:null,whenAppended:null,whenRedelivered:null,whenDeclared:!1,thenEvents:[],thenEventsInAnyOrder:!1,thenNoEvents:!1,thenReadModels:[],thenErrors:[],givenClock:null,givenTimeZone:null,givenCaptures:[],whenClock:null,whenTrigger:null,whenCapture:null,whenQuery:null,thenResults:[],thenNoResult:null,thenDenied:null,givenCaller:null,thenReturns:null};for(let u=t.peekChild(n.indent);u!==void 0;u=t.peekChild(n.indent)){if(t.reader.takeSignificant(),te(u)||parseOperationStep(t,u,l))continue;let n=L.test(u.content)?`then`:c(u.content);if(n===`parameter`){let e=_(t,u);e!==null&&a.push(e)}else if(n===`case`){let e=g(t,u);e!==null&&s.push(e)}else n===`description`?i=b(t,u,i,`Specification '${r}'`):n===`given`?parseGiven(t,u,l):n===`when`?parseWhen(t,u,l,r):n===`then`?parseThen(t,u,l):(t.error(e.UnknownSpecificationDirective,`Unexpected '${c(u.content)}' in specification body`,o(u)),t.skipBlock(u.indent))}l.noEventsLine!==void 0&&(l.thenEvents.length>0||l.thenEventsInAnyOrder||l.thenErrors.length>0||l.thenDenied!==null)&&t.error(e.InvalidNoEventsExpectation,`'then no events' cannot accompany event, event-order, error or denial expectations.`,o(l.noEventsLine)),validateQueryRejection(t,n,l);let{whenDeclared:u,noEventsLine:d,...f}=l,p={kind:`SpecificationSyntax`,sourceOptions:t.sourceOptions,name:r,description:i,...f,...a.length===0?{}:{parameters:a},...s.length===0?{}:{cases:s},location:o(n)};return y(p,t),p}function validateQueryRejection(t,n,r){isQueryRejectionCandidate(r)&&!isWellFormedQueryRejection(r)&&t.error(e.MismatchedSpecificationQueryResult,`A query rejection requires exactly one query and one 'then error', no action, and no other outcomes`,o(n))}function isQueryRejectionCandidate(e){return e.thenErrors.length>0&&queriedCallCount(e)>0&&(e.whenQuery!==null||!hasAction(e))}function isWellFormedQueryRejection(e){return!hasAction(e)&&hasOneQueryAndOneError(e)&&!hasOtherOutcome(e)}function hasOneQueryAndOneError(e){return queriedCallCount(e)===1&&e.thenErrors.length===1}function hasAction(e){return[e.when,e.whenAppended,e.whenClock,e.whenTrigger,e.whenCapture,e.whenRedelivered].some(e=>e!==null)}function queriedCallCount(e){return e.thenQueries.length+(e.whenQuery===null?0:1)}function hasOtherOutcome(e){return[e.thenResults.length>0,e.thenNoResult!==null,e.thenDenied!==null,e.thenEvents.length>0,e.thenNoEvents,e.thenEventsInAnyOrder,e.thenReadModels.length>0,e.thenAbsentReadModels.length>0,e.thenReturns!==null,e.thenQueries.some(e=>e.results.length>0)].some(e=>e)}function parseOperationStep(t,n,r){if(!T.test(n.content))return!1;let i=E.exec(n.content);if(i===null||i[1]===`given operation`!=(i[3]!==void 0))t.error(e.InvalidOperationSpecification,`Expected 'given operation <Name> fails', 'then operation <Name>' or 'then compensated <Name>'.`,o(n)),skipBody(t,n.indent);else if(i[1]===`then operation`){let a=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=f(t,r,z,e.InvalidOperationSpecification);n!==null&&a.push(n)}r.thenOperations.push({kind:`SpecificationOperationSyntax`,operation:i[2],values:a,location:o(n)})}else S(t,n,e.InvalidOperationSpecification,`Failure and compensation assertions cannot have children.`),i[1]===`given operation`?r.givenOperationFailures.push({kind:`SpecificationOperationFailureSyntax`,operation:i[2],location:o(n)}):r.thenCompensated.push({kind:`SpecificationCompensatedSyntax`,operation:i[2],location:o(n)});return!0}function parseGiven(t,r,i){if(U.test(r.content))i.givenClock===null?i.givenClock=parseClock(t,r,`given`):(t.error(e.InvalidSpecificationClock,`A specification states its clock at most once.`,o(r)),skipBody(t,r.indent));else if(V.test(r.content)){let a=H.exec(r.content);skipBody(t,r.indent),i.givenTimeZone!==null||a===null?t.error(e.InvalidSpecificationTimeZone,`A specification states its time zone at most once, as 'given time zone "<id>"'.`,o(r)):i.givenTimeZone={kind:`SpecificationTimeZoneSyntax`,id:n(a[1]),location:o(r)}}else if(W.test(r.content)){let e=parseGivenGenerated(t,r);e!==null&&(i.givenGenerated??=[]).push(e)}else if(ne.test(r.content)){let e=parseCapture(t,r,`given`);e!==null&&i.givenCaptures.push(e)}else if(r.content.startsWith(`given caller`)){if(i.givenCaller!==null||i.givenCallerPersona!==void 0)t.error(e.DuplicateSpecificationCallerOrDenied,`A specification has at most one 'given caller' block.`,o(r)),t.skipBlock(r.indent);else if(r.content.startsWith(`given caller as`)){let n=O.exec(r.content);n===null&&t.error(e.InvalidSpecificationCallerPersona,`Expected 'given caller as <Persona>'.`,o(r));let a=t.peekChild(r.indent);a!==void 0&&t.error(e.InvalidSpecificationCallerPersona,`'given caller as <Persona>' has no body; use an explicit 'given caller' for refinements.`,o(a)),skipBody(t,r.indent),n!==null&&(i.givenCallerPersona={kind:`SpecificationCallerPersonaSyntax`,name:n[1],location:o(r)})}else i.givenCaller=parseCaller(t,r)}else if(P.test(r.content)){let e=parseReadModelStep(t,r,F,`given`);e!==void 0&&i.givenReadModels.push(e)}else{let e=parseEventStep(t,r,k,`given`);e!==void 0&&i.given.push(e)}}const pe=a(`^role${r}+"(${t})"$`),me=a(`^claim${r}+"(${t})"${r}*=${r}*"(${t})"$`);function parseCaller(t,r){if(r.content!==`given caller`)return t.error(e.InvalidSpecificationCaller,`Expected exactly 'given caller'.`,o(r)),t.skipBlock(r.indent),null;let i=!1,a=[],s=[];for(let c=t.peekChild(r.indent);c!==void 0;c=t.peekChild(r.indent)){t.reader.takeSignificant();let r=pe.exec(c.content),l=me.exec(c.content);c.content===`authenticated`&&!i?i=!0:r===null?l===null?t.error(h(c.content)?e.InvalidSpecificationCaseReference:e.InvalidSpecificationCaller,`Invalid caller fixture '${c.content}' - expected authenticated, role "...", or claim "..." = "...".`,o(c)):s.push({kind:`SpecificationCallerClaimSyntax`,type:n(l[1]),value:n(l[2]),location:o(c)}):a.push(n(r[1]))}return{kind:`SpecificationCallerSyntax`,authenticated:i,roles:a,claims:s,location:o(r)}}function parseWhen(t,n,r,i){let a=n.content.startsWith(`when append`);if(r.whenDeclared){let s=r.whenAppended!==null||a?e.ConflictingSpecificationActions:e.DuplicateSpecificationWhen;t.error(s,`Specification '${i}' already declares a 'when' - a specification can have at most one`,o(n)),skipBody(t,n.indent);return}if(r.whenDeclared=!0,a){r.whenAppended=parseEventStep(t,n,A,`when append`)??null;return}if(re.test(n.content)){let i=ie.exec(n.content);i===null?(t.error(e.UnmatchedRedeliveredOccurrence,`Expected 'when redelivered <Event> to <Reaction>'.`,o(n)),skipBody(t,n.indent)):r.whenRedelivered={kind:`SpecificationRedeliverySyntax`,eventType:i[1],reaction:i[2],...parseValuesWithEventSource(t,n,void 0,void 0,`when redelivered`),location:o(n)};return}if(K.test(n.content)){r.whenClock=parseClock(t,n,`when`);return}if(q.test(n.content)){r.whenTrigger=parseNamedStep(t,n,se,e.InvalidSpecificationTrigger,`when trigger`,`when trigger <Trigger>`,(e,t)=>({kind:`SpecificationTriggerSyntax`,trigger:e,values:t,location:o(n)}));return}if(J.test(n.content)){r.whenCapture=parseCapture(t,n,`when`);return}if(Y.test(n.content)){r.whenQuery=parseNamedStep(t,n,le,e.InvalidSpecificationQueryAction,`when query`,`when query <Query>`,(e,t)=>({kind:`SpecificationWhenQuerySyntax`,query:e,arguments:t,location:o(n)}),!0);return}let s=j.exec(n.content);if(s===null){t.error(e.InvalidSpecificationWhen,`Invalid 'when' declaration '${n.content}' - expected 'when <CommandType>' or 'when append <EventType>'`,o(n)),skipBody(t,n.indent);return}let c=[],l=parseValuesWithEventSource(t,n,c,s);r.when={kind:`SpecificationCommandSyntax`,commandType:s[1],...l,generatedValues:c,inlineProperty:s.groups?.property??null,location:o(n)}}function parseThen(t,r,i){if(ae.test(r.content)){r.content!==`then no events`||i.thenNoEvents?t.error(e.InvalidNoEventsExpectation,`Expected one 'then no events' directive.`,o(r)):(i.thenNoEvents=!0,i.noEventsLine=r);let n=t.peekChild(r.indent);n!==void 0&&t.error(e.InvalidNoEventsExpectation,`'then no events' cannot have child mappings.`,o(n)),skipBody(t,r.indent);return}if(m.test(r.content)){let n=p(t,r);i.thenReturns===null?i.thenReturns=n:t.error(e.InvalidReturnExpectation,`A specification declares at most one return expectation.`,o(r));return}if(r.content.startsWith(`then events`)){r.content!==`then events in any order`||i.thenEventsInAnyOrder?t.error(e.InvalidSpecificationEventOrder,`Expected one 'then events in any order' directive.`,o(r)):i.thenEventsInAnyOrder=!0,skipBody(t,r.indent);return}if(X.test(r.content)){parseResult(t,r,i);return}if(Z.test(r.content)){r.content!==`then no result`||i.thenNoResult!==null?t.error(e.InvalidSpecificationQueryAction,`Expected one 'then no result' directive.`,o(r)):i.thenNoResult={kind:`SpecificationNoResultSyntax`,location:o(r)},skipBody(t,r.indent);return}if(r.content.startsWith(`then denied`)){r.content===`then denied`?i.thenDenied===null?i.thenDenied={kind:`SpecificationDeniedSyntax`,location:o(r)}:t.error(e.DuplicateSpecificationCallerOrDenied,`A specification has at most one 'then denied' outcome.`,o(r)):(t.error(e.InvalidSpecificationDenied,`Expected exactly 'then denied'.`,o(r)),skipBody(t,r.indent));return}if(r.content===`then error`){i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:null,location:o(r)});return}if(r.content.startsWith(`then error case.`)){let e=v(r.content.substring(11),{...o(r),column:o(r).column+11},t);e.kind===`CaseValueExpressionSyntax`&&i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:null,caseValue:e,location:o(r)});return}let a=R.exec(r.content);if(a!==null){i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:n(a[1]),location:o(r)});return}if(c(r.content.substring(4).trim())===`error`){t.error(e.InvalidThenError,`Invalid 'then error' declaration '${r.content}' - expected 'then error' or 'then error "<reason>"'`,o(r)),skipBody(t,r.indent);return}if(L.test(r.content)){if(t.sourceOptions.numericMode===`exact`){let e=parseAbsentReadModel(t,r);e!==null&&i.thenAbsentReadModels.push(e);return}let e=Q.exec(r.content);if(e!==null&&!e[2].endsWith(` exactly`)){let n=v(e[2].trim(),o(r),t.valueContext);(n.kind===`LiteralExpressionSyntax`||n.kind===`ObjectExpressionSyntax`||n.kind===`CaseValueExpressionSyntax`)&&i.thenAbsentReadModels.push({kind:`SpecificationAbsentReadModelSyntax`,name:e[1],key:n,location:o(r)})}t.skipOpaqueBlock(r.indent);return}if(N.test(r.content)){let n=t.sourceOptions.numericMode===`exact`,reject=(e,r,i)=>{if(!n)return t.skipOpaqueBlock(i.indent);t.error(e,r,o(i)),t.skipBlock(i.indent)},a=fe.exec(r.content);if(a===null)return reject(e.InvalidSpecificationQuery,`Invalid 'then query' declaration '${r.content}' - expected 'then query <Query> [exactly]'`,r);let s=[],l=[],u=!1;for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent))t.reader.takeSignificant(),n.content===`arguments`&&!u?s.push(...parseValues(t.valueContext,n,!0,void 0,t)):n.content===`arguments`?reject(e.DuplicateSpecificationQueryArguments,`Query assertion '${a[1]}' already declares arguments`,n):n.content===`result`?l.push({kind:`SpecificationQueryResultSyntax`,properties:parseValues(t.valueContext,n,!0),exactly:!1,location:o(n)}):reject(e.UnknownSpecificationQueryDirective,`Unexpected '${c(n.content)}' in 'then query' body - expected arguments or result`,n),u||=n.content===`arguments`;i.thenQueries.push({kind:`SpecificationQuerySyntax`,query:a[1],arguments:s,results:l,exactly:a[2]!==void 0,location:o(r)});return}if(P.test(r.content)){let e=parseReadModelStep(t,r,I,`then`);e!==void 0&&i.thenReadModels.push(e);return}let s=parseEventStep(t,r,M,`then`);s!==void 0&&i.thenEvents.push(s)}function parseAbsentReadModel(t,n){let r=Q.exec(n.content);if(r===null||r[2].endsWith(` exactly`))return t.error(e.InvalidAbsentReadModelStep,`Invalid absence assertion '${n.content}' - expected 'then no readmodel <ReadModelType> for <key>'`,o(n)),skipBody(t,n.indent),null;let i=r[2].trim(),a=!(i.startsWith(`"`)||i.startsWith(`'`))||de.test(i)?v(i,o(n),t.valueContext):null,s=a!==null&&(a.kind===`LiteralExpressionSyntax`||a.kind===`ObjectExpressionSyntax`||a.kind===`CaseValueExpressionSyntax`);s||t.error(e.InvalidAbsentReadModelStep,`Invalid absence key '${i}' - expected exactly one concrete value.`,o(n));let c=!1;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent))t.reader.takeSignificant(),t.error(e.InvalidAbsentReadModelStep,`An absent read model assertion cannot have child mappings.`,o(r)),c=!0;return c||!s?null:{kind:`SpecificationAbsentReadModelSyntax`,name:r[1],key:a,location:o(n)}}function skipBody(e,t){if(e.sourceOptions.numericMode!==`exact`)return e.skipBlock(t);e.skipOpaqueBlock(t)}function parseClock(t,n,r){let i=oe.exec(n.content);return skipBody(t,n.indent),i===null||i[1]!==r?(t.error(h(n.content)?e.InvalidSpecificationCaseReference:e.InvalidSpecificationClock,`Invalid '${r} clock' - expected '${r} clock "<ISO 8601 instant>"', such as '${r} clock "2026-10-05T08:00:00Z"'`,o(n)),null):{kind:`SpecificationClockSyntax`,instant:i[2],location:o(n)}}function parseGivenGenerated(t,n){let r=G.exec(n.content);if(r===null)return t.error(e.InvalidGeneratedFixture,`Expected 'given generated <Command>.<property> = <value>' with exactly one concrete value.`,o(n)),t.skipBlock(n.indent),null;let i=o(n),a=d(t,r[3],{...i,column:i.column+n.content.indexOf(r[3],n.content.indexOf(`=`)+1)},e.InvalidGeneratedFixture),s=t.peekChild(n.indent);return s!==void 0&&(t.error(e.InvalidGeneratedFixture,`A pinned generated value cannot have child directives.`,o(s)),t.skipBlock(n.indent)),a===null?null:{kind:`SpecificationGeneratedValueSyntax`,command:r[1],property:r[2],source:a,location:i}}function parseCapture(t,n,r){return parseNamedStep(t,n,ce,e.InvalidSpecificationCapture,`${r} capture`,`${r} capture <Capture>`,(e,t)=>({kind:`SpecificationCaptureSyntax`,capture:e,record:t,location:o(n)}))}function parseNamedStep(e,t,n,r,i,a,s,c=!1){let l=n.exec(t.content);return l===null?(e.error(r,`Invalid '${i}' declaration '${t.content}' - expected '${a}'`,o(t)),skipBody(e,t.indent),null):s(l[1],parseValues(e,t,!1,void 0,c?e:void 0))}function parseResult(t,n,r){let i=ue.exec(n.content);i===null?(t.error(e.InvalidSpecificationQueryAction,`Invalid 'then result' declaration '${n.content}' - expected 'then result [exactly]'`,o(n)),skipBody(t,n.indent)):r.thenResults.push({kind:`SpecificationQueryResultSyntax`,properties:parseValues(t,n),exactly:i[1]!==void 0,location:o(n)})}function parseReadModelStep(t,n,r,i){let a=r.exec(n.content);if(a===null)t.error(e.InvalidReadModelStep,`Invalid '${i} readmodel' declaration '${n.content}' - expected '${i} readmodel <ReadModelType>'`,o(n)),skipBody(t,n.indent);else return{kind:`SpecificationReadModelSyntax`,name:a[1],properties:parseValues(t,n,!1,a),exactly:i===`then`&&a.groups?.exactly!==void 0,inlineProperty:a.groups?.property??null,location:o(n)}}function parseEventStep(t,n,r,i){let a=r.exec(n.content);if(a===null)t.error(e.InvalidEventStep,`Invalid '${i}' declaration '${n.content}' - expected '${i} <EventType>'`,o(n)),skipBody(t,n.indent);else return{kind:`SpecificationEventSyntax`,eventType:a[1],...parseValuesWithEventSource(t,n,void 0,a,i),inlineProperty:a.groups?.property??null,location:o(n)}}const $=x(`^stream\\s+([A-Za-z_]\\w*)\\.([A-Za-z_]\\w*)$`),he=a(`^streamId\\s*=(?!=|>)\\s*(.+)$`);function parseValuesWithEventSource(t,n,r,i,a){let d=[];w(t,n,i,d);let p=null,m,h,g=!1;for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent)){if(t.reader.takeSignificant(),r!==void 0&&u.test(i.content)){let n=f(t,i,l,e.InvalidGeneratedFixture);n!==null&&r.push(n);continue}let n=z.exec(i.content);if(n!==null)C(t,d,mappingOf(t,i,n));else if(c(i.content)===`stream`||i.content.startsWith(`no stream`)){if(a===void 0){t.error(e.SpecificationStreamOnCommand,`A command occurrence cannot declare a route; assert it on a then event.`,o(i)),t.skipBlock(i.indent);continue}if(g){t.error(e.InvalidSpecificationStream,`An event occurrence declares at most one stream or no stream directive.`,o(i)),t.skipBlock(i.indent);continue}let n=$.exec(i.content);i.content===`no stream`&&(a===`then`||a===`when redelivered`)?(h={kind:`SpecificationNoStreamSyntax`,location:o(i)},g=!0,rejectSpecificationRouteChildren(t,i)):n===null?(t.error(e.InvalidSpecificationStream,`Expected 'stream Source.Stream', or 'no stream' on a then event.`,o(i)),t.skipBlock(i.indent)):(m=parseSpecificationStream(t,i,n),g=!0)}else if(c(i.content)===`for`){let n=i.content.substring(3).trim();n.length===0?t.error(e.InvalidSpecificationEventSource,`Invalid event-source assertion 'for' - expected 'for <value>'`,o(i)):p===null?p=v(n,o(i),t):t.error(e.DuplicateSpecificationEventSource,`A specification step can declare its event-source assertion only once`,o(i))}else t.error(e.InvalidSpecificationValue,`Invalid property mapping '${i.content}' - expected '<property> = <value>'`,o(i),s(`text`,i.content))}return{values:d,for:p,...m===void 0?{}:{stream:m},...h===void 0?{}:{noStream:h}}}function parseSpecificationStream(t,n,r){let i=null,a=[],s=!1,c={};for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){if(t.reader.takeSignificant(),r.content===`streamId`){i!==null||s?(t.error(e.InvalidSpecificationStream,`Declare either one 'streamId = <literal>' mapping or one streamId part block.`,o(r)),t.skipBlock(r.indent)):(s=!0,c.streamId=o(r),a=ee(t,r,e.InvalidSpecificationStream).map(e=>e.source.kind===`PathExpressionSyntax`&&e.source.path.startsWith(`case.`)?{...e,source:v(e.source.path,e.source.location,t)}:e));continue}let n=he.exec(r.content);if(n===null||i!==null||s){t.error(e.InvalidSpecificationStream,`Declare either one 'streamId = <literal>' mapping or one streamId part block.`,o(r)),t.skipBlock(r.indent);continue}let l={...o(r),column:r.indent+1+r.content.indexOf(n[1],r.content.indexOf(`=`)+1)};i={kind:`PropertyMappingSyntax`,property:`streamId`,source:v(n[1],l,t),location:o(r)},rejectSpecificationRouteChildren(t,r)}return{kind:`SpecificationStreamSyntax`,eventSource:r[1],stream:r[2],streamId:i,streamIdParts:a,directiveLocations:c,referenceLocation:{...o(n),column:n.indent+1+n.content.indexOf(r[1],6)},referenceLength:r[1].length+1+r[2].length,location:o(n)}}function rejectSpecificationRouteChildren(t,n){let r=t.peekChild(n.indent);r!==void 0&&(t.error(e.InvalidSpecificationStream,`This directive cannot have children.`,o(r)),t.skipBlock(n.indent))}function parseValues(t,n,r=!1,i,a){let c=[];w(t,n,i,c);for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent)){t.reader.takeSignificant();let n=(r||t.sourceOptions.numericMode===`exact`?B:z).exec(i.content);if(n===null){t.error(e.InvalidSpecificationValue,`Invalid property mapping '${i.content}' - expected '<property> = <value>'`,o(i),s(`text`,i.content));continue}let l=mappingOf(t,i,n,r);a===void 0?C(t,c,l):(c.some(e=>e.property===l.property)&&a.error(e.UnknownSpecificationQueryArgument,`Query argument '${l.property}' is repeated.`,l.location,s(`argument`,l.property)),c.push(l))}return c}function mappingOf(e,t,n,r=!1){return{kind:`PropertyMappingSyntax`,property:n[1],source:v(n[2],o(t),e,r),location:o(t)}}export{parseSpecification,parseSpecificationStream,rejectSpecificationRouteChildren,$ as specificationStream};
2
2
  //# sourceMappingURL=SpecificationParser.js.map