@cratis/screenplay-language 4.224.0 → 4.225.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/Parsing/CommandParser.js +1 -1
- package/dist/bundles/compiler/Parsing/CommandParser.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/ScreenParser.js +1 -1
- package/dist/bundles/compiler/Parsing/ScreenParser.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 +1 -1
- package/dist/bundles/completion-items.js.map +1 -1
- package/dist/completion-items.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i}from"./SourceLine.js";import{dependencySources as a}from"../Syntax/DependencySources.js";import{parseMappingSource as o}from"./ExpressionParser.js";import{isPendingHandler as s,validateHandlerOccurrences as c}from"./CommandHandlerValidator.js";import{firstWord as l}from"./LineText.js";import{reportInvalidModifierOrder as u,reportLegacyOptionalSuffix as d,tryParseProperty as f}from"./PropertyLineParser.js";import{combineAuthorize as p,parseAuthorize as m}from"./AuthorizeParser.js";import{parseDescription as h}from"./DescriptionParser.js";import{parseDocumentation as g}from"./DocumentationParser.js";import{parseCondition as _}from"./ConditionParser.js";import{ParserContext as v}from"./ParserContext.js";import{isReactionIdentityLine as y,misplacedReactionIdentity as b}from"./ReactionIdentityParser.js";import{sourceStreamPattern as x}from"../Text/SourceStreamNames.js";import{parseCommandStream as S}from"./EventSourceParser.js";import{isCode as C,isFile as w,parseCode as T,parseFile as E,parseHandler as D,parseImplementationWrapper as O}from"./ImplementationParser.js";import{parseCommandResponse as k,scalarResponsePattern as A}from"./CommandResponseParser.js";import{matchSubject as j,validateMatchOperand as M}from"./MatchOperandValidation.js";import{commandReadSources as N}from"./CommandReadSources.js";import{captureConcurrency as P}from"./DependencySourceParser.js";import{parseReads as F}from"./ReadsParser.js";import{parseProduces as I}from"./ProducesParser.js";const L=r(`^command\\s+([A-Za-z_]\\w*)$`),R=x(`^stream\\s+[A-Za-z_]\\w*\\.[A-Za-z_]\\w*$`),z=r(`\\bseverity\\s+(\\S+)$`),B=r(`\\bmessage\\s+(?:"(${t})"|(\\$strings\\.\\S*))$`),V=r(`^([\\w.]+)\\s+(.+)$`),H=r(`^(not empty|length ==|all >=|all >|matches|not contains|contains|starts with|ends with|max|min|rule|>=|<=|==|!=|>|<)\\s*(.*)$`),U=x(`^[A-Za-z_]\\w*$`),W=r(`^reads\\s+[A-Z]\\w*\\s+optional(?:\\s|$)`),G={max:`Max`,min:`Min`,">":`GreaterThan`,">=":`GreaterThanOrEqual`,"<":`LessThan`,"<=":`LessThanOrEqual`,"==":`Equal`,"!=":`NotEqual`,"length ==":`Length`,matches:`Matches`,contains:`Contains`,"not contains":`NotContains`,"starts with":`StartsWith`,"ends with":`EndsWith`,"all >":`AllGreaterThan`,"all >=":`AllGreaterThanOrEqual`},K={information:`Information`,warning:`Warning`,error:`Error`},q=/* @__PURE__ */ new Set([`reads`,`concurrency`]),J=/* @__PURE__ */ new Set([`description`,`documentation`,`handler`,`concurrency`]);function parseCommand(e,t){let n=/* @__PURE__ */ new Set,r=new v(e.reader.fork(),e.path,e.languages);return r.sourceOptions=e.sourceOptions,r.streamCandidates=e.streamCandidates,parseCommandBody(r,t,void 0,n),parseCommandBody(e,t,n)}function parseCommandBody(t,n,r,o){let d=L.exec(n.content)?.[1]??``;d===``&&t.error(e.InvalidCommandDeclaration,`Invalid command declaration '${n.content}' - expected 'command <Name>'`,i(n));let _=[],v=[],x,C=[],w=[],T=[],E=[],O,j=null,M=null,z=null,B=null,V=[],H=null,U=[];for(let a=t.peekChild(n.indent);a!==void 0;a=t.peekChild(n.indent)){t.reader.takeSignificant();let n=l(a.content),o=f(a);if(o!==void 0&&(J.has(n)||n===`validate`&&a.content!==`validate csharp`))x=addProperty(t,_,o,d,a,x);else if(n===`returns`){let e=A.exec(a.content);e!==null&&!e[1].startsWith(`@`)&&o!==void 0?r===void 0?(_.push(o),v.push({line:a,candidate:o,response:null})):r.has(o.type.name)?v.push({line:a,candidate:null,response:k(t,a)}):x=addProperty(t,_,o,d,a,x):o===void 0?u(t,a)?t.skipBlock(a.indent):v.push({line:a,candidate:null,response:k(t,a)}):x=addProperty(t,_,o,d,a,x)}else if(n===`stream`&&R.test(a.content)&&o!==void 0&&t.streamCandidates?.hasSource(o.type.name.split(`.`)[0])===!0){let[n,r]=o.type.name.split(`.`),s=t.streamCandidates.hasPropertyType(o.type.name)&&t.streamCandidates.hasUniqueStream(n,r),c=S(t,a,o,s);(H!==null||U.length>0)&&t.error(e.InvalidCommandStream,`A command declares at most one stream route.`,i(a)),s||H!==null?U.push(c):H=c}else if(n===`runs`&&y(a))b(t,a);else if(n===`description`)j=h(t,a,j,`Command '${d}'`);else if(n===`documentation`)M=g(t,a,M,`Command '${d}'`);else if(n===`authorize`)z=p(z,m(t,a));else if(n===`validate`){let e=parseValidate(t,a,`command`,d);e!==void 0&&C.push(e)}else if(n===`produces`){let e=I(t,a,!0);e!==void 0&&w.push(e)}else if(n===`handler`)B=D(t,a),V.push({handler:B,location:i(a)});else if(q.has(n)){let r=n===`reads`?F(t,a):void 0;r!==void 0&&E.push(r),n===`concurrency`&&O===void 0&&(O=P(t,a));let o=/^reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?$/.exec(a.content);o!==null&&T.push({readModel:o[1],alias:o[2]??null}),W.test(a.content)&&t.error(e.OptionalReadsNotSupported,`Optional reads are not yet supported (see #308).`,i(a)),t.skipOpaqueBlock(a.indent)}else o===void 0?(u(t,a),t.error(e.UnknownCommandDirective,`Unexpected '${a.content}' in command body`,i(a)),t.skipBlock(a.indent)):x=addProperty(t,_,o,d,a,x)}let G=new Set(v.flatMap(e=>e.candidate===null?[]:[e.candidate])),K=new Set(_.filter(e=>!G.has(e)).map(e=>e.name));v.some(e=>e.candidate!==null&&!K.has(e.candidate.type.name)&&e.candidate.type.name!==`returns`)&&K.add(`returns`);for(let e of K)o?.add(e);let Y=null,X=/* @__PURE__ */ new Set;for(let n of v){let r=n.response;if(n.candidate!==null){if(!K.has(n.candidate.type.name))continue;X.add(n.candidate),r={kind:`ScalarCommandResponseSyntax`,source:{kind:`PropertyResponseSourceSyntax`,property:n.candidate.type.name,location:n.candidate.type.location},location:i(n.line)}}r!==null&&(Y===null?Y=r:t.error(e.InvalidCommandResponse,`A command declares at most one unconditional response.`,i(n.line)))}c(V,t),B!==null&&!s(B)&&w.length>0&&t.error(e.CommandWithProducesAndHandler,`Command '${d}' cannot declare both 'produces' and 'handler'`,i(n));let Z={kind:`CommandSyntax`,name:d,description:j,documentation:M,authorize:z,properties:_.filter(e=>!X.has(e)),validations:C,produces:w,handler:B,response:Y,stream:H,streamCandidates:U,location:i(n)};return N.set(Z,T),a.set(Z,{reads:E,concurrency:O}),Z}function addProperty(t,n,r,i,a,o){return d(t,r.type,a),r.isIdentifier&&o!==void 0&&(t.error(e.DuplicateCommandIdentifier,`Command '${i}' already marks '${o.name}' as identifier - only one property can be the identifier`,r.location),r={...r,isIdentifier:!1}),n.push(r),o??(r.isIdentifier?r:void 0)}function parseValidate(t,r,a,o){if(r.content===`validate`){let s=t.peekChild(r.indent);if(s!==void 0&&s.content.startsWith("```")){t.reader.takeSignificant();let e=T(t.valueContext,s);return e===null&&t.skipFencedBody(),{kind:`CodeValidateSyntax`,code:e,location:i(r)}}let c=[],u=[],d;for(let s=t.peekChild(r.indent);s!==void 0;s=t.peekChild(r.indent)){if(t.reader.takeSignificant(),a===`concept`){if(t.sourceOptions.numericMode===`legacy`&&s.content.startsWith("```")){t.skipFencedBody();continue}if(d!==void 0&&s.indent<=d&&(d=void 0),d!==void 0||l(s.content)===`implementation`){t.error(e.InvalidValidationRule,`Invalid validation rule '${s.content}'`,i(s)),d??=s.indent;continue}}if(l(s.content)===`require`){let e=_(a===`concept`?t.valueContext:t,s.content.substring(7).trim(),i(s)),r=null,o=`Error`,c=!1;for(let e=t.peekChild(s.indent);e!==void 0;e=t.peekChild(s.indent)){t.reader.takeSignificant();let i=B.exec(e.content);i!==null&&i.index===0?r=i[1]===void 0?i[2]:n(i[1]):l(e.content)===`severity`?(c||(o=K[e.content.substring(8).trim()]??`Error`),c=!0):t.skipOpaqueBlock(e.indent)}e!==null&&u.push({kind:`RequirementSyntax`,condition:e,message:r,severity:o,location:i(s)});continue}let r=parseValidationRule(t,a===`concept`?{...s,content:`value ${s.content}`}:s,a,o);r!==void 0&&c.push(r)}return{kind:`DeclarativeValidateSyntax`,rules:c,requirements:u,location:i(r)}}if(a===`concept`&&l(r.content.substring(8).trimStart())===`checksum`){let e=parseValidationRule(t,{...r,content:`value ${r.content.substring(8).trimStart()}`},a,o);return e===void 0?void 0:{kind:`DeclarativeValidateSyntax`,rules:[e],requirements:[],location:i(r)}}if(r.content===`validate csharp`){let e=T(t.valueContext,{...r,content:`csharp`});return e===null&&t.skipOpaqueBlock(r.indent),{kind:`CodeValidateSyntax`,code:e,location:i(r)}}t.error(e.InvalidValidateDeclaration,`Invalid validate declaration '${r.content}' - expected 'validate' or 'validate csharp'`,i(r)),t.skipBlock(r.indent)}function parseValidationRule(t,n,r,a){let o=l(V.exec(n.content)?.[2]??``)===`checksum`,s=r===`concept`&&!o?t.valueContext:t,{content:c,message:u}=splitMessage(n.content),d=splitSeverity(s,n,c);if(d===void 0)return;let f=V.exec(d.content);if(f===null){s.error(e.InvalidValidationRule,`Invalid validation rule '${n.content}'`,i(n));return}let p=parseRule(s,f[2],n);if(p===void 0)return;p.kind===`Matches`&&p.value!==null&&M(t,p.value,i(n),n.raw,j(t,r,a,f[1]));let m=p.kind===`Rule`?parseRuleImplementation(t,n,r===`command`):{file:null,code:null,implementation:null};return{kind:`ValidationRuleSyntax`,property:f[1],rule:p.kind,value:p.value,message:u,severity:d.severity,...m,location:i(n)}}function parseRuleImplementation(t,n,r){let a=t.peekChild(n.indent);if(a===void 0)return{file:null,code:null,implementation:null};t.reader.takeSignificant();let o=r&&l(a.content)===`implementation`,s=o?O(t,a):{file:w(a)?E(t,a):null,code:!w(a)&&C(t,a)?T(t,a):null,implementation:null};!o&&s.file===null&&s.code===null&&(t.error(e.UnknownRuleImplementationDirective,`Unexpected '${a.content}' in rule implementation - expected 'file <path>' or an inline code block`,i(a)),t.skipBlock(a.indent));for(let a=t.peekChild(n.indent);a!==void 0&&(o||r&&l(a.content)===`implementation`);a=t.peekChild(n.indent))t.reader.takeSignificant(),t.error(o&&l(a.content)===`implementation`?e.InvalidImplementationBlock:e.ConflictingImplementationSources,`A named rule has one implementation wrapper and cannot mix wrapped and direct sources.`,i(a)),C(t,a)?T(t,a):t.skipBlock(a.indent);return s}function splitMessage(e){let t=B.exec(e);if(t===null)return{content:e,message:null};let r=t[1]===void 0?t[2]:n(t[1]);return{content:e.substring(0,t.index).trimEnd(),message:r}}function splitSeverity(t,n,r){let a=z.exec(r);if(a===null)return{content:r,severity:`Error`};let o=K[a[1]];if(o===void 0)t.error(e.InvalidValidationSeverity,`Unknown validation severity '${a[1]}' - expected information, warning or error`,i(n));else return{content:r.substring(0,a.index).trimEnd(),severity:o}}function parseRule(t,n,r){if(n===`not empty`)return{kind:`NotEmpty`,value:null};if(l(n)===`checksum`){let a=n.substring(8).trim();if(a!==`luhn`&&a!==`mod11`&&a!==`mod97`){t.error(e.InvalidGenerationArgument,`Checksum validation requires luhn, mod11 or mod97.`,i(r));return}return{kind:`Checksum`,value:{kind:`LiteralExpressionSyntax`,value:a,location:i(r)}}}let a=H.exec(n);if(a===null)t.error(e.InvalidValidationRule,`Invalid validation rule '${r.content}'`,i(r));else{if(a[1]===`rule`){let n=a[2].trim();if(!U.test(n)){t.error(e.InvalidRuleName,`Invalid rule name '${n}' in '${r.content}' - expected 'rule <Name>' with an identifier`,i(r));return}return{kind:`Rule`,value:{kind:`PathExpressionSyntax`,path:n,location:i(r)}}}return{kind:G[a[1]],value:o(a[2],i(r),t)}}}export{parseCommand,parseValidate};
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i}from"./SourceLine.js";import{dependencySources as a}from"../Syntax/DependencySources.js";import{parseMappingSource as o}from"./ExpressionParser.js";import{isPendingHandler as s,validateHandlerOccurrences as c}from"./CommandHandlerValidator.js";import{firstWord as l}from"./LineText.js";import{reportInvalidModifierOrder as u,reportLegacyOptionalSuffix as d,tryParseProperty as f}from"./PropertyLineParser.js";import{combineAuthorize as p,parseAuthorize as m}from"./AuthorizeParser.js";import{parseDescription as h}from"./DescriptionParser.js";import{parseDocumentation as g}from"./DocumentationParser.js";import{parseCondition as _}from"./ConditionParser.js";import{ParserContext as v}from"./ParserContext.js";import{isReactionIdentityLine as y,misplacedReactionIdentity as b}from"./ReactionIdentityParser.js";import{sourceStreamPattern as x}from"../Text/SourceStreamNames.js";import{parseCommandStream as S}from"./EventSourceParser.js";import{isCode as C,isFile as w,parseCode as T,parseFile as E,parseHandler as D,parseImplementationWrapper as O}from"./ImplementationParser.js";import{parseCommandResponse as k,scalarResponsePattern as A}from"./CommandResponseParser.js";import{matchSubject as j,validateMatchOperand as M}from"./MatchOperandValidation.js";import{commandReadSources as N}from"./CommandReadSources.js";import{captureConcurrency as P}from"./DependencySourceParser.js";import{parseReads as F}from"./ReadsParser.js";import{parseProduces as I}from"./ProducesParser.js";const L=r(`^command\\s+([A-Za-z_]\\w*)$`),R=x(`^stream\\s+[A-Za-z_]\\w*\\.[A-Za-z_]\\w*$`),z=r(`\\bseverity\\s+(\\S+)$`),B=r(`\\bmessage\\s+(?:"(${t})"|(\\$strings\\.\\S*))$`),V=r(`^([\\w.]+)\\s+(.+)$`),H=r(`^(not empty|length ==|decimals <=|all >=|all >|matches|not contains|contains|starts with|ends with|max|min|rule|>=|<=|==|!=|>|<)\\s*(.*)$`),U=x(`^[A-Za-z_]\\w*$`),W=r(`^reads\\s+[A-Z]\\w*\\s+optional(?:\\s|$)`),G={max:`Max`,min:`Min`,">":`GreaterThan`,">=":`GreaterThanOrEqual`,"<":`LessThan`,"<=":`LessThanOrEqual`,"==":`Equal`,"!=":`NotEqual`,"length ==":`Length`,"decimals <=":`DecimalPlaces`,matches:`Matches`,contains:`Contains`,"not contains":`NotContains`,"starts with":`StartsWith`,"ends with":`EndsWith`,"all >":`AllGreaterThan`,"all >=":`AllGreaterThanOrEqual`},K={information:`Information`,warning:`Warning`,error:`Error`},q=/* @__PURE__ */ new Set([`reads`,`concurrency`]),J=/* @__PURE__ */ new Set([`description`,`documentation`,`handler`,`concurrency`]);function parseCommand(e,t){let n=/* @__PURE__ */ new Set,r=new v(e.reader.fork(),e.path,e.languages);return r.sourceOptions=e.sourceOptions,r.streamCandidates=e.streamCandidates,parseCommandBody(r,t,void 0,n),parseCommandBody(e,t,n)}function parseCommandBody(t,n,r,o){let d=L.exec(n.content)?.[1]??``;d===``&&t.error(e.InvalidCommandDeclaration,`Invalid command declaration '${n.content}' - expected 'command <Name>'`,i(n));let _=[],v=[],x,C=[],w=[],T=[],E=[],O,j=null,M=null,z=null,B=null,V=[],H=null,U=[];for(let a=t.peekChild(n.indent);a!==void 0;a=t.peekChild(n.indent)){t.reader.takeSignificant();let n=l(a.content),o=f(a);if(o!==void 0&&(J.has(n)||n===`validate`&&a.content!==`validate csharp`))x=addProperty(t,_,o,d,a,x);else if(n===`returns`){let e=A.exec(a.content);e!==null&&!e[1].startsWith(`@`)&&o!==void 0?r===void 0?(_.push(o),v.push({line:a,candidate:o,response:null})):r.has(o.type.name)?v.push({line:a,candidate:null,response:k(t,a)}):x=addProperty(t,_,o,d,a,x):o===void 0?u(t,a)?t.skipBlock(a.indent):v.push({line:a,candidate:null,response:k(t,a)}):x=addProperty(t,_,o,d,a,x)}else if(n===`stream`&&R.test(a.content)&&o!==void 0&&t.streamCandidates?.hasSource(o.type.name.split(`.`)[0])===!0){let[n,r]=o.type.name.split(`.`),s=t.streamCandidates.hasPropertyType(o.type.name)&&t.streamCandidates.hasUniqueStream(n,r),c=S(t,a,o,s);(H!==null||U.length>0)&&t.error(e.InvalidCommandStream,`A command declares at most one stream route.`,i(a)),s||H!==null?U.push(c):H=c}else if(n===`runs`&&y(a))b(t,a);else if(n===`description`)j=h(t,a,j,`Command '${d}'`);else if(n===`documentation`)M=g(t,a,M,`Command '${d}'`);else if(n===`authorize`)z=p(z,m(t,a));else if(n===`validate`){let e=parseValidate(t,a,`command`,d);e!==void 0&&C.push(e)}else if(n===`produces`){let e=I(t,a,!0);e!==void 0&&w.push(e)}else if(n===`handler`)B=D(t,a),V.push({handler:B,location:i(a)});else if(q.has(n)){let r=n===`reads`?F(t,a):void 0;r!==void 0&&E.push(r),n===`concurrency`&&O===void 0&&(O=P(t,a));let o=/^reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?$/.exec(a.content);o!==null&&T.push({readModel:o[1],alias:o[2]??null}),W.test(a.content)&&t.error(e.OptionalReadsNotSupported,`Optional reads are not yet supported (see #308).`,i(a)),t.skipOpaqueBlock(a.indent)}else o===void 0?(u(t,a),t.error(e.UnknownCommandDirective,`Unexpected '${a.content}' in command body`,i(a)),t.skipBlock(a.indent)):x=addProperty(t,_,o,d,a,x)}let G=new Set(v.flatMap(e=>e.candidate===null?[]:[e.candidate])),K=new Set(_.filter(e=>!G.has(e)).map(e=>e.name));v.some(e=>e.candidate!==null&&!K.has(e.candidate.type.name)&&e.candidate.type.name!==`returns`)&&K.add(`returns`);for(let e of K)o?.add(e);let Y=null,X=/* @__PURE__ */ new Set;for(let n of v){let r=n.response;if(n.candidate!==null){if(!K.has(n.candidate.type.name))continue;X.add(n.candidate),r={kind:`ScalarCommandResponseSyntax`,source:{kind:`PropertyResponseSourceSyntax`,property:n.candidate.type.name,location:n.candidate.type.location},location:i(n.line)}}r!==null&&(Y===null?Y=r:t.error(e.InvalidCommandResponse,`A command declares at most one unconditional response.`,i(n.line)))}c(V,t),B!==null&&!s(B)&&w.length>0&&t.error(e.CommandWithProducesAndHandler,`Command '${d}' cannot declare both 'produces' and 'handler'`,i(n));let Z={kind:`CommandSyntax`,name:d,description:j,documentation:M,authorize:z,properties:_.filter(e=>!X.has(e)),validations:C,produces:w,handler:B,response:Y,stream:H,streamCandidates:U,location:i(n)};return N.set(Z,T),a.set(Z,{reads:E,concurrency:O}),Z}function addProperty(t,n,r,i,a,o){return d(t,r.type,a),r.isIdentifier&&o!==void 0&&(t.error(e.DuplicateCommandIdentifier,`Command '${i}' already marks '${o.name}' as identifier - only one property can be the identifier`,r.location),r={...r,isIdentifier:!1}),n.push(r),o??(r.isIdentifier?r:void 0)}function parseValidate(t,r,a,o){if(r.content===`validate`){let s=t.peekChild(r.indent);if(s!==void 0&&s.content.startsWith("```")){t.reader.takeSignificant();let e=T(t.valueContext,s);return e===null&&t.skipFencedBody(),{kind:`CodeValidateSyntax`,code:e,location:i(r)}}let c=[],u=[],d;for(let s=t.peekChild(r.indent);s!==void 0;s=t.peekChild(r.indent)){if(t.reader.takeSignificant(),a===`concept`){if(t.sourceOptions.numericMode===`legacy`&&s.content.startsWith("```")){t.skipFencedBody();continue}if(d!==void 0&&s.indent<=d&&(d=void 0),d!==void 0||l(s.content)===`implementation`){t.error(e.InvalidValidationRule,`Invalid validation rule '${s.content}'`,i(s)),d??=s.indent;continue}}if(l(s.content)===`require`){let e=_(a===`concept`?t.valueContext:t,s.content.substring(7).trim(),i(s)),r=null,o=`Error`,c=!1;for(let e=t.peekChild(s.indent);e!==void 0;e=t.peekChild(s.indent)){t.reader.takeSignificant();let i=B.exec(e.content);i!==null&&i.index===0?r=i[1]===void 0?i[2]:n(i[1]):l(e.content)===`severity`?(c||(o=K[e.content.substring(8).trim()]??`Error`),c=!0):t.skipOpaqueBlock(e.indent)}e!==null&&u.push({kind:`RequirementSyntax`,condition:e,message:r,severity:o,location:i(s)});continue}let r=parseValidationRule(t,a===`concept`?{...s,content:`value ${s.content}`}:s,a,o);r!==void 0&&c.push(r)}return{kind:`DeclarativeValidateSyntax`,rules:c,requirements:u,location:i(r)}}if(a===`concept`&&l(r.content.substring(8).trimStart())===`checksum`){let e=parseValidationRule(t,{...r,content:`value ${r.content.substring(8).trimStart()}`},a,o);return e===void 0?void 0:{kind:`DeclarativeValidateSyntax`,rules:[e],requirements:[],location:i(r)}}if(r.content===`validate csharp`){let e=T(t.valueContext,{...r,content:`csharp`});return e===null&&t.skipOpaqueBlock(r.indent),{kind:`CodeValidateSyntax`,code:e,location:i(r)}}t.error(e.InvalidValidateDeclaration,`Invalid validate declaration '${r.content}' - expected 'validate' or 'validate csharp'`,i(r)),t.skipBlock(r.indent)}function parseValidationRule(t,n,r,a){let o=l(V.exec(n.content)?.[2]??``)===`checksum`,s=r===`concept`&&!o?t.valueContext:t,{content:c,message:u}=splitMessage(n.content),d=splitSeverity(s,n,c);if(d===void 0)return;let f=V.exec(d.content);if(f===null){s.error(e.InvalidValidationRule,`Invalid validation rule '${n.content}'`,i(n));return}let p=parseRule(s,f[2],n);if(p===void 0)return;p.kind===`Matches`&&p.value!==null&&M(t,p.value,i(n),n.raw,j(t,r,a,f[1]));let m=p.kind===`Rule`?parseRuleImplementation(t,n,r===`command`):{file:null,code:null,implementation:null};return{kind:`ValidationRuleSyntax`,property:f[1],rule:p.kind,value:p.value,message:u,severity:d.severity,...m,location:i(n)}}function parseRuleImplementation(t,n,r){let a=t.peekChild(n.indent);if(a===void 0)return{file:null,code:null,implementation:null};t.reader.takeSignificant();let o=r&&l(a.content)===`implementation`,s=o?O(t,a):{file:w(a)?E(t,a):null,code:!w(a)&&C(t,a)?T(t,a):null,implementation:null};!o&&s.file===null&&s.code===null&&(t.error(e.UnknownRuleImplementationDirective,`Unexpected '${a.content}' in rule implementation - expected 'file <path>' or an inline code block`,i(a)),t.skipBlock(a.indent));for(let a=t.peekChild(n.indent);a!==void 0&&(o||r&&l(a.content)===`implementation`);a=t.peekChild(n.indent))t.reader.takeSignificant(),t.error(o&&l(a.content)===`implementation`?e.InvalidImplementationBlock:e.ConflictingImplementationSources,`A named rule has one implementation wrapper and cannot mix wrapped and direct sources.`,i(a)),C(t,a)?T(t,a):t.skipBlock(a.indent);return s}function splitMessage(e){let t=B.exec(e);if(t===null)return{content:e,message:null};let r=t[1]===void 0?t[2]:n(t[1]);return{content:e.substring(0,t.index).trimEnd(),message:r}}function splitSeverity(t,n,r){let a=z.exec(r);if(a===null)return{content:r,severity:`Error`};let o=K[a[1]];if(o===void 0)t.error(e.InvalidValidationSeverity,`Unknown validation severity '${a[1]}' - expected information, warning or error`,i(n));else return{content:r.substring(0,a.index).trimEnd(),severity:o}}function parseRule(t,n,r){if(n===`not empty`)return{kind:`NotEmpty`,value:null};if(l(n)===`checksum`){let a=n.substring(8).trim();if(a!==`luhn`&&a!==`mod11`&&a!==`mod97`){t.error(e.InvalidGenerationArgument,`Checksum validation requires luhn, mod11 or mod97.`,i(r));return}return{kind:`Checksum`,value:{kind:`LiteralExpressionSyntax`,value:a,location:i(r)}}}let a=H.exec(n);if(a===null)t.error(e.InvalidValidationRule,`Invalid validation rule '${r.content}'`,i(r));else{if(a[1]===`rule`){let n=a[2].trim();if(!U.test(n)){t.error(e.InvalidRuleName,`Invalid rule name '${n}' in '${r.content}' - expected 'rule <Name>' with an identifier`,i(r));return}return{kind:`Rule`,value:{kind:`PathExpressionSyntax`,path:n,location:i(r)}}}return{kind:G[a[1]],value:o(a[2],i(r),t)}}}export{parseCommand,parseValidate};
|
|
2
2
|
//# sourceMappingURL=CommandParser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandParser.js","names":["header","pattern","routeHeader","sourceStreamPattern","severityPattern","messagePattern","stringBodyPattern","rulePattern","operandPattern","ruleNamePattern","optionalReads","operandKinds","severities","opaqueDirectives","propertyShapedDirectives","names","lookahead","ParserContext","context","line","name","DiagnosticCodes","locationOf","properties","responses","identifier","validations","produces","reads","referenceReads","concurrency","description","documentation","authorize","handler","handlers","stream","streamCandidates","child","keyword","firstWord","asProperty","tryParseProperty","scalar","scalarResponsePattern","responseNames","parseCommandResponse","reportInvalidModifierOrder","source","streamName","ambiguous","route","parseCommandStream","isReactionIdentityLine","misplacedReactionIdentity","parseDescription","parseDocumentation","combineAuthorize","parseAuthorize","validate","production","parseProduces","parseHandler","reference","parseReads","captureConcurrency","read","candidates","entry","property","discoveredNames","response","removed","parsed","validateHandlerOccurrences","isPendingHandler","syntax","commandReadSources","dependencySources","reportLegacyOptionalSuffix","commandName","fence","code","parseCode","rules","requirements","wrapperIndent","owner","condition","parseCondition","message","severity","hasSeverity","directive","matched","unescapeString","rule","ownerName","checksum","valueContext","withSeverity","match","validateMatchOperand","matchSubject","body","wrapped","commandOwner","parseImplementationWrapper","isFile","parseFile","isCode","extra","content","text","algorithm","operand","parseMappingSource"],"sources":["../../../../../../Compiler/Parsing/CommandParser.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 { isPendingHandler, validateHandlerOccurrences } from './CommandHandlerValidator';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { RequirementSyntax } from '../Syntax/Conditions';\nimport { parseCondition } from './ConditionParser';\nimport { AuthorizeSyntax } from '../Syntax/Authorization';\nimport { CommandSyntax, ValidateSyntax, ValidationRuleKind, ValidationRuleSyntax, ValidationSeverity } from '../Syntax/Commands';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { CommandStreamSyntax } from '../Syntax/EventSources';\nimport { parseCommandStream } from './EventSourceParser';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { ProducesSyntax } from '../Syntax/Reactions';\nimport { CommandResponseSyntax } from '../Syntax/Responses';\nimport { pattern } from '../Text/patterns';\nimport { sourceStreamPattern } from '../Text/SourceStreamNames';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { combineAuthorize, parseAuthorize } from './AuthorizeParser';\nimport { parseCommandResponse, scalarResponsePattern } from './CommandResponseParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { isCode, isFile, parseCode, parseFile, parseHandler, parseImplementationWrapper } from './ImplementationParser';\nimport { CodeBlockSyntax, FileReferenceSyntax, HandlerSyntax, ImplementationSyntax } from '../Syntax/Implementations';\nimport { parseMappingSource } from './ExpressionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { matchSubject, validateMatchOperand } from './MatchOperandValidation';\nimport { isReactionIdentityLine, misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { commandReadSources } from './CommandReadSources';\nimport { dependencySources, ReadsSyntax, ConcurrencySyntax } from '../Syntax/DependencySources';\nimport { captureConcurrency } from './DependencySourceParser';\nimport { parseReads } from './ReadsParser';\nimport { parseProduces } from './ProducesParser';\nimport { reportInvalidModifierOrder, reportLegacyOptionalSuffix, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^command\\\\s+([A-Za-z_]\\\\w*)$');\nconst routeHeader = sourceStreamPattern('^stream\\\\s+[A-Za-z_]\\\\w*\\\\.[A-Za-z_]\\\\w*$');\nconst severityPattern = pattern('\\\\bseverity\\\\s+(\\\\S+)$');\nconst messagePattern = pattern(`\\\\bmessage\\\\s+(?:\"(${stringBodyPattern})\"|(\\\\$strings\\\\.\\\\S*))$`);\nconst rulePattern = pattern('^([\\\\w.]+)\\\\s+(.+)$');\nconst operandPattern = pattern('^(not empty|length ==|all >=|all >|matches|not contains|contains|starts with|ends with|max|min|rule|>=|<=|==|!=|>|<)\\\\s*(.*)$');\nconst ruleNamePattern = sourceStreamPattern('^[A-Za-z_]\\\\w*$');\nconst optionalReads = pattern('^reads\\\\s+[A-Z]\\\\w*\\\\s+optional(?:\\\\s|$)');\n\n// Every operand the pattern matches has a kind, so an operand never goes unrecognized here.\nconst operandKinds: Record<string, ValidationRuleKind> = {\n max: 'Max',\n min: 'Min',\n '>': 'GreaterThan',\n '>=': 'GreaterThanOrEqual',\n '<': 'LessThan',\n '<=': 'LessThanOrEqual',\n '==': 'Equal',\n '!=': 'NotEqual',\n 'length ==': 'Length',\n matches: 'Matches',\n contains: 'Contains',\n 'not contains': 'NotContains',\n 'starts with': 'StartsWith',\n 'ends with': 'EndsWith',\n 'all >': 'AllGreaterThan',\n 'all >=': 'AllGreaterThanOrEqual',\n};\n\nconst severities: Record<string, ValidationSeverity> = { information: 'Information', warning: 'Warning', error: 'Error' };\n\n// Command directives this compiler does not model. They are skipped whole.\nconst opaqueDirectives = new Set(['reads', 'concurrency']);\n\n// The bare directives cannot take a type reference, so a line with property shape is a property whatever\n// keyword it starts with - 'description String' declares a property called description.\nconst propertyShapedDirectives = new Set(['description', 'documentation', 'handler', 'concurrency']);\n\nexport function parseCommand(context: ParserContext, line: SourceLine): CommandSyntax {\n // Properties are leaves, not indentation owners. Resolve ambiguous returns spelling\n // before the committed pass decides whether its deeper lines belong to a response.\n const names = new Set<string>();\n const lookahead = new ParserContext(context.reader.fork(), context.path, context.languages);\n lookahead.sourceOptions = context.sourceOptions;\n lookahead.streamCandidates = context.streamCandidates;\n parseCommandBody(lookahead, line, undefined, names);\n return parseCommandBody(context, line, names);\n}\n\nfunction parseCommandBody(context: ParserContext, line: SourceLine, responseNames?: ReadonlySet<string>, discoveredNames?: Set<string>): CommandSyntax {\n const name = header.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidCommandDeclaration, `Invalid command declaration '${line.content}' - expected 'command <Name>'`, locationOf(line));\n }\n const properties: PropertySyntax[] = [];\n const responses: { line: SourceLine; candidate: PropertySyntax | null; response: CommandResponseSyntax | null }[] = [];\n let identifier: PropertySyntax | undefined;\n const validations: ValidateSyntax[] = [];\n const produces: ProducesSyntax[] = [];\n const reads: { readModel: string; alias: string | null }[] = [];\n const referenceReads: ReadsSyntax[] = [];\n let concurrency: ConcurrencySyntax | undefined;\n let description: string | null = null;\n let documentation: string | null = null;\n let authorize: AuthorizeSyntax | null = null;\n let handler: HandlerSyntax | null = null;\n const handlers: { handler: HandlerSyntax | null; location: SourceLocation }[] = [];\n let stream: CommandStreamSyntax | null = null;\n const streamCandidates: CommandStreamSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n const asProperty = tryParseProperty(child);\n if (asProperty !== undefined && (propertyShapedDirectives.has(keyword) || (keyword === 'validate' && child.content !== 'validate csharp'))) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (keyword === 'returns') {\n const scalar = scalarResponsePattern.exec(child.content);\n if (scalar !== null && !scalar[1].startsWith('@') && asProperty !== undefined) {\n if (responseNames === undefined) {\n properties.push(asProperty);\n responses.push({ line: child, candidate: asProperty, response: null });\n } else if (responseNames.has(asProperty.type.name)) {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n } else {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n }\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (reportInvalidModifierOrder(context, child)) {\n context.skipBlock(child.indent);\n } else {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n }\n } else if (keyword === 'stream' && routeHeader.test(child.content) && asProperty !== undefined && context.streamCandidates?.hasSource(asProperty.type.name.split('.')[0]) === true) {\n const [source, streamName] = asProperty.type.name.split('.');\n const ambiguous = context.streamCandidates.hasPropertyType(asProperty.type.name) && context.streamCandidates.hasUniqueStream(source, streamName);\n const route = parseCommandStream(context, child, asProperty, ambiguous);\n if (stream !== null || streamCandidates.length > 0) context.error(DiagnosticCodes.InvalidCommandStream, 'A command declares at most one stream route.', locationOf(child));\n if (ambiguous || stream !== null) streamCandidates.push(route);\n else stream = route;\n } else if (keyword === 'runs' && isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n } else if (keyword === 'description') {\n description = parseDescription(context, child, description, `Command '${name}'`);\n } else if (keyword === 'documentation') {\n documentation = parseDocumentation(context, child, documentation, `Command '${name}'`);\n } else if (keyword === 'authorize') {\n authorize = combineAuthorize(authorize, parseAuthorize(context, child));\n } else if (keyword === 'validate') {\n const validate = parseValidate(context, child, 'command', name);\n if (validate !== undefined) {\n validations.push(validate);\n }\n } else if (keyword === 'produces') {\n const production = parseProduces(context, child, true);\n if (production !== undefined) produces.push(production);\n } else if (keyword === 'handler') {\n handler = parseHandler(context, child);\n handlers.push({ handler, location: locationOf(child) });\n } else if (opaqueDirectives.has(keyword)) {\n const reference = keyword === 'reads' ? parseReads(context, child) : undefined;\n if (reference !== undefined) referenceReads.push(reference);\n if (keyword === 'concurrency' && concurrency === undefined) concurrency = captureConcurrency(context, child);\n const read = /^reads\\s+([A-Z]\\w*)(?:\\s+as\\s+([a-z_]\\w*))?(?:\\s+by\\s+([a-z_]\\w*))?$/.exec(child.content);\n if (read !== null) reads.push({ readModel: read[1], alias: read[2] ?? null });\n if (optionalReads.test(child.content)) {\n context.error(DiagnosticCodes.OptionalReadsNotSupported, 'Optional reads are not yet supported (see #308).', locationOf(child));\n }\n context.skipOpaqueBlock(child.indent);\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else {\n reportInvalidModifierOrder(context, child);\n context.error(DiagnosticCodes.UnknownCommandDirective, `Unexpected '${child.content}' in command body`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const candidates = new Set(responses.flatMap(entry => entry.candidate === null ? [] : [entry.candidate]));\n const names = new Set(properties.filter(property => !candidates.has(property)).map(property => property.name));\n if (responses.some(entry => entry.candidate !== null && !names.has(entry.candidate.type.name) && entry.candidate.type.name !== 'returns')) names.add('returns');\n for (const name of names) discoveredNames?.add(name);\n let response: CommandResponseSyntax | null = null;\n const removed = new Set<PropertySyntax>();\n for (const entry of responses) {\n let parsed = entry.response;\n if (entry.candidate !== null) {\n if (!names.has(entry.candidate.type.name)) continue;\n removed.add(entry.candidate);\n parsed = { kind: 'ScalarCommandResponseSyntax', source: { kind: 'PropertyResponseSourceSyntax', property: entry.candidate.type.name, location: entry.candidate.type.location }, location: locationOf(entry.line) };\n }\n if (parsed === null) continue;\n if (response !== null) {\n context.error(DiagnosticCodes.InvalidCommandResponse, 'A command declares at most one unconditional response.', locationOf(entry.line));\n } else {\n response = parsed;\n }\n }\n validateHandlerOccurrences(handlers, context);\n if (handler !== null && !isPendingHandler(handler) && produces.length > 0) {\n context.error(DiagnosticCodes.CommandWithProducesAndHandler, `Command '${name}' cannot declare both 'produces' and 'handler'`, locationOf(line));\n }\n const syntax: CommandSyntax = { kind: 'CommandSyntax', name, description, documentation, authorize, properties: properties.filter(property => !removed.has(property)), validations, produces, handler, response, stream, streamCandidates, location: locationOf(line) };\n commandReadSources.set(syntax, reads);\n dependencySources.set(syntax, { reads: referenceReads, concurrency });\n return syntax;\n}\n\nfunction addProperty(context: ParserContext, properties: PropertySyntax[], property: PropertySyntax, commandName: string, line: SourceLine, identifier: PropertySyntax | undefined): PropertySyntax | undefined {\n reportLegacyOptionalSuffix(context, property.type, line);\n if (property.isIdentifier && identifier !== undefined) {\n context.error(DiagnosticCodes.DuplicateCommandIdentifier, `Command '${commandName}' already marks '${identifier.name}' as identifier - only one property can be the identifier`, property.location);\n property = { ...property, isIdentifier: false };\n }\n properties.push(property);\n return identifier ?? (property.isIdentifier ? property : undefined);\n}\n\n// Reads a 'validate' block: declarative rules, or code - which is recognized but not modeled.\nexport function parseValidate(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidateSyntax | undefined {\n if (line.content === 'validate') {\n const fence = context.peekChild(line.indent);\n if (fence !== undefined && fence.content.startsWith('```')) {\n context.reader.takeSignificant();\n const code = parseCode(context.valueContext, fence);\n if (code === null) context.skipFencedBody();\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n const rules: ValidationRuleSyntax[] = [];\n const requirements: RequirementSyntax[] = [];\n let wrapperIndent: number | undefined;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (owner === 'concept') {\n if (context.sourceOptions.numericMode === 'legacy' && child.content.startsWith('```')) { context.skipFencedBody(); continue; }\n if (wrapperIndent !== undefined && child.indent <= wrapperIndent) wrapperIndent = undefined;\n if (wrapperIndent !== undefined || firstWord(child.content) === 'implementation') {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${child.content}'`, locationOf(child));\n wrapperIndent ??= child.indent;\n continue;\n }\n }\n if (firstWord(child.content) === 'require') {\n const condition = parseCondition(owner === 'concept' ? context.valueContext : context, child.content.substring('require'.length).trim(), locationOf(child));\n let message: string | null = null;\n let severity: ValidationSeverity = 'Error';\n let hasSeverity = false;\n for (let directive = context.peekChild(child.indent); directive !== undefined; directive = context.peekChild(child.indent)) {\n context.reader.takeSignificant();\n const matched = messagePattern.exec(directive.content);\n if (matched !== null && matched.index === 0) message = matched[1] !== undefined ? unescapeString(matched[1]) : matched[2];\n else if (firstWord(directive.content) === 'severity') {\n if (!hasSeverity) severity = severities[directive.content.substring('severity'.length).trim()] ?? 'Error';\n hasSeverity = true;\n } else context.skipOpaqueBlock(directive.indent);\n }\n if (condition !== null) requirements.push({ kind: 'RequirementSyntax', condition, message, severity, location: locationOf(child) });\n continue;\n }\n const rule = parseValidationRule(context, owner === 'concept' ? { ...child, content: `value ${child.content}` } : child, owner, ownerName);\n if (rule !== undefined) {\n rules.push(rule);\n }\n }\n return { kind: 'DeclarativeValidateSyntax', rules, requirements, location: locationOf(line) };\n }\n if (owner === 'concept' && firstWord(line.content.substring('validate'.length).trimStart()) === 'checksum') {\n const ruleLine = { ...line, content: `value ${line.content.substring('validate'.length).trimStart()}` };\n const rule = parseValidationRule(context, ruleLine, owner, ownerName);\n return rule === undefined ? undefined : { kind: 'DeclarativeValidateSyntax', rules: [rule], requirements: [], location: locationOf(line) };\n }\n if (line.content === 'validate csharp') {\n const code = parseCode(context.valueContext, { ...line, content: 'csharp' });\n if (code === null) context.skipOpaqueBlock(line.indent);\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n context.error(DiagnosticCodes.InvalidValidateDeclaration, `Invalid validate declaration '${line.content}' - expected 'validate' or 'validate csharp'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n}\n\nfunction parseValidationRule(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidationRuleSyntax | undefined {\n // Checksum is a new declaration, not enrichment of a formerly opaque Legacy rule.\n const checksum = firstWord(rulePattern.exec(line.content)?.[2] ?? '') === 'checksum';\n const valueContext = owner === 'concept' && !checksum ? context.valueContext : context;\n const { content: withSeverity, message } = splitMessage(line.content);\n const severity = splitSeverity(valueContext, line, withSeverity);\n if (severity === undefined) {\n return undefined;\n }\n const match = rulePattern.exec(severity.content);\n if (match === null) {\n valueContext.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n const parsed = parseRule(valueContext, match[2], line);\n if (parsed === undefined) {\n return undefined;\n }\n if (parsed.kind === 'Matches' && parsed.value !== null) validateMatchOperand(context, parsed.value, locationOf(line), line.raw, matchSubject(context, owner, ownerName, match[1]));\n const source = parsed.kind === 'Rule' ? parseRuleImplementation(context, line, owner === 'command') : { file: null, code: null, implementation: null };\n return {\n kind: 'ValidationRuleSyntax',\n property: match[1],\n rule: parsed.kind,\n value: parsed.value,\n message,\n severity: severity.severity,\n ...source,\n location: locationOf(line),\n };\n}\n\nfunction parseRuleImplementation(context: ParserContext, rule: SourceLine, commandOwner: boolean): { file: FileReferenceSyntax | null; code: CodeBlockSyntax | null; implementation: ImplementationSyntax | null } {\n const body = context.peekChild(rule.indent);\n if (body === undefined) return { file: null, code: null, implementation: null };\n context.reader.takeSignificant();\n const wrapped = commandOwner && firstWord(body.content) === 'implementation';\n const source = wrapped ? parseImplementationWrapper(context, body) : {\n file: isFile(body) ? parseFile(context, body) : null,\n code: !isFile(body) && isCode(context, body) ? parseCode(context, body) : null,\n implementation: null,\n };\n if (!wrapped && source.file === null && source.code === null) {\n context.error(DiagnosticCodes.UnknownRuleImplementationDirective, `Unexpected '${body.content}' in rule implementation - expected 'file <path>' or an inline code block`, locationOf(body));\n context.skipBlock(body.indent);\n }\n for (let extra = context.peekChild(rule.indent); extra !== undefined && (wrapped || (commandOwner && firstWord(extra.content) === 'implementation')); extra = context.peekChild(rule.indent)) {\n context.reader.takeSignificant();\n context.error(wrapped && firstWord(extra.content) === 'implementation' ? DiagnosticCodes.InvalidImplementationBlock : DiagnosticCodes.ConflictingImplementationSources,\n 'A named rule has one implementation wrapper and cannot mix wrapped and direct sources.', locationOf(extra));\n if (isCode(context, extra)) parseCode(context, extra);\n else context.skipBlock(extra.indent);\n }\n return source;\n}\n\nfunction splitMessage(content: string): { content: string; message: string | null } {\n const match = messagePattern.exec(content);\n if (match === null) {\n return { content, message: null };\n }\n const message = match[1] !== undefined ? unescapeString(match[1]) : match[2];\n return { content: content.substring(0, match.index).trimEnd(), message };\n}\n\nfunction splitSeverity(context: ParserContext, line: SourceLine, text: string): { content: string; severity: ValidationSeverity } | undefined {\n const match = severityPattern.exec(text);\n if (match === null) {\n return { content: text, severity: 'Error' };\n }\n const severity = severities[match[1]];\n if (severity === undefined) {\n context.error(DiagnosticCodes.InvalidValidationSeverity, `Unknown validation severity '${match[1]}' - expected information, warning or error`, locationOf(line));\n return undefined;\n }\n return { content: text.substring(0, match.index).trimEnd(), severity };\n}\n\nfunction parseRule(context: ParserContext, rule: string, line: SourceLine): { kind: ValidationRuleKind; value: ExpressionSyntax | null } | undefined {\n if (rule === 'not empty') {\n return { kind: 'NotEmpty', value: null };\n }\n if (firstWord(rule) === 'checksum') {\n const algorithm = rule.substring('checksum'.length).trim();\n if (algorithm !== 'luhn' && algorithm !== 'mod11' && algorithm !== 'mod97') {\n context.error(DiagnosticCodes.InvalidGenerationArgument, 'Checksum validation requires luhn, mod11 or mod97.', locationOf(line));\n return undefined;\n }\n return { kind: 'Checksum', value: { kind: 'LiteralExpressionSyntax', value: algorithm, location: locationOf(line) } };\n }\n const operand = operandPattern.exec(rule);\n if (operand === null) {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n if (operand[1] === 'rule') {\n const name = operand[2].trim();\n if (!ruleNamePattern.test(name)) {\n context.error(DiagnosticCodes.InvalidRuleName, `Invalid rule name '${name}' in '${line.content}' - expected 'rule <Name>' with an identifier`, locationOf(line));\n return undefined;\n }\n return { kind: 'Rule', value: { kind: 'PathExpressionSyntax', path: name, location: locationOf(line) } };\n }\n return { kind: operandKinds[operand[1]], value: parseMappingSource(operand[2], locationOf(line), context) };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CommandParser.js","names":["header","pattern","routeHeader","sourceStreamPattern","severityPattern","messagePattern","stringBodyPattern","rulePattern","operandPattern","ruleNamePattern","optionalReads","operandKinds","severities","opaqueDirectives","propertyShapedDirectives","names","lookahead","ParserContext","context","line","name","DiagnosticCodes","locationOf","properties","responses","identifier","validations","produces","reads","referenceReads","concurrency","description","documentation","authorize","handler","handlers","stream","streamCandidates","child","keyword","firstWord","asProperty","tryParseProperty","scalar","scalarResponsePattern","responseNames","parseCommandResponse","reportInvalidModifierOrder","source","streamName","ambiguous","route","parseCommandStream","isReactionIdentityLine","misplacedReactionIdentity","parseDescription","parseDocumentation","combineAuthorize","parseAuthorize","validate","production","parseProduces","parseHandler","reference","parseReads","captureConcurrency","read","candidates","entry","property","discoveredNames","response","removed","parsed","validateHandlerOccurrences","isPendingHandler","syntax","commandReadSources","dependencySources","reportLegacyOptionalSuffix","commandName","fence","code","parseCode","rules","requirements","wrapperIndent","owner","condition","parseCondition","message","severity","hasSeverity","directive","matched","unescapeString","rule","ownerName","checksum","valueContext","withSeverity","match","validateMatchOperand","matchSubject","body","wrapped","commandOwner","parseImplementationWrapper","isFile","parseFile","isCode","extra","content","text","algorithm","operand","parseMappingSource"],"sources":["../../../../../../Compiler/Parsing/CommandParser.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 { isPendingHandler, validateHandlerOccurrences } from './CommandHandlerValidator';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { RequirementSyntax } from '../Syntax/Conditions';\nimport { parseCondition } from './ConditionParser';\nimport { AuthorizeSyntax } from '../Syntax/Authorization';\nimport { CommandSyntax, ValidateSyntax, ValidationRuleKind, ValidationRuleSyntax, ValidationSeverity } from '../Syntax/Commands';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { CommandStreamSyntax } from '../Syntax/EventSources';\nimport { parseCommandStream } from './EventSourceParser';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { ProducesSyntax } from '../Syntax/Reactions';\nimport { CommandResponseSyntax } from '../Syntax/Responses';\nimport { pattern } from '../Text/patterns';\nimport { sourceStreamPattern } from '../Text/SourceStreamNames';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { combineAuthorize, parseAuthorize } from './AuthorizeParser';\nimport { parseCommandResponse, scalarResponsePattern } from './CommandResponseParser';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { isCode, isFile, parseCode, parseFile, parseHandler, parseImplementationWrapper } from './ImplementationParser';\nimport { CodeBlockSyntax, FileReferenceSyntax, HandlerSyntax, ImplementationSyntax } from '../Syntax/Implementations';\nimport { parseMappingSource } from './ExpressionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { matchSubject, validateMatchOperand } from './MatchOperandValidation';\nimport { isReactionIdentityLine, misplacedReactionIdentity } from './ReactionIdentityParser';\nimport { commandReadSources } from './CommandReadSources';\nimport { dependencySources, ReadsSyntax, ConcurrencySyntax } from '../Syntax/DependencySources';\nimport { captureConcurrency } from './DependencySourceParser';\nimport { parseReads } from './ReadsParser';\nimport { parseProduces } from './ProducesParser';\nimport { reportInvalidModifierOrder, reportLegacyOptionalSuffix, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^command\\\\s+([A-Za-z_]\\\\w*)$');\nconst routeHeader = sourceStreamPattern('^stream\\\\s+[A-Za-z_]\\\\w*\\\\.[A-Za-z_]\\\\w*$');\nconst severityPattern = pattern('\\\\bseverity\\\\s+(\\\\S+)$');\nconst messagePattern = pattern(`\\\\bmessage\\\\s+(?:\"(${stringBodyPattern})\"|(\\\\$strings\\\\.\\\\S*))$`);\nconst rulePattern = pattern('^([\\\\w.]+)\\\\s+(.+)$');\nconst operandPattern = pattern('^(not empty|length ==|decimals <=|all >=|all >|matches|not contains|contains|starts with|ends with|max|min|rule|>=|<=|==|!=|>|<)\\\\s*(.*)$');\nconst ruleNamePattern = sourceStreamPattern('^[A-Za-z_]\\\\w*$');\nconst optionalReads = pattern('^reads\\\\s+[A-Z]\\\\w*\\\\s+optional(?:\\\\s|$)');\n\n// Every operand the pattern matches has a kind, so an operand never goes unrecognized here.\nconst operandKinds: Record<string, ValidationRuleKind> = {\n max: 'Max',\n min: 'Min',\n '>': 'GreaterThan',\n '>=': 'GreaterThanOrEqual',\n '<': 'LessThan',\n '<=': 'LessThanOrEqual',\n '==': 'Equal',\n '!=': 'NotEqual',\n 'length ==': 'Length',\n 'decimals <=': 'DecimalPlaces',\n matches: 'Matches',\n contains: 'Contains',\n 'not contains': 'NotContains',\n 'starts with': 'StartsWith',\n 'ends with': 'EndsWith',\n 'all >': 'AllGreaterThan',\n 'all >=': 'AllGreaterThanOrEqual',\n};\n\nconst severities: Record<string, ValidationSeverity> = { information: 'Information', warning: 'Warning', error: 'Error' };\n\n// Command directives this compiler does not model. They are skipped whole.\nconst opaqueDirectives = new Set(['reads', 'concurrency']);\n\n// The bare directives cannot take a type reference, so a line with property shape is a property whatever\n// keyword it starts with - 'description String' declares a property called description.\nconst propertyShapedDirectives = new Set(['description', 'documentation', 'handler', 'concurrency']);\n\nexport function parseCommand(context: ParserContext, line: SourceLine): CommandSyntax {\n // Properties are leaves, not indentation owners. Resolve ambiguous returns spelling\n // before the committed pass decides whether its deeper lines belong to a response.\n const names = new Set<string>();\n const lookahead = new ParserContext(context.reader.fork(), context.path, context.languages);\n lookahead.sourceOptions = context.sourceOptions;\n lookahead.streamCandidates = context.streamCandidates;\n parseCommandBody(lookahead, line, undefined, names);\n return parseCommandBody(context, line, names);\n}\n\nfunction parseCommandBody(context: ParserContext, line: SourceLine, responseNames?: ReadonlySet<string>, discoveredNames?: Set<string>): CommandSyntax {\n const name = header.exec(line.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidCommandDeclaration, `Invalid command declaration '${line.content}' - expected 'command <Name>'`, locationOf(line));\n }\n const properties: PropertySyntax[] = [];\n const responses: { line: SourceLine; candidate: PropertySyntax | null; response: CommandResponseSyntax | null }[] = [];\n let identifier: PropertySyntax | undefined;\n const validations: ValidateSyntax[] = [];\n const produces: ProducesSyntax[] = [];\n const reads: { readModel: string; alias: string | null }[] = [];\n const referenceReads: ReadsSyntax[] = [];\n let concurrency: ConcurrencySyntax | undefined;\n let description: string | null = null;\n let documentation: string | null = null;\n let authorize: AuthorizeSyntax | null = null;\n let handler: HandlerSyntax | null = null;\n const handlers: { handler: HandlerSyntax | null; location: SourceLocation }[] = [];\n let stream: CommandStreamSyntax | null = null;\n const streamCandidates: CommandStreamSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n const asProperty = tryParseProperty(child);\n if (asProperty !== undefined && (propertyShapedDirectives.has(keyword) || (keyword === 'validate' && child.content !== 'validate csharp'))) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (keyword === 'returns') {\n const scalar = scalarResponsePattern.exec(child.content);\n if (scalar !== null && !scalar[1].startsWith('@') && asProperty !== undefined) {\n if (responseNames === undefined) {\n properties.push(asProperty);\n responses.push({ line: child, candidate: asProperty, response: null });\n } else if (responseNames.has(asProperty.type.name)) {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n } else {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n }\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else if (reportInvalidModifierOrder(context, child)) {\n context.skipBlock(child.indent);\n } else {\n responses.push({ line: child, candidate: null, response: parseCommandResponse(context, child) });\n }\n } else if (keyword === 'stream' && routeHeader.test(child.content) && asProperty !== undefined && context.streamCandidates?.hasSource(asProperty.type.name.split('.')[0]) === true) {\n const [source, streamName] = asProperty.type.name.split('.');\n const ambiguous = context.streamCandidates.hasPropertyType(asProperty.type.name) && context.streamCandidates.hasUniqueStream(source, streamName);\n const route = parseCommandStream(context, child, asProperty, ambiguous);\n if (stream !== null || streamCandidates.length > 0) context.error(DiagnosticCodes.InvalidCommandStream, 'A command declares at most one stream route.', locationOf(child));\n if (ambiguous || stream !== null) streamCandidates.push(route);\n else stream = route;\n } else if (keyword === 'runs' && isReactionIdentityLine(child)) {\n misplacedReactionIdentity(context, child);\n } else if (keyword === 'description') {\n description = parseDescription(context, child, description, `Command '${name}'`);\n } else if (keyword === 'documentation') {\n documentation = parseDocumentation(context, child, documentation, `Command '${name}'`);\n } else if (keyword === 'authorize') {\n authorize = combineAuthorize(authorize, parseAuthorize(context, child));\n } else if (keyword === 'validate') {\n const validate = parseValidate(context, child, 'command', name);\n if (validate !== undefined) {\n validations.push(validate);\n }\n } else if (keyword === 'produces') {\n const production = parseProduces(context, child, true);\n if (production !== undefined) produces.push(production);\n } else if (keyword === 'handler') {\n handler = parseHandler(context, child);\n handlers.push({ handler, location: locationOf(child) });\n } else if (opaqueDirectives.has(keyword)) {\n const reference = keyword === 'reads' ? parseReads(context, child) : undefined;\n if (reference !== undefined) referenceReads.push(reference);\n if (keyword === 'concurrency' && concurrency === undefined) concurrency = captureConcurrency(context, child);\n const read = /^reads\\s+([A-Z]\\w*)(?:\\s+as\\s+([a-z_]\\w*))?(?:\\s+by\\s+([a-z_]\\w*))?$/.exec(child.content);\n if (read !== null) reads.push({ readModel: read[1], alias: read[2] ?? null });\n if (optionalReads.test(child.content)) {\n context.error(DiagnosticCodes.OptionalReadsNotSupported, 'Optional reads are not yet supported (see #308).', locationOf(child));\n }\n context.skipOpaqueBlock(child.indent);\n } else if (asProperty !== undefined) {\n identifier = addProperty(context, properties, asProperty, name, child, identifier);\n } else {\n reportInvalidModifierOrder(context, child);\n context.error(DiagnosticCodes.UnknownCommandDirective, `Unexpected '${child.content}' in command body`, locationOf(child));\n context.skipBlock(child.indent);\n }\n }\n const candidates = new Set(responses.flatMap(entry => entry.candidate === null ? [] : [entry.candidate]));\n const names = new Set(properties.filter(property => !candidates.has(property)).map(property => property.name));\n if (responses.some(entry => entry.candidate !== null && !names.has(entry.candidate.type.name) && entry.candidate.type.name !== 'returns')) names.add('returns');\n for (const name of names) discoveredNames?.add(name);\n let response: CommandResponseSyntax | null = null;\n const removed = new Set<PropertySyntax>();\n for (const entry of responses) {\n let parsed = entry.response;\n if (entry.candidate !== null) {\n if (!names.has(entry.candidate.type.name)) continue;\n removed.add(entry.candidate);\n parsed = { kind: 'ScalarCommandResponseSyntax', source: { kind: 'PropertyResponseSourceSyntax', property: entry.candidate.type.name, location: entry.candidate.type.location }, location: locationOf(entry.line) };\n }\n if (parsed === null) continue;\n if (response !== null) {\n context.error(DiagnosticCodes.InvalidCommandResponse, 'A command declares at most one unconditional response.', locationOf(entry.line));\n } else {\n response = parsed;\n }\n }\n validateHandlerOccurrences(handlers, context);\n if (handler !== null && !isPendingHandler(handler) && produces.length > 0) {\n context.error(DiagnosticCodes.CommandWithProducesAndHandler, `Command '${name}' cannot declare both 'produces' and 'handler'`, locationOf(line));\n }\n const syntax: CommandSyntax = { kind: 'CommandSyntax', name, description, documentation, authorize, properties: properties.filter(property => !removed.has(property)), validations, produces, handler, response, stream, streamCandidates, location: locationOf(line) };\n commandReadSources.set(syntax, reads);\n dependencySources.set(syntax, { reads: referenceReads, concurrency });\n return syntax;\n}\n\nfunction addProperty(context: ParserContext, properties: PropertySyntax[], property: PropertySyntax, commandName: string, line: SourceLine, identifier: PropertySyntax | undefined): PropertySyntax | undefined {\n reportLegacyOptionalSuffix(context, property.type, line);\n if (property.isIdentifier && identifier !== undefined) {\n context.error(DiagnosticCodes.DuplicateCommandIdentifier, `Command '${commandName}' already marks '${identifier.name}' as identifier - only one property can be the identifier`, property.location);\n property = { ...property, isIdentifier: false };\n }\n properties.push(property);\n return identifier ?? (property.isIdentifier ? property : undefined);\n}\n\n// Reads a 'validate' block: declarative rules, or code - which is recognized but not modeled.\nexport function parseValidate(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidateSyntax | undefined {\n if (line.content === 'validate') {\n const fence = context.peekChild(line.indent);\n if (fence !== undefined && fence.content.startsWith('```')) {\n context.reader.takeSignificant();\n const code = parseCode(context.valueContext, fence);\n if (code === null) context.skipFencedBody();\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n const rules: ValidationRuleSyntax[] = [];\n const requirements: RequirementSyntax[] = [];\n let wrapperIndent: number | undefined;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (owner === 'concept') {\n if (context.sourceOptions.numericMode === 'legacy' && child.content.startsWith('```')) { context.skipFencedBody(); continue; }\n if (wrapperIndent !== undefined && child.indent <= wrapperIndent) wrapperIndent = undefined;\n if (wrapperIndent !== undefined || firstWord(child.content) === 'implementation') {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${child.content}'`, locationOf(child));\n wrapperIndent ??= child.indent;\n continue;\n }\n }\n if (firstWord(child.content) === 'require') {\n const condition = parseCondition(owner === 'concept' ? context.valueContext : context, child.content.substring('require'.length).trim(), locationOf(child));\n let message: string | null = null;\n let severity: ValidationSeverity = 'Error';\n let hasSeverity = false;\n for (let directive = context.peekChild(child.indent); directive !== undefined; directive = context.peekChild(child.indent)) {\n context.reader.takeSignificant();\n const matched = messagePattern.exec(directive.content);\n if (matched !== null && matched.index === 0) message = matched[1] !== undefined ? unescapeString(matched[1]) : matched[2];\n else if (firstWord(directive.content) === 'severity') {\n if (!hasSeverity) severity = severities[directive.content.substring('severity'.length).trim()] ?? 'Error';\n hasSeverity = true;\n } else context.skipOpaqueBlock(directive.indent);\n }\n if (condition !== null) requirements.push({ kind: 'RequirementSyntax', condition, message, severity, location: locationOf(child) });\n continue;\n }\n const rule = parseValidationRule(context, owner === 'concept' ? { ...child, content: `value ${child.content}` } : child, owner, ownerName);\n if (rule !== undefined) {\n rules.push(rule);\n }\n }\n return { kind: 'DeclarativeValidateSyntax', rules, requirements, location: locationOf(line) };\n }\n if (owner === 'concept' && firstWord(line.content.substring('validate'.length).trimStart()) === 'checksum') {\n const ruleLine = { ...line, content: `value ${line.content.substring('validate'.length).trimStart()}` };\n const rule = parseValidationRule(context, ruleLine, owner, ownerName);\n return rule === undefined ? undefined : { kind: 'DeclarativeValidateSyntax', rules: [rule], requirements: [], location: locationOf(line) };\n }\n if (line.content === 'validate csharp') {\n const code = parseCode(context.valueContext, { ...line, content: 'csharp' });\n if (code === null) context.skipOpaqueBlock(line.indent);\n return { kind: 'CodeValidateSyntax', code, location: locationOf(line) };\n }\n context.error(DiagnosticCodes.InvalidValidateDeclaration, `Invalid validate declaration '${line.content}' - expected 'validate' or 'validate csharp'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n}\n\nfunction parseValidationRule(context: ParserContext, line: SourceLine, owner: 'command' | 'concept', ownerName: string): ValidationRuleSyntax | undefined {\n // Checksum is a new declaration, not enrichment of a formerly opaque Legacy rule.\n const checksum = firstWord(rulePattern.exec(line.content)?.[2] ?? '') === 'checksum';\n const valueContext = owner === 'concept' && !checksum ? context.valueContext : context;\n const { content: withSeverity, message } = splitMessage(line.content);\n const severity = splitSeverity(valueContext, line, withSeverity);\n if (severity === undefined) {\n return undefined;\n }\n const match = rulePattern.exec(severity.content);\n if (match === null) {\n valueContext.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n const parsed = parseRule(valueContext, match[2], line);\n if (parsed === undefined) {\n return undefined;\n }\n if (parsed.kind === 'Matches' && parsed.value !== null) validateMatchOperand(context, parsed.value, locationOf(line), line.raw, matchSubject(context, owner, ownerName, match[1]));\n const source = parsed.kind === 'Rule' ? parseRuleImplementation(context, line, owner === 'command') : { file: null, code: null, implementation: null };\n return {\n kind: 'ValidationRuleSyntax',\n property: match[1],\n rule: parsed.kind,\n value: parsed.value,\n message,\n severity: severity.severity,\n ...source,\n location: locationOf(line),\n };\n}\n\nfunction parseRuleImplementation(context: ParserContext, rule: SourceLine, commandOwner: boolean): { file: FileReferenceSyntax | null; code: CodeBlockSyntax | null; implementation: ImplementationSyntax | null } {\n const body = context.peekChild(rule.indent);\n if (body === undefined) return { file: null, code: null, implementation: null };\n context.reader.takeSignificant();\n const wrapped = commandOwner && firstWord(body.content) === 'implementation';\n const source = wrapped ? parseImplementationWrapper(context, body) : {\n file: isFile(body) ? parseFile(context, body) : null,\n code: !isFile(body) && isCode(context, body) ? parseCode(context, body) : null,\n implementation: null,\n };\n if (!wrapped && source.file === null && source.code === null) {\n context.error(DiagnosticCodes.UnknownRuleImplementationDirective, `Unexpected '${body.content}' in rule implementation - expected 'file <path>' or an inline code block`, locationOf(body));\n context.skipBlock(body.indent);\n }\n for (let extra = context.peekChild(rule.indent); extra !== undefined && (wrapped || (commandOwner && firstWord(extra.content) === 'implementation')); extra = context.peekChild(rule.indent)) {\n context.reader.takeSignificant();\n context.error(wrapped && firstWord(extra.content) === 'implementation' ? DiagnosticCodes.InvalidImplementationBlock : DiagnosticCodes.ConflictingImplementationSources,\n 'A named rule has one implementation wrapper and cannot mix wrapped and direct sources.', locationOf(extra));\n if (isCode(context, extra)) parseCode(context, extra);\n else context.skipBlock(extra.indent);\n }\n return source;\n}\n\nfunction splitMessage(content: string): { content: string; message: string | null } {\n const match = messagePattern.exec(content);\n if (match === null) {\n return { content, message: null };\n }\n const message = match[1] !== undefined ? unescapeString(match[1]) : match[2];\n return { content: content.substring(0, match.index).trimEnd(), message };\n}\n\nfunction splitSeverity(context: ParserContext, line: SourceLine, text: string): { content: string; severity: ValidationSeverity } | undefined {\n const match = severityPattern.exec(text);\n if (match === null) {\n return { content: text, severity: 'Error' };\n }\n const severity = severities[match[1]];\n if (severity === undefined) {\n context.error(DiagnosticCodes.InvalidValidationSeverity, `Unknown validation severity '${match[1]}' - expected information, warning or error`, locationOf(line));\n return undefined;\n }\n return { content: text.substring(0, match.index).trimEnd(), severity };\n}\n\nfunction parseRule(context: ParserContext, rule: string, line: SourceLine): { kind: ValidationRuleKind; value: ExpressionSyntax | null } | undefined {\n if (rule === 'not empty') {\n return { kind: 'NotEmpty', value: null };\n }\n if (firstWord(rule) === 'checksum') {\n const algorithm = rule.substring('checksum'.length).trim();\n if (algorithm !== 'luhn' && algorithm !== 'mod11' && algorithm !== 'mod97') {\n context.error(DiagnosticCodes.InvalidGenerationArgument, 'Checksum validation requires luhn, mod11 or mod97.', locationOf(line));\n return undefined;\n }\n return { kind: 'Checksum', value: { kind: 'LiteralExpressionSyntax', value: algorithm, location: locationOf(line) } };\n }\n const operand = operandPattern.exec(rule);\n if (operand === null) {\n context.error(DiagnosticCodes.InvalidValidationRule, `Invalid validation rule '${line.content}'`, locationOf(line));\n return undefined;\n }\n if (operand[1] === 'rule') {\n const name = operand[2].trim();\n if (!ruleNamePattern.test(name)) {\n context.error(DiagnosticCodes.InvalidRuleName, `Invalid rule name '${name}' in '${line.content}' - expected 'rule <Name>' with an identifier`, locationOf(line));\n return undefined;\n }\n return { kind: 'Rule', value: { kind: 'PathExpressionSyntax', path: name, location: locationOf(line) } };\n }\n return { kind: operandKinds[operand[1]], value: parseMappingSource(operand[2], locationOf(line), context) };\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{diagnosticText as r}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as i,splitTopLevel as a,unescapeIdentifier as o}from"./LineText.js";import{parseDescription as s}from"./DescriptionParser.js";import{isFileDirective as c}from"./FileReferences.js";import{parseProjectionExpression as l}from"./ProjectionExpressionParser.js";import{validateProjectionEventScopes as u}from"./ProjectionEventScopeValidator.js";const d=t(`^projection\\s+(@?[\\w.]+)\\s*(?:=>\\s*([\\w.]+))?$`),f=t(`^(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),p=t(`^join\\s+(@?[\\w.]+)\\s+on\\s+(@?[\\w.]+)$`),m=t(`^with\\s+(@?[\\w.]+)$`),h=t(`^children\\s+(@?[\\w.]+)\\s+identified\\s+by\\s+(.+)$`),g=t(`^nested\\s+(@?[\\w.]+)$`),_=t(`^remove\\s+with\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),v=t(`^remove\\s+via\\s+join\\s+on\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),y=t(`^clear\\s+with\\s+(@?[\\w.]+)$`),b=t(`^variant\\s+(@?[\\w.]+)\\s*$`),x=t(`^enters\\s+on\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),S=t(`^(increment|decrement|count|clear)\\s+(@?[$\\w.]+)$`),C=t(`^(add|subtract)\\s+(@?[$\\w.]+)\\s+by\\s+(.+)$`),w=t(`^set\\s+(@?[$\\w.]+)\\s+(?:=|to)\\s+(.+)$`),T=t(`^(@?[$\\w.@]+)\\s*=(?!=|>)\\s*(.+)$`),E={increment:`IncrementMappingSyntax`,decrement:`DecrementMappingSyntax`,clear:`ClearMappingSyntax`,count:`CountMappingSyntax`};function parseProjection(t,r){let a=d.exec(r.content);if(a===null)return t.error(e.InvalidProjectionDeclaration,`Invalid projection declaration '${r.content}' - expected 'projection <Name> [=> <ReadModel>]'`,n(r)),t.skipBlock(r.indent),{kind:`ProjectionSyntax`,sourceOptions:t.sourceOptions,name:i(r.content),readModel:null,sequence:null,autoMap:`Inherit`,blocks:[],location:n(r)};let o=a[1],l=null,f=null,p=`Inherit`,m=null,h=[];for(let e=t.peekChild(r.indent);e!==void 0;e=t.peekChild(r.indent)){if(t.reader.takeSignificant(),c(e))continue;let n=i(e.content);if(n===`description`)f=s(t,e,f,`Projection '${o}'`);else if(n===`sequence`)l=e.content.substring(8).trim();else if(n===`automap`)p=`Enabled`;else if(e.content===`no automap`)p=`Disabled`;else if(n===`key`)m=parseKey(t,e);else if(n===`variant`)h.push(parseVariant(t,e));else{let n=parseBlock(t,e,!1);n!==void 0&&h.push(n)}}return reportVariantConflicts(t,h,o),u(t,o,h),h.length===0&&t.error(e.EmptyProjection,`Projection '${o}' must contain at least one directive`,n(r)),{kind:`ProjectionSyntax`,sourceOptions:t.sourceOptions,name:o,readModel:a[2]??null,sequence:l,autoMap:p,key:m,blocks:h,description:f,location:n(r)}}function reportVariantConflicts(t,n,r){let i=n.filter(e=>e.kind===`ProjectionVariantSyntax`),a=/* @__PURE__ */ new Map;i.forEach(e=>a.set(e.name,[...a.get(e.name)??[],e]));for(let n of[...a.values()].flatMap(e=>e.slice(1)))t.error(e.DuplicateProjectionVariant,`Duplicate variant '${n.name}' - a variant name is declared once`,n.location);let o=/* @__PURE__ */ new Set;for(let i of n.flatMap(e=>e.kind===`ProjectionVariantSyntax`?e.entersOn:[]))i.event.length>0&&o.has(i.event)&&t.error(e.DuplicateVariantEnteringEvent,`Entering event '${i.event}' is claimed more than once in projection '${r}'`,i.location),o.add(i.event)}function parseBlock(t,r,a){let o=n(r);switch(i(r.content)){case`from`:return parseFrom(t,r);case`every`:{let e=!0,{autoMap:n,mappings:i}=parseMappingBlock(t,r,t=>t.content===`exclude children`&&(e=!1,!0));return{kind:`EverySyntax`,includeChildren:e,autoMap:n,mappings:i,location:o}}case`all`:{let{autoMap:e,mappings:n}=parseMappingBlock(t,r);return{kind:`AllSyntax`,autoMap:e,mappings:n,location:o}}case`join`:return parseJoin(t,r);case`children`:return parseChildren(t,r);case`nested`:return parseNested(t,r);case`remove`:return parseRemove(t,r);case`clear`:return a||t.error(e.ClearWithOutsideNestedBlock,`'clear with' is only valid inside a nested block`,o),parseClearWith(t,r);default:t.error(e.UnknownProjectionDirective,`Unexpected '${i(r.content)}' in projection body`,o),t.skipBlock(r.indent);return}}function parseFrom(t,r){let s=[];for(let i of a(r.content.substring(4),`,`)){let a=i.trim();if(a.length===0){t.error(e.FromWithoutEvent,`Expected an event type after 'from'`,n(r));continue}let c=f.exec(a);c===null?t.error(e.InvalidEventReference,`Invalid event reference '${a}'`,n(r)):s.push({kind:`EventSpecSyntax`,event:o(c[1]),key:c[2]===void 0?null:l(c[2],n(r),t),location:n(r)})}let c=[],u=null,d=null;for(let e=t.peekChild(r.indent);e!==void 0;e=t.peekChild(r.indent)){t.reader.takeSignificant();let r=i(e.content);r===`key`?u=parseKey(t,e):r===`parent`?d=l(e.content.substring(6),n(e),t):pushMapping(t,e,c)}return{kind:`FromSyntax`,events:s,key:u,parentKey:d,mappings:c,location:n(r)}}function parseJoin(t,r){let i=p.exec(r.content);if(i===null)return t.error(e.InvalidJoinDeclaration,`Invalid join declaration '${r.content}' - expected 'join <property> on <key>'`,n(r)),t.skipBlock(r.indent),{kind:`JoinSyntax`,property:``,on:``,events:[],location:n(r)};let a=[];for(let i=t.peekChild(r.indent);i!==void 0;i=t.peekChild(r.indent)){t.reader.takeSignificant();let r=m.exec(i.content);if(r===null){t.error(e.JoinWithoutEvent,`Expected 'with <EventType>' in join block, got '${i.content}'`,n(i)),t.skipBlock(i.indent);continue}let{autoMap:s,mappings:c}=parseMappingBlock(t,i);a.push({kind:`JoinEventSyntax`,event:o(r[1]),autoMap:s,mappings:c,location:n(i)})}return{kind:`JoinSyntax`,property:o(i[1]),on:o(i[2]),events:a,location:n(r)}}function parseChildren(t,r){let i=h.exec(r.content);if(i===null)return t.error(e.InvalidChildrenDeclaration,`Invalid children declaration '${r.content}' - expected 'children <collection> identified by <key>'`,n(r)),t.skipBlock(r.indent),{kind:`ChildrenSyntax`,property:``,autoMap:`Inherit`,blocks:[],location:n(r)};let{autoMap:a,blocks:s}=parseChildBlocks(t,r);return{kind:`ChildrenSyntax`,property:o(i[1]),identifiedBy:l(i[2],n(r),t),autoMap:a,blocks:s,location:n(r)}}function parseNested(t,r){let i=g.exec(r.content);if(i===null)return t.error(e.InvalidNestedDeclaration,`Invalid nested declaration '${r.content}' - expected 'nested <property>'`,n(r)),t.skipBlock(r.indent),{kind:`NestedSyntax`,property:``,autoMap:`Inherit`,blocks:[],location:n(r)};let a=o(i[1]),{autoMap:s,blocks:c}=parseChildBlocks(t,r);return c.some(e=>e.kind===`FromSyntax`)||t.error(e.NestedBlockWithoutFrom,`Nested block '${a}' must contain at least one 'from' directive`,n(r)),{kind:`NestedSyntax`,property:a,autoMap:s,blocks:c,location:n(r)}}function parseChildBlocks(e,t){let n=[],r=`Inherit`;for(let i=e.peekChild(t.indent);i!==void 0;i=e.peekChild(t.indent)){if(e.reader.takeSignificant(),i.content===`automap`){r=`Enabled`;continue}if(i.content===`no automap`){r=`Disabled`;continue}let t=parseBlock(e,i,!0);t!==void 0&&n.push(t)}return{autoMap:r,blocks:n}}function parseRemove(t,r){let a=v.exec(r.content);if(a!==null)return{kind:`RemoveViaJoinSyntax`,event:o(a[1]),key:a[2]===void 0?null:l(a[2],n(r),t),location:n(r)};let s=_.exec(r.content);if(s===null){t.error(e.InvalidRemoveDeclaration,`Invalid remove declaration '${r.content}' - expected 'remove with <EventType>' or 'remove via join on <EventType>'`,n(r)),t.skipBlock(r.indent);return}let c=s[2]===void 0?null:l(s[2],n(r),t),u=null,d=null;for(let a=t.peekChild(r.indent);a!==void 0;a=t.peekChild(r.indent))if(t.reader.takeSignificant(),i(a.content)===`parent`)d=l(a.content.substring(6),n(a),t);else if(i(a.content)===`key`){(c!==null||u!==null)&&t.error(e.InvalidReadModelKeyLookup,`A removal can only declare one key.`,n(a));let r=parseKey(t,a);r.kind===`CompositeKeySyntax`?u=r:c=r.expression}else t.error(e.UnknownRemoveDirective,`Unexpected '${a.content}' in remove block - only 'parent' or 'key' is allowed`,n(a));return{kind:`RemoveWithSyntax`,event:o(s[1]),key:c,...u===null?{}:{partsKey:u},parentKey:d,location:n(r)}}function parseClearWith(t,r){let i=y.exec(r.content);return i===null?(t.error(e.InvalidClearDeclaration,`Invalid clear declaration '${r.content}' - expected 'clear with <EventType>'`,n(r)),{kind:`ClearWithSyntax`,event:``,location:n(r)}):{kind:`ClearWithSyntax`,event:o(i[1]),location:n(r)}}function parseVariant(t,r){let a=b.exec(r.content);if(a===null)return t.error(e.InvalidProjectionVariantDeclaration,`Invalid variant declaration '${r.content}' - expected 'variant <Name>'`,n(r)),t.skipBlock(r.indent),{kind:`ProjectionVariantSyntax`,name:i(r.content),entersOn:[],blocks:[],location:n(r)};let s=o(a[1]),c=[],l=[];for(let a=t.peekChild(r.indent);a!==void 0;a=t.peekChild(r.indent)){t.reader.takeSignificant();let r=i(a.content);if(r===`enters`)c.push(parseEntersOn(t,a));else if(r===`variant`)t.error(e.NestedProjectionVariantNotAllowed,`A variant cannot be declared inside another variant`,n(a)),t.skipBlock(a.indent);else{let e=parseBlock(t,a,!1);e!==void 0&&l.push(e)}}return c.length===0&&t.error(e.VariantRequiresEnteringEvent,`Variant '${s}' must declare at least one 'enters on' event`,n(r)),{kind:`ProjectionVariantSyntax`,name:s,entersOn:c,blocks:l,location:n(r)}}function parseEntersOn(t,r){let i=x.exec(r.content);return i===null?(t.error(e.InvalidEntersOnDeclaration,`Invalid 'enters on' declaration '${r.content}' - expected 'enters on <EventType> [key <expression>]'`,n(r)),t.skipBlock(r.indent),{kind:`ProjectionEntersOnSyntax`,event:``,key:null,location:n(r)}):{kind:`ProjectionEntersOnSyntax`,event:o(i[1]),key:i[2]===void 0?null:l(i[2],n(r),t),location:n(r)}}function parseKey(t,r){let i=r.content.substring(3).trim();if(t.peekChild(r.indent)===void 0)return{kind:`ExpressionKeySyntax`,expression:l(i,n(r),t),location:n(r)};let a=[];for(let s=t.peekChild(r.indent);s!==void 0;s=t.peekChild(r.indent)){if(t.reader.takeSignificant(),s.content===`}`)continue;let r=T.exec(s.content);if(r===null){t.sourceOptions.numericMode===`exact`&&t.error(e.InvalidCompositeKeyPart,`Invalid composite key part '${s.content}' - expected '<property> = <expression>'`,n(s));continue}let c=l(r[2],n(s),t);t.sourceOptions.numericMode===`exact`&&i.replace(/\{$/,``).trim().length>0&&c.kind===`TemplateExpressionSyntax`&&t.error(e.TemplateInCompositeKey,`Template expressions are not allowed in composite keys`,n(s)),a.push({kind:`KeyPartSyntax`,property:o(r[1]),expression:c,location:n(s)})}let s=t.reader.peekSignificant();return s!==void 0&&s.indent===r.indent&&s.content===`}`&&t.reader.takeSignificant(),t.sourceOptions.numericMode===`exact`&&a.length===0&&t.error(e.EmptyCompositeKey,`Composite keys must contain at least one part`,n(r)),{kind:`CompositeKeySyntax`,type:i.replace(/\{$/,``).trim(),parts:a,location:n(r)}}function parseMappingBlock(e,t,n=()=>!1){let r=`Inherit`,i=[];for(let a=e.peekChild(t.indent);a!==void 0;a=e.peekChild(t.indent))e.reader.takeSignificant(),a.content===`automap`?r=`Enabled`:a.content===`no automap`?r=`Disabled`:n(a)||pushMapping(e,a,i);return{autoMap:r,mappings:i}}function pushMapping(t,i,a){let s=n(i),c=S.exec(i.content);if(c!==null){c[1]!==`clear`||c[2]!==`with`?a.push({kind:E[c[1]],property:o(c[2]),location:s}):t.sourceOptions.numericMode===`exact`&&t.error(e.InvalidProjectionMapping,`Invalid mapping '${i.content}' - 'clear with' is a block directive and needs an event type; to clear a property named 'with', write 'clear @with'`,s,r(`text`,i.content));return}let u=C.exec(i.content);if(u!==null){a.push({kind:u[1]===`add`?`AddMappingSyntax`:`SubtractMappingSyntax`,property:o(u[2]),value:l(u[3],s,t),location:s});return}let d=w.exec(i.content)??T.exec(i.content);d===null?t.sourceOptions.numericMode===`exact`&&t.error(e.InvalidProjectionMapping,`Invalid mapping '${i.content}'`,s,r(`text`,i.content)):a.push({kind:`SetMappingSyntax`,property:o(d[1]),source:l(d[2],s,t),location:s})}export{parseProjection};
|
|
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{diagnosticText as r}from"../Diagnostics/DiagnosticArgument.js";import{firstWord as i,splitTopLevel as a,unescapeIdentifier as o}from"./LineText.js";import{parseDescription as s}from"./DescriptionParser.js";import{isFileDirective as c}from"./FileReferences.js";import{parseProjectionExpression as l}from"./ProjectionExpressionParser.js";import{validateProjectionEventScopes as u}from"./ProjectionEventScopeValidator.js";const d=t(`^projection\\s+(@?[\\w.]+)\\s*(?:=>\\s*([\\w.]+))?$`),f=t(`^(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),p=t(`^join\\s+(@?[\\w.]+)\\s+on\\s+(@?[\\w.]+)$`),m=t(`^with\\s+(@?[\\w.]+)$`),h=t(`^children\\s+(@?[\\w.]+)\\s+identified\\s+by\\s+(.+)$`),g=t(`^nested\\s+(@?[\\w.]+)$`),_=t(`^remove\\s+with\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),v=t(`^remove\\s+via\\s+join\\s+on\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),y=t(`^clear\\s+with\\s+(@?[\\w.]+)$`),b=t(`^variant\\s+(@?[\\w.]+)\\s*$`),x=t(`^enters\\s+on\\s+(@?[\\w.]+)(?:\\s+key\\s+(.+))?$`),S=t(`^(increment|decrement|count|clear)\\s+(@?[$\\w.]+)$`),C=t(`^(add|subtract)\\s+(@?[$\\w.]+)\\s+by\\s+(.+?)(?:\\s+\\*\\s+(.+))?$`),w=t(`^set\\s+(@?[$\\w.]+)\\s+(?:=|to)\\s+(.+)$`),T=t(`^(@?[$\\w.@]+)\\s*=(?!=|>)\\s*(.+)$`),E={increment:`IncrementMappingSyntax`,decrement:`DecrementMappingSyntax`,clear:`ClearMappingSyntax`,count:`CountMappingSyntax`};function parseProjection(t,r){let a=d.exec(r.content);if(a===null)return t.error(e.InvalidProjectionDeclaration,`Invalid projection declaration '${r.content}' - expected 'projection <Name> [=> <ReadModel>]'`,n(r)),t.skipBlock(r.indent),{kind:`ProjectionSyntax`,sourceOptions:t.sourceOptions,name:i(r.content),readModel:null,sequence:null,autoMap:`Inherit`,blocks:[],location:n(r)};let o=a[1],l=null,f=null,p=`Inherit`,m=null,h=[];for(let e=t.peekChild(r.indent);e!==void 0;e=t.peekChild(r.indent)){if(t.reader.takeSignificant(),c(e))continue;let n=i(e.content);if(n===`description`)f=s(t,e,f,`Projection '${o}'`);else if(n===`sequence`)l=e.content.substring(8).trim();else if(n===`automap`)p=`Enabled`;else if(e.content===`no automap`)p=`Disabled`;else if(n===`key`)m=parseKey(t,e);else if(n===`variant`)h.push(parseVariant(t,e));else{let n=parseBlock(t,e,!1);n!==void 0&&h.push(n)}}return reportVariantConflicts(t,h,o),u(t,o,h),h.length===0&&t.error(e.EmptyProjection,`Projection '${o}' must contain at least one directive`,n(r)),{kind:`ProjectionSyntax`,sourceOptions:t.sourceOptions,name:o,readModel:a[2]??null,sequence:l,autoMap:p,key:m,blocks:h,description:f,location:n(r)}}function reportVariantConflicts(t,n,r){let i=n.filter(e=>e.kind===`ProjectionVariantSyntax`),a=/* @__PURE__ */ new Map;i.forEach(e=>a.set(e.name,[...a.get(e.name)??[],e]));for(let n of[...a.values()].flatMap(e=>e.slice(1)))t.error(e.DuplicateProjectionVariant,`Duplicate variant '${n.name}' - a variant name is declared once`,n.location);let o=/* @__PURE__ */ new Set;for(let i of n.flatMap(e=>e.kind===`ProjectionVariantSyntax`?e.entersOn:[]))i.event.length>0&&o.has(i.event)&&t.error(e.DuplicateVariantEnteringEvent,`Entering event '${i.event}' is claimed more than once in projection '${r}'`,i.location),o.add(i.event)}function parseBlock(t,r,a){let o=n(r);switch(i(r.content)){case`from`:return parseFrom(t,r);case`every`:{let e=!0,{autoMap:n,mappings:i}=parseMappingBlock(t,r,t=>t.content===`exclude children`&&(e=!1,!0));return{kind:`EverySyntax`,includeChildren:e,autoMap:n,mappings:i,location:o}}case`all`:{let{autoMap:e,mappings:n}=parseMappingBlock(t,r);return{kind:`AllSyntax`,autoMap:e,mappings:n,location:o}}case`join`:return parseJoin(t,r);case`children`:return parseChildren(t,r);case`nested`:return parseNested(t,r);case`remove`:return parseRemove(t,r);case`clear`:return a||t.error(e.ClearWithOutsideNestedBlock,`'clear with' is only valid inside a nested block`,o),parseClearWith(t,r);default:t.error(e.UnknownProjectionDirective,`Unexpected '${i(r.content)}' in projection body`,o),t.skipBlock(r.indent);return}}function parseFrom(t,r){let s=[];for(let i of a(r.content.substring(4),`,`)){let a=i.trim();if(a.length===0){t.error(e.FromWithoutEvent,`Expected an event type after 'from'`,n(r));continue}let c=f.exec(a);c===null?t.error(e.InvalidEventReference,`Invalid event reference '${a}'`,n(r)):s.push({kind:`EventSpecSyntax`,event:o(c[1]),key:c[2]===void 0?null:l(c[2],n(r),t),location:n(r)})}let c=[],u=null,d=null;for(let e=t.peekChild(r.indent);e!==void 0;e=t.peekChild(r.indent)){t.reader.takeSignificant();let r=i(e.content);r===`key`?u=parseKey(t,e):r===`parent`?d=l(e.content.substring(6),n(e),t):pushMapping(t,e,c)}return{kind:`FromSyntax`,events:s,key:u,parentKey:d,mappings:c,location:n(r)}}function parseJoin(t,r){let i=p.exec(r.content);if(i===null)return t.error(e.InvalidJoinDeclaration,`Invalid join declaration '${r.content}' - expected 'join <property> on <key>'`,n(r)),t.skipBlock(r.indent),{kind:`JoinSyntax`,property:``,on:``,events:[],location:n(r)};let a=[];for(let i=t.peekChild(r.indent);i!==void 0;i=t.peekChild(r.indent)){t.reader.takeSignificant();let r=m.exec(i.content);if(r===null){t.error(e.JoinWithoutEvent,`Expected 'with <EventType>' in join block, got '${i.content}'`,n(i)),t.skipBlock(i.indent);continue}let{autoMap:s,mappings:c}=parseMappingBlock(t,i);a.push({kind:`JoinEventSyntax`,event:o(r[1]),autoMap:s,mappings:c,location:n(i)})}return{kind:`JoinSyntax`,property:o(i[1]),on:o(i[2]),events:a,location:n(r)}}function parseChildren(t,r){let i=h.exec(r.content);if(i===null)return t.error(e.InvalidChildrenDeclaration,`Invalid children declaration '${r.content}' - expected 'children <collection> identified by <key>'`,n(r)),t.skipBlock(r.indent),{kind:`ChildrenSyntax`,property:``,autoMap:`Inherit`,blocks:[],location:n(r)};let{autoMap:a,blocks:s}=parseChildBlocks(t,r);return{kind:`ChildrenSyntax`,property:o(i[1]),identifiedBy:l(i[2],n(r),t),autoMap:a,blocks:s,location:n(r)}}function parseNested(t,r){let i=g.exec(r.content);if(i===null)return t.error(e.InvalidNestedDeclaration,`Invalid nested declaration '${r.content}' - expected 'nested <property>'`,n(r)),t.skipBlock(r.indent),{kind:`NestedSyntax`,property:``,autoMap:`Inherit`,blocks:[],location:n(r)};let a=o(i[1]),{autoMap:s,blocks:c}=parseChildBlocks(t,r);return c.some(e=>e.kind===`FromSyntax`)||t.error(e.NestedBlockWithoutFrom,`Nested block '${a}' must contain at least one 'from' directive`,n(r)),{kind:`NestedSyntax`,property:a,autoMap:s,blocks:c,location:n(r)}}function parseChildBlocks(e,t){let n=[],r=`Inherit`;for(let i=e.peekChild(t.indent);i!==void 0;i=e.peekChild(t.indent)){if(e.reader.takeSignificant(),i.content===`automap`){r=`Enabled`;continue}if(i.content===`no automap`){r=`Disabled`;continue}let t=parseBlock(e,i,!0);t!==void 0&&n.push(t)}return{autoMap:r,blocks:n}}function parseRemove(t,r){let a=v.exec(r.content);if(a!==null)return{kind:`RemoveViaJoinSyntax`,event:o(a[1]),key:a[2]===void 0?null:l(a[2],n(r),t),location:n(r)};let s=_.exec(r.content);if(s===null){t.error(e.InvalidRemoveDeclaration,`Invalid remove declaration '${r.content}' - expected 'remove with <EventType>' or 'remove via join on <EventType>'`,n(r)),t.skipBlock(r.indent);return}let c=s[2]===void 0?null:l(s[2],n(r),t),u=null,d=null;for(let a=t.peekChild(r.indent);a!==void 0;a=t.peekChild(r.indent))if(t.reader.takeSignificant(),i(a.content)===`parent`)d=l(a.content.substring(6),n(a),t);else if(i(a.content)===`key`){(c!==null||u!==null)&&t.error(e.InvalidReadModelKeyLookup,`A removal can only declare one key.`,n(a));let r=parseKey(t,a);r.kind===`CompositeKeySyntax`?u=r:c=r.expression}else t.error(e.UnknownRemoveDirective,`Unexpected '${a.content}' in remove block - only 'parent' or 'key' is allowed`,n(a));return{kind:`RemoveWithSyntax`,event:o(s[1]),key:c,...u===null?{}:{partsKey:u},parentKey:d,location:n(r)}}function parseClearWith(t,r){let i=y.exec(r.content);return i===null?(t.error(e.InvalidClearDeclaration,`Invalid clear declaration '${r.content}' - expected 'clear with <EventType>'`,n(r)),{kind:`ClearWithSyntax`,event:``,location:n(r)}):{kind:`ClearWithSyntax`,event:o(i[1]),location:n(r)}}function parseVariant(t,r){let a=b.exec(r.content);if(a===null)return t.error(e.InvalidProjectionVariantDeclaration,`Invalid variant declaration '${r.content}' - expected 'variant <Name>'`,n(r)),t.skipBlock(r.indent),{kind:`ProjectionVariantSyntax`,name:i(r.content),entersOn:[],blocks:[],location:n(r)};let s=o(a[1]),c=[],l=[];for(let a=t.peekChild(r.indent);a!==void 0;a=t.peekChild(r.indent)){t.reader.takeSignificant();let r=i(a.content);if(r===`enters`)c.push(parseEntersOn(t,a));else if(r===`variant`)t.error(e.NestedProjectionVariantNotAllowed,`A variant cannot be declared inside another variant`,n(a)),t.skipBlock(a.indent);else{let e=parseBlock(t,a,!1);e!==void 0&&l.push(e)}}return c.length===0&&t.error(e.VariantRequiresEnteringEvent,`Variant '${s}' must declare at least one 'enters on' event`,n(r)),{kind:`ProjectionVariantSyntax`,name:s,entersOn:c,blocks:l,location:n(r)}}function parseEntersOn(t,r){let i=x.exec(r.content);return i===null?(t.error(e.InvalidEntersOnDeclaration,`Invalid 'enters on' declaration '${r.content}' - expected 'enters on <EventType> [key <expression>]'`,n(r)),t.skipBlock(r.indent),{kind:`ProjectionEntersOnSyntax`,event:``,key:null,location:n(r)}):{kind:`ProjectionEntersOnSyntax`,event:o(i[1]),key:i[2]===void 0?null:l(i[2],n(r),t),location:n(r)}}function parseKey(t,r){let i=r.content.substring(3).trim();if(t.peekChild(r.indent)===void 0)return{kind:`ExpressionKeySyntax`,expression:l(i,n(r),t),location:n(r)};let a=[];for(let s=t.peekChild(r.indent);s!==void 0;s=t.peekChild(r.indent)){if(t.reader.takeSignificant(),s.content===`}`)continue;let r=T.exec(s.content);if(r===null){t.sourceOptions.numericMode===`exact`&&t.error(e.InvalidCompositeKeyPart,`Invalid composite key part '${s.content}' - expected '<property> = <expression>'`,n(s));continue}let c=l(r[2],n(s),t);t.sourceOptions.numericMode===`exact`&&i.replace(/\{$/,``).trim().length>0&&c.kind===`TemplateExpressionSyntax`&&t.error(e.TemplateInCompositeKey,`Template expressions are not allowed in composite keys`,n(s)),a.push({kind:`KeyPartSyntax`,property:o(r[1]),expression:c,location:n(s)})}let s=t.reader.peekSignificant();return s!==void 0&&s.indent===r.indent&&s.content===`}`&&t.reader.takeSignificant(),t.sourceOptions.numericMode===`exact`&&a.length===0&&t.error(e.EmptyCompositeKey,`Composite keys must contain at least one part`,n(r)),{kind:`CompositeKeySyntax`,type:i.replace(/\{$/,``).trim(),parts:a,location:n(r)}}function parseMappingBlock(e,t,n=()=>!1){let r=`Inherit`,i=[];for(let a=e.peekChild(t.indent);a!==void 0;a=e.peekChild(t.indent))e.reader.takeSignificant(),a.content===`automap`?r=`Enabled`:a.content===`no automap`?r=`Disabled`:n(a)||pushMapping(e,a,i);return{autoMap:r,mappings:i}}function pushMapping(t,i,a){let s=n(i),c=S.exec(i.content);if(c!==null){c[1]!==`clear`||c[2]!==`with`?a.push({kind:E[c[1]],property:o(c[2]),location:s}):t.sourceOptions.numericMode===`exact`&&t.error(e.InvalidProjectionMapping,`Invalid mapping '${i.content}' - 'clear with' is a block directive and needs an event type; to clear a property named 'with', write 'clear @with'`,s,r(`text`,i.content));return}let u=C.exec(i.content);if(u!==null){a.push({kind:u[1]===`add`?`AddMappingSyntax`:`SubtractMappingSyntax`,property:o(u[2]),value:l(u[3],s,t),...u[4]===void 0?{}:{factor:l(u[4],s,t)},location:s});return}let d=w.exec(i.content)??T.exec(i.content);d===null?t.sourceOptions.numericMode===`exact`&&t.error(e.InvalidProjectionMapping,`Invalid mapping '${i.content}'`,s,r(`text`,i.content)):a.push({kind:`SetMappingSyntax`,property:o(d[1]),source:l(d[2],s,t),location:s})}export{parseProjection};
|
|
2
2
|
//# sourceMappingURL=ProjectionParser.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectionParser.js","names":["header","pattern","eventSpecPattern","joinPattern","withPattern","childrenPattern","nestedPattern","removeWithPattern","removeViaJoinPattern","clearWithPattern","variantPattern","entersOnPattern","keywordMappingPattern","arithmeticPattern","setPattern","assignmentPattern","keywordMappings","match","line","context","DiagnosticCodes","locationOf","firstWord","name","sequence","description","autoMap","key","blocks","child","isFileDirective","keyword","parseDescription","block","validateProjectionEventScopes","variants","byName","variant","duplicate","group","entering","entry","location","includeChildren","nestedScope","events","spec","splitTopLevel","text","unescapeIdentifier","parseProjectionExpression","mappings","parentKey","withMatch","property","viaJoin","partsKey","parsed","entersOn","parts","expression","closing","extra","diagnosticText","arithmetic","assigned"],"sources":["../../../../../../Compiler/Parsing/ProjectionParser.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 {\n AutoMapMode, ChildrenSyntax, ClearWithSyntax, CompositeKeySyntax, EventSpecSyntax, FromSyntax, JoinEventSyntax, JoinSyntax, MappingKind, MappingSyntax, NestedSyntax,\n KeyPartSyntax, KeySyntax, ProjectionBlockSyntax, ProjectionEntersOnSyntax, ProjectionSyntax, ProjectionVariantSyntax,\n} from '../Syntax/Projections';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { pattern } from '../Text/patterns';\nimport { parseProjectionExpression } from './ProjectionExpressionParser';\nimport { validateProjectionEventScopes } from './ProjectionEventScopeValidator';\nimport { isFileDirective } from './FileReferences';\nimport { parseDescription } from './DescriptionParser';\nimport { firstWord, splitTopLevel, unescapeIdentifier } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^projection\\\\s+(@?[\\\\w.]+)\\\\s*(?:=>\\\\s*([\\\\w.]+))?$');\nconst eventSpecPattern = pattern('^(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst joinPattern = pattern('^join\\\\s+(@?[\\\\w.]+)\\\\s+on\\\\s+(@?[\\\\w.]+)$');\nconst withPattern = pattern('^with\\\\s+(@?[\\\\w.]+)$');\nconst childrenPattern = pattern('^children\\\\s+(@?[\\\\w.]+)\\\\s+identified\\\\s+by\\\\s+(.+)$');\nconst nestedPattern = pattern('^nested\\\\s+(@?[\\\\w.]+)$');\nconst removeWithPattern = pattern('^remove\\\\s+with\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst removeViaJoinPattern = pattern('^remove\\\\s+via\\\\s+join\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst clearWithPattern = pattern('^clear\\\\s+with\\\\s+(@?[\\\\w.]+)$');\nconst variantPattern = pattern('^variant\\\\s+(@?[\\\\w.]+)\\\\s*$');\nconst entersOnPattern = pattern('^enters\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst keywordMappingPattern = pattern('^(increment|decrement|count|clear)\\\\s+(@?[$\\\\w.]+)$');\nconst arithmeticPattern = pattern('^(add|subtract)\\\\s+(@?[$\\\\w.]+)\\\\s+by\\\\s+(.+)$');\nconst setPattern = pattern('^set\\\\s+(@?[$\\\\w.]+)\\\\s+(?:=|to)\\\\s+(.+)$');\nconst assignmentPattern = pattern('^(@?[$\\\\w.@]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst keywordMappings: Record<string, MappingKind> = {\n increment: 'IncrementMappingSyntax',\n decrement: 'DecrementMappingSyntax',\n clear: 'ClearMappingSyntax',\n count: 'CountMappingSyntax',\n};\n\n// Reads a projection's structure: its name, the read model it builds, the events each block consumes, the\n// properties each mapping sets and where automap is turned on or off. Keys, and where a mapping takes its\n// value from, are recognized and skipped.\nexport function parseProjection(context: ParserContext, line: SourceLine): ProjectionSyntax {\n const match = header.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionDeclaration, `Invalid projection declaration '${line.content}' - expected 'projection <Name> [=> <ReadModel>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name: firstWord(line.content), readModel: null, sequence: null, autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const name = match[1];\n let sequence: string | null = null;\n let description: string | null = null;\n let autoMap: AutoMapMode = 'Inherit';\n let key: KeySyntax | null = null;\n const blocks: ProjectionBlockSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (isFileDirective(child)) {\n continue;\n }\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Projection '${name}'`);\n } else if (keyword === 'sequence') {\n sequence = child.content.substring('sequence'.length).trim();\n } else if (keyword === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (keyword === 'key') {\n key = parseKey(context, child);\n } else if (keyword === 'variant') {\n blocks.push(parseVariant(context, child));\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n reportVariantConflicts(context, blocks, name);\n validateProjectionEventScopes(context, name, blocks);\n if (blocks.length === 0) {\n context.error(DiagnosticCodes.EmptyProjection, `Projection '${name}' must contain at least one directive`, locationOf(line));\n }\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name, readModel: match[2] ?? null, sequence, autoMap, key, blocks, description, location: locationOf(line) };\n}\n\nfunction reportVariantConflicts(context: ParserContext, blocks: readonly ProjectionBlockSyntax[], name: string): void {\n // Grouped by name in the order each name first appears, as the C# parser reports them.\n const variants = blocks.filter((block): block is ProjectionVariantSyntax => block.kind === 'ProjectionVariantSyntax');\n const byName = new Map<string, ProjectionVariantSyntax[]>();\n variants.forEach(variant => byName.set(variant.name, [...(byName.get(variant.name) ?? []), variant]));\n for (const duplicate of [...byName.values()].flatMap(group => group.slice(1))) {\n context.error(DiagnosticCodes.DuplicateProjectionVariant, `Duplicate variant '${duplicate.name}' - a variant name is declared once`, duplicate.location);\n }\n const entering = new Set<string>();\n for (const entry of blocks.flatMap(block => block.kind === 'ProjectionVariantSyntax' ? block.entersOn : [])) {\n if (entry.event.length > 0 && entering.has(entry.event)) {\n context.error(DiagnosticCodes.DuplicateVariantEnteringEvent, `Entering event '${entry.event}' is claimed more than once in projection '${name}'`, entry.location);\n }\n entering.add(entry.event);\n }\n}\n\nfunction parseBlock(context: ParserContext, line: SourceLine, nestedScope: boolean): ProjectionBlockSyntax | undefined {\n const location = locationOf(line);\n switch (firstWord(line.content)) {\n case 'from':\n return parseFrom(context, line);\n case 'every': {\n let includeChildren = true;\n const { autoMap, mappings } = parseMappingBlock(context, line, child => {\n if (child.content !== 'exclude children') {\n return false;\n }\n includeChildren = false;\n return true;\n });\n return { kind: 'EverySyntax', includeChildren, autoMap, mappings, location };\n }\n case 'all': {\n const { autoMap, mappings } = parseMappingBlock(context, line);\n return { kind: 'AllSyntax', autoMap, mappings, location };\n }\n case 'join':\n return parseJoin(context, line);\n case 'children':\n return parseChildren(context, line);\n case 'nested':\n return parseNested(context, line);\n case 'remove':\n return parseRemove(context, line);\n case 'clear':\n if (!nestedScope) {\n context.error(DiagnosticCodes.ClearWithOutsideNestedBlock, '\\'clear with\\' is only valid inside a nested block', location);\n }\n return parseClearWith(context, line);\n default:\n context.error(DiagnosticCodes.UnknownProjectionDirective, `Unexpected '${firstWord(line.content)}' in projection body`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n}\n\nfunction parseFrom(context: ParserContext, line: SourceLine): FromSyntax {\n const events: EventSpecSyntax[] = [];\n for (const spec of splitTopLevel(line.content.substring('from'.length), ',')) {\n const text = spec.trim();\n if (text.length === 0) {\n context.error(DiagnosticCodes.FromWithoutEvent, 'Expected an event type after \\'from\\'', locationOf(line));\n continue;\n }\n const match = eventSpecPattern.exec(text);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventReference, `Invalid event reference '${text}'`, locationOf(line));\n continue;\n }\n events.push({ kind: 'EventSpecSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) });\n }\n const mappings: MappingSyntax[] = [];\n let key: KeySyntax | null = null;\n let parentKey: ExpressionSyntax | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'key') key = parseKey(context, child);\n else if (keyword === 'parent') parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n else pushMapping(context, child, mappings);\n }\n return { kind: 'FromSyntax', events, key, parentKey, mappings, location: locationOf(line) };\n}\n\nfunction parseJoin(context: ParserContext, line: SourceLine): JoinSyntax {\n const match = joinPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidJoinDeclaration, `Invalid join declaration '${line.content}' - expected 'join <property> on <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'JoinSyntax', property: '', on: '', events: [], location: locationOf(line) };\n }\n const events: JoinEventSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const withMatch = withPattern.exec(child.content);\n if (withMatch === null) {\n context.error(DiagnosticCodes.JoinWithoutEvent, `Expected 'with <EventType>' in join block, got '${child.content}'`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n const { autoMap, mappings } = parseMappingBlock(context, child);\n events.push({ kind: 'JoinEventSyntax', event: unescapeIdentifier(withMatch[1]), autoMap, mappings, location: locationOf(child) });\n }\n return { kind: 'JoinSyntax', property: unescapeIdentifier(match[1]), on: unescapeIdentifier(match[2]), events, location: locationOf(line) };\n}\n\nfunction parseChildren(context: ParserContext, line: SourceLine): ChildrenSyntax {\n const match = childrenPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidChildrenDeclaration, `Invalid children declaration '${line.content}' - expected 'children <collection> identified by <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ChildrenSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const { autoMap, blocks } = parseChildBlocks(context, line);\n return { kind: 'ChildrenSyntax', property: unescapeIdentifier(match[1]), identifiedBy: parseProjectionExpression(match[2], locationOf(line), context), autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseNested(context: ParserContext, line: SourceLine): NestedSyntax {\n const match = nestedPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidNestedDeclaration, `Invalid nested declaration '${line.content}' - expected 'nested <property>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'NestedSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const property = unescapeIdentifier(match[1]);\n const { autoMap, blocks } = parseChildBlocks(context, line);\n if (!blocks.some(block => block.kind === 'FromSyntax')) {\n context.error(DiagnosticCodes.NestedBlockWithoutFrom, `Nested block '${property}' must contain at least one 'from' directive`, locationOf(line));\n }\n return { kind: 'NestedSyntax', property, autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseChildBlocks(context: ParserContext, line: SourceLine): { autoMap: AutoMapMode; blocks: ProjectionBlockSyntax[] } {\n const blocks: ProjectionBlockSyntax[] = [];\n let autoMap: AutoMapMode = 'Inherit';\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n continue;\n }\n if (child.content === 'no automap') {\n autoMap = 'Disabled';\n continue;\n }\n const block = parseBlock(context, child, true);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n return { autoMap, blocks };\n}\n\nfunction parseRemove(context: ParserContext, line: SourceLine): ProjectionBlockSyntax | undefined {\n const viaJoin = removeViaJoinPattern.exec(line.content);\n if (viaJoin !== null) {\n return { kind: 'RemoveViaJoinSyntax', event: unescapeIdentifier(viaJoin[1]), key: viaJoin[2] === undefined ? null : parseProjectionExpression(viaJoin[2], locationOf(line), context), location: locationOf(line) };\n }\n const match = removeWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidRemoveDeclaration, `Invalid remove declaration '${line.content}' - expected 'remove with <EventType>' or 'remove via join on <EventType>'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n }\n let key = match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context);\n let partsKey: CompositeKeySyntax | null = null;\n let parentKey: ExpressionSyntax | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (firstWord(child.content) === 'parent') {\n parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n } else if (firstWord(child.content) === 'key') {\n if (key !== null || partsKey !== null) context.error(DiagnosticCodes.InvalidReadModelKeyLookup, 'A removal can only declare one key.', locationOf(child));\n const parsed = parseKey(context, child);\n if (parsed.kind === 'CompositeKeySyntax') partsKey = parsed;\n else key = parsed.expression;\n } else {\n context.error(DiagnosticCodes.UnknownRemoveDirective, `Unexpected '${child.content}' in remove block - only 'parent' or 'key' is allowed`, locationOf(child));\n }\n }\n return { kind: 'RemoveWithSyntax', event: unescapeIdentifier(match[1]), key, ...(partsKey === null ? {} : { partsKey }), parentKey, location: locationOf(line) };\n}\n\nfunction parseClearWith(context: ParserContext, line: SourceLine): ClearWithSyntax {\n const match = clearWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidClearDeclaration, `Invalid clear declaration '${line.content}' - expected 'clear with <EventType>'`, locationOf(line));\n return { kind: 'ClearWithSyntax', event: '', location: locationOf(line) };\n }\n return { kind: 'ClearWithSyntax', event: unescapeIdentifier(match[1]), location: locationOf(line) };\n}\n\nfunction parseVariant(context: ParserContext, line: SourceLine): ProjectionVariantSyntax {\n const match = variantPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionVariantDeclaration, `Invalid variant declaration '${line.content}' - expected 'variant <Name>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionVariantSyntax', name: firstWord(line.content), entersOn: [], blocks: [], location: locationOf(line) };\n }\n const name = unescapeIdentifier(match[1]);\n const entersOn: ProjectionEntersOnSyntax[] = [];\n const blocks: ProjectionBlockSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'enters') {\n entersOn.push(parseEntersOn(context, child));\n } else if (keyword === 'variant') {\n context.error(DiagnosticCodes.NestedProjectionVariantNotAllowed, 'A variant cannot be declared inside another variant', locationOf(child));\n context.skipBlock(child.indent);\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n if (entersOn.length === 0) {\n context.error(DiagnosticCodes.VariantRequiresEnteringEvent, `Variant '${name}' must declare at least one 'enters on' event`, locationOf(line));\n }\n return { kind: 'ProjectionVariantSyntax', name, entersOn, blocks, location: locationOf(line) };\n}\n\nfunction parseEntersOn(context: ParserContext, line: SourceLine): ProjectionEntersOnSyntax {\n const match = entersOnPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEntersOnDeclaration, `Invalid 'enters on' declaration '${line.content}' - expected 'enters on <EventType> [key <expression>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionEntersOnSyntax', event: '', key: null, location: locationOf(line) };\n }\n return { kind: 'ProjectionEntersOnSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) };\n}\n\n// A key with a body is a composite key: its parts, then a closing '}' at the key's own indent.\nfunction parseKey(context: ParserContext, line: SourceLine): KeySyntax {\n const text = line.content.substring('key'.length).trim();\n if (context.peekChild(line.indent) === undefined) return { kind: 'ExpressionKeySyntax', expression: parseProjectionExpression(text, locationOf(line), context), location: locationOf(line) };\n const parts: KeyPartSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === '}') continue;\n const match = assignmentPattern.exec(child.content);\n if (match === null) {\n if (context.sourceOptions.numericMode === 'exact') context.error(DiagnosticCodes.InvalidCompositeKeyPart, `Invalid composite key part '${child.content}' - expected '<property> = <expression>'`, locationOf(child));\n continue;\n }\n const expression = parseProjectionExpression(match[2], locationOf(child), context);\n if (context.sourceOptions.numericMode === 'exact' && text.replace(/\\{$/, '').trim().length > 0 && expression.kind === 'TemplateExpressionSyntax') context.error(DiagnosticCodes.TemplateInCompositeKey, 'Template expressions are not allowed in composite keys', locationOf(child));\n parts.push({ kind: 'KeyPartSyntax', property: unescapeIdentifier(match[1]), expression, location: locationOf(child) });\n }\n const closing = context.reader.peekSignificant();\n if (closing !== undefined && closing.indent === line.indent && closing.content === '}') context.reader.takeSignificant();\n if (context.sourceOptions.numericMode === 'exact' && parts.length === 0) context.error(DiagnosticCodes.EmptyCompositeKey, 'Composite keys must contain at least one part', locationOf(line));\n return { kind: 'CompositeKeySyntax', type: text.replace(/\\{$/, '').trim(), parts, location: locationOf(line) };\n}\n\n// Mapping lines carry no body, so a mapping block is its direct children. The last automap setting wins;\n// a line 'extra' claims is not a mapping.\nfunction parseMappingBlock(context: ParserContext, line: SourceLine, extra: (child: SourceLine) => boolean = () => false): { autoMap: AutoMapMode; mappings: MappingSyntax[] } {\n let autoMap: AutoMapMode = 'Inherit';\n const mappings: MappingSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (!extra(child)) {\n pushMapping(context, child, mappings);\n }\n }\n return { autoMap, mappings };\n}\n\n// The property one mapping line sets, and how - the port of the C# ParseMappingLine. Exact reports\n// malformed mappings; Legacy keeps the existing skip behavior.\nfunction pushMapping(context: ParserContext, line: SourceLine, mappings: MappingSyntax[]): void {\n const location = locationOf(line);\n const keyword = keywordMappingPattern.exec(line.content);\n if (keyword !== null) {\n if (keyword[1] !== 'clear' || keyword[2] !== 'with') {\n mappings.push({ kind: keywordMappings[keyword[1]], property: unescapeIdentifier(keyword[2]), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}' - 'clear with' is a block directive and needs an event type; to clear a property named 'with', write 'clear @with'`, location, diagnosticText('text', line.content));\n }\n return;\n }\n const arithmetic = arithmeticPattern.exec(line.content);\n if (arithmetic !== null) {\n mappings.push({ kind: arithmetic[1] === 'add' ? 'AddMappingSyntax' : 'SubtractMappingSyntax', property: unescapeIdentifier(arithmetic[2]), value: parseProjectionExpression(arithmetic[3], location, context), location });\n return;\n }\n const assigned = setPattern.exec(line.content) ?? assignmentPattern.exec(line.content);\n if (assigned !== null) {\n mappings.push({ kind: 'SetMappingSyntax', property: unescapeIdentifier(assigned[1]), source: parseProjectionExpression(assigned[2], location, context), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}'`, location, diagnosticText('text', line.content));\n }\n}\n"],"mappings":"8nBAmBA,MAAMA,EAASC,EAAQ,qDAAqD,EACtEC,EAAmBD,EAAQ,mCAAmC,EAC9DE,EAAcF,EAAQ,4CAA4C,EAClEG,EAAcH,EAAQ,uBAAuB,EAC7CI,EAAkBJ,EAAQ,uDAAuD,EACjFK,EAAgBL,EAAQ,yBAAyB,EACjDM,EAAoBN,EAAQ,qDAAqD,EACjFO,EAAuBP,EAAQ,kEAAkE,EACjGQ,EAAmBR,EAAQ,gCAAgC,EAC3DS,EAAiBT,EAAQ,8BAA8B,EACvDU,EAAkBV,EAAQ,mDAAmD,EAC7EW,EAAwBX,EAAQ,qDAAqD,EACrFY,EAAoBZ,EAAQ,gDAAgD,EAC5Ea,EAAab,EAAQ,2CAA2C,EAChEc,EAAoBd,EAAQ,qCAAqC,EACjEe,EAA+C,CACjD,UAAW,yBACX,UAAW,yBACX,MAAO,qBACP,MAAO,oBACX,EAKA,SAAgB,gBAAgB,EAAwB,EAAoC,CACxF,IAAMC,EAAQjB,EAAO,KAAKkB,EAAK,OAAO,EACtC,GAAID,IAAU,KAGV,OAFAE,EAAQ,MAAMC,EAAgB,6BAA8B,mCAAmCF,EAAK,QAAQ,mDAAoDG,EAAWH,CAAI,CAAC,EAChLC,EAAQ,UAAUD,EAAK,MAAM,EACtB,CAAE,KAAM,mBAAoB,cAAeC,EAAQ,cAAe,KAAMG,EAAUJ,EAAK,OAAO,EAAG,UAAW,KAAM,SAAU,KAAM,QAAS,UAAW,OAAQ,CAAC,EAAG,SAAUG,EAAWH,CAAI,CAAE,EAExM,IAAMK,EAAON,EAAM,GACfO,EAA0B,KAC1BC,EAA6B,KAC7BC,EAAuB,UACvBC,EAAwB,KACtBC,EAAkC,CAAC,EACzC,IAAK,IAAIC,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAG,CAE1G,GADAC,EAAQ,OAAO,gBAAgB,EAC3BW,EAAgBD,CAAK,EACrB,SAEJ,IAAME,EAAUT,EAAUO,EAAM,OAAO,EACvC,GAAIE,IAAY,cACZ,EAAcC,EAAiBb,EAASU,EAAOJ,EAAa,eAAeF,EAAK,EAAE,OAC/E,GAAIQ,IAAY,WACnB,EAAWF,EAAM,QAAQ,UAAU,CAAiB,CAAC,CAAC,KAAK,OACxD,GAAIE,IAAY,UACnB,EAAU,eACP,GAAIF,EAAM,UAAY,aACzB,EAAU,gBACP,GAAIE,IAAY,MACnB,EAAM,SAASZ,EAASU,CAAK,OAC1B,GAAIE,IAAY,UACnBH,EAAO,KAAK,aAAaT,EAASU,CAAK,CAAC,MACrC,CACH,IAAMI,EAAQ,WAAWd,EAASU,EAAO,EAAK,EAC1CI,IAAU,IAAA,IACVL,EAAO,KAAKK,CAAK,CAEzB,CACJ,CAMA,OALA,uBAAuBd,EAASS,EAAQL,CAAI,EAC5CW,EAA8Bf,EAASI,EAAMK,CAAM,EAC/CA,EAAO,SAAW,GAClBT,EAAQ,MAAMC,EAAgB,gBAAiB,eAAeG,EAAK,uCAAwCF,EAAWH,CAAI,CAAC,EAExH,CAAE,KAAM,mBAAoB,cAAeC,EAAQ,cAAe,OAAM,UAAWF,EAAM,IAAM,KAAM,WAAU,UAAS,MAAK,SAAQ,cAAa,SAAUI,EAAWH,CAAI,CAAE,CACxL,CAEA,SAAS,uBAAuB,EAAwB,EAA0C,EAAoB,CAElH,IAAMiB,EAAWP,EAAO,OAAQ,GAA4CK,EAAM,OAAS,yBAAyB,EAC9GG,kBAAS,IAAI,IACnBD,EAAS,QAAQ,GAAWC,EAAO,IAAIC,EAAQ,KAAM,CAAC,GAAID,EAAO,IAAIC,EAAQ,IAAI,GAAK,CAAC,EAAIA,CAAO,CAAC,CAAC,EACpG,IAAK,IAAMC,IAAa,CAAC,GAAGF,EAAO,OAAO,CAAC,CAAC,CAAC,QAAQ,GAASG,EAAM,MAAM,CAAC,CAAC,EACxEpB,EAAQ,MAAMC,EAAgB,2BAA4B,sBAAsBkB,EAAU,KAAK,qCAAsCA,EAAU,QAAQ,EAE3J,IAAME,kBAAW,IAAI,IACrB,IAAK,IAAMC,KAASb,EAAO,QAAQ,GAASK,EAAM,OAAS,0BAA4BA,EAAM,SAAW,CAAC,CAAC,EAClGQ,EAAM,MAAM,OAAS,GAAKD,EAAS,IAAIC,EAAM,KAAK,GAClDtB,EAAQ,MAAMC,EAAgB,8BAA+B,mBAAmBqB,EAAM,MAAM,6CAA6ClB,EAAK,GAAIkB,EAAM,QAAQ,EAEpKD,EAAS,IAAIC,EAAM,KAAK,CAEhC,CAEA,SAAS,WAAW,EAAwB,EAAkB,EAAyD,CACnH,IAAMC,EAAWrB,EAAWH,CAAI,EAChC,OAAQI,EAAUJ,EAAK,OAAO,EAA9B,CACI,IAAK,OACD,OAAO,UAAUC,EAASD,CAAI,EAClC,IAAK,QAAS,CACV,IAAIyB,EAAkB,GAChB,CAAE,UAAS,YAAa,kBAAkBxB,EAASD,EAAM,GACvDW,EAAM,UAAY,qBAGtB,EAAkB,GACX,GACV,EACD,MAAO,CAAE,KAAM,cAAe,kBAAiB,UAAS,WAAU,UAAS,CAC/E,CACA,IAAK,MAAO,CACR,GAAM,CAAE,UAAS,YAAa,kBAAkBV,EAASD,CAAI,EAC7D,MAAO,CAAE,KAAM,YAAa,UAAS,WAAU,UAAS,CAC5D,CACA,IAAK,OACD,OAAO,UAAUC,EAASD,CAAI,EAClC,IAAK,WACD,OAAO,cAAcC,EAASD,CAAI,EACtC,IAAK,SACD,OAAO,YAAYC,EAASD,CAAI,EACpC,IAAK,SACD,OAAO,YAAYC,EAASD,CAAI,EACpC,IAAK,QAID,OAHK0B,GACDzB,EAAQ,MAAMC,EAAgB,4BAA6B,mDAAsDsB,CAAQ,EAEtH,eAAevB,EAASD,CAAI,EACvC,QACIC,EAAQ,MAAMC,EAAgB,2BAA4B,eAAeE,EAAUJ,EAAK,OAAO,EAAE,sBAAuBwB,CAAQ,EAChIvB,EAAQ,UAAUD,EAAK,MAAM,EAC7B,MACR,CACJ,CAEA,SAAS,UAAU,EAAwB,EAA8B,CACrE,IAAM2B,EAA4B,CAAC,EACnC,IAAK,IAAMC,KAAQC,EAAc7B,EAAK,QAAQ,UAAU,CAAa,EAAG,GAAG,EAAG,CAC1E,IAAM8B,EAAOF,EAAK,KAAK,EACvB,GAAIE,EAAK,SAAW,EAAG,CACnB7B,EAAQ,MAAMC,EAAgB,iBAAkB,sCAAyCC,EAAWH,CAAI,CAAC,EACzG,QACJ,CACA,IAAMD,EAAQf,EAAiB,KAAK8C,CAAI,EACpC/B,IAAU,KACVE,EAAQ,MAAMC,EAAgB,sBAAuB,4BAA4B4B,EAAK,GAAI3B,EAAWH,CAAI,CAAC,EAG9G2B,EAAO,KAAK,CAAE,KAAM,kBAAmB,MAAOI,EAAmBhC,EAAM,EAAE,EAAG,IAAKA,EAAM,KAAO,IAAA,GAAY,KAAOiC,EAA0BjC,EAAM,GAAII,EAAWH,CAAI,EAAGC,CAAO,EAAG,SAAUE,EAAWH,CAAI,CAAE,CAAC,CACjN,CACA,IAAMiC,EAA4B,CAAC,EAC/BxB,EAAwB,KACxByB,EAAqC,KACzC,IAAK,IAAIvB,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAG,CAC1GC,EAAQ,OAAO,gBAAgB,EAC/B,IAAMY,EAAUT,EAAUO,EAAM,OAAO,EACnCE,IAAY,MAAO,EAAM,SAASZ,EAASU,CAAK,EAC3CE,IAAY,SAAU,EAAYmB,EAA0BrB,EAAM,QAAQ,UAAU,CAAe,EAAGR,EAAWQ,CAAK,EAAGV,CAAO,EACpI,YAAYA,EAASU,EAAOsB,CAAQ,CAC7C,CACA,MAAO,CAAE,KAAM,aAAc,SAAQ,MAAK,YAAW,WAAU,SAAU9B,EAAWH,CAAI,CAAE,CAC9F,CAEA,SAAS,UAAU,EAAwB,EAA8B,CACrE,IAAMD,EAAQd,EAAY,KAAKe,EAAK,OAAO,EAC3C,GAAID,IAAU,KAGV,OAFAE,EAAQ,MAAMC,EAAgB,uBAAwB,6BAA6BF,EAAK,QAAQ,yCAA0CG,EAAWH,CAAI,CAAC,EAC1JC,EAAQ,UAAUD,EAAK,MAAM,EACtB,CAAE,KAAM,aAAc,SAAU,GAAI,GAAI,GAAI,OAAQ,CAAC,EAAG,SAAUG,EAAWH,CAAI,CAAE,EAE9F,IAAM2B,EAA4B,CAAC,EACnC,IAAK,IAAIhB,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAG,CAC1GC,EAAQ,OAAO,gBAAgB,EAC/B,IAAMkC,EAAYjD,EAAY,KAAKyB,EAAM,OAAO,EAChD,GAAIwB,IAAc,KAAM,CACpBlC,EAAQ,MAAMC,EAAgB,iBAAkB,mDAAmDS,EAAM,QAAQ,GAAIR,EAAWQ,CAAK,CAAC,EACtIV,EAAQ,UAAUU,EAAM,MAAM,EAC9B,QACJ,CACA,GAAM,CAAE,UAAS,YAAa,kBAAkBV,EAASU,CAAK,EAC9DgB,EAAO,KAAK,CAAE,KAAM,kBAAmB,MAAOI,EAAmBI,EAAU,EAAE,EAAG,UAAS,WAAU,SAAUhC,EAAWQ,CAAK,CAAE,CAAC,CACpI,CACA,MAAO,CAAE,KAAM,aAAc,SAAUoB,EAAmBhC,EAAM,EAAE,EAAG,GAAIgC,EAAmBhC,EAAM,EAAE,EAAG,SAAQ,SAAUI,EAAWH,CAAI,CAAE,CAC9I,CAEA,SAAS,cAAc,EAAwB,EAAkC,CAC7E,IAAMD,EAAQZ,EAAgB,KAAKa,EAAK,OAAO,EAC/C,GAAID,IAAU,KAGV,OAFAE,EAAQ,MAAMC,EAAgB,2BAA4B,iCAAiCF,EAAK,QAAQ,0DAA2DG,EAAWH,CAAI,CAAC,EACnLC,EAAQ,UAAUD,EAAK,MAAM,EACtB,CAAE,KAAM,iBAAkB,SAAU,GAAI,QAAS,UAAW,OAAQ,CAAC,EAAG,SAAUG,EAAWH,CAAI,CAAE,EAE9G,GAAM,CAAE,UAAS,UAAW,iBAAiBC,EAASD,CAAI,EAC1D,MAAO,CAAE,KAAM,iBAAkB,SAAU+B,EAAmBhC,EAAM,EAAE,EAAG,aAAciC,EAA0BjC,EAAM,GAAII,EAAWH,CAAI,EAAGC,CAAO,EAAG,UAAS,SAAQ,SAAUE,EAAWH,CAAI,CAAE,CACvM,CAEA,SAAS,YAAY,EAAwB,EAAgC,CACzE,IAAMD,EAAQX,EAAc,KAAKY,EAAK,OAAO,EAC7C,GAAID,IAAU,KAGV,OAFAE,EAAQ,MAAMC,EAAgB,yBAA0B,+BAA+BF,EAAK,QAAQ,kCAAmCG,EAAWH,CAAI,CAAC,EACvJC,EAAQ,UAAUD,EAAK,MAAM,EACtB,CAAE,KAAM,eAAgB,SAAU,GAAI,QAAS,UAAW,OAAQ,CAAC,EAAG,SAAUG,EAAWH,CAAI,CAAE,EAE5G,IAAMoC,EAAWL,EAAmBhC,EAAM,EAAE,EACtC,CAAE,UAAS,UAAW,iBAAiBE,EAASD,CAAI,EAI1D,OAHKU,EAAO,KAAK,GAASK,EAAM,OAAS,YAAY,GACjDd,EAAQ,MAAMC,EAAgB,uBAAwB,iBAAiBkC,EAAS,8CAA+CjC,EAAWH,CAAI,CAAC,EAE5I,CAAE,KAAM,eAAgB,WAAU,UAAS,SAAQ,SAAUG,EAAWH,CAAI,CAAE,CACzF,CAEA,SAAS,iBAAiB,EAAwB,EAA6E,CAC3H,IAAMU,EAAkC,CAAC,EACrCF,EAAuB,UAC3B,IAAK,IAAIG,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAG,CAE1G,GADAC,EAAQ,OAAO,gBAAgB,EAC3BU,EAAM,UAAY,UAAW,CAC7B,EAAU,UACV,QACJ,CACA,GAAIA,EAAM,UAAY,aAAc,CAChC,EAAU,WACV,QACJ,CACA,IAAMI,EAAQ,WAAWd,EAASU,EAAO,EAAI,EACzCI,IAAU,IAAA,IACVL,EAAO,KAAKK,CAAK,CAEzB,CACA,MAAO,CAAE,UAAS,QAAO,CAC7B,CAEA,SAAS,YAAY,EAAwB,EAAqD,CAC9F,IAAMsB,EAAU/C,EAAqB,KAAKU,EAAK,OAAO,EACtD,GAAIqC,IAAY,KACZ,MAAO,CAAE,KAAM,sBAAuB,MAAON,EAAmBM,EAAQ,EAAE,EAAG,IAAKA,EAAQ,KAAO,IAAA,GAAY,KAAOL,EAA0BK,EAAQ,GAAIlC,EAAWH,CAAI,EAAGC,CAAO,EAAG,SAAUE,EAAWH,CAAI,CAAE,EAErN,IAAMD,EAAQV,EAAkB,KAAKW,EAAK,OAAO,EACjD,GAAID,IAAU,KAAM,CAChBE,EAAQ,MAAMC,EAAgB,yBAA0B,+BAA+BF,EAAK,QAAQ,4EAA6EG,EAAWH,CAAI,CAAC,EACjMC,EAAQ,UAAUD,EAAK,MAAM,EAC7B,MACJ,CACA,IAAIS,EAAMV,EAAM,KAAO,IAAA,GAAY,KAAOiC,EAA0BjC,EAAM,GAAII,EAAWH,CAAI,EAAGC,CAAO,EACnGqC,EAAsC,KACtCJ,EAAqC,KACzC,IAAK,IAAIvB,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAEvG,GADAC,EAAQ,OAAO,gBAAgB,EAC3BG,EAAUO,EAAM,OAAO,IAAM,SAC7B,EAAYqB,EAA0BrB,EAAM,QAAQ,UAAU,CAAe,EAAGR,EAAWQ,CAAK,EAAGV,CAAO,OACvG,GAAIG,EAAUO,EAAM,OAAO,IAAM,MAAO,EACvCF,IAAQ,MAAQ6B,IAAa,OAAMrC,EAAQ,MAAMC,EAAgB,0BAA2B,sCAAuCC,EAAWQ,CAAK,CAAC,EACxJ,IAAM4B,EAAS,SAAStC,EAASU,CAAK,EAClC4B,EAAO,OAAS,qBAAsB,EAAWA,EAChD,EAAMA,EAAO,UACtB,MACItC,EAAQ,MAAMC,EAAgB,uBAAwB,eAAeS,EAAM,QAAQ,uDAAwDR,EAAWQ,CAAK,CAAC,EAGpK,MAAO,CAAE,KAAM,mBAAoB,MAAOoB,EAAmBhC,EAAM,EAAE,EAAG,MAAK,GAAIuC,IAAa,KAAO,CAAC,EAAI,CAAE,UAAS,EAAI,YAAW,SAAUnC,EAAWH,CAAI,CAAE,CACnK,CAEA,SAAS,eAAe,EAAwB,EAAmC,CAC/E,IAAMD,EAAQR,EAAiB,KAAKS,EAAK,OAAO,EAKhD,OAJID,IAAU,MACVE,EAAQ,MAAMC,EAAgB,wBAAyB,8BAA8BF,EAAK,QAAQ,uCAAwCG,EAAWH,CAAI,CAAC,EACnJ,CAAE,KAAM,kBAAmB,MAAO,GAAI,SAAUG,EAAWH,CAAI,CAAE,GAErE,CAAE,KAAM,kBAAmB,MAAO+B,EAAmBhC,EAAM,EAAE,EAAG,SAAUI,EAAWH,CAAI,CAAE,CACtG,CAEA,SAAS,aAAa,EAAwB,EAA2C,CACrF,IAAMD,EAAQP,EAAe,KAAKQ,EAAK,OAAO,EAC9C,GAAID,IAAU,KAGV,OAFAE,EAAQ,MAAMC,EAAgB,oCAAqC,gCAAgCF,EAAK,QAAQ,+BAAgCG,EAAWH,CAAI,CAAC,EAChKC,EAAQ,UAAUD,EAAK,MAAM,EACtB,CAAE,KAAM,0BAA2B,KAAMI,EAAUJ,EAAK,OAAO,EAAG,SAAU,CAAC,EAAG,OAAQ,CAAC,EAAG,SAAUG,EAAWH,CAAI,CAAE,EAElI,IAAMK,EAAO0B,EAAmBhC,EAAM,EAAE,EAClCyC,EAAuC,CAAC,EACxC9B,EAAkC,CAAC,EACzC,IAAK,IAAIC,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAG,CAC1GC,EAAQ,OAAO,gBAAgB,EAC/B,IAAMY,EAAUT,EAAUO,EAAM,OAAO,EACvC,GAAIE,IAAY,SACZ2B,EAAS,KAAK,cAAcvC,EAASU,CAAK,CAAC,OACxC,GAAIE,IAAY,UACnBZ,EAAQ,MAAMC,EAAgB,kCAAmC,sDAAuDC,EAAWQ,CAAK,CAAC,EACzIV,EAAQ,UAAUU,EAAM,MAAM,MAC3B,CACH,IAAMI,EAAQ,WAAWd,EAASU,EAAO,EAAK,EAC1CI,IAAU,IAAA,IACVL,EAAO,KAAKK,CAAK,CAEzB,CACJ,CAIA,OAHIyB,EAAS,SAAW,GACpBvC,EAAQ,MAAMC,EAAgB,6BAA8B,YAAYG,EAAK,+CAAgDF,EAAWH,CAAI,CAAC,EAE1I,CAAE,KAAM,0BAA2B,OAAM,WAAU,SAAQ,SAAUG,EAAWH,CAAI,CAAE,CACjG,CAEA,SAAS,cAAc,EAAwB,EAA4C,CACvF,IAAMD,EAAQN,EAAgB,KAAKO,EAAK,OAAO,EAM/C,OALID,IAAU,MACVE,EAAQ,MAAMC,EAAgB,2BAA4B,oCAAoCF,EAAK,QAAQ,yDAA0DG,EAAWH,CAAI,CAAC,EACrLC,EAAQ,UAAUD,EAAK,MAAM,EACtB,CAAE,KAAM,2BAA4B,MAAO,GAAI,IAAK,KAAM,SAAUG,EAAWH,CAAI,CAAE,GAEzF,CAAE,KAAM,2BAA4B,MAAO+B,EAAmBhC,EAAM,EAAE,EAAG,IAAKA,EAAM,KAAO,IAAA,GAAY,KAAOiC,EAA0BjC,EAAM,GAAII,EAAWH,CAAI,EAAGC,CAAO,EAAG,SAAUE,EAAWH,CAAI,CAAE,CACpN,CAGA,SAAS,SAAS,EAAwB,EAA6B,CACnE,IAAM8B,EAAO9B,EAAK,QAAQ,UAAU,CAAY,CAAC,CAAC,KAAK,EACvD,GAAIC,EAAQ,UAAUD,EAAK,MAAM,IAAM,IAAA,GAAW,MAAO,CAAE,KAAM,sBAAuB,WAAYgC,EAA0BF,EAAM3B,EAAWH,CAAI,EAAGC,CAAO,EAAG,SAAUE,EAAWH,CAAI,CAAE,EAC3L,IAAMyC,EAAyB,CAAC,EAChC,IAAK,IAAI9B,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAG,CAE1G,GADAC,EAAQ,OAAO,gBAAgB,EAC3BU,EAAM,UAAY,IAAK,SAC3B,IAAMZ,EAAQF,EAAkB,KAAKc,EAAM,OAAO,EAClD,GAAIZ,IAAU,KAAM,CACZE,EAAQ,cAAc,cAAgB,SAASA,EAAQ,MAAMC,EAAgB,wBAAyB,+BAA+BS,EAAM,QAAQ,0CAA2CR,EAAWQ,CAAK,CAAC,EACnN,QACJ,CACA,IAAM+B,EAAaV,EAA0BjC,EAAM,GAAII,EAAWQ,CAAK,EAAGV,CAAO,EAC7EA,EAAQ,cAAc,cAAgB,SAAW6B,EAAK,QAAQ,MAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,OAAS,GAAKY,EAAW,OAAS,4BAA4BzC,EAAQ,MAAMC,EAAgB,uBAAwB,yDAA0DC,EAAWQ,CAAK,CAAC,EACnR8B,EAAM,KAAK,CAAE,KAAM,gBAAiB,SAAUV,EAAmBhC,EAAM,EAAE,EAAG,aAAY,SAAUI,EAAWQ,CAAK,CAAE,CAAC,CACzH,CACA,IAAMgC,EAAU1C,EAAQ,OAAO,gBAAgB,EAG/C,OAFI0C,IAAY,IAAA,IAAaA,EAAQ,SAAW3C,EAAK,QAAU2C,EAAQ,UAAY,KAAK1C,EAAQ,OAAO,gBAAgB,EACnHA,EAAQ,cAAc,cAAgB,SAAWwC,EAAM,SAAW,GAAGxC,EAAQ,MAAMC,EAAgB,kBAAmB,gDAAiDC,EAAWH,CAAI,CAAC,EACpL,CAAE,KAAM,qBAAsB,KAAM8B,EAAK,QAAQ,MAAO,EAAE,CAAC,CAAC,KAAK,EAAG,QAAO,SAAU3B,EAAWH,CAAI,CAAE,CACjH,CAIA,SAAS,kBAAkB,EAAwB,EAAkB,MAA8C,GAA4D,CAC3K,IAAIQ,EAAuB,UACrByB,EAA4B,CAAC,EACnC,IAAK,IAAItB,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EAAGW,IAAU,IAAA,GAAW,EAAQV,EAAQ,UAAUD,EAAK,MAAM,EACvGC,EAAQ,OAAO,gBAAgB,EAC3BU,EAAM,UAAY,UAClB,EAAU,UACHA,EAAM,UAAY,aACzB,EAAU,WACFiC,EAAMjC,CAAK,GACnB,YAAYV,EAASU,EAAOsB,CAAQ,EAG5C,MAAO,CAAE,UAAS,UAAS,CAC/B,CAIA,SAAS,YAAY,EAAwB,EAAkB,EAAiC,CAC5F,IAAMT,EAAWrB,EAAWH,CAAI,EAC1Ba,EAAUnB,EAAsB,KAAKM,EAAK,OAAO,EACvD,GAAIa,IAAY,KAAM,CACdA,EAAQ,KAAO,SAAWA,EAAQ,KAAO,OACzCoB,EAAS,KAAK,CAAE,KAAMnC,EAAgBe,EAAQ,IAAK,SAAUkB,EAAmBlB,EAAQ,EAAE,EAAG,UAAS,CAAC,EAChGZ,EAAQ,cAAc,cAAgB,SAC7CA,EAAQ,MAAMC,EAAgB,yBAA0B,oBAAoBF,EAAK,QAAQ,sHAAuHwB,EAAUqB,EAAe,OAAQ7C,EAAK,OAAO,CAAC,EAElQ,MACJ,CACA,IAAM8C,EAAanD,EAAkB,KAAKK,EAAK,OAAO,EACtD,GAAI8C,IAAe,KAAM,CACrBb,EAAS,KAAK,CAAE,KAAMa,EAAW,KAAO,MAAQ,mBAAqB,wBAAyB,SAAUf,EAAmBe,EAAW,EAAE,EAAG,MAAOd,EAA0Bc,EAAW,GAAItB,EAAUvB,CAAO,EAAG,UAAS,CAAC,EACzN,MACJ,CACA,IAAM8C,EAAWnD,EAAW,KAAKI,EAAK,OAAO,GAAKH,EAAkB,KAAKG,EAAK,OAAO,EACjF+C,IAAa,KAEN9C,EAAQ,cAAc,cAAgB,SAC7CA,EAAQ,MAAMC,EAAgB,yBAA0B,oBAAoBF,EAAK,QAAQ,GAAIwB,EAAUqB,EAAe,OAAQ7C,EAAK,OAAO,CAAC,EAF3IiC,EAAS,KAAK,CAAE,KAAM,mBAAoB,SAAUF,EAAmBgB,EAAS,EAAE,EAAG,OAAQf,EAA0Be,EAAS,GAAIvB,EAAUvB,CAAO,EAAG,UAAS,CAAC,CAI1K"}
|
|
1
|
+
{"version":3,"file":"ProjectionParser.js","names":["header","pattern","eventSpecPattern","joinPattern","withPattern","childrenPattern","nestedPattern","removeWithPattern","removeViaJoinPattern","clearWithPattern","variantPattern","entersOnPattern","keywordMappingPattern","arithmeticPattern","setPattern","assignmentPattern","keywordMappings","match","line","context","DiagnosticCodes","locationOf","firstWord","name","sequence","description","autoMap","key","blocks","child","isFileDirective","keyword","parseDescription","block","validateProjectionEventScopes","variants","byName","variant","duplicate","group","entering","entry","location","includeChildren","nestedScope","events","spec","splitTopLevel","text","unescapeIdentifier","parseProjectionExpression","mappings","parentKey","withMatch","property","viaJoin","partsKey","parsed","entersOn","parts","expression","closing","extra","diagnosticText","arithmetic","assigned"],"sources":["../../../../../../Compiler/Parsing/ProjectionParser.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 {\n AutoMapMode, ChildrenSyntax, ClearWithSyntax, CompositeKeySyntax, EventSpecSyntax, FromSyntax, JoinEventSyntax, JoinSyntax, MappingKind, MappingSyntax, NestedSyntax,\n KeyPartSyntax, KeySyntax, ProjectionBlockSyntax, ProjectionEntersOnSyntax, ProjectionSyntax, ProjectionVariantSyntax,\n} from '../Syntax/Projections';\nimport { ExpressionSyntax } from '../Syntax/Expressions';\nimport { pattern } from '../Text/patterns';\nimport { parseProjectionExpression } from './ProjectionExpressionParser';\nimport { validateProjectionEventScopes } from './ProjectionEventScopeValidator';\nimport { isFileDirective } from './FileReferences';\nimport { parseDescription } from './DescriptionParser';\nimport { firstWord, splitTopLevel, unescapeIdentifier } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = pattern('^projection\\\\s+(@?[\\\\w.]+)\\\\s*(?:=>\\\\s*([\\\\w.]+))?$');\nconst eventSpecPattern = pattern('^(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst joinPattern = pattern('^join\\\\s+(@?[\\\\w.]+)\\\\s+on\\\\s+(@?[\\\\w.]+)$');\nconst withPattern = pattern('^with\\\\s+(@?[\\\\w.]+)$');\nconst childrenPattern = pattern('^children\\\\s+(@?[\\\\w.]+)\\\\s+identified\\\\s+by\\\\s+(.+)$');\nconst nestedPattern = pattern('^nested\\\\s+(@?[\\\\w.]+)$');\nconst removeWithPattern = pattern('^remove\\\\s+with\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst removeViaJoinPattern = pattern('^remove\\\\s+via\\\\s+join\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst clearWithPattern = pattern('^clear\\\\s+with\\\\s+(@?[\\\\w.]+)$');\nconst variantPattern = pattern('^variant\\\\s+(@?[\\\\w.]+)\\\\s*$');\nconst entersOnPattern = pattern('^enters\\\\s+on\\\\s+(@?[\\\\w.]+)(?:\\\\s+key\\\\s+(.+))?$');\nconst keywordMappingPattern = pattern('^(increment|decrement|count|clear)\\\\s+(@?[$\\\\w.]+)$');\nconst arithmeticPattern = pattern('^(add|subtract)\\\\s+(@?[$\\\\w.]+)\\\\s+by\\\\s+(.+?)(?:\\\\s+\\\\*\\\\s+(.+))?$');\nconst setPattern = pattern('^set\\\\s+(@?[$\\\\w.]+)\\\\s+(?:=|to)\\\\s+(.+)$');\nconst assignmentPattern = pattern('^(@?[$\\\\w.@]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst keywordMappings: Record<string, MappingKind> = {\n increment: 'IncrementMappingSyntax',\n decrement: 'DecrementMappingSyntax',\n clear: 'ClearMappingSyntax',\n count: 'CountMappingSyntax',\n};\n\n// Reads a projection's structure: its name, the read model it builds, the events each block consumes, the\n// properties each mapping sets and where automap is turned on or off. Keys, and where a mapping takes its\n// value from, are recognized and skipped.\nexport function parseProjection(context: ParserContext, line: SourceLine): ProjectionSyntax {\n const match = header.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionDeclaration, `Invalid projection declaration '${line.content}' - expected 'projection <Name> [=> <ReadModel>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name: firstWord(line.content), readModel: null, sequence: null, autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const name = match[1];\n let sequence: string | null = null;\n let description: string | null = null;\n let autoMap: AutoMapMode = 'Inherit';\n let key: KeySyntax | null = null;\n const blocks: ProjectionBlockSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (isFileDirective(child)) {\n continue;\n }\n const keyword = firstWord(child.content);\n if (keyword === 'description') {\n description = parseDescription(context, child, description, `Projection '${name}'`);\n } else if (keyword === 'sequence') {\n sequence = child.content.substring('sequence'.length).trim();\n } else if (keyword === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (keyword === 'key') {\n key = parseKey(context, child);\n } else if (keyword === 'variant') {\n blocks.push(parseVariant(context, child));\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n reportVariantConflicts(context, blocks, name);\n validateProjectionEventScopes(context, name, blocks);\n if (blocks.length === 0) {\n context.error(DiagnosticCodes.EmptyProjection, `Projection '${name}' must contain at least one directive`, locationOf(line));\n }\n return { kind: 'ProjectionSyntax', sourceOptions: context.sourceOptions, name, readModel: match[2] ?? null, sequence, autoMap, key, blocks, description, location: locationOf(line) };\n}\n\nfunction reportVariantConflicts(context: ParserContext, blocks: readonly ProjectionBlockSyntax[], name: string): void {\n // Grouped by name in the order each name first appears, as the C# parser reports them.\n const variants = blocks.filter((block): block is ProjectionVariantSyntax => block.kind === 'ProjectionVariantSyntax');\n const byName = new Map<string, ProjectionVariantSyntax[]>();\n variants.forEach(variant => byName.set(variant.name, [...(byName.get(variant.name) ?? []), variant]));\n for (const duplicate of [...byName.values()].flatMap(group => group.slice(1))) {\n context.error(DiagnosticCodes.DuplicateProjectionVariant, `Duplicate variant '${duplicate.name}' - a variant name is declared once`, duplicate.location);\n }\n const entering = new Set<string>();\n for (const entry of blocks.flatMap(block => block.kind === 'ProjectionVariantSyntax' ? block.entersOn : [])) {\n if (entry.event.length > 0 && entering.has(entry.event)) {\n context.error(DiagnosticCodes.DuplicateVariantEnteringEvent, `Entering event '${entry.event}' is claimed more than once in projection '${name}'`, entry.location);\n }\n entering.add(entry.event);\n }\n}\n\nfunction parseBlock(context: ParserContext, line: SourceLine, nestedScope: boolean): ProjectionBlockSyntax | undefined {\n const location = locationOf(line);\n switch (firstWord(line.content)) {\n case 'from':\n return parseFrom(context, line);\n case 'every': {\n let includeChildren = true;\n const { autoMap, mappings } = parseMappingBlock(context, line, child => {\n if (child.content !== 'exclude children') {\n return false;\n }\n includeChildren = false;\n return true;\n });\n return { kind: 'EverySyntax', includeChildren, autoMap, mappings, location };\n }\n case 'all': {\n const { autoMap, mappings } = parseMappingBlock(context, line);\n return { kind: 'AllSyntax', autoMap, mappings, location };\n }\n case 'join':\n return parseJoin(context, line);\n case 'children':\n return parseChildren(context, line);\n case 'nested':\n return parseNested(context, line);\n case 'remove':\n return parseRemove(context, line);\n case 'clear':\n if (!nestedScope) {\n context.error(DiagnosticCodes.ClearWithOutsideNestedBlock, '\\'clear with\\' is only valid inside a nested block', location);\n }\n return parseClearWith(context, line);\n default:\n context.error(DiagnosticCodes.UnknownProjectionDirective, `Unexpected '${firstWord(line.content)}' in projection body`, location);\n context.skipBlock(line.indent);\n return undefined;\n }\n}\n\nfunction parseFrom(context: ParserContext, line: SourceLine): FromSyntax {\n const events: EventSpecSyntax[] = [];\n for (const spec of splitTopLevel(line.content.substring('from'.length), ',')) {\n const text = spec.trim();\n if (text.length === 0) {\n context.error(DiagnosticCodes.FromWithoutEvent, 'Expected an event type after \\'from\\'', locationOf(line));\n continue;\n }\n const match = eventSpecPattern.exec(text);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventReference, `Invalid event reference '${text}'`, locationOf(line));\n continue;\n }\n events.push({ kind: 'EventSpecSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) });\n }\n const mappings: MappingSyntax[] = [];\n let key: KeySyntax | null = null;\n let parentKey: ExpressionSyntax | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'key') key = parseKey(context, child);\n else if (keyword === 'parent') parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n else pushMapping(context, child, mappings);\n }\n return { kind: 'FromSyntax', events, key, parentKey, mappings, location: locationOf(line) };\n}\n\nfunction parseJoin(context: ParserContext, line: SourceLine): JoinSyntax {\n const match = joinPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidJoinDeclaration, `Invalid join declaration '${line.content}' - expected 'join <property> on <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'JoinSyntax', property: '', on: '', events: [], location: locationOf(line) };\n }\n const events: JoinEventSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const withMatch = withPattern.exec(child.content);\n if (withMatch === null) {\n context.error(DiagnosticCodes.JoinWithoutEvent, `Expected 'with <EventType>' in join block, got '${child.content}'`, locationOf(child));\n context.skipBlock(child.indent);\n continue;\n }\n const { autoMap, mappings } = parseMappingBlock(context, child);\n events.push({ kind: 'JoinEventSyntax', event: unescapeIdentifier(withMatch[1]), autoMap, mappings, location: locationOf(child) });\n }\n return { kind: 'JoinSyntax', property: unescapeIdentifier(match[1]), on: unescapeIdentifier(match[2]), events, location: locationOf(line) };\n}\n\nfunction parseChildren(context: ParserContext, line: SourceLine): ChildrenSyntax {\n const match = childrenPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidChildrenDeclaration, `Invalid children declaration '${line.content}' - expected 'children <collection> identified by <key>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ChildrenSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const { autoMap, blocks } = parseChildBlocks(context, line);\n return { kind: 'ChildrenSyntax', property: unescapeIdentifier(match[1]), identifiedBy: parseProjectionExpression(match[2], locationOf(line), context), autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseNested(context: ParserContext, line: SourceLine): NestedSyntax {\n const match = nestedPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidNestedDeclaration, `Invalid nested declaration '${line.content}' - expected 'nested <property>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'NestedSyntax', property: '', autoMap: 'Inherit', blocks: [], location: locationOf(line) };\n }\n const property = unescapeIdentifier(match[1]);\n const { autoMap, blocks } = parseChildBlocks(context, line);\n if (!blocks.some(block => block.kind === 'FromSyntax')) {\n context.error(DiagnosticCodes.NestedBlockWithoutFrom, `Nested block '${property}' must contain at least one 'from' directive`, locationOf(line));\n }\n return { kind: 'NestedSyntax', property, autoMap, blocks, location: locationOf(line) };\n}\n\nfunction parseChildBlocks(context: ParserContext, line: SourceLine): { autoMap: AutoMapMode; blocks: ProjectionBlockSyntax[] } {\n const blocks: ProjectionBlockSyntax[] = [];\n let autoMap: AutoMapMode = 'Inherit';\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n continue;\n }\n if (child.content === 'no automap') {\n autoMap = 'Disabled';\n continue;\n }\n const block = parseBlock(context, child, true);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n return { autoMap, blocks };\n}\n\nfunction parseRemove(context: ParserContext, line: SourceLine): ProjectionBlockSyntax | undefined {\n const viaJoin = removeViaJoinPattern.exec(line.content);\n if (viaJoin !== null) {\n return { kind: 'RemoveViaJoinSyntax', event: unescapeIdentifier(viaJoin[1]), key: viaJoin[2] === undefined ? null : parseProjectionExpression(viaJoin[2], locationOf(line), context), location: locationOf(line) };\n }\n const match = removeWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidRemoveDeclaration, `Invalid remove declaration '${line.content}' - expected 'remove with <EventType>' or 'remove via join on <EventType>'`, locationOf(line));\n context.skipBlock(line.indent);\n return undefined;\n }\n let key = match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context);\n let partsKey: CompositeKeySyntax | null = null;\n let parentKey: ExpressionSyntax | null = null;\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (firstWord(child.content) === 'parent') {\n parentKey = parseProjectionExpression(child.content.substring('parent'.length), locationOf(child), context);\n } else if (firstWord(child.content) === 'key') {\n if (key !== null || partsKey !== null) context.error(DiagnosticCodes.InvalidReadModelKeyLookup, 'A removal can only declare one key.', locationOf(child));\n const parsed = parseKey(context, child);\n if (parsed.kind === 'CompositeKeySyntax') partsKey = parsed;\n else key = parsed.expression;\n } else {\n context.error(DiagnosticCodes.UnknownRemoveDirective, `Unexpected '${child.content}' in remove block - only 'parent' or 'key' is allowed`, locationOf(child));\n }\n }\n return { kind: 'RemoveWithSyntax', event: unescapeIdentifier(match[1]), key, ...(partsKey === null ? {} : { partsKey }), parentKey, location: locationOf(line) };\n}\n\nfunction parseClearWith(context: ParserContext, line: SourceLine): ClearWithSyntax {\n const match = clearWithPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidClearDeclaration, `Invalid clear declaration '${line.content}' - expected 'clear with <EventType>'`, locationOf(line));\n return { kind: 'ClearWithSyntax', event: '', location: locationOf(line) };\n }\n return { kind: 'ClearWithSyntax', event: unescapeIdentifier(match[1]), location: locationOf(line) };\n}\n\nfunction parseVariant(context: ParserContext, line: SourceLine): ProjectionVariantSyntax {\n const match = variantPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidProjectionVariantDeclaration, `Invalid variant declaration '${line.content}' - expected 'variant <Name>'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionVariantSyntax', name: firstWord(line.content), entersOn: [], blocks: [], location: locationOf(line) };\n }\n const name = unescapeIdentifier(match[1]);\n const entersOn: ProjectionEntersOnSyntax[] = [];\n const blocks: ProjectionBlockSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(child.content);\n if (keyword === 'enters') {\n entersOn.push(parseEntersOn(context, child));\n } else if (keyword === 'variant') {\n context.error(DiagnosticCodes.NestedProjectionVariantNotAllowed, 'A variant cannot be declared inside another variant', locationOf(child));\n context.skipBlock(child.indent);\n } else {\n const block = parseBlock(context, child, false);\n if (block !== undefined) {\n blocks.push(block);\n }\n }\n }\n if (entersOn.length === 0) {\n context.error(DiagnosticCodes.VariantRequiresEnteringEvent, `Variant '${name}' must declare at least one 'enters on' event`, locationOf(line));\n }\n return { kind: 'ProjectionVariantSyntax', name, entersOn, blocks, location: locationOf(line) };\n}\n\nfunction parseEntersOn(context: ParserContext, line: SourceLine): ProjectionEntersOnSyntax {\n const match = entersOnPattern.exec(line.content);\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEntersOnDeclaration, `Invalid 'enters on' declaration '${line.content}' - expected 'enters on <EventType> [key <expression>]'`, locationOf(line));\n context.skipBlock(line.indent);\n return { kind: 'ProjectionEntersOnSyntax', event: '', key: null, location: locationOf(line) };\n }\n return { kind: 'ProjectionEntersOnSyntax', event: unescapeIdentifier(match[1]), key: match[2] === undefined ? null : parseProjectionExpression(match[2], locationOf(line), context), location: locationOf(line) };\n}\n\n// A key with a body is a composite key: its parts, then a closing '}' at the key's own indent.\nfunction parseKey(context: ParserContext, line: SourceLine): KeySyntax {\n const text = line.content.substring('key'.length).trim();\n if (context.peekChild(line.indent) === undefined) return { kind: 'ExpressionKeySyntax', expression: parseProjectionExpression(text, locationOf(line), context), location: locationOf(line) };\n const parts: KeyPartSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === '}') continue;\n const match = assignmentPattern.exec(child.content);\n if (match === null) {\n if (context.sourceOptions.numericMode === 'exact') context.error(DiagnosticCodes.InvalidCompositeKeyPart, `Invalid composite key part '${child.content}' - expected '<property> = <expression>'`, locationOf(child));\n continue;\n }\n const expression = parseProjectionExpression(match[2], locationOf(child), context);\n if (context.sourceOptions.numericMode === 'exact' && text.replace(/\\{$/, '').trim().length > 0 && expression.kind === 'TemplateExpressionSyntax') context.error(DiagnosticCodes.TemplateInCompositeKey, 'Template expressions are not allowed in composite keys', locationOf(child));\n parts.push({ kind: 'KeyPartSyntax', property: unescapeIdentifier(match[1]), expression, location: locationOf(child) });\n }\n const closing = context.reader.peekSignificant();\n if (closing !== undefined && closing.indent === line.indent && closing.content === '}') context.reader.takeSignificant();\n if (context.sourceOptions.numericMode === 'exact' && parts.length === 0) context.error(DiagnosticCodes.EmptyCompositeKey, 'Composite keys must contain at least one part', locationOf(line));\n return { kind: 'CompositeKeySyntax', type: text.replace(/\\{$/, '').trim(), parts, location: locationOf(line) };\n}\n\n// Mapping lines carry no body, so a mapping block is its direct children. The last automap setting wins;\n// a line 'extra' claims is not a mapping.\nfunction parseMappingBlock(context: ParserContext, line: SourceLine, extra: (child: SourceLine) => boolean = () => false): { autoMap: AutoMapMode; mappings: MappingSyntax[] } {\n let autoMap: AutoMapMode = 'Inherit';\n const mappings: MappingSyntax[] = [];\n for (let child = context.peekChild(line.indent); child !== undefined; child = context.peekChild(line.indent)) {\n context.reader.takeSignificant();\n if (child.content === 'automap') {\n autoMap = 'Enabled';\n } else if (child.content === 'no automap') {\n autoMap = 'Disabled';\n } else if (!extra(child)) {\n pushMapping(context, child, mappings);\n }\n }\n return { autoMap, mappings };\n}\n\n// The property one mapping line sets, and how - the port of the C# ParseMappingLine. Exact reports\n// malformed mappings; Legacy keeps the existing skip behavior.\nfunction pushMapping(context: ParserContext, line: SourceLine, mappings: MappingSyntax[]): void {\n const location = locationOf(line);\n const keyword = keywordMappingPattern.exec(line.content);\n if (keyword !== null) {\n if (keyword[1] !== 'clear' || keyword[2] !== 'with') {\n mappings.push({ kind: keywordMappings[keyword[1]], property: unescapeIdentifier(keyword[2]), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}' - 'clear with' is a block directive and needs an event type; to clear a property named 'with', write 'clear @with'`, location, diagnosticText('text', line.content));\n }\n return;\n }\n const arithmetic = arithmeticPattern.exec(line.content);\n if (arithmetic !== null) {\n mappings.push({ kind: arithmetic[1] === 'add' ? 'AddMappingSyntax' : 'SubtractMappingSyntax', property: unescapeIdentifier(arithmetic[2]), value: parseProjectionExpression(arithmetic[3], location, context), ...(arithmetic[4] === undefined ? {} : { factor: parseProjectionExpression(arithmetic[4], location, context) }), location });\n return;\n }\n const assigned = setPattern.exec(line.content) ?? assignmentPattern.exec(line.content);\n if (assigned !== null) {\n mappings.push({ kind: 'SetMappingSyntax', property: unescapeIdentifier(assigned[1]), source: parseProjectionExpression(assigned[2], location, context), location });\n } else if (context.sourceOptions.numericMode === 'exact') {\n context.error(DiagnosticCodes.InvalidProjectionMapping, `Invalid mapping '${line.content}'`, location, diagnosticText('text', line.content));\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i}from"./SourceLine.js";import{parseMappingSource as a}from"./ExpressionParser.js";import{firstWord as o}from"./LineText.js";import{parseTypeRef as s}from"./PropertyLineParser.js";import{parseFencedText as c}from"./CodeBlockParser.js";import{parseDescription as l}from"./DescriptionParser.js";import{parseGuardedAction as u}from"./GuardedActionParser.js";import{collectInputUses as d}from"./InputUses.js";import{isFileDirective as f}from"./FileReferences.js";import{isValidTemplateVersionRange as p,parseBlueprintReference as m,startsBlueprintReference as h}from"./TemplateReferenceText.js";import{parseFromClause as g}from"./UiBindingParser.js";const _=`(?:"(${t})"|(\\$strings\\.\\w+(?:\\.\\w+)*))`,v=r(`^screen\\s+([A-Za-z_]\\w*)$`),y=r(`^data\\s+([\\w.]+(?:\\[\\])?)\\s+via\\s+query\\s+(\\w+(?:\\.\\w+)*)(?:\\s+by\\s+(\\w+))?$`),b=r(`^action\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),x=r(`^label\\s+${_}$`),S=r(`^action\\s+${_}$`),C=r(`^navigate\\s+to\\s+(\\w+(?:\\.\\w+)*)(?:\\s+by\\s+(\\w+))?$`),w=r(`^route\\s+${_}$`),T=r(`^outlet\\s+([A-Za-z_]\\w*)$`),E=r(`^contribute\\s+to\\s+([A-Za-z_]\\w*)(?:\\s+order\\s+(-?\\d+))?$`),D=r(`^parameter\\s+([A-Za-z_]\\w*)\\s+from\\s+(.+)$`),O=r(`^component\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)\\s+([A-Za-z_]\\w*)$`),k=r(`^id\\s+(?:"(${t})"|(\\S+))$`),A=r(`^property\\s+([\\w.]+)\\s+from\\s+(.+)$`),j=r(`^property\\s+([\\w.]+)\\s*=\\s+(.+)$`),M=r(`^exposes\\s+([A-Za-z_]\\w*)\\s+from\\s+(.+)$`),N=r(`^presentation\\s+([A-Za-z_]\\w*)\\s+${_}$`),P=r(`^item\\s+([A-Za-z_]\\w*)\\s+(action|navigate|dialog)(?:\\s+to)?\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),F=r(`^button\\s+(?:"(${t})"|([A-Za-z_][\\w-]*))(?:\\s+(.*))?$`),I=new RegExp(r(`\\s*(title|slice|emphasis|icon)\\s+(?:"(${t})"|(\\$strings\\.\\w+(?:\\.\\w+)*)|([A-Za-z_][\\w.-]*))(?=\\s|$)`).source,`uy`),L=r(`^[A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*$`),R=r(`^[a-z_]\\w*$`),z=r(`^title\\s+${_}$`),B=r(`^column\\s+([\\w.]+)(?:\\s+label\\s+${_})?$`),V=r(`^on\\s+row-click\\s+(navigate\\s+to\\s+.+)$`),H=r(`^field\\s+([\\w.]+)\\s+label\\s+${_}$`),operandText=(e,t)=>e[t]===void 0?e[t+1]:n(e[t]),isInteraction=e=>[`on`,`uses`].includes(o(e.content)),isCodeLine=(e,t)=>t.content.startsWith("```")||e.languages.has(t.content);function parseScreen(t,n){let r=v.exec(n.content);r===null&&t.error(e.InvalidScreenDeclaration,`Invalid screen declaration '${n.content}' - expected 'screen <Name>'`,i(n));let a=[],s=[],c=null;for(let e=t.peekChild(n.indent);e!==void 0;e=t.peekChild(n.indent))if(t.reader.takeSignificant(),o(e.content)===`contribute`){let n=parseScreenContribution(t,e);n!==void 0&&s.push(n)}else o(e.content)===`description`?c=l(t,e,c,`Screen '${r?.[1]??``}'`):f(e)||pushDirective(t,e,a);return{kind:`ScreenSyntax`,name:r?.[1]??``,directives:a,description:c,...s.length>0?{contributions:s}:{},location:i(n)}}function parseScreenContribution(t,n){let r=E.exec(n.content);if(r===null)t.error(e.UnknownScreenDirective,`Invalid screen contribution '${n.content}' - expected 'contribute to <Point> [order <n>]'`,i(n)),t.skipBlock(n.indent);else return{kind:`ScreenContributionSyntax`,contributionPoint:r[1],order:r[2]===void 0?null:Number(r[2]),directives:parseDirectives(t,n),location:i(n)}}function pushDirective(e,t,n){let r=parseDirective(e,t);r!==void 0&&n.push(r)}function parseDirectives(e,t){let n=[];for(let r=e.peekChild(t.indent);r!==void 0;r=e.peekChild(t.indent))e.reader.takeSignificant(),pushDirective(e,r,n);return n}function parseDirective(t,n){switch(o(n.content)){case`data`:return parseData(t,n);case`action`:return parseAction(t,n);case`template`:return parseTemplateReference(t,n);case`section`:return parseSection(t,n);case`title`:return parseTitle(t,n);case`table`:return parseTable(t,n);case`summary`:return parseSummary(t,n);case`component`:return parseComponent(t,n);case`toolbar`:return parseToolbar(t,n);case`navigate`:return parseNavigate(t,n.content,n);case`on`:return d(t,n),{kind:`ScreenBehaviorSyntax`,location:i(n)};case`uses`:return d(t,n),{kind:`ScreenUsesBehaviorSyntax`,location:i(n)};default:if(isCodeLine(t,n))return parseCode(t,n);t.error(e.UnknownScreenDirective,`Unexpected '${n.content}' in screen body`,i(n)),t.skipBlock(n.indent);return}}function parseData(t,n){let r=y.exec(n.content);if(r===null)t.error(e.InvalidDataDirective,`Invalid data directive '${n.content}' - expected 'data <ReadModel> via query <Query> [by <param>]'`,i(n));else return{kind:`ScreenDataSyntax`,type:s(r[1],i(n)),query:r[2],by:r[3]??null,location:i(n)}}function parseAction(t,n){let r=S.exec(n.content);if(r!==null)return u(t,n,operandText(r,1),parseNavigate);let a=b.exec(n.content);if(a===null){t.error(e.InvalidActionDirective,`Invalid action directive '${n.content}' - expected 'action <Command>'`,i(n)),t.skipBlock(n.indent);return}let s=null,c=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=x.exec(r.content);n===null?o(r.content)===`navigate`?c=parseNavigate(t,r.content,r)??null:t.error(e.UnknownActionDirective,`Unexpected '${r.content}' in action - expected 'label "..."' or 'navigate to ...'`,i(r)):s=operandText(n,1)}return{kind:`ScreenActionSyntax`,command:a[1],label:s,navigate:c,location:i(n)}}function parseNavigate(t,n,r){let a=C.exec(n);if(a===null){t.error(e.InvalidNavigation,`Invalid navigation '${n}' - expected 'navigate to <Screen> [by <param>]'`,i(r));return}let o=[],s=null,c=null;for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent)){t.reader.takeSignificant();let r=D.exec(n.content);if(r!==null){o.push({kind:`ScreenNavigationParameterSyntax`,name:r[1],binding:g(t,r[2],i(n)),location:i(n)});continue}let a=w.exec(n.content);if(a!==null){s=operandText(a,1);continue}let l=T.exec(n.content);l===null?t.error(e.InvalidNavigation,`Unexpected '${n.content}' in navigation - expected 'route "..."', 'outlet <name>' or 'parameter <name> from <binding>'`,i(n)):c=l[1]}return{kind:`ScreenNavigateSyntax`,screen:a[1],by:a[2]??null,route:s,...c===null?{}:{outlet:c},parameters:o,location:i(r)}}function parseTemplateReference(t,n){let r=n.content.substring(8).trim(),a=null,o=null;if(h(r)){let s=m(r);s===void 0?t.error(e.UnknownLayoutDirective,`Invalid template reference '${n.content}' - expected 'template <Name>' or 'template blueprint <Blueprint> <Name> [version "<range>"]'`,i(n)):({blueprint:a,name:r,version:o}=s,o!==null&&!p(o)&&t.error(e.InvalidTemplateVersionRange,`The template version range '${o}' is not one Scene understands - use '*', an exact version or a ^, ~, >=, >, <= or < range such as "^1.2"`,i(n)))}let s=[];for(let a=t.peekChild(n.indent);a!==void 0;a=t.peekChild(n.indent))t.reader.takeSignificant(),R.test(a.content)?s.push({kind:`ScreenSlotSyntax`,name:a.content,directives:parseDirectives(t,a),location:i(a)}):(t.error(e.InvalidScreenLayoutSlot,`Expected a slot name in template '${r}', got '${a.content}'`,i(a)),t.skipBlock(a.indent));return{kind:`ScreenTemplateReferenceSyntax`,name:r,slots:s,...a===null?{}:{blueprint:a},...o===null?{}:{version:o},location:i(n)}}function parseSection(e,t){return{kind:`ScreenSectionSyntax`,name:t.content.substring(7).trim(),directives:parseDirectives(e,t),location:i(t)}}function parseTitle(t,n){let r=z.exec(n.content);return r===null?(t.error(e.InvalidTitleDirective,`Invalid title directive '${n.content}' - expected 'title "..."'`,i(n)),{kind:`ScreenTitleSyntax`,text:``,location:i(n)}):{kind:`ScreenTitleSyntax`,text:operandText(r,1),location:i(n)}}function parseTable(t,n){let r=n.content.substring(5).trim(),a=[],s=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=B.exec(r.content),c=V.exec(r.content);if(n!==null){let e=n[2]!==void 0||n[3]!==void 0;a.push({kind:`ScreenColumnSyntax`,property:n[1],label:e?operandText(n,2):null,location:i(r)})}else c===null?o(r.content)===`on`||isInteraction(r)?d(t,r):t.error(e.UnknownTableDirective,`Unexpected '${r.content}' in table - expected 'column ...', 'on row-click navigate to ...', 'on <trigger>' or 'uses <Behavior>'`,i(r)):s=parseNavigate(t,c[1],r)??null}return{kind:`ScreenTableSyntax`,target:r,columns:a,rowClick:s,location:i(n)}}function parseSummary(t,n){let r=n.content.substring(7).trim(),a=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=H.exec(r.content);n===null?t.error(e.UnknownSummaryDirective,`Unexpected '${r.content}' in summary - expected 'field <property> label "..."'`,i(r)):a.push({kind:`ScreenFieldSyntax`,property:n[1],label:operandText(n,2),location:i(r)})}return{kind:`ScreenSummarySyntax`,target:r,fields:a,location:i(n)}}function parseComponent(t,n){let r=O.exec(n.content);if(r===null){t.error(e.UnknownScreenDirective,`Invalid component directive '${n.content}' - expected 'component <Package.Component> <name>'`,i(n)),t.skipBlock(n.indent);return}let a=null,s=null,c=null,l=[],u=[],f=[],p=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent))switch(t.reader.takeSignificant(),o(r.content)){case`context`:a=parseUiContext(t,r);break;case`id`:s=parseStableId(t,r);break;case`property`:parseComponentProperty(t,r,l);break;case`icon`:c=r.content.substring(4).trim();break;case`presentation`:parsePresentationValue(t,r,f);break;case`exposes`:parseExposedValue(t,r,u);break;case`outlet`:p.push({kind:`ComponentOutletSyntax`,name:r.content.substring(6).trim(),directives:parseDirectives(t,r),location:i(r)});break;case`on`:d(t,r);break;case`uses`:d(t,r);break;default:t.error(e.UnknownScreenDirective,`Unexpected '${r.content}' in component - expected context, id, property, icon, presentation, exposes, outlet, on or uses`,i(r)),t.skipBlock(r.indent)}return{kind:`ScreenComponentSyntax`,component:r[1],name:r[2],stableId:s,context:a,properties:l,exposes:u,presentation:f,icon:c,outlets:p,location:i(n)}}function parseUiContext(e,t){return parseUiBindingValue(e,t.content.substring(7).trim(),t)}function parseComponentProperty(t,n,r){let o=A.exec(n.content);if(o!==null){r.push({kind:`ComponentPropertySyntax`,property:o[1],binding:g(t,o[2],i(n)),value:null,location:i(n)});return}let s=j.exec(n.content);s===null?t.error(e.UnknownScreenDirective,`Invalid component property '${n.content}' - expected 'property <path> from <binding>' or 'property <path> = <literal|object|array|null>'`,i(n)):r.push({kind:`ComponentPropertySyntax`,property:s[1],binding:null,value:a(s[2],i(n),t),location:i(n)})}function parseStableId(t,n){let r=k.exec(n.content);return r===null?(t.error(e.UnknownScreenDirective,`Invalid component id '${n.content}' - expected 'id "stable-id"'`,i(n)),null):operandText(r,1)}function parseExposedValue(t,n,r){let a=M.exec(n.content);a===null?t.error(e.UnknownScreenDirective,`Invalid exposed value '${n.content}' - expected 'exposes <name> from <binding>'`,i(n)):r.push({kind:`ComponentExposedValueSyntax`,name:a[1],binding:g(t,a[2],i(n)),location:i(n)})}function parsePresentationValue(t,n,r){let a=N.exec(n.content);a===null?t.error(e.UnknownScreenDirective,`Invalid presentation value '${n.content}' - expected 'presentation <key> "value"'`,i(n)):r.push({kind:`PresentationValueSyntax`,name:a[1],value:operandText(a,2),location:i(n)})}function parseToolbar(e,t){let n=t.content.substring(7).trim(),r=[],a=[];for(let n=e.peekChild(t.indent);n!==void 0;n=e.peekChild(t.indent)){if(e.reader.takeSignificant(),o(n.content)===`button`){let t=parseToolbarButton(e,n);t!==void 0&&a.push(t);continue}let t=parseToolbarItem(e,n);t!==void 0&&r.push(t)}return{kind:`ScreenToolbarSyntax`,name:n,items:r,...a.length>0?{buttons:a}:{},location:i(t)}}const U=`button <id> title "<text>" [slice <Module>.<Feature>.<Slice>] [emphasis primary|secondary|quiet] [icon <name>]`;function parseToolbarButton(t,r){let a=F.exec(r.content);if(a===null){t.error(e.InvalidToolbarButton,`Invalid toolbar button '${r.content}' - expected ${U}`,i(r)),t.skipBlock(r.indent);return}let o=a[1]===void 0?a[2]:n(a[1]),s=a[3]??``,c,l,u,d,f=!0,p=0;for(;p<s.length;){I.lastIndex=p;let a=I.exec(s);if(a===null){t.error(e.InvalidToolbarButton,`Invalid toolbar button '${r.content}' - unexpected '${s.substring(p).trim()}'; expected ${U}`,i(r)),f=!1;break}p=a.index+a[0].length;let m=a[1],h=a[2]!==void 0,g=a[3]!==void 0,_=h?n(a[2]):g?a[3]:a[4];(m===`title`?c!==void 0:m===`slice`?l!==void 0:m===`icon`?u!==void 0:d!==void 0)?t.error(e.InvalidToolbarButton,`Toolbar button '${o}' states '${m}' more than once`,i(r)):m===`title`?h||g?c=_:(t.error(e.InvalidToolbarButton,`Invalid title '${_}' on toolbar button '${o}' - expected a quoted string or a $strings.<key> token`,i(r)),f=!1):m===`slice`?!h&&!g&&L.test(_)?l=_:(t.error(e.InvalidToolbarButton,`Invalid slice '${_}' on toolbar button '${o}' - expected <Module>.<Feature>.<Slice>`,i(r)),f=!1):m===`emphasis`?!h&&!g&&[`primary`,`secondary`,`quiet`].includes(_)?d=_===`primary`?`Primary`:_===`secondary`?`Secondary`:`Quiet`:(t.error(e.InvalidToolbarButton,`Invalid emphasis '${_}' on toolbar button '${o}' - expected primary, secondary or quiet`,i(r)),f=!1):u=_}return c===void 0&&f&&t.error(e.InvalidToolbarButton,`Toolbar button '${o}' has no title - expected 'button ${o} title "<text>"'`,i(r)),t.peekChild(r.indent)!==void 0&&(t.error(e.InvalidToolbarButton,`Unexpected block under toolbar button '${o}' - a button is one line`,i(r)),t.skipBlock(r.indent)),{kind:`ToolbarButtonSyntax`,id:o,title:c??``,...l===void 0?{}:{slice:l},...d===void 0?{}:{emphasis:d},...u===void 0?{}:{icon:u},location:i(r)}}function parseToolbarItem(t,n){let r=P.exec(n.content);if(r===null){t.error(e.UnknownScreenDirective,`Invalid toolbar item '${n.content}' - expected 'item <name> action <Command>', 'item <name> navigate to <Screen>', 'item <name> dialog <DialogTemplate>' or 'button <id> title "<text>" slice <Slice>'`,i(n)),t.skipBlock(n.indent);return}let a=null,s=null,c=[],l=[];for(let e=t.peekChild(n.indent);e!==void 0;e=t.peekChild(n.indent)){t.reader.takeSignificant();let n=x.exec(e.content);if(n!==null){a=operandText(n,1);continue}let r=D.exec(e.content);r===null?o(e.content)===`icon`?s=e.content.substring(4).trim():parsePresentationValue(t,e,l):c.push({kind:`ScreenNavigationParameterSyntax`,name:r[1],binding:g(t,r[2],i(e)),location:i(e)})}let u=r[2]===`navigate`?`Navigate`:r[2]===`dialog`?`Dialog`:`Action`;return{kind:`ToolbarItemSyntax`,name:r[1],syntaxKind:u,target:r[3],label:a,icon:s,parameters:c,presentation:l,location:i(n)}}function parseUiBindingValue(e,t,n){return g(e,t,i(n))}function parseCode(t,n){let r=n.content.startsWith("```")?n.content.substring(3):n.content;if(!t.languages.has(r)){t.error(e.ExpectedCodeFence,`Expected a registered language on the opening fence, not '${n.content}'`,i(n));return}n.content.startsWith("```")||t.warning(e.LegacyInlineCodeFence,`'${r}' on its own line is deprecated - use '\`\`\`${r}' instead`,i(n));let a=c(t,r,n);return a===null?void 0:{kind:`ScreenCodeSyntax`,code:{kind:`CodeBlockSyntax`,language:r,code:a,location:i(n)},location:i(n)}}export{parseScreen};
|
|
1
|
+
import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i}from"./SourceLine.js";import{parseMappingSource as a}from"./ExpressionParser.js";import{firstWord as o}from"./LineText.js";import{parseTypeRef as s}from"./PropertyLineParser.js";import{parseAuthorize as c}from"./AuthorizeParser.js";import{parseFencedText as l}from"./CodeBlockParser.js";import{parseDescription as u}from"./DescriptionParser.js";import{parseGuardedAction as d}from"./GuardedActionParser.js";import{collectInputUses as f}from"./InputUses.js";import{isFileDirective as p}from"./FileReferences.js";import{isValidTemplateVersionRange as m,parseBlueprintReference as h,startsBlueprintReference as g}from"./TemplateReferenceText.js";import{parseFromClause as _}from"./UiBindingParser.js";const v=`(?:"(${t})"|(\\$strings\\.\\w+(?:\\.\\w+)*))`,y=r(`^screen\\s+([A-Za-z_]\\w*)$`),b=r(`^data\\s+([\\w.]+(?:\\[\\])?)\\s+via\\s+query\\s+(\\w+(?:\\.\\w+)*)(?:\\s+by\\s+(\\w+))?$`),x=r(`^action\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),S=r(`^label\\s+${v}$`),C=r(`^action\\s+${v}$`),w=r(`^navigate\\s+to\\s+(\\w+(?:\\.\\w+)*)(?:\\s+by\\s+(\\w+))?$`),T=r(`^route\\s+${v}$`),E=r(`^outlet\\s+([A-Za-z_]\\w*)$`),D=r(`^contribute\\s+to\\s+([A-Za-z_]\\w*)(?:\\s+order\\s+(-?\\d+))?$`),O=r(`^parameter\\s+([A-Za-z_]\\w*)\\s+from\\s+(.+)$`),k=r(`^component\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)\\s+([A-Za-z_]\\w*)$`),A=r(`^id\\s+(?:"(${t})"|(\\S+))$`),j=r(`^property\\s+([\\w.]+)\\s+from\\s+(.+)$`),M=r(`^property\\s+([\\w.]+)\\s*=\\s+(.+)$`),N=r(`^exposes\\s+([A-Za-z_]\\w*)\\s+from\\s+(.+)$`),P=r(`^presentation\\s+([A-Za-z_]\\w*)\\s+${v}$`),F=r(`^item\\s+([A-Za-z_]\\w*)\\s+(action|navigate|dialog)(?:\\s+to)?\\s+([A-Za-z_]\\w*(?:\\.\\w+)*)$`),I=r(`^button\\s+(?:"(${t})"|([A-Za-z_][\\w-]*))(?:\\s+(.*))?$`),L=new RegExp(r(`\\s*(title|slice|emphasis|icon)\\s+(?:"(${t})"|(\\$strings\\.\\w+(?:\\.\\w+)*)|([A-Za-z_][\\w.-]*))(?=\\s|$)`).source,`uy`),R=r(`^[A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*$`),z=r(`^[a-z_]\\w*$`),B=r(`^title\\s+${v}$`),V=r(`^column\\s+([\\w.]+)(?:\\s+label\\s+${v})?$`),H=r(`^on\\s+row-click\\s+(navigate\\s+to\\s+.+)$`),U=r(`^field\\s+([\\w.]+)\\s+label\\s+${v}$`),operandText=(e,t)=>e[t]===void 0?e[t+1]:n(e[t]),isInteraction=e=>[`on`,`uses`].includes(o(e.content)),isCodeLine=(e,t)=>t.content.startsWith("```")||e.languages.has(t.content);function parseScreen(t,n){let r=y.exec(n.content);r===null&&t.error(e.InvalidScreenDeclaration,`Invalid screen declaration '${n.content}' - expected 'screen <Name>'`,i(n));let a=[],s=[],c=null;for(let e=t.peekChild(n.indent);e!==void 0;e=t.peekChild(n.indent))if(t.reader.takeSignificant(),o(e.content)===`contribute`){let n=parseScreenContribution(t,e);n!==void 0&&s.push(n)}else o(e.content)===`description`?c=u(t,e,c,`Screen '${r?.[1]??``}'`):p(e)||pushDirective(t,e,a);return{kind:`ScreenSyntax`,name:r?.[1]??``,directives:a,description:c,...s.length>0?{contributions:s}:{},location:i(n)}}function parseScreenContribution(t,n){let r=D.exec(n.content);if(r===null)t.error(e.UnknownScreenDirective,`Invalid screen contribution '${n.content}' - expected 'contribute to <Point> [order <n>]'`,i(n)),t.skipBlock(n.indent);else return{kind:`ScreenContributionSyntax`,contributionPoint:r[1],order:r[2]===void 0?null:Number(r[2]),directives:parseDirectives(t,n),location:i(n)}}function pushDirective(e,t,n){let r=parseDirective(e,t);r!==void 0&&n.push(r)}function parseDirectives(e,t){let n=[];for(let r=e.peekChild(t.indent);r!==void 0;r=e.peekChild(t.indent))e.reader.takeSignificant(),pushDirective(e,r,n);return n}function parseDirective(t,n){switch(o(n.content)){case`data`:return parseData(t,n);case`action`:return parseAction(t,n);case`template`:return parseTemplateReference(t,n);case`section`:return parseSection(t,n);case`title`:return parseTitle(t,n);case`table`:return parseTable(t,n);case`summary`:return parseSummary(t,n);case`component`:return parseComponent(t,n);case`toolbar`:return parseToolbar(t,n);case`navigate`:return parseNavigate(t,n.content,n);case`on`:return f(t,n),{kind:`ScreenBehaviorSyntax`,location:i(n)};case`uses`:return f(t,n),{kind:`ScreenUsesBehaviorSyntax`,location:i(n)};default:if(isCodeLine(t,n))return parseCode(t,n);t.error(e.UnknownScreenDirective,`Unexpected '${n.content}' in screen body`,i(n)),t.skipBlock(n.indent);return}}function parseData(t,n){let r=b.exec(n.content);if(r===null)t.error(e.InvalidDataDirective,`Invalid data directive '${n.content}' - expected 'data <ReadModel> via query <Query> [by <param>]'`,i(n));else return{kind:`ScreenDataSyntax`,type:s(r[1],i(n)),query:r[2],by:r[3]??null,location:i(n)}}function parseAction(t,n){let r=C.exec(n.content);if(r!==null)return d(t,n,operandText(r,1),parseNavigate);let a=x.exec(n.content);if(a===null){t.error(e.InvalidActionDirective,`Invalid action directive '${n.content}' - expected 'action <Command>'`,i(n)),t.skipBlock(n.indent);return}let s=null,c=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=S.exec(r.content);n===null?o(r.content)===`navigate`?c=parseNavigate(t,r.content,r)??null:t.error(e.UnknownActionDirective,`Unexpected '${r.content}' in action - expected 'label "..."' or 'navigate to ...'`,i(r)):s=operandText(n,1)}return{kind:`ScreenActionSyntax`,command:a[1],label:s,navigate:c,location:i(n)}}function parseNavigate(t,n,r){let a=w.exec(n);if(a===null){t.error(e.InvalidNavigation,`Invalid navigation '${n}' - expected 'navigate to <Screen> [by <param>]'`,i(r));return}let o=[],s=null,c=null;for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent)){t.reader.takeSignificant();let r=O.exec(n.content);if(r!==null){o.push({kind:`ScreenNavigationParameterSyntax`,name:r[1],binding:_(t,r[2],i(n)),location:i(n)});continue}let a=T.exec(n.content);if(a!==null){s=operandText(a,1);continue}let l=E.exec(n.content);l===null?t.error(e.InvalidNavigation,`Unexpected '${n.content}' in navigation - expected 'route "..."', 'outlet <name>' or 'parameter <name> from <binding>'`,i(n)):c=l[1]}return{kind:`ScreenNavigateSyntax`,screen:a[1],by:a[2]??null,route:s,...c===null?{}:{outlet:c},parameters:o,location:i(r)}}function parseTemplateReference(t,n){let r=n.content.substring(8).trim(),a=null,o=null;if(g(r)){let s=h(r);s===void 0?t.error(e.UnknownLayoutDirective,`Invalid template reference '${n.content}' - expected 'template <Name>' or 'template blueprint <Blueprint> <Name> [version "<range>"]'`,i(n)):({blueprint:a,name:r,version:o}=s,o!==null&&!m(o)&&t.error(e.InvalidTemplateVersionRange,`The template version range '${o}' is not one Scene understands - use '*', an exact version or a ^, ~, >=, >, <= or < range such as "^1.2"`,i(n)))}let s=[];for(let a=t.peekChild(n.indent);a!==void 0;a=t.peekChild(n.indent))t.reader.takeSignificant(),z.test(a.content)?s.push({kind:`ScreenSlotSyntax`,name:a.content,directives:parseDirectives(t,a),location:i(a)}):(t.error(e.InvalidScreenLayoutSlot,`Expected a slot name in template '${r}', got '${a.content}'`,i(a)),t.skipBlock(a.indent));return{kind:`ScreenTemplateReferenceSyntax`,name:r,slots:s,...a===null?{}:{blueprint:a},...o===null?{}:{version:o},location:i(n)}}function parseSection(e,t){return{kind:`ScreenSectionSyntax`,name:t.content.substring(7).trim(),directives:parseDirectives(e,t),location:i(t)}}function parseTitle(t,n){let r=B.exec(n.content);return r===null?(t.error(e.InvalidTitleDirective,`Invalid title directive '${n.content}' - expected 'title "..."'`,i(n)),{kind:`ScreenTitleSyntax`,text:``,location:i(n)}):{kind:`ScreenTitleSyntax`,text:operandText(r,1),location:i(n)}}function parseTable(t,n){let r=n.content.substring(5).trim(),a=[],s=null;for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=V.exec(r.content),c=H.exec(r.content);if(n!==null){let e=n[2]!==void 0||n[3]!==void 0;a.push({kind:`ScreenColumnSyntax`,property:n[1],label:e?operandText(n,2):null,location:i(r)})}else c===null?o(r.content)===`on`||isInteraction(r)?f(t,r):t.error(e.UnknownTableDirective,`Unexpected '${r.content}' in table - expected 'column ...', 'on row-click navigate to ...', 'on <trigger>' or 'uses <Behavior>'`,i(r)):s=parseNavigate(t,c[1],r)??null}return{kind:`ScreenTableSyntax`,target:r,columns:a,rowClick:s,location:i(n)}}function parseSummary(t,n){let r=n.content.substring(7).trim(),a=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent)){t.reader.takeSignificant();let n=U.exec(r.content);n===null?t.error(e.UnknownSummaryDirective,`Unexpected '${r.content}' in summary - expected 'field <property> label "..."'`,i(r)):a.push({kind:`ScreenFieldSyntax`,property:n[1],label:operandText(n,2),location:i(r)})}return{kind:`ScreenSummarySyntax`,target:r,fields:a,location:i(n)}}function parseComponent(t,n){let r=k.exec(n.content);if(r===null){t.error(e.UnknownScreenDirective,`Invalid component directive '${n.content}' - expected 'component <Package.Component> <name>'`,i(n)),t.skipBlock(n.indent);return}let a=null,s=null,c=null,l=[],u=[],d=[],p=[];for(let r=t.peekChild(n.indent);r!==void 0;r=t.peekChild(n.indent))switch(t.reader.takeSignificant(),o(r.content)){case`context`:a=parseUiContext(t,r);break;case`id`:s=parseStableId(t,r);break;case`property`:parseComponentProperty(t,r,l);break;case`icon`:c=r.content.substring(4).trim();break;case`presentation`:parsePresentationValue(t,r,d);break;case`exposes`:parseExposedValue(t,r,u);break;case`outlet`:p.push({kind:`ComponentOutletSyntax`,name:r.content.substring(6).trim(),directives:parseDirectives(t,r),location:i(r)});break;case`on`:f(t,r);break;case`uses`:f(t,r);break;default:t.error(e.UnknownScreenDirective,`Unexpected '${r.content}' in component - expected context, id, property, icon, presentation, exposes, outlet, on or uses`,i(r)),t.skipBlock(r.indent)}return{kind:`ScreenComponentSyntax`,component:r[1],name:r[2],stableId:s,context:a,properties:l,exposes:u,presentation:d,icon:c,outlets:p,location:i(n)}}function parseUiContext(e,t){return parseUiBindingValue(e,t.content.substring(7).trim(),t)}function parseComponentProperty(t,n,r){let o=j.exec(n.content);if(o!==null){r.push({kind:`ComponentPropertySyntax`,property:o[1],binding:_(t,o[2],i(n)),value:null,location:i(n)});return}let s=M.exec(n.content);s===null?t.error(e.UnknownScreenDirective,`Invalid component property '${n.content}' - expected 'property <path> from <binding>' or 'property <path> = <literal|object|array|null>'`,i(n)):r.push({kind:`ComponentPropertySyntax`,property:s[1],binding:null,value:a(s[2],i(n),t),location:i(n)})}function parseStableId(t,n){let r=A.exec(n.content);return r===null?(t.error(e.UnknownScreenDirective,`Invalid component id '${n.content}' - expected 'id "stable-id"'`,i(n)),null):operandText(r,1)}function parseExposedValue(t,n,r){let a=N.exec(n.content);a===null?t.error(e.UnknownScreenDirective,`Invalid exposed value '${n.content}' - expected 'exposes <name> from <binding>'`,i(n)):r.push({kind:`ComponentExposedValueSyntax`,name:a[1],binding:_(t,a[2],i(n)),location:i(n)})}function parsePresentationValue(t,n,r){let a=P.exec(n.content);a===null?t.error(e.UnknownScreenDirective,`Invalid presentation value '${n.content}' - expected 'presentation <key> "value"'`,i(n)):r.push({kind:`PresentationValueSyntax`,name:a[1],value:operandText(a,2),location:i(n)})}function parseToolbar(e,t){let n=t.content.substring(7).trim(),r=[],a=[];for(let n=e.peekChild(t.indent);n!==void 0;n=e.peekChild(t.indent)){if(e.reader.takeSignificant(),o(n.content)===`button`){let t=parseToolbarButton(e,n);t!==void 0&&a.push(t);continue}let t=parseToolbarItem(e,n);t!==void 0&&r.push(t)}return{kind:`ScreenToolbarSyntax`,name:n,items:r,...a.length>0?{buttons:a}:{},location:i(t)}}const W=`button <id> title "<text>" [slice <Module>.<Feature>.<Slice>] [emphasis primary|secondary|quiet] [icon <name>]`;function parseToolbarButton(t,r){let a=I.exec(r.content);if(a===null){t.error(e.InvalidToolbarButton,`Invalid toolbar button '${r.content}' - expected ${W}`,i(r)),t.skipBlock(r.indent);return}let s=a[1]===void 0?a[2]:n(a[1]),l=a[3]??``,u,d,f,p,m=!0,h=0;for(;h<l.length;){L.lastIndex=h;let a=L.exec(l);if(a===null){t.error(e.InvalidToolbarButton,`Invalid toolbar button '${r.content}' - unexpected '${l.substring(h).trim()}'; expected ${W}`,i(r)),m=!1;break}h=a.index+a[0].length;let o=a[1],c=a[2]!==void 0,g=a[3]!==void 0,_=c?n(a[2]):g?a[3]:a[4];(o===`title`?u!==void 0:o===`slice`?d!==void 0:o===`icon`?f!==void 0:p!==void 0)?t.error(e.InvalidToolbarButton,`Toolbar button '${s}' states '${o}' more than once`,i(r)):o===`title`?c||g?u=_:(t.error(e.InvalidToolbarButton,`Invalid title '${_}' on toolbar button '${s}' - expected a quoted string or a $strings.<key> token`,i(r)),m=!1):o===`slice`?!c&&!g&&R.test(_)?d=_:(t.error(e.InvalidToolbarButton,`Invalid slice '${_}' on toolbar button '${s}' - expected <Module>.<Feature>.<Slice>`,i(r)),m=!1):o===`emphasis`?!c&&!g&&[`primary`,`secondary`,`quiet`].includes(_)?p=_===`primary`?`Primary`:_===`secondary`?`Secondary`:`Quiet`:(t.error(e.InvalidToolbarButton,`Invalid emphasis '${_}' on toolbar button '${s}' - expected primary, secondary or quiet`,i(r)),m=!1):f=_}u===void 0&&m&&t.error(e.InvalidToolbarButton,`Toolbar button '${s}' has no title - expected 'button ${s} title "<text>"'`,i(r));let g=null;for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent))t.reader.takeSignificant(),o(n.content)===`authorize`&&g===null?g=c(t,n):(t.error(e.InvalidToolbarButton,`Unexpected '${n.content}' under toolbar button '${s}' - a button takes one 'authorize' line and nothing else`,i(n)),t.skipBlock(n.indent));return{kind:`ToolbarButtonSyntax`,id:s,title:u??``,...d===void 0?{}:{slice:d},...p===void 0?{}:{emphasis:p},...f===void 0?{}:{icon:f},...g===null?{}:{authorize:g},location:i(r)}}function parseToolbarItem(t,n){let r=F.exec(n.content);if(r===null){t.error(e.UnknownScreenDirective,`Invalid toolbar item '${n.content}' - expected 'item <name> action <Command>', 'item <name> navigate to <Screen>', 'item <name> dialog <DialogTemplate>' or 'button <id> title "<text>" slice <Slice>'`,i(n)),t.skipBlock(n.indent);return}let a=null,s=null,c=[],l=[];for(let e=t.peekChild(n.indent);e!==void 0;e=t.peekChild(n.indent)){t.reader.takeSignificant();let n=S.exec(e.content);if(n!==null){a=operandText(n,1);continue}let r=O.exec(e.content);r===null?o(e.content)===`icon`?s=e.content.substring(4).trim():parsePresentationValue(t,e,l):c.push({kind:`ScreenNavigationParameterSyntax`,name:r[1],binding:_(t,r[2],i(e)),location:i(e)})}let u=r[2]===`navigate`?`Navigate`:r[2]===`dialog`?`Dialog`:`Action`;return{kind:`ToolbarItemSyntax`,name:r[1],syntaxKind:u,target:r[3],label:a,icon:s,parameters:c,presentation:l,location:i(n)}}function parseUiBindingValue(e,t,n){return _(e,t,i(n))}function parseCode(t,n){let r=n.content.startsWith("```")?n.content.substring(3):n.content;if(!t.languages.has(r)){t.error(e.ExpectedCodeFence,`Expected a registered language on the opening fence, not '${n.content}'`,i(n));return}n.content.startsWith("```")||t.warning(e.LegacyInlineCodeFence,`'${r}' on its own line is deprecated - use '\`\`\`${r}' instead`,i(n));let a=l(t,r,n);return a===null?void 0:{kind:`ScreenCodeSyntax`,code:{kind:`CodeBlockSyntax`,language:r,code:a,location:i(n)},location:i(n)}}export{parseScreen};
|
|
2
2
|
//# sourceMappingURL=ScreenParser.js.map
|