@cratis/screenplay-language 4.259.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles/compiler/Authoring/QuickFixes.js +6 -2
- package/dist/bundles/compiler/Authoring/QuickFixes.js.map +1 -1
- package/dist/bundles/compiler/Authoring/StructuredValueQuickFix.js +3 -0
- package/dist/bundles/compiler/Authoring/StructuredValueQuickFix.js.map +1 -0
- package/dist/bundles/compiler/Dependencies/SliceReferences.js +1 -1
- package/dist/bundles/compiler/Dependencies/SliceReferences.js.map +1 -1
- package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js +1 -1
- package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js.map +1 -1
- package/dist/bundles/compiler/Files/PlayFolderMerge.js +1 -1
- package/dist/bundles/compiler/Files/PlayFolderMerge.js.map +1 -1
- package/dist/bundles/compiler/Parsing/CaptureParser.js +1 -1
- package/dist/bundles/compiler/Parsing/CaptureParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/CompositionParser.js +1 -1
- package/dist/bundles/compiler/Parsing/CompositionParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ExpressionParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ExpressionParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/OperationParser.js +1 -1
- package/dist/bundles/compiler/Parsing/OperationParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ProducesParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ProducesParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ProjectionParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ProjectionParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ReactionParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ReactionParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ScreenParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ScreenParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/ScreenplayParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ScreenplayParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/SeedParser.js +1 -1
- package/dist/bundles/compiler/Parsing/SeedParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationCaseParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationExampleParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationParser.js +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js +1 -1
- package/dist/bundles/compiler/Parsing/SpecificationResponseParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/StateMachineParser.js +2 -0
- package/dist/bundles/compiler/Parsing/StateMachineParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/StructuredBlockParser.js +2 -0
- package/dist/bundles/compiler/Parsing/StructuredBlockParser.js.map +1 -0
- package/dist/bundles/compiler/Parsing/UiBindingParser.js +1 -1
- package/dist/bundles/compiler/Parsing/UiBindingParser.js.map +1 -1
- package/dist/bundles/compiler/Parsing/WorkflowParser.js +2 -0
- package/dist/bundles/compiler/Parsing/WorkflowParser.js.map +1 -0
- package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js +1 -1
- package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js.map +1 -1
- package/dist/bundles/compiler/Syntax/Structure.js.map +1 -1
- package/dist/bundles/compiler/Syntax/SyntaxCollections.js +1 -1
- package/dist/bundles/compiler/Syntax/SyntaxCollections.js.map +1 -1
- package/dist/bundles/completion-items.js +22 -16
- package/dist/bundles/completion-items.js.map +1 -1
- package/dist/bundles/completion-planner.js +2 -2
- package/dist/bundles/completion-planner.js.map +1 -1
- package/dist/bundles/example-analysis.js +1 -1
- package/dist/bundles/example-analysis.js.map +1 -1
- package/dist/bundles/keyword-docs.js +1 -1
- package/dist/bundles/keyword-docs.js.map +1 -1
- package/dist/bundles/language.js +1 -1
- package/dist/bundles/language.js.map +1 -1
- package/dist/bundles/tokens.js +1 -1
- package/dist/bundles/tokens.js.map +1 -1
- package/dist/completion-items.d.ts +3 -0
- package/dist/completion-items.d.ts.map +1 -1
- package/dist/completion-planner.d.ts.map +1 -1
- package/dist/keyword-docs.d.ts.map +1 -1
- package/dist/language.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SeedParser.js","names":["pattern","parseMappingSource","headerPattern","stringBodyPattern","forPattern","eventPattern","nativePattern","mappingPattern","groups","context","headerMatch","header","DiagnosticCodes","locationOf","position","group","firstWord","parseCanvasPair","match","events","event","properties","property","mapped","parseModeledMappingSource","unescapeString"],"sources":["../../../../../../Compiler/Parsing/SeedParser.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 { PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SeedEventSyntax, SeedGroupSyntax, SeedSyntax } from '../Syntax/Seeds';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { nativePattern as pattern } from '../Text/patterns';\nimport { parseCanvasPair } from './CanvasPlacement';\nimport { parseModeledMappingSource as parseMappingSource } from './ExpressionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst headerPattern = new RegExp(`^seed(?:\\\\s+\"(${stringBodyPattern})\")?$`, 'u');\nconst forPattern = new RegExp(`^for\\\\s+\"(${stringBodyPattern})\"$`, 'u');\nconst eventPattern = pattern('^[A-Z]\\\\w*$');\nconst mappingPattern = pattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\n\nexport function parseSeed(context: ParserContext, header: SourceLine): SeedSyntax {\n const groups: SeedGroupSyntax[] = [];\n context = context.valueContext;\n const headerMatch = headerPattern.exec(header.content);\n if (headerMatch === null) {\n context.error(DiagnosticCodes.InvalidSeedDeclaration, `Invalid seed declaration '${header.content}' - expected 'seed' or 'seed \"<name>\"'`, locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return { kind: 'SeedSyntax', groups, location: locationOf(header) };\n }\n let position: readonly [number, number] | null = null;\n for (let group = context.peekChild(header.indent); group !== undefined; group = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (firstWord(group.content) === 'position') {\n position = parseCanvasPair(context, group, 'position', 'x', 'y', position, true) ?? position;\n continue;\n }\n const match = forPattern.exec(group.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSeedGroup, `Invalid seed group '${group.content}' - expected 'for \"<event source id>\"'`, locationOf(group));\n context.skipOpaqueBlock(group.indent);\n continue;\n }\n const events: SeedEventSyntax[] = [];\n for (let event = context.peekChild(group.indent); event !== undefined; event = context.peekChild(group.indent)) {\n context.reader.takeSignificant();\n if (!eventPattern.test(event.content)) {\n context.error(DiagnosticCodes.InvalidSeedEvent, `Invalid seed event '${event.content}' - expected an event type name`, locationOf(event));\n context.skipOpaqueBlock(event.indent);\n continue;\n }\n const properties: PropertyMappingSyntax[] = [];\n for (let property = context.peekChild(event.indent); property !== undefined; property = context.peekChild(event.indent)) {\n context.reader.takeSignificant();\n const mapped = mappingPattern.exec(property.content);\n if (mapped !== null) properties.push({ kind: 'PropertyMappingSyntax', property: mapped[1], source: parseMappingSource(mapped[2], locationOf(property), context), location: locationOf(property) });\n else context.error(DiagnosticCodes.InvalidSeedPropertyAssignment, `Invalid property assignment '${property.content}' - expected '<property> = <value>'`, locationOf(property));\n }\n events.push({ kind: 'SeedEventSyntax', event: event.content, properties, location: locationOf(event) });\n }\n groups.push({ kind: 'SeedGroupSyntax', eventSourceId: unescapeString(match[1]), events, location: locationOf(group) });\n }\n return { kind: 'SeedSyntax', groups, ...(headerMatch[1] === undefined ? {} : { name: unescapeString(headerMatch[1]) }), ...(position === null ? {} : { x: position[0], y: position[1] }), location: locationOf(header) };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SeedParser.js","names":["pattern","parseMappingSource","headerPattern","stringBodyPattern","forPattern","eventPattern","nativePattern","mappingPattern","groups","context","headerMatch","header","DiagnosticCodes","locationOf","position","group","firstWord","parseCanvasPair","match","events","event","properties","property","mapped","structured","tryParseStructuredMapping","parseModeledMappingSource","unescapeString"],"sources":["../../../../../../Compiler/Parsing/SeedParser.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 { PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SeedEventSyntax, SeedGroupSyntax, SeedSyntax } from '../Syntax/Seeds';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { nativePattern as pattern } from '../Text/patterns';\nimport { parseCanvasPair } from './CanvasPlacement';\nimport { parseModeledMappingSource as parseMappingSource } from './ExpressionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { tryParseStructuredMapping } from './StructuredBlockParser';\n\nconst headerPattern = new RegExp(`^seed(?:\\\\s+\"(${stringBodyPattern})\")?$`, 'u');\nconst forPattern = new RegExp(`^for\\\\s+\"(${stringBodyPattern})\"$`, 'u');\nconst eventPattern = pattern('^[A-Z]\\\\w*$');\nconst mappingPattern = pattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\n\nexport function parseSeed(context: ParserContext, header: SourceLine): SeedSyntax {\n const groups: SeedGroupSyntax[] = [];\n context = context.valueContext;\n const headerMatch = headerPattern.exec(header.content);\n if (headerMatch === null) {\n context.error(DiagnosticCodes.InvalidSeedDeclaration, `Invalid seed declaration '${header.content}' - expected 'seed' or 'seed \"<name>\"'`, locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return { kind: 'SeedSyntax', groups, location: locationOf(header) };\n }\n let position: readonly [number, number] | null = null;\n for (let group = context.peekChild(header.indent); group !== undefined; group = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (firstWord(group.content) === 'position') {\n position = parseCanvasPair(context, group, 'position', 'x', 'y', position, true) ?? position;\n continue;\n }\n const match = forPattern.exec(group.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSeedGroup, `Invalid seed group '${group.content}' - expected 'for \"<event source id>\"'`, locationOf(group));\n context.skipOpaqueBlock(group.indent);\n continue;\n }\n const events: SeedEventSyntax[] = [];\n for (let event = context.peekChild(group.indent); event !== undefined; event = context.peekChild(group.indent)) {\n context.reader.takeSignificant();\n if (!eventPattern.test(event.content)) {\n context.error(DiagnosticCodes.InvalidSeedEvent, `Invalid seed event '${event.content}' - expected an event type name`, locationOf(event));\n context.skipOpaqueBlock(event.indent);\n continue;\n }\n const properties: PropertyMappingSyntax[] = [];\n for (let property = context.peekChild(event.indent); property !== undefined; property = context.peekChild(event.indent)) {\n context.reader.takeSignificant();\n const mapped = mappingPattern.exec(property.content);\n const structured = mapped === null ? tryParseStructuredMapping(context, property) : undefined;\n if (mapped !== null) properties.push({ kind: 'PropertyMappingSyntax', property: mapped[1], source: parseMappingSource(mapped[2], locationOf(property), context), location: locationOf(property) });\n else if (structured !== undefined) properties.push(structured);\n else context.error(DiagnosticCodes.InvalidSeedPropertyAssignment, `Invalid property assignment '${property.content}' - expected '<property> = <value>'`, locationOf(property));\n }\n events.push({ kind: 'SeedEventSyntax', event: event.content, properties, location: locationOf(event) });\n }\n groups.push({ kind: 'SeedGroupSyntax', eventSourceId: unescapeString(match[1]), events, location: locationOf(group) });\n }\n return { kind: 'SeedSyntax', groups, ...(headerMatch[1] === undefined ? {} : { name: unescapeString(headerMatch[1]) }), ...(position === null ? {} : { x: position[0], y: position[1] }), location: locationOf(header) };\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{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{parseMappingSource as r}from"./ExpressionParser.js";import{diagnosticText as i}from"../Diagnostics/DiagnosticArgument.js";import{parseProperty as a}from"./PropertyLineParser.js";import{
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{parseMappingSource as r}from"./ExpressionParser.js";import{diagnosticText as i}from"../Diagnostics/DiagnosticArgument.js";import{parseProperty as a}from"./PropertyLineParser.js";import{tryParseStructuredMapping as o}from"./StructuredBlockParser.js";import{parseConcrete as s}from"./SpecificationResponseParser.js";const c=t(`^case\\s+([A-Za-z_]\\w*)(?:\\s+(?<property>[\\w.]+)\\s*=(?!=|>)\\s*(?<value>.+))?$`),l=t(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),u=t(`^case\\.([a-z_]\\w*)$`);function containsCaseReference(e){return/\bcase\.[a-z_]\w*/.test(e.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g,``))}function parseSpecificationValue(t,n,i,a=!1){if(!t.startsWith(`case.`))return containsCaseReference(t)&&i.error(e.InvalidSpecificationCaseReference,`A case reference fills a whole value position; it cannot occur inside a structured value or expression.`,n),r(t,n,i,a);let o=u.exec(t);return o===null&&i.error(e.InvalidSpecificationCaseReference,`A case reference fills a whole value position: 'case.<parameter>'.`,n),{kind:`CaseValueExpressionSyntax`,parameter:o?.[1]??t.substring(5),location:n}}function parseParameter(t,r){let i=r.content.indexOf(` `)+1,o=i>0?a(t,{...r,content:r.content.substring(i),indent:r.indent+i}):void 0;if(o===void 0||o.isGenerated||o.isIdentifier)return t.error(e.InvalidSpecificationParameter,`Expected 'parameter <name> <Type>', with optional collection and optional modifiers.`,n(r)),t.skipOpaqueBlock(r.indent),null;let s=t.peekChild(r.indent);return s!==void 0&&(t.error(e.InvalidSpecificationParameter,`A parameter has no body or default.`,n(s)),t.skipOpaqueBlock(r.indent)),{kind:`SpecificationParameterSyntax`,name:o.name,type:o.type,location:n(r)}}function parseCase(t,r){let a=c.exec(r.content);if(a===null)return t.error(e.InvalidSpecificationCase,`Expected 'case <Name>' with at most one inline parameter assignment.`,n(r)),t.skipOpaqueBlock(r.indent),null;let u=[],d=r.content.indexOf(a.groups?.property??``,r.content.indexOf(a[1],4)+a[1].length),add=(a,o,c)=>{let l=n(c),f={...l,column:l.column+c.content.indexOf(o,c.content.indexOf(`=`)+1)};if(o.startsWith(`case.`)){t.error(e.InvalidSpecificationCaseValue,`A case assigns concrete values, not case references.`,f,i(`text`,o));return}let p=s(t,o,f,e.InvalidSpecificationCaseValue);p!==null&&u.push({kind:`PropertyMappingSyntax`,property:a,source:p,location:c===r?{...l,column:l.column+d}:l})};a.groups?.property!==void 0&&add(a.groups.property,a.groups.value,r);for(let s=t.peekChild(r.indent);s!==void 0;s=t.peekChild(r.indent)){t.reader.takeSignificant();let r=l.exec(s.content),c=r===null?o(t,s):void 0;if(c!==void 0){u.push(c);continue}if(r===null){t.error(e.InvalidSpecificationCaseAssignment,`Expected '<parameter> = <concrete value>' in a case.`,n(s)),t.skipOpaqueBlock(s.indent);continue}add(r[1],r[2],s);let d=t.peekChild(s.indent);d!==void 0&&(t.error(e.InvalidSpecificationCaseValue,`A case value must fit on one line.`,n(d),{...i(`case`,a[1]),...i(`parameter`,r[1]),...i(`text`,d.content)}),t.skipOpaqueBlock(s.indent))}return{kind:`SpecificationCaseSyntax`,name:a[1],values:u,location:n(r)}}function caseReferences(e){return Array.isArray(e)?e.flatMap(caseReferences):typeof e!=`object`||!e?[]:`kind`in e&&e.kind===`CaseValueExpressionSyntax`?[e]:Object.values(e).flatMap(caseReferences)}function validateTable(t,n){let r=t.parameters??[],i=t.cases??[];r.length===0!=(i.length===0)&&n.error(e.IncompleteSpecificationTable,`A specification table requires parameters and at least one case.`,t.location),r.forEach((t,i)=>{r.slice(0,i).some(e=>e.name===t.name)&&n.error(e.DuplicateSpecificationParameter,`Parameter '${t.name}' is declared more than once.`,t.location)}),i.forEach((t,a)=>{i.slice(0,a).some(e=>e.name===t.name)&&n.error(e.DuplicateSpecificationCase,`Case '${t.name}' is declared more than once.`,t.location);for(let i of t.values.filter(e=>!r.some(t=>t.name===e.property)))n.error(e.InvalidSpecificationCaseAssignment,`Case '${t.name}' assigns undeclared parameter '${i.property}'.`,i.location);for(let i of r.filter(e=>t.values.filter(t=>t.property===e.name).length!==1))n.error(e.InvalidSpecificationCaseAssignment,`Case '${t.name}' must assign parameter '${i.name}' exactly once.`,t.location)});let a=caseReferences(t);for(let t of a)(i.length===0||!r.some(e=>e.name===t.parameter))&&n.error(e.InvalidSpecificationCaseReference,`Case reference '${t.parameter}' requires a declared parameter in a specification table.`,t.location);for(let t of r.filter(e=>!a.some(t=>t.parameter===e.name)))n.warning(e.UnusedSpecificationParameter,`Parameter '${t.name}' is never referenced.`,t.location);for(let r of caseReferences(t.whenRedelivered))n.error(e.InvalidSpecificationCaseReference,`Case references are not permitted in redelivery locators.`,r.location)}function substituteCase(e,t,n=/* @__PURE__ */ new WeakMap){if(typeof e==`object`&&e&&n.has(e))return n.get(e);if(Array.isArray(e)){let r=e.map(e=>substituteCase(e,t,n));return n.set(e,r),r}if(typeof e!=`object`||!e||!(`kind`in e))return e;if(e.kind===`CaseValueExpressionSyntax`){let n=e.parameter;return t.values.find(e=>e.property===n)?.source??e}let r=Object.fromEntries(Object.entries(e).map(([e,r])=>[e,substituteCase(r,t,n)]));if(e.kind===`SpecificationErrorSyntax`&&`caseValue`in e&&e.caseValue!==void 0){let e=r.caseValue;r.name=e.kind===`LiteralExpressionSyntax`?e.value:null,delete r.caseValue}return n.set(e,r),r}export{caseReferences,containsCaseReference,parseCase,parseParameter,parseSpecificationValue,substituteCase,validateTable};
|
|
2
2
|
//# sourceMappingURL=SpecificationCaseParser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpecificationCaseParser.js","names":["caseHeader","pattern","assignment","reference","text","context","DiagnosticCodes","location","parseMappingSource","nativeIdentifiers","match","offset","line","property","parseProperty","locationOf","child","values","inlinePropertyColumn","owner","valueLocation","diagnosticText","source","parseConcrete","value","nested","parameters","specification","cases","index","prior","parameter","row","references","copies","result","item","key"],"sources":["../../../../../../Compiler/Parsing/SpecificationCaseParser.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 { diagnosticText } from '../Diagnostics/DiagnosticArgument';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { CaseValueExpressionSyntax, ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SpecificationCaseSyntax, SpecificationParameterSyntax, SpecificationSyntax } from '../Syntax/Specifications';\nimport { pattern } from '../Text/patterns';\nimport { parseMappingSource } from './ExpressionParser';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { parseConcrete } from './SpecificationResponseParser';\n\n// No 'd' (hasIndices) flag: another extension in the shared VS Code extension host can patch RegExp and fail on it.\nconst caseHeader = pattern('^case\\\\s+([A-Za-z_]\\\\w*)(?:\\\\s+(?<property>[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(?<value>.+))?$');\nconst assignment = pattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst reference = pattern('^case\\\\.([a-z_]\\\\w*)$');\n\nexport function containsCaseReference(text: string): boolean {\n return /\\bcase\\.[a-z_]\\w*/.test(text.replace(/\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/g, ''));\n}\n\nexport function parseSpecificationValue(text: string, location: SourceLocation, context: ParserContext, nativeIdentifiers = false): ExpressionSyntax {\n if (!text.startsWith('case.')) {\n if (containsCaseReference(text)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'A case reference fills a whole value position; it cannot occur inside a structured value or expression.', location);\n return parseMappingSource(text, location, context, nativeIdentifiers);\n }\n const match = reference.exec(text);\n if (match === null) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, \"A case reference fills a whole value position: 'case.<parameter>'.\", location);\n return { kind: 'CaseValueExpressionSyntax', parameter: match?.[1] ?? text.substring(5), location };\n}\n\nexport function parseParameter(context: ParserContext, line: SourceLine): SpecificationParameterSyntax | null {\n const offset = line.content.indexOf(' ') + 1;\n const property = offset > 0 ? parseProperty(context, { ...line, content: line.content.substring(offset), indent: line.indent + offset }) : undefined;\n if (property === undefined || property.isGenerated || property.isIdentifier) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, \"Expected 'parameter <name> <Type>', with optional collection and optional modifiers.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const child = context.peekChild(line.indent);\n if (child !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, 'A parameter has no body or default.', locationOf(child));\n context.skipOpaqueBlock(line.indent);\n }\n return { kind: 'SpecificationParameterSyntax', name: property.name, type: property.type, location: locationOf(line) };\n}\n\nexport function parseCase(context: ParserContext, line: SourceLine): SpecificationCaseSyntax | null {\n const match = caseHeader.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCase, \"Expected 'case <Name>' with at most one inline parameter assignment.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const values: PropertyMappingSyntax[] = [];\n const inlinePropertyColumn = line.content.indexOf(match.groups?.property ?? '', line.content.indexOf(match[1], 'case'.length) + match[1].length);\n const add = (property: string, text: string, owner: SourceLine) => {\n const location = locationOf(owner);\n const valueLocation = { ...location, column: location.column + owner.content.indexOf(text, owner.content.indexOf('=') + 1) };\n if (text.startsWith('case.')) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case assigns concrete values, not case references.', valueLocation, diagnosticText('text', text));\n return;\n }\n const source = parseConcrete(context, text, valueLocation, DiagnosticCodes.InvalidSpecificationCaseValue);\n if (source !== null) values.push({ kind: 'PropertyMappingSyntax', property, source, location: owner === line ? { ...location, column: location.column + inlinePropertyColumn } : location });\n };\n if (match.groups?.property !== undefined) add(match.groups.property, match.groups.value, line);\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const value = assignment.exec(child.content);\n if (value === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, \"Expected '<parameter> = <concrete value>' in a case.\", locationOf(child));\n context.skipOpaqueBlock(child.indent);\n continue;\n }\n add(value[1], value[2], child);\n const nested = context.peekChild(child.indent);\n if (nested !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case value must fit on one line.', locationOf(nested), { ...diagnosticText('case', match[1]), ...diagnosticText('parameter', value[1]), ...diagnosticText('text', nested.content) });\n context.skipOpaqueBlock(child.indent);\n }\n }\n return { kind: 'SpecificationCaseSyntax', name: match[1], values, location: locationOf(line) };\n}\n\nexport function caseReferences(value: unknown): CaseValueExpressionSyntax[] {\n if (Array.isArray(value)) return value.flatMap(caseReferences);\n if (value === null || typeof value !== 'object') return [];\n if ('kind' in value && value.kind === 'CaseValueExpressionSyntax') return [value as CaseValueExpressionSyntax];\n return Object.values(value).flatMap(caseReferences);\n}\n\nexport function validateTable(specification: SpecificationSyntax, context: ParserContext): void {\n const parameters = specification.parameters ?? [];\n const cases = specification.cases ?? [];\n if ((parameters.length === 0) !== (cases.length === 0)) context.error(DiagnosticCodes.IncompleteSpecificationTable, 'A specification table requires parameters and at least one case.', specification.location);\n parameters.forEach((parameter, index) => {\n if (parameters.slice(0, index).some(prior => prior.name === parameter.name)) context.error(DiagnosticCodes.DuplicateSpecificationParameter, `Parameter '${parameter.name}' is declared more than once.`, parameter.location);\n });\n cases.forEach((row, index) => {\n if (cases.slice(0, index).some(prior => prior.name === row.name)) context.error(DiagnosticCodes.DuplicateSpecificationCase, `Case '${row.name}' is declared more than once.`, row.location);\n for (const value of row.values.filter(value => !parameters.some(parameter => parameter.name === value.property))) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' assigns undeclared parameter '${value.property}'.`, value.location);\n for (const parameter of parameters.filter(parameter => row.values.filter(value => value.property === parameter.name).length !== 1)) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' must assign parameter '${parameter.name}' exactly once.`, row.location);\n });\n const references = caseReferences(specification);\n for (const value of references) {\n if (cases.length === 0 || !parameters.some(parameter => parameter.name === value.parameter)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, `Case reference '${value.parameter}' requires a declared parameter in a specification table.`, value.location);\n }\n for (const parameter of parameters.filter(parameter => !references.some(value => value.parameter === parameter.name))) context.warning(DiagnosticCodes.UnusedSpecificationParameter, `Parameter '${parameter.name}' is never referenced.`, parameter.location);\n for (const value of caseReferences(specification.whenRedelivered)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'Case references are not permitted in redelivery locators.', value.location);\n}\n\nexport function substituteCase<T>(value: T, row: SpecificationCaseSyntax, copies = new WeakMap<object, unknown>()): T {\n if (value !== null && typeof value === 'object' && copies.has(value)) return copies.get(value) as T;\n if (Array.isArray(value)) {\n const result = value.map(item => substituteCase(item, row, copies));\n copies.set(value, result);\n return result as T;\n }\n if (value === null || typeof value !== 'object' || !('kind' in value)) return value;\n if (value.kind === 'CaseValueExpressionSyntax') {\n const parameter = (value as unknown as CaseValueExpressionSyntax).parameter;\n return (row.values.find(value => value.property === parameter)?.source ?? value) as T;\n }\n const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, substituteCase(item, row, copies)]));\n if (value.kind === 'SpecificationErrorSyntax' && 'caseValue' in value && value.caseValue !== undefined) {\n const source = result.caseValue as ExpressionSyntax;\n result.name = source.kind === 'LiteralExpressionSyntax' ? source.value : null;\n delete result.caseValue;\n }\n copies.set(value, result);\n return result as T;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SpecificationCaseParser.js","names":["caseHeader","pattern","assignment","reference","text","context","DiagnosticCodes","location","parseMappingSource","nativeIdentifiers","match","offset","line","property","parseProperty","locationOf","child","values","inlinePropertyColumn","owner","valueLocation","diagnosticText","source","parseConcrete","value","structured","tryParseStructuredMapping","nested","parameters","specification","cases","index","prior","parameter","row","references","copies","result","item","key"],"sources":["../../../../../../Compiler/Parsing/SpecificationCaseParser.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 { diagnosticText } from '../Diagnostics/DiagnosticArgument';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { CaseValueExpressionSyntax, ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SpecificationCaseSyntax, SpecificationParameterSyntax, SpecificationSyntax } from '../Syntax/Specifications';\nimport { pattern } from '../Text/patterns';\nimport { parseMappingSource } from './ExpressionParser';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { parseConcrete } from './SpecificationResponseParser';\nimport { tryParseStructuredMapping } from './StructuredBlockParser';\n\n// No 'd' (hasIndices) flag: another extension in the shared VS Code extension host can patch RegExp and fail on it.\nconst caseHeader = pattern('^case\\\\s+([A-Za-z_]\\\\w*)(?:\\\\s+(?<property>[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(?<value>.+))?$');\nconst assignment = pattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst reference = pattern('^case\\\\.([a-z_]\\\\w*)$');\n\nexport function containsCaseReference(text: string): boolean {\n return /\\bcase\\.[a-z_]\\w*/.test(text.replace(/\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'/g, ''));\n}\n\nexport function parseSpecificationValue(text: string, location: SourceLocation, context: ParserContext, nativeIdentifiers = false): ExpressionSyntax {\n if (!text.startsWith('case.')) {\n if (containsCaseReference(text)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'A case reference fills a whole value position; it cannot occur inside a structured value or expression.', location);\n return parseMappingSource(text, location, context, nativeIdentifiers);\n }\n const match = reference.exec(text);\n if (match === null) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, \"A case reference fills a whole value position: 'case.<parameter>'.\", location);\n return { kind: 'CaseValueExpressionSyntax', parameter: match?.[1] ?? text.substring(5), location };\n}\n\nexport function parseParameter(context: ParserContext, line: SourceLine): SpecificationParameterSyntax | null {\n const offset = line.content.indexOf(' ') + 1;\n const property = offset > 0 ? parseProperty(context, { ...line, content: line.content.substring(offset), indent: line.indent + offset }) : undefined;\n if (property === undefined || property.isGenerated || property.isIdentifier) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, \"Expected 'parameter <name> <Type>', with optional collection and optional modifiers.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const child = context.peekChild(line.indent);\n if (child !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationParameter, 'A parameter has no body or default.', locationOf(child));\n context.skipOpaqueBlock(line.indent);\n }\n return { kind: 'SpecificationParameterSyntax', name: property.name, type: property.type, location: locationOf(line) };\n}\n\nexport function parseCase(context: ParserContext, line: SourceLine): SpecificationCaseSyntax | null {\n const match = caseHeader.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCase, \"Expected 'case <Name>' with at most one inline parameter assignment.\", locationOf(line));\n context.skipOpaqueBlock(line.indent);\n return null;\n }\n const values: PropertyMappingSyntax[] = [];\n const inlinePropertyColumn = line.content.indexOf(match.groups?.property ?? '', line.content.indexOf(match[1], 'case'.length) + match[1].length);\n const add = (property: string, text: string, owner: SourceLine) => {\n const location = locationOf(owner);\n const valueLocation = { ...location, column: location.column + owner.content.indexOf(text, owner.content.indexOf('=') + 1) };\n if (text.startsWith('case.')) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case assigns concrete values, not case references.', valueLocation, diagnosticText('text', text));\n return;\n }\n const source = parseConcrete(context, text, valueLocation, DiagnosticCodes.InvalidSpecificationCaseValue);\n if (source !== null) values.push({ kind: 'PropertyMappingSyntax', property, source, location: owner === line ? { ...location, column: location.column + inlinePropertyColumn } : location });\n };\n if (match.groups?.property !== undefined) add(match.groups.property, match.groups.value, line);\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const value = assignment.exec(child.content);\n const structured = value === null ? tryParseStructuredMapping(context, child) : undefined;\n if (structured !== undefined) {\n values.push(structured);\n continue;\n }\n if (value === null) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, \"Expected '<parameter> = <concrete value>' in a case.\", locationOf(child));\n context.skipOpaqueBlock(child.indent);\n continue;\n }\n add(value[1], value[2], child);\n const nested = context.peekChild(child.indent);\n if (nested !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationCaseValue, 'A case value must fit on one line.', locationOf(nested), { ...diagnosticText('case', match[1]), ...diagnosticText('parameter', value[1]), ...diagnosticText('text', nested.content) });\n context.skipOpaqueBlock(child.indent);\n }\n }\n return { kind: 'SpecificationCaseSyntax', name: match[1], values, location: locationOf(line) };\n}\n\nexport function caseReferences(value: unknown): CaseValueExpressionSyntax[] {\n if (Array.isArray(value)) return value.flatMap(caseReferences);\n if (value === null || typeof value !== 'object') return [];\n if ('kind' in value && value.kind === 'CaseValueExpressionSyntax') return [value as CaseValueExpressionSyntax];\n return Object.values(value).flatMap(caseReferences);\n}\n\nexport function validateTable(specification: SpecificationSyntax, context: ParserContext): void {\n const parameters = specification.parameters ?? [];\n const cases = specification.cases ?? [];\n if ((parameters.length === 0) !== (cases.length === 0)) context.error(DiagnosticCodes.IncompleteSpecificationTable, 'A specification table requires parameters and at least one case.', specification.location);\n parameters.forEach((parameter, index) => {\n if (parameters.slice(0, index).some(prior => prior.name === parameter.name)) context.error(DiagnosticCodes.DuplicateSpecificationParameter, `Parameter '${parameter.name}' is declared more than once.`, parameter.location);\n });\n cases.forEach((row, index) => {\n if (cases.slice(0, index).some(prior => prior.name === row.name)) context.error(DiagnosticCodes.DuplicateSpecificationCase, `Case '${row.name}' is declared more than once.`, row.location);\n for (const value of row.values.filter(value => !parameters.some(parameter => parameter.name === value.property))) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' assigns undeclared parameter '${value.property}'.`, value.location);\n for (const parameter of parameters.filter(parameter => row.values.filter(value => value.property === parameter.name).length !== 1)) context.error(DiagnosticCodes.InvalidSpecificationCaseAssignment, `Case '${row.name}' must assign parameter '${parameter.name}' exactly once.`, row.location);\n });\n const references = caseReferences(specification);\n for (const value of references) {\n if (cases.length === 0 || !parameters.some(parameter => parameter.name === value.parameter)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, `Case reference '${value.parameter}' requires a declared parameter in a specification table.`, value.location);\n }\n for (const parameter of parameters.filter(parameter => !references.some(value => value.parameter === parameter.name))) context.warning(DiagnosticCodes.UnusedSpecificationParameter, `Parameter '${parameter.name}' is never referenced.`, parameter.location);\n for (const value of caseReferences(specification.whenRedelivered)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'Case references are not permitted in redelivery locators.', value.location);\n}\n\nexport function substituteCase<T>(value: T, row: SpecificationCaseSyntax, copies = new WeakMap<object, unknown>()): T {\n if (value !== null && typeof value === 'object' && copies.has(value)) return copies.get(value) as T;\n if (Array.isArray(value)) {\n const result = value.map(item => substituteCase(item, row, copies));\n copies.set(value, result);\n return result as T;\n }\n if (value === null || typeof value !== 'object' || !('kind' in value)) return value;\n if (value.kind === 'CaseValueExpressionSyntax') {\n const parameter = (value as unknown as CaseValueExpressionSyntax).parameter;\n return (row.values.find(value => value.property === parameter)?.source ?? value) as T;\n }\n const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, substituteCase(item, row, copies)]));\n if (value.kind === 'SpecificationErrorSyntax' && 'caseValue' in value && value.caseValue !== undefined) {\n const source = result.caseValue as ExpressionSyntax;\n result.name = source.kind === 'LiteralExpressionSyntax' ? source.value : null;\n delete result.caseValue;\n }\n copies.set(value, result);\n return result as T;\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{dotNetWhitespace as t,nativePattern as n}from"../Text/patterns.js";import{locationOf as r}from"./SourceLine.js";import{diagnosticText as i}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as a}from"./LineText.js";import{generatedFixturePattern as
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{dotNetWhitespace as t,nativePattern as n}from"../Text/patterns.js";import{locationOf as r}from"./SourceLine.js";import{diagnosticText as i}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as a}from"./LineText.js";import{tryParseStructuredMapping as o}from"./StructuredBlockParser.js";import{generatedFixturePattern as s,generatedFixturePrefix as c,parseConcrete as l,parseConcreteMapping as u}from"./SpecificationResponseParser.js";import{caseReferences as d,parseSpecificationValue as f}from"./SpecificationCaseParser.js";import{parseDescription as p}from"./DescriptionParser.js";import{parseSpecificationStream as m,rejectSpecificationRouteChildren as h,specificationStream as g}from"./SpecificationParser.js";const _=n(`^example\\s+([A-Z]\\w*)\\s*:\\s*([A-Z]\\w*(?:\\.\\w+)*)$`.replaceAll(`\\s`,t)),v=n(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`.replaceAll(`\\s`,t));function parseExample(t,n){let a=_.exec(n.content);if(a===null)return t.error(e.InvalidSpecificationExample,`Invalid example declaration '${n.content}' - expected 'example <Name> : <EventOrCommandOrReadModel>'`,r(n),i(`text`,n.content)),t.skipOpaqueBlock(n.indent),{kind:`SpecificationExampleSyntax`,name:``,type:``,values:[],generatedValues:[],for:null,description:null,location:r(n)};let o=parseFixtureBody(t,n,void 0,!0,a[1]);for(let n of d(o))t.error(e.InvalidSpecificationCaseReference,`Case references are not permitted in example bodies.`,n.location);return{kind:`SpecificationExampleSyntax`,name:a[1],type:a[2],...o,location:r(n)}}function addInlineValue(t,n,i,a){if(i?.groups?.property===void 0)return;let o=i.groups.property,s=i.groups.value,c=n.content.length-s.length,u=r(n),d=l(t,s,{...u,column:u.column+c},e.InvalidSpecificationValue);d!==null&&a.push({kind:`PropertyMappingSyntax`,property:o,source:d,location:{...u,column:u.column+n.content.lastIndexOf(o,n.content.indexOf(`=`))}})}function addFixtureValue(t,n,r,a=[]){[...n,...a].some(e=>e.property===r.property)?t.error(e.DuplicateSpecificationAssignment,`Property '${r.property}' is assigned more than once in this fixture - assign it only once, inline or indented`,r.location,i(`property`,r.property)):n.push(r)}function parseFixtureBody(t,n,l,d=!1,_){let y=[],b=[],x=null,S=null,C,w;addInlineValue(t,n,l,y);for(let l=t.peekChild(n.indent);l!==void 0;l=t.peekChild(n.indent)){t.reader.takeSignificant();let n;if(_!==void 0&&a(l.content)===`description`){S=p(t,l,S,`Example '${_}'`);continue}if(d&&c.test(l.content)){let n=u(t,l,s,e.InvalidGeneratedFixture);n!==null&&(_===void 0?b.push(n):addFixtureValue(t,b,n,y));continue}let T=v.exec(l.content);if(_!==void 0&&T===null&&(a(l.content)===`stream`||l.content.startsWith(`no stream`))){let n=g.exec(l.content);C!==void 0||w!==void 0?(t.error(e.InvalidSpecificationStream,`An event occurrence declares at most one stream or no stream directive.`,r(l)),t.skipOpaqueBlock(l.indent)):l.content===`no stream`?(w={kind:`SpecificationNoStreamSyntax`,location:r(l)},h(t,l)):n===null?(t.error(e.InvalidSpecificationStream,`Expected 'stream Source.Stream', or 'no stream' on an event example.`,r(l)),t.skipOpaqueBlock(l.indent)):C=m(t,l,n)}else if(T!==null)addFixtureValue(t,y,{kind:`PropertyMappingSyntax`,property:T[1],source:f(T[2],r(l),t),location:r(l)},b);else if(a(l.content)===`for`){let n=l.content.substring(3).trim();n.length===0?t.error(e.InvalidSpecificationEventSource,`Invalid event-source assertion 'for' - expected 'for <value>'`,r(l)):x===null?x=f(n,r(l),t):t.error(e.DuplicateSpecificationEventSource,`A specification step can declare its event-source assertion only once`,r(l))}else(n=o(t,l))===void 0?t.error(e.InvalidSpecificationValue,`Invalid property mapping '${l.content}' - expected '<property> = <value>'`,r(l),i(`text`,l.content)):addFixtureValue(t,y,n,b)}return{values:y,for:x,generatedValues:b,description:S,...C===void 0?{}:{stream:C},...w===void 0?{}:{noStream:w}}}export{addFixtureValue,addInlineValue,parseExample,parseFixtureBody};
|
|
2
2
|
//# sourceMappingURL=SpecificationExampleParser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpecificationExampleParser.js","names":["parseMappingSource","header","nativePattern","dotNetWhitespace","mapping","match","line","context","DiagnosticCodes","locationOf","diagnosticText","body","reference","caseReferences","property","text","offset","location","source","parseConcrete","values","other","existing","value","generatedValues","eventSource","description","stream","noStream","parent","inline","child","example","firstWord","parseDescription","allowGenerated","generatedFixturePrefix","fixture","parseConcreteMapping","generatedFixturePattern","route","specificationStream","rejectSpecificationRouteChildren","parseSpecificationStream","parseSpecificationValue"],"sources":["../../../../../../Compiler/Parsing/SpecificationExampleParser.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 { diagnosticText } from '../Diagnostics/DiagnosticArgument';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SpecificationNoStreamSyntax, SpecificationStreamSyntax, SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { dotNetWhitespace, nativePattern } from '../Text/patterns';\nimport { parseSpecificationStream, rejectSpecificationRouteChildren, specificationStream } from './SpecificationParser';\nimport { parseDescription } from './DescriptionParser';\nimport { caseReferences, parseSpecificationValue as parseMappingSource } from './SpecificationCaseParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { generatedFixturePattern, generatedFixturePrefix, parseConcrete, parseConcreteMapping } from './SpecificationResponseParser';\n\nconst header = nativePattern('^example\\\\s+([A-Z]\\\\w*)\\\\s*:\\\\s*([A-Z]\\\\w*(?:\\\\.\\\\w+)*)$'.replaceAll('\\\\s', dotNetWhitespace));\nconst mapping = nativePattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$'.replaceAll('\\\\s', dotNetWhitespace));\n\nexport function parseExample(context: ParserContext, line: SourceLine): SpecificationExampleSyntax {\n const match = header.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSpecificationExample, `Invalid example declaration '${line.content}' - expected 'example <Name> : <EventOrCommandOrReadModel>'`, locationOf(line), diagnosticText('text', line.content));\n context.skipOpaqueBlock(line.indent);\n return { kind: 'SpecificationExampleSyntax', name: '', type: '', values: [], generatedValues: [], for: null, description: null, location: locationOf(line) };\n }\n const body = parseFixtureBody(context, line, undefined, true, match[1]);\n for (const reference of caseReferences(body)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'Case references are not permitted in example bodies.', reference.location);\n return { kind: 'SpecificationExampleSyntax', name: match[1], type: match[2], ...body, location: locationOf(line) };\n}\n\nexport function addInlineValue(context: ParserContext, line: SourceLine, match: RegExpExecArray | undefined, values: PropertyMappingSyntax[]): void {\n if (match?.groups?.property === undefined) return;\n const property = match.groups.property;\n const text = match.groups.value;\n const offset = line.content.length - text.length;\n const location = locationOf(line);\n const source = parseConcrete(context, text, { ...location, column: location.column + offset }, DiagnosticCodes.InvalidSpecificationValue);\n if (source !== null) values.push({ kind: 'PropertyMappingSyntax', property, source, location: { ...location, column: location.column + line.content.lastIndexOf(property, line.content.indexOf('=')) } });\n}\n\nexport function addFixtureValue(context: ParserContext, values: PropertyMappingSyntax[], value: PropertyMappingSyntax, other: readonly PropertyMappingSyntax[] = []): void {\n if ([...values, ...other].some(existing => existing.property === value.property)) {\n context.error(DiagnosticCodes.DuplicateSpecificationAssignment, `Property '${value.property}' is assigned more than once in this fixture - assign it only once, inline or indented`, value.location, diagnosticText('property', value.property));\n return;\n }\n values.push(value);\n}\n\nexport function parseFixtureBody(context: ParserContext, parent: SourceLine, inline?: RegExpExecArray, allowGenerated = false, example?: string): {\n values: PropertyMappingSyntax[]; for: ExpressionSyntax | null; generatedValues: PropertyMappingSyntax[]; description: string | null;\n stream?: SpecificationStreamSyntax; noStream?: SpecificationNoStreamSyntax;\n} {\n const values: PropertyMappingSyntax[] = [];\n const generatedValues: PropertyMappingSyntax[] = [];\n let eventSource: ExpressionSyntax | null = null;\n let description: string | null = null;\n let stream: SpecificationStreamSyntax | undefined;\n let noStream: SpecificationNoStreamSyntax | undefined;\n addInlineValue(context, parent, inline, values);\n for (let child = context.peekChild(parent.indent); child !== undefined; child = context.peekChild(parent.indent)) {\n context.reader.takeSignificant();\n if (example !== undefined && firstWord(child.content) === 'description') {\n description = parseDescription(context, child, description, `Example '${example}'`);\n continue;\n }\n if (allowGenerated && generatedFixturePrefix.test(child.content)) {\n const fixture = parseConcreteMapping(context, child, generatedFixturePattern, DiagnosticCodes.InvalidGeneratedFixture);\n if (fixture !== null) {\n // Preserve validator-owned PLAY0490 for existing generated step fixtures.\n if (example === undefined) generatedValues.push(fixture);\n else addFixtureValue(context, generatedValues, fixture, values);\n }\n continue;\n }\n const match = mapping.exec(child.content);\n if (example !== undefined && match === null && (firstWord(child.content) === 'stream' || child.content.startsWith('no stream'))) {\n const route = specificationStream.exec(child.content);\n if (stream !== undefined || noStream !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationStream, 'An event occurrence declares at most one stream or no stream directive.', locationOf(child));\n context.skipOpaqueBlock(child.indent);\n } else if (child.content === 'no stream') {\n noStream = { kind: 'SpecificationNoStreamSyntax', location: locationOf(child) };\n rejectSpecificationRouteChildren(context, child);\n } else if (route !== null) {\n stream = parseSpecificationStream(context, child, route);\n } else {\n context.error(DiagnosticCodes.InvalidSpecificationStream, \"Expected 'stream Source.Stream', or 'no stream' on an event example.\", locationOf(child));\n context.skipOpaqueBlock(child.indent);\n }\n continue;\n }\n if (match !== null) {\n addFixtureValue(context, values, { kind: 'PropertyMappingSyntax', property: match[1], source: parseMappingSource(match[2], locationOf(child), context), location: locationOf(child) }, generatedValues);\n } else if (firstWord(child.content) === 'for') {\n const source = child.content.substring('for'.length).trim();\n if (source.length === 0) context.error(DiagnosticCodes.InvalidSpecificationEventSource, \"Invalid event-source assertion 'for' - expected 'for <value>'\", locationOf(child));\n else if (eventSource !== null) context.error(DiagnosticCodes.DuplicateSpecificationEventSource, 'A specification step can declare its event-source assertion only once', locationOf(child));\n else eventSource = parseMappingSource(source, locationOf(child), context);\n } else {\n context.error(DiagnosticCodes.InvalidSpecificationValue, `Invalid property mapping '${child.content}' - expected '<property> = <value>'`, locationOf(child), diagnosticText('text', child.content));\n }\n }\n return { values, for: eventSource, generatedValues, description, ...(stream === undefined ? {} : { stream }), ...(noStream === undefined ? {} : { noStream }) };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SpecificationExampleParser.js","names":["parseMappingSource","header","nativePattern","dotNetWhitespace","mapping","match","line","context","DiagnosticCodes","locationOf","diagnosticText","body","reference","caseReferences","property","text","offset","location","source","parseConcrete","values","other","existing","value","generatedValues","eventSource","description","stream","noStream","parent","inline","child","structured","example","firstWord","parseDescription","allowGenerated","generatedFixturePrefix","fixture","parseConcreteMapping","generatedFixturePattern","route","specificationStream","rejectSpecificationRouteChildren","parseSpecificationStream","parseSpecificationValue","tryParseStructuredMapping"],"sources":["../../../../../../Compiler/Parsing/SpecificationExampleParser.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 { diagnosticText } from '../Diagnostics/DiagnosticArgument';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { SpecificationNoStreamSyntax, SpecificationStreamSyntax, SpecificationExampleSyntax } from '../Syntax/Specifications';\nimport { dotNetWhitespace, nativePattern } from '../Text/patterns';\nimport { parseSpecificationStream, rejectSpecificationRouteChildren, specificationStream } from './SpecificationParser';\nimport { parseDescription } from './DescriptionParser';\nimport { caseReferences, parseSpecificationValue as parseMappingSource } from './SpecificationCaseParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\nimport { generatedFixturePattern, generatedFixturePrefix, parseConcrete, parseConcreteMapping } from './SpecificationResponseParser';\nimport { tryParseStructuredMapping } from './StructuredBlockParser';\n\nconst header = nativePattern('^example\\\\s+([A-Z]\\\\w*)\\\\s*:\\\\s*([A-Z]\\\\w*(?:\\\\.\\\\w+)*)$'.replaceAll('\\\\s', dotNetWhitespace));\nconst mapping = nativePattern('^([\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$'.replaceAll('\\\\s', dotNetWhitespace));\n\nexport function parseExample(context: ParserContext, line: SourceLine): SpecificationExampleSyntax {\n const match = header.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidSpecificationExample, `Invalid example declaration '${line.content}' - expected 'example <Name> : <EventOrCommandOrReadModel>'`, locationOf(line), diagnosticText('text', line.content));\n context.skipOpaqueBlock(line.indent);\n return { kind: 'SpecificationExampleSyntax', name: '', type: '', values: [], generatedValues: [], for: null, description: null, location: locationOf(line) };\n }\n const body = parseFixtureBody(context, line, undefined, true, match[1]);\n for (const reference of caseReferences(body)) context.error(DiagnosticCodes.InvalidSpecificationCaseReference, 'Case references are not permitted in example bodies.', reference.location);\n return { kind: 'SpecificationExampleSyntax', name: match[1], type: match[2], ...body, location: locationOf(line) };\n}\n\nexport function addInlineValue(context: ParserContext, line: SourceLine, match: RegExpExecArray | undefined, values: PropertyMappingSyntax[]): void {\n if (match?.groups?.property === undefined) return;\n const property = match.groups.property;\n const text = match.groups.value;\n const offset = line.content.length - text.length;\n const location = locationOf(line);\n const source = parseConcrete(context, text, { ...location, column: location.column + offset }, DiagnosticCodes.InvalidSpecificationValue);\n if (source !== null) values.push({ kind: 'PropertyMappingSyntax', property, source, location: { ...location, column: location.column + line.content.lastIndexOf(property, line.content.indexOf('=')) } });\n}\n\nexport function addFixtureValue(context: ParserContext, values: PropertyMappingSyntax[], value: PropertyMappingSyntax, other: readonly PropertyMappingSyntax[] = []): void {\n if ([...values, ...other].some(existing => existing.property === value.property)) {\n context.error(DiagnosticCodes.DuplicateSpecificationAssignment, `Property '${value.property}' is assigned more than once in this fixture - assign it only once, inline or indented`, value.location, diagnosticText('property', value.property));\n return;\n }\n values.push(value);\n}\n\nexport function parseFixtureBody(context: ParserContext, parent: SourceLine, inline?: RegExpExecArray, allowGenerated = false, example?: string): {\n values: PropertyMappingSyntax[]; for: ExpressionSyntax | null; generatedValues: PropertyMappingSyntax[]; description: string | null;\n stream?: SpecificationStreamSyntax; noStream?: SpecificationNoStreamSyntax;\n} {\n const values: PropertyMappingSyntax[] = [];\n const generatedValues: PropertyMappingSyntax[] = [];\n let eventSource: ExpressionSyntax | null = null;\n let description: string | null = null;\n let stream: SpecificationStreamSyntax | undefined;\n let noStream: SpecificationNoStreamSyntax | undefined;\n addInlineValue(context, parent, inline, values);\n for (let child = context.peekChild(parent.indent); child !== undefined; child = context.peekChild(parent.indent)) {\n context.reader.takeSignificant();\n let structured: PropertyMappingSyntax | undefined;\n if (example !== undefined && firstWord(child.content) === 'description') {\n description = parseDescription(context, child, description, `Example '${example}'`);\n continue;\n }\n if (allowGenerated && generatedFixturePrefix.test(child.content)) {\n const fixture = parseConcreteMapping(context, child, generatedFixturePattern, DiagnosticCodes.InvalidGeneratedFixture);\n if (fixture !== null) {\n // Preserve validator-owned PLAY0490 for existing generated step fixtures.\n if (example === undefined) generatedValues.push(fixture);\n else addFixtureValue(context, generatedValues, fixture, values);\n }\n continue;\n }\n const match = mapping.exec(child.content);\n if (example !== undefined && match === null && (firstWord(child.content) === 'stream' || child.content.startsWith('no stream'))) {\n const route = specificationStream.exec(child.content);\n if (stream !== undefined || noStream !== undefined) {\n context.error(DiagnosticCodes.InvalidSpecificationStream, 'An event occurrence declares at most one stream or no stream directive.', locationOf(child));\n context.skipOpaqueBlock(child.indent);\n } else if (child.content === 'no stream') {\n noStream = { kind: 'SpecificationNoStreamSyntax', location: locationOf(child) };\n rejectSpecificationRouteChildren(context, child);\n } else if (route !== null) {\n stream = parseSpecificationStream(context, child, route);\n } else {\n context.error(DiagnosticCodes.InvalidSpecificationStream, \"Expected 'stream Source.Stream', or 'no stream' on an event example.\", locationOf(child));\n context.skipOpaqueBlock(child.indent);\n }\n continue;\n }\n if (match !== null) {\n addFixtureValue(context, values, { kind: 'PropertyMappingSyntax', property: match[1], source: parseMappingSource(match[2], locationOf(child), context), location: locationOf(child) }, generatedValues);\n } else if (firstWord(child.content) === 'for') {\n const source = child.content.substring('for'.length).trim();\n if (source.length === 0) context.error(DiagnosticCodes.InvalidSpecificationEventSource, \"Invalid event-source assertion 'for' - expected 'for <value>'\", locationOf(child));\n else if (eventSource !== null) context.error(DiagnosticCodes.DuplicateSpecificationEventSource, 'A specification step can declare its event-source assertion only once', locationOf(child));\n else eventSource = parseMappingSource(source, locationOf(child), context);\n } else if ((structured = tryParseStructuredMapping(context, child)) !== undefined) {\n addFixtureValue(context, values, structured, generatedValues);\n } else {\n context.error(DiagnosticCodes.InvalidSpecificationValue, `Invalid property mapping '${child.content}' - expected '<property> = <value>'`, locationOf(child), diagnosticText('text', child.content));\n }\n }\n return { values, for: eventSource, generatedValues, description, ...(stream === undefined ? {} : { stream }), ...(noStream === undefined ? {} : { noStream }) };\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 ee,parseSpecificationValue as _,validateTable as v}from"./SpecificationCaseParser.js";import{parseDescription as y}from"./DescriptionParser.js";import{sourceStreamPattern as b}from"../Text/SourceStreamNames.js";import{parseRouteParts as x}from"./EventSourceParser.js";import{isFileDirective as te}from"./FileReferences.js";import{rejectOperationChildren as ne}from"./OperationParser.js";import{addFixtureValue as S,addInlineValue as C}from"./SpecificationExampleParser.js";const w=a(`^(?:given\\s+operation|then\\s+(?:operation|compensated))(?:\\s|$)`),T=a(`^(given operation|then operation|then compensated)\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)(\\s+fails)?$`),E=a(`^specification\\s+([A-Za-z_]\\w*)$`),D=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)),O=stepPattern(`given`),k=stepPattern(`when\\s+append`),A=stepPattern(`when`),j=stepPattern(`then`),M=a(`^then\\s+query\\b`),N=a(`^(?:given|then)\\s+readmodel\\b`),P=stepPattern(`given\\s+readmodel`),F=stepPattern(`then\\s+readmodel`,`(?<exactly>\\s+exactly)?`),I=a(`^then\\s+no\\b`),L=a(`^then\\s+error\\s+"(${t})"$`),R=a(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),z=i(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),B=a(`^given\\s+time\\s+zone\\b`),V=a(`^given\\s+time\\s+zone\\s+"(${t})"$`),H=a(`^given\\s+clock\\b`),re=a(`^given\\s+capture\\b`),U=a(`^then\\s+invokes\\b`),W=a(`^then\\s+invokes\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),G=a(`^given\\s+generated\\b`),K=a(`^given\\s+generated\\s+([A-Z]\\w*)\\.([a-z_]\\w*)\\s*=(?!=|>)\\s*(.+)$`),q=a(`^when\\s+clock\\b`),J=a(`^when\\s+trigger\\b`),Y=a(`^when\\s+capture\\b`),X=a(`^when\\s+query\\b`),ie=a(`^then\\s+result\\b`),ae=a(`^then\\s+no\\s+result\\b`),oe=i(`^when\\s+redelivered\\b`),se=i(`^when\\s+redelivered\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)\\s+to\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),ce=a(`^then\\s+no\\s+events\\b`),le=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}))"$`),ue=a(`^when\\s+trigger\\s+([A-Za-z_]\\w*)$`),de=a(`^(?:given|when)\\s+capture\\s+([A-Za-z_]\\w*)$`),fe=a(`^when\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),pe=a(`^then\\s+result(\\s+exactly)?$`),Z=i(`^then\\s+no\\s+readmodel\\s+([A-Z]\\w*)\\s+for\\s+(.+)$`),me=i(`^(?:"${t}"|'(?:[^'\\\\]|\\\\.)*')$`),Q=i(`^then\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)(\\s+exactly)?$`);function parseSpecification(t,n){let r=E.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=I.test(u.content)?`then`:c(u.content);if(n===`parameter`){let e=ee(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=y(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 v(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(!w.test(n.content))return!1;let i=T.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,R,e.InvalidOperationSpecification);n!==null&&a.push(n)}r.thenOperations.push({kind:`SpecificationOperationSyntax`,operation:i[2],values:a,location:o(n)})}else ne(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(H.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(B.test(r.content)){let a=V.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(G.test(r.content)){let e=parseGivenGenerated(t,r);e!==null&&(i.givenGenerated??=[]).push(e)}else if(re.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=D.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(N.test(r.content)){let e=parseReadModelStep(t,r,P,`given`);e!==void 0&&i.givenReadModels.push(e)}else{let e=parseEventStep(t,r,O,`given`);e!==void 0&&i.given.push(e)}}const he=a(`^role${r}+"(${t})"$`),ge=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=he.exec(c.content),l=ge.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,k,`when append`)??null;return}if(oe.test(n.content)){let i=se.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(q.test(n.content)){r.whenClock=parseClock(t,n,`when`);return}if(J.test(n.content)){r.whenTrigger=parseNamedStep(t,n,ue,e.InvalidSpecificationTrigger,`when trigger`,`when trigger <Trigger>`,(e,t)=>({kind:`SpecificationTriggerSyntax`,trigger:e,values:t,location:o(n)}));return}if(Y.test(n.content)){r.whenCapture=parseCapture(t,n,`when`);return}if(X.test(n.content)){r.whenQuery=parseNamedStep(t,n,fe,e.InvalidSpecificationQueryAction,`when query`,`when query <Query>`,(e,t)=>({kind:`SpecificationWhenQuerySyntax`,query:e,arguments:t,location:o(n)}),!0);return}let s=A.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(ce.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(ie.test(r.content)){parseResult(t,r,i);return}if(ae.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(U.test(r.content)){let n=parseNamedStep(t,r,W,e.InvalidSpecificationInvocation,`then invokes`,`then invokes <Command>`,(e,t)=>({kind:`SpecificationInvocationSyntax`,command:e,values:t,location:o(r)}));n!==null&&(i.thenInvocations??=[]).push(n);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=_(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=L.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(I.test(r.content)){if(t.sourceOptions.numericMode===`exact`){let e=parseAbsentReadModel(t,r);e!==null&&i.thenAbsentReadModels.push(e);return}let e=Z.exec(r.content);if(e!==null&&!e[2].endsWith(` exactly`)){let n=_(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(M.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=Q.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(N.test(r.content)){let e=parseReadModelStep(t,r,F,`then`);e!==void 0&&i.thenReadModels.push(e);return}let s=parseEventStep(t,r,j,`then`);s!==void 0&&i.thenEvents.push(s)}function parseAbsentReadModel(t,n){let r=Z.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(`'`))||me.test(i)?_(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=le.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=K.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,de,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=pe.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 $=b(`^stream\\s+([A-Za-z_]\\w*)\\.([A-Za-z_]\\w*)$`),_e=a(`^streamId\\s*=(?!=|>)\\s*(.+)$`);function parseValuesWithEventSource(t,n,r,i,a){let d=[];C(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=R.exec(i.content);if(n!==null)S(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=_(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=x(t,r,e.InvalidSpecificationStream).map(e=>e.source.kind===`PathExpressionSyntax`&&e.source.path.startsWith(`case.`)?{...e,source:_(e.source.path,e.source.location,t)}:e));continue}let n=_e.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:_(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=[];C(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`?z:R).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?S(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:_(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{sourceLocation as o}from"../Diagnostics/SourceLocation.js";import{locationOf as s}from"./SourceLine.js";import{diagnosticText as c}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as l}from"./LineText.js";import{parseStructuredValue as u,tryParseStructuredMapping as d}from"./StructuredBlockParser.js";import{generatedFixturePattern as f,generatedFixturePrefix as p,parseConcrete as m,parseConcreteMapping as h,parseReturn as g,thenReturnsPrefix as _}from"./SpecificationResponseParser.js";import{containsCaseReference as v,parseCase as y,parseParameter as b,parseSpecificationValue as x,validateTable as S}from"./SpecificationCaseParser.js";import{parseDescription as C}from"./DescriptionParser.js";import{sourceStreamPattern as ee}from"../Text/SourceStreamNames.js";import{parseRouteParts as w}from"./EventSourceParser.js";import{isFileDirective as T}from"./FileReferences.js";import{rejectOperationChildren as E}from"./OperationParser.js";import{addFixtureValue as D,addInlineValue as O}from"./SpecificationExampleParser.js";const te=a(`^(?:given\\s+operation|then\\s+(?:operation|compensated))(?:\\s|$)`),ne=a(`^(given operation|then operation|then compensated)\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)(\\s+fails)?$`),k=a(`^specification\\s+([A-Za-z_]\\w*)$`),A=k,j=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)),M=stepPattern(`given`),N=stepPattern(`when\\s+append`),P=stepPattern(`when`),F=stepPattern(`then`),I=a(`^then\\s+query\\b`),L=a(`^(?:given|then)\\s+readmodel\\b`),R=stepPattern(`given\\s+readmodel`),z=stepPattern(`then\\s+readmodel`,`(?<exactly>\\s+exactly)?`),B=a(`^then\\s+no\\b`),V=a(`^then\\s+error\\s+"(${t})"$`),H=a(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),U=i(`^([\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),W=a(`^given\\s+time\\s+zone\\b`),G=a(`^given\\s+time\\s+zone\\s+"(${t})"$`),K=a(`^given\\s+clock\\b`),q=a(`^given\\s+capture\\b`),J=a(`^then\\s+invokes\\b`),Y=a(`^then\\s+invokes\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),re=a(`^given\\s+generated\\b`),X=a(`^given\\s+generated\\s+([A-Z]\\w*)\\.([a-z_]\\w*)\\s*=(?!=|>)\\s*(.+)$`),ie=a(`^given\\s+generated\\s+([A-Z]\\w*)\\.([a-z_]\\w*)(?:\\s+(none|empty))?$`),ae=a(`^when\\s+clock\\b`),oe=a(`^when\\s+trigger\\b`),se=a(`^when\\s+capture\\b`),ce=a(`^when\\s+query\\b`),le=a(`^then\\s+result\\b`),ue=a(`^then\\s+no\\s+result\\b`),de=i(`^when\\s+redelivered\\b`),fe=i(`^when\\s+redelivered\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)\\s+to\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),pe=a(`^then\\s+no\\s+events\\b`),me=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}))"$`),he=a(`^when\\s+trigger\\s+([A-Za-z_]\\w*)$`),ge=a(`^(?:given|when)\\s+capture\\s+([A-Za-z_]\\w*)$`),_e=a(`^when\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),ve=a(`^then\\s+result(\\s+exactly)?$`),Z=i(`^then\\s+no\\s+readmodel\\s+([A-Z]\\w*)\\s+for(?:\\s+(.+))?$`),ye=i(`^(?:"${t}"|'(?:[^'\\\\]|\\\\.)*')$`),be=i(`^then\\s+query\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)(\\s+exactly)?$`);function parseSpecification(t,n){let r=k.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidSpecificationDeclaration,`Invalid specification declaration '${n.content}' - expected 'specification <Name>'`,s(n));let i=null,a=[],o=[],c={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(),T(u)||parseOperationStep(t,u,c))continue;let n=B.test(u.content)?`then`:l(u.content);if(n===`parameter`){let e=b(t,u);e!==null&&a.push(e)}else if(n===`case`){let e=y(t,u);e!==null&&o.push(e)}else n===`description`?i=C(t,u,i,`Specification '${r}'`):n===`given`?parseGiven(t,u,c):n===`when`?parseWhen(t,u,c,r):n===`then`?parseThen(t,u,c):(t.error(e.UnknownSpecificationDirective,`Unexpected '${l(u.content)}' in specification body`,s(u)),t.skipBlock(u.indent))}c.noEventsLine!==void 0&&(c.thenEvents.length>0||c.thenEventsInAnyOrder||c.thenErrors.length>0||c.thenDenied!==null)&&t.error(e.InvalidNoEventsExpectation,`'then no events' cannot accompany event, event-order, error or denial expectations.`,s(c.noEventsLine)),validateQueryRejection(t,n,c);let{whenDeclared:u,noEventsLine:d,...f}=c,p={kind:`SpecificationSyntax`,sourceOptions:t.sourceOptions,name:r,description:i,...f,...a.length===0?{}:{parameters:a},...o.length===0?{}:{cases:o},location:s(n)};return S(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`,s(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(!te.test(n.content))return!1;let i=ne.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>'.`,s(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=h(t,r,H,e.InvalidOperationSpecification);n!==null&&a.push(n)}r.thenOperations.push({kind:`SpecificationOperationSyntax`,operation:i[2],values:a,location:s(n)})}else E(t,n,e.InvalidOperationSpecification,`Failure and compensation assertions cannot have children.`),i[1]===`given operation`?r.givenOperationFailures.push({kind:`SpecificationOperationFailureSyntax`,operation:i[2],location:s(n)}):r.thenCompensated.push({kind:`SpecificationCompensatedSyntax`,operation:i[2],location:s(n)});return!0}function parseGiven(t,r,i){if(K.test(r.content))i.givenClock===null?i.givenClock=parseClock(t,r,`given`):(t.error(e.InvalidSpecificationClock,`A specification states its clock at most once.`,s(r)),skipBody(t,r.indent));else if(W.test(r.content)){let a=G.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>"'.`,s(r)):i.givenTimeZone={kind:`SpecificationTimeZoneSyntax`,id:n(a[1]),location:s(r)}}else if(re.test(r.content)){let e=parseGivenGenerated(t,r);e!==null&&(i.givenGenerated??=[]).push(e)}else if(q.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.`,s(r)),t.skipBlock(r.indent);else if(r.content.startsWith(`given caller as`)){let n=j.exec(r.content);n===null&&t.error(e.InvalidSpecificationCallerPersona,`Expected 'given caller as <Persona>'.`,s(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.`,s(a)),skipBody(t,r.indent),n!==null&&(i.givenCallerPersona={kind:`SpecificationCallerPersonaSyntax`,name:n[1],location:s(r)})}else i.givenCaller=parseCaller(t,r)}else if(L.test(r.content)){let e=parseReadModelStep(t,r,R,`given`);e!==void 0&&i.givenReadModels.push(e)}else{let e=parseEventStep(t,r,M,`given`);e!==void 0&&i.given.push(e)}}const xe=a(`^role${r}+"(${t})"$`),Se=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'.`,s(r)),t.skipBlock(r.indent),null;let i=!1,a=[],o=[];for(let c=t.peekChild(r.indent);c!==void 0;c=t.peekChild(r.indent)){t.reader.takeSignificant();let r=xe.exec(c.content),l=Se.exec(c.content);c.content===`authenticated`&&!i?i=!0:r===null?l===null?t.error(v(c.content)?e.InvalidSpecificationCaseReference:e.InvalidSpecificationCaller,`Invalid caller fixture '${c.content}' - expected authenticated, role "...", or claim "..." = "...".`,s(c)):o.push({kind:`SpecificationCallerClaimSyntax`,type:n(l[1]),value:n(l[2]),location:s(c)}):a.push(n(r[1]))}return{kind:`SpecificationCallerSyntax`,authenticated:i,roles:a,claims:o,location:s(r)}}function parseWhen(t,n,r,i){let a=n.content.startsWith(`when append`);if(r.whenDeclared){let o=r.whenAppended!==null||a?e.ConflictingSpecificationActions:e.DuplicateSpecificationWhen;t.error(o,`Specification '${i}' already declares a 'when' - a specification can have at most one`,s(n)),skipBody(t,n.indent);return}if(r.whenDeclared=!0,a){r.whenAppended=parseEventStep(t,n,N,`when append`)??null;return}if(de.test(n.content)){let i=fe.exec(n.content);i===null?(t.error(e.UnmatchedRedeliveredOccurrence,`Expected 'when redelivered <Event> to <Reaction>'.`,s(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:s(n)};return}if(ae.test(n.content)){r.whenClock=parseClock(t,n,`when`);return}if(oe.test(n.content)){r.whenTrigger=parseNamedStep(t,n,he,e.InvalidSpecificationTrigger,`when trigger`,`when trigger <Trigger>`,(e,t)=>({kind:`SpecificationTriggerSyntax`,trigger:e,values:t,location:s(n)}));return}if(se.test(n.content)){r.whenCapture=parseCapture(t,n,`when`);return}if(ce.test(n.content)){r.whenQuery=parseNamedStep(t,n,_e,e.InvalidSpecificationQueryAction,`when query`,`when query <Query>`,(e,t)=>({kind:`SpecificationWhenQuerySyntax`,query:e,arguments:t,location:s(n)}),!0);return}let o=P.exec(n.content);if(o===null){t.error(e.InvalidSpecificationWhen,`Invalid 'when' declaration '${n.content}' - expected 'when <CommandType>' or 'when append <EventType>'`,s(n)),skipBody(t,n.indent);return}let c=[],l=parseValuesWithEventSource(t,n,c,o);r.when={kind:`SpecificationCommandSyntax`,commandType:o[1],...l,generatedValues:c,inlineProperty:o.groups?.property??null,location:s(n)}}function parseThen(t,r,i){if(pe.test(r.content)){r.content!==`then no events`||i.thenNoEvents?t.error(e.InvalidNoEventsExpectation,`Expected one 'then no events' directive.`,s(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.`,s(n)),skipBody(t,r.indent);return}if(_.test(r.content)){let n=g(t,r);i.thenReturns===null?i.thenReturns=n:t.error(e.InvalidReturnExpectation,`A specification declares at most one return expectation.`,s(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.`,s(r)):i.thenEventsInAnyOrder=!0,skipBody(t,r.indent);return}if(le.test(r.content)){parseResult(t,r,i);return}if(ue.test(r.content)){r.content!==`then no result`||i.thenNoResult!==null?t.error(e.InvalidSpecificationQueryAction,`Expected one 'then no result' directive.`,s(r)):i.thenNoResult={kind:`SpecificationNoResultSyntax`,location:s(r)},skipBody(t,r.indent);return}if(J.test(r.content)){let n=parseNamedStep(t,r,Y,e.InvalidSpecificationInvocation,`then invokes`,`then invokes <Command>`,(e,t)=>({kind:`SpecificationInvocationSyntax`,command:e,values:t,location:s(r)}));n!==null&&(i.thenInvocations??=[]).push(n);return}if(r.content.startsWith(`then denied`)){r.content===`then denied`?i.thenDenied===null?i.thenDenied={kind:`SpecificationDeniedSyntax`,location:s(r)}:t.error(e.DuplicateSpecificationCallerOrDenied,`A specification has at most one 'then denied' outcome.`,s(r)):(t.error(e.InvalidSpecificationDenied,`Expected exactly 'then denied'.`,s(r)),skipBody(t,r.indent));return}if(r.content===`then error`){i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:null,location:s(r)});return}if(r.content.startsWith(`then error case.`)){let e=x(r.content.substring(11),{...s(r),column:s(r).column+11},t);e.kind===`CaseValueExpressionSyntax`&&i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:null,caseValue:e,location:s(r)});return}let a=V.exec(r.content);if(a!==null){i.thenErrors.push({kind:`SpecificationErrorSyntax`,name:n(a[1]),location:s(r)});return}if(l(r.content.substring(4).trim())===`error`){t.error(e.InvalidThenError,`Invalid 'then error' declaration '${r.content}' - expected 'then error' or 'then error "<reason>"'`,s(r)),skipBody(t,r.indent);return}if(B.test(r.content)){if(t.sourceOptions.numericMode===`exact`){let e=parseAbsentReadModel(t,r);e!==null&&i.thenAbsentReadModels.push(e);return}let e=Z.exec(r.content);if(e!==null&&e[2]===void 0&&t.peekChild(r.indent)!==void 0){i.thenAbsentReadModels.push({kind:`SpecificationAbsentReadModelSyntax`,name:e[1],key:u(t.valueContext,r,void 0),location:s(r)});return}if(e!==null&&e[2]!==void 0&&!e[2].endsWith(` exactly`)){let n=x(e[2].trim(),s(r),t.valueContext);(n.kind===`LiteralExpressionSyntax`||n.kind===`ObjectExpressionSyntax`||n.kind===`CaseValueExpressionSyntax`)&&i.thenAbsentReadModels.push({kind:`SpecificationAbsentReadModelSyntax`,name:e[1],key:n,location:s(r)})}t.skipOpaqueBlock(r.indent);return}if(I.test(r.content)){let n=t.sourceOptions.numericMode===`exact`,reject=(e,r,i)=>{if(!n)return t.skipOpaqueBlock(i.indent);t.error(e,r,s(i)),t.skipBlock(i.indent)},a=be.exec(r.content);if(a===null)return reject(e.InvalidSpecificationQuery,`Invalid 'then query' declaration '${r.content}' - expected 'then query <Query> [exactly]'`,r);let o=[],c=[],u=!1;for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent))t.reader.takeSignificant(),n.content===`arguments`&&!u?o.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`?c.push({kind:`SpecificationQueryResultSyntax`,properties:parseValues(t.valueContext,n,!0),exactly:!1,location:s(n)}):reject(e.UnknownSpecificationQueryDirective,`Unexpected '${l(n.content)}' in 'then query' body - expected arguments or result`,n),u||=n.content===`arguments`;i.thenQueries.push({kind:`SpecificationQuerySyntax`,query:a[1],arguments:o,results:c,exactly:a[2]!==void 0,location:s(r)});return}if(L.test(r.content)){let e=parseReadModelStep(t,r,z,`then`);e!==void 0&&i.thenReadModels.push(e);return}let o=parseEventStep(t,r,F,`then`);o!==void 0&&i.thenEvents.push(o)}function parseAbsentReadModel(t,n){let r=Z.exec(n.content);if(r!==null&&r[2]===void 0&&t.peekChild(n.indent)!==void 0)return{kind:`SpecificationAbsentReadModelSyntax`,name:r[1],key:u(t,n,void 0),location:s(n)};if(r===null||r[2]===void 0||r[2].endsWith(` exactly`))return t.error(e.InvalidAbsentReadModelStep,`Invalid absence assertion '${n.content}' - expected 'then no readmodel <ReadModelType> for <key>'`,s(n)),skipBody(t,n.indent),null;let i=r[2].trim(),a=!(i.startsWith(`"`)||i.startsWith(`'`))||ye.test(i)?x(i,s(n),t.valueContext):null,o=a!==null&&(a.kind===`LiteralExpressionSyntax`||a.kind===`ObjectExpressionSyntax`||a.kind===`CaseValueExpressionSyntax`);o||t.error(e.InvalidAbsentReadModelStep,`Invalid absence key '${i}' - expected exactly one concrete value.`,s(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.`,s(r)),c=!0;return c||!o?null:{kind:`SpecificationAbsentReadModelSyntax`,name:r[1],key:a,location:s(n)}}function skipBody(e,t){if(e.sourceOptions.numericMode!==`exact`)return e.skipBlock(t);e.skipOpaqueBlock(t)}function parseClock(t,n,r){let i=me.exec(n.content);return skipBody(t,n.indent),i===null||i[1]!==r?(t.error(v(n.content)?e.InvalidSpecificationCaseReference:e.InvalidSpecificationClock,`Invalid '${r} clock' - expected '${r} clock "<ISO 8601 instant>"', such as '${r} clock "2026-10-05T08:00:00Z"'`,s(n)),null):{kind:`SpecificationClockSyntax`,instant:i[2],location:s(n)}}function parseGivenGenerated(t,n){let r=X.exec(n.content),i=r===null?ie.exec(n.content):null;if(i!==null)return{kind:`SpecificationGeneratedValueSyntax`,command:i[1],property:i[2],source:u(t,n,i[3]),location:s(n)};if(r===null)return t.error(e.InvalidGeneratedFixture,`Expected 'given generated <Command>.<property> = <value>' with exactly one concrete value.`,s(n)),t.skipBlock(n.indent),null;let a=s(n),o=m(t,r[3],{...a,column:a.column+n.content.indexOf(r[3],n.content.indexOf(`=`)+1)},e.InvalidGeneratedFixture),c=t.peekChild(n.indent);return c!==void 0&&(t.error(e.InvalidGeneratedFixture,`A pinned generated value cannot have child directives.`,s(c)),t.skipBlock(n.indent)),o===null?null:{kind:`SpecificationGeneratedValueSyntax`,command:r[1],property:r[2],source:o,location:a}}function parseCapture(t,n,r){return parseNamedStep(t,n,ge,e.InvalidSpecificationCapture,`${r} capture`,`${r} capture <Capture>`,(e,t)=>({kind:`SpecificationCaptureSyntax`,capture:e,record:t,location:s(n)}))}function parseNamedStep(e,t,n,r,i,a,o,c=!1){let l=n.exec(t.content);return l===null?(e.error(r,`Invalid '${i}' declaration '${t.content}' - expected '${a}'`,s(t)),skipBody(e,t.indent),null):o(l[1],parseValues(e,t,!1,void 0,c?e:void 0))}function parseResult(t,n,r){let i=ve.exec(n.content);i===null?(t.error(e.InvalidSpecificationQueryAction,`Invalid 'then result' declaration '${n.content}' - expected 'then result [exactly]'`,s(n)),skipBody(t,n.indent)):r.thenResults.push({kind:`SpecificationQueryResultSyntax`,properties:parseValues(t,n),exactly:i[1]!==void 0,location:s(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>'`,s(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:s(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>'`,s(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:s(n)}}const Q=ee(`^stream\\s+([A-Za-z_]\\w*)\\.([A-Za-z_]\\w*)$`),Ce=a(`^streamId\\s*=(?!=|>)\\s*(.+)$`);function parseValuesWithEventSource(t,n,r,i,a){let o=[];O(t,n,i,o);let u=null,m,g,_=!1;for(let i=t.peekChild(n.indent);i!==void 0;i=t.peekChild(n.indent)){t.reader.takeSignificant();let n;if(r!==void 0&&p.test(i.content)){let n=h(t,i,f,e.InvalidGeneratedFixture);n!==null&&r.push(n);continue}let v=H.exec(i.content);if(v!==null)D(t,o,mappingOf(t,i,v));else if(l(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.`,s(i)),t.skipBlock(i.indent);continue}if(_){t.error(e.InvalidSpecificationStream,`An event occurrence declares at most one stream or no stream directive.`,s(i)),t.skipBlock(i.indent);continue}let n=Q.exec(i.content);i.content===`no stream`&&(a===`then`||a===`when redelivered`)?(g={kind:`SpecificationNoStreamSyntax`,location:s(i)},_=!0,rejectSpecificationRouteChildren(t,i)):n===null?(t.error(e.InvalidSpecificationStream,`Expected 'stream Source.Stream', or 'no stream' on a then event.`,s(i)),t.skipBlock(i.indent)):(m=parseSpecificationStream(t,i,n),_=!0)}else if(l(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>'`,s(i)):u===null?u=x(n,s(i),t):t.error(e.DuplicateSpecificationEventSource,`A specification step can declare its event-source assertion only once`,s(i))}else(n=d(t,i))===void 0?t.error(e.InvalidSpecificationValue,`Invalid property mapping '${i.content}' - expected '<property> = <value>'`,s(i),c(`text`,i.content)):D(t,o,n)}return{values:o,for:u,...m===void 0?{}:{stream:m},...g===void 0?{}:{noStream:g}}}function parseSpecificationStream(t,n,r){let i=null,a=[],o=!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||o?(t.error(e.InvalidSpecificationStream,`Declare either one 'streamId = <literal>' mapping or one streamId part block.`,s(r)),t.skipBlock(r.indent)):(o=!0,c.streamId=s(r),a=w(t,r,e.InvalidSpecificationStream).map(e=>e.source.kind===`PathExpressionSyntax`&&e.source.path.startsWith(`case.`)?{...e,source:x(e.source.path,e.source.location,t)}:e));continue}let n=Ce.exec(r.content);if(n===null||i!==null||o){t.error(e.InvalidSpecificationStream,`Declare either one 'streamId = <literal>' mapping or one streamId part block.`,s(r)),t.skipBlock(r.indent);continue}let l={...s(r),column:r.indent+1+r.content.indexOf(n[1],r.content.indexOf(`=`)+1)};i={kind:`PropertyMappingSyntax`,property:`streamId`,source:x(n[1],l,t),location:s(r)},rejectSpecificationRouteChildren(t,r)}return{kind:`SpecificationStreamSyntax`,eventSource:r[1],stream:r[2],streamId:i,streamIdParts:a,directiveLocations:c,referenceLocation:{...s(n),column:n.indent+1+n.content.indexOf(r[1],6)},referenceLength:r[1].length+1+r[2].length,location:s(n)}}function rejectSpecificationRouteChildren(t,n){let r=t.peekChild(n.indent);r!==void 0&&(t.error(e.InvalidSpecificationStream,`This directive cannot have children.`,s(r)),t.skipBlock(n.indent))}function parseValues(t,n,r=!1,i,a){let o=[];O(t,n,i,o);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`?U:H).exec(i.content),l=n===null?d(t,i):void 0;if(n===null&&l===void 0){t.error(e.InvalidSpecificationValue,`Invalid property mapping '${i.content}' - expected '<property> = <value>'`,s(i),c(`text`,i.content));continue}let u=l??mappingOf(t,i,n,r);a===void 0?D(t,o,u):(o.some(e=>e.property===u.property)&&a.error(e.UnknownSpecificationQueryArgument,`Query argument '${u.property}' is repeated.`,u.location,c(`argument`,u.property)),o.push(u))}return o}function mappingOf(e,t,n,r=!1){return{kind:`PropertyMappingSyntax`,property:n[1],source:x(n[2],s(t),e,r),location:s(t)}}const $=a(`^when\\s+start\\s+(.+)$`),we=a(`^outcome\\s+([A-Za-z_]\\w*)\\s+([A-Za-z_]\\w*)$`),Te=a(`^then\\s+(is|sends|starts|completes|fails\\s+at|waits\\s+at)(?:\\s+([A-Za-z_]\\w*))?$`);function lifecycleExpectation(e){let t=Te.exec(e.content);if(t===null)return;let n=t[1].replace(/\s+/g,` `),r=n===`is`?`State`:n===`sends`?`Sends`:n===`starts`?`Starts`:n===`completes`?`Completes`:n===`fails at`?`Fails`:`Waits`;if(t[2]!==void 0!=(r===`Completes`))return{kind:`LifecycleExpectationSyntax`,expectation:r,target:t[2]??null,location:s(e)}}function parseLifecycleSpecification(e,t,n){let r=A.exec(t.content);if(r===null)return e.error(n,`Invalid specification '${t.content}' - expected 'specification <Name>'.`,s(t)),skipBody(e,t.indent),{kind:`LifecycleSpecificationSyntax`,name:``,description:null,given:[],whenAppended:null,whenStarted:null,outcomes:[],then:[],location:s(t)};let i=r[1],a=null,c=[],u=null,d=null,f=!1,p=[],m=[],h={};for(let r=e.peekChild(t.indent);r!==void 0;r=e.peekChild(t.indent)){e.reader.takeSignificant();let t=l(r.content);if(t===`description`)a=C(e,r,a,`Specification '${i}'`),h.description??=s(r);else if(t===`given`){let t=parseEventStep(e,r,M,`given`);t!==void 0&&c.push(t)}else if(t===`when`){if(f){e.error(n,`Specification '${i}' already declares a 'when'.`,s(r)),skipBody(e,r.indent);continue}f=!0;let t=$.exec(r.content);if(t!==null){let n=r.content.indexOf(t[1],10);d=x(t[1].trim(),o(r.number,r.indent+(r.contentOffset??0)+1+n,r.path),e)}else r.content.startsWith(`when append`)?u=parseEventStep(e,r,N,`when append`)??null:(e.error(n,`Invalid '${r.content}' - expected 'when append <Event>' or 'when start <key>'.`,s(r)),skipBody(e,r.indent))}else if(t===`outcome`){let t=we.exec(r.content);t===null?e.error(n,`Invalid outcome '${r.content}' - expected 'outcome <Node> <outlet>'.`,s(r)):p.push({kind:`LifecycleOutcomeSyntax`,node:t[1],outlet:t[2],location:s(r)}),E(e,r,n,`An outcome cannot have children.`)}else if(t===`then`){let t=lifecycleExpectation(r);t===void 0?e.error(n,`Invalid '${r.content}' - expected 'then is <State>', 'then sends <Command>', 'then starts <Workflow>', 'then completes', 'then fails at <Node>' or 'then waits at <Node>'.`,s(r)):m.push(t),E(e,r,n,`A then line cannot have children.`)}else e.error(n,`Unexpected '${r.content}' in specification '${i}' - expected description, given, when, outcome or then.`,s(r)),e.skipBlock(r.indent)}return{kind:`LifecycleSpecificationSyntax`,name:i,description:a,given:c,whenAppended:u,whenStarted:d,outcomes:p,then:m,location:s(t),directiveLocations:h}}export{parseLifecycleSpecification,parseSpecification,parseSpecificationStream,rejectSpecificationRouteChildren,Q as specificationStream};
|
|
2
2
|
//# sourceMappingURL=SpecificationParser.js.map
|