@cratis/screenplay-language 5.3.2 → 5.4.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.
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{validateHandlerContracts as t}from"./CommandHandlerValidator.js";import{parseCondition as n}from"./ConditionParser.js";import{parseCommandStream as r}from"./EventSourceParser.js";import{pattern as i}from"../Text/patterns.js";import{sourceStreamPattern as a}from"../Text/SourceStreamNames.js";import{stringBodyPattern as o,unescapeString as s}from"../Text/StringLiteral.js";import{combineAuthorize as c,parseAuthorize as l}from"./AuthorizeParser.js";import{parseCommandResponse as u,scalarResponsePattern as d}from"./CommandResponseParser.js";import{parseDescription as f}from"./DescriptionParser.js";import{parseDocumentation as p}from"./DocumentationParser.js";import{isCode as m,isFile as h,parseCode as g,parseFile as _,parseHandler as v,parseImplementationWrapper as y}from"./ImplementationParser.js";import{parseMappingSource as b}from"./ExpressionParser.js";import{firstWord as x}from"./LineText.js";import{ParserContext as S}from"./ParserContext.js";import{matchSubject as C,validateMatchOperand as w}from"./MatchOperandValidation.js";import{isReactionIdentityLine as T,misplacedReactionIdentity as E}from"./ReactionIdentityParser.js";import{commandReadSources as D}from"./CommandReadSources.js";import{dependencySources as O}from"../Syntax/DependencySources.js";import{captureConcurrency as k}from"./DependencySourceParser.js";import{parseReads as A}from"./ReadsParser.js";import{parseProduces as j}from"./ProducesParser.js";import{reportInvalidModifierOrder as M,reportLegacyOptionalSuffix as N,tryParseProperty as P}from"./PropertyLineParser.js";import{locationOf as F}from"./SourceLine.js";import{isFileDirectiveAmongProperties as I}from"./FileReferences.js";const ee=i(`^command\\s+([A-Za-z_]\\w*)$`),te=a(`^stream\\s+[A-Za-z_]\\w*\\.[A-Za-z_]\\w*$`),L=i(`^calendar\\s+(?:"|from\\s+\\$context\\.)`),R=i(`^calendar\\s+(?:"(${o})"|from\\s+\\$context\\.([A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*))$`),z=i(`\\bseverity\\s+(\\S+)$`),B=i(`\\bmessage\\s+(?:"(${o})"|(\\$strings\\.\\S*))$`),V=i(`^([\\w.]+)\\s+(.+)$`),H=i(`^(?:(not empty|matches|not contains|contains|starts with|ends with|max|min|rule)(?:\\s+|$)|(length ==|decimals <=|all >=|all >|>=|<=|==|!=|>|<)\\s*)(.*)$`),U=a(`^[A-Za-z_]\\w*$`),W=i(`^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 S(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(n,i,a,o){let m=ee.exec(i.content)?.[1]??``;m===``&&n.error(e.InvalidCommandDeclaration,`Invalid command declaration '${i.content}' - expected 'command <Name>'`,F(i));let h=[],g=[],_,y=[],b=[],S=[],C=[],w,N=null,I=null,z=null,B=!1,V=null,H=[],U=null,G=[],K=null;for(let t=n.peekChild(i.indent);t!==void 0;t=n.peekChild(i.indent)){n.reader.takeSignificant();let i=x(t.content),o=P(t);if(i===`calendar`&&L.test(t.content)){let r=R.exec(t.content);K!==null||r===null?n.error(e.InvalidCommandCalendar,`A command declares at most one 'calendar "<id>"' or 'calendar from $context.<member>'.`,F(t)):K={kind:`CommandCalendarSyntax`,id:r[1]===void 0?null:s(r[1]),contextMember:r[2]??null,location:F(t)}}else if(o!==void 0&&(J.has(i)||i===`validate`&&t.content!==`validate csharp`))_=addProperty(n,h,o,m,t,_);else if(i===`returns`){let e=d.exec(t.content);e!==null&&!e[1].startsWith(`@`)&&o!==void 0?a===void 0?(h.push(o),g.push({line:t,candidate:o,response:null})):a.has(o.type.name)?g.push({line:t,candidate:null,response:u(n,t)}):_=addProperty(n,h,o,m,t,_):o===void 0?M(n,t)?n.skipBlock(t.indent):g.push({line:t,candidate:null,response:u(n,t)}):_=addProperty(n,h,o,m,t,_)}else if(i===`stream`&&te.test(t.content)&&o!==void 0&&n.streamCandidates?.hasSource(o.type.name.split(`.`)[0])===!0){let[i,a]=o.type.name.split(`.`),s=n.streamCandidates.hasPropertyType(o.type.name)&&n.streamCandidates.hasUniqueStream(i,a),c=r(n,t,o,s);(U!==null||G.length>0)&&n.error(e.InvalidCommandStream,`A command declares at most one stream route.`,F(t)),s||U!==null?G.push(c):U=c}else if(i===`runs`&&T(t))E(n,t);else if(i===`description`)N=f(n,t,N,`Command '${m}'`);else if(i===`documentation`)I=p(n,t,I,`Command '${m}'`);else if(i===`authorize`){let e=l(n,t);if(!B){let t=z;z=c(z,e,n),B=t!==null&&z===null}}else if(i===`validate`){let e=parseValidate(n,t,`command`,m);e!==void 0&&y.push(e)}else if(i===`produces`){let e=j(n,t,!0);e!==void 0&&b.push(e)}else if(i===`handler`)V=v(n,t),H.push({handler:V,location:F(t)});else if(q.has(i)){let r=i===`reads`?A(n,t):void 0;r!==void 0&&C.push(r),i===`concurrency`&&w===void 0&&(w=k(n,t));let a=/^reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?$/.exec(t.content);a!==null&&S.push({readModel:a[1],alias:a[2]??null}),W.test(t.content)&&n.error(e.OptionalReadsNotSupported,`Optional reads are not yet supported (see #308).`,F(t)),n.skipOpaqueBlock(t.indent)}else o===void 0?(M(n,t),n.error(e.UnknownCommandDirective,`Unexpected '${t.content}' in command body`,F(t)),n.skipBlock(t.indent)):_=addProperty(n,h,o,m,t,_)}let Y=new Set(g.flatMap(e=>e.candidate===null?[]:[e.candidate])),X=new Set(h.filter(e=>!Y.has(e)).map(e=>e.name));g.some(e=>e.candidate!==null&&!X.has(e.candidate.type.name)&&e.candidate.type.name!==`returns`)&&X.add(`returns`);for(let e of X)o?.add(e);let Z=null,Q=/* @__PURE__ */ new Set;for(let t of g){let r=t.response;if(t.candidate!==null){if(!X.has(t.candidate.type.name))continue;Q.add(t.candidate),r={kind:`ScalarCommandResponseSyntax`,source:{kind:`PropertyResponseSourceSyntax`,property:t.candidate.type.name,location:t.candidate.type.location},location:F(t.line)}}r!==null&&(Z===null?Z=r:n.error(e.InvalidCommandResponse,`A command declares at most one unconditional response.`,F(t.line)))}t(H,V,b.length>0,n);let $={kind:`CommandSyntax`,name:m,description:N,documentation:I,authorize:z,properties:h.filter(e=>!Q.has(e)),validations:y,produces:b,handler:V,response:Z,stream:U,streamCandidates:G,...K===null?{}:{calendar:K},location:F(i)};return D.set($,S),O.set($,{reads:C,concurrency:w}),$}function addProperty(t,n,r,i,a,o){return N(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 parseValidationFile(e,t,n){let r=_(e,n);return r===void 0?void 0:{kind:`FileValidateSyntax`,file:r,location:F(t)}}function hasValidationOperand(e){let t=V.exec(e.content);if(t===null)return!1;let n=t[2];return x(n)===`not`&&x(n.substring(3).trimStart())===`empty`||x(n)===`checksum`||H.test(n)}function isValidationFileBody(e,t,n){if(!I(n)||hasValidationOperand(n))return!1;let r=e.reader.fork();r.takeSignificant();let i=r.peekSignificant();return i===void 0||i.indent<=t.indent}function parseValidate(t,r,i,a){if(r.content===`validate`){let o=t.peekChild(r.indent);if(o!==void 0&&isValidationFileBody(t,r,o))return t.reader.takeSignificant(),parseValidationFile(t,r,o);if(o!==void 0&&o.content.startsWith("```")){t.reader.takeSignificant();let e=g(t.valueContext,o);return e===null&&t.skipFencedBody(),{kind:`CodeValidateSyntax`,code:e,location:F(r)}}let c=[],l=[],u;for(let o=t.peekChild(r.indent);o!==void 0;o=t.peekChild(r.indent)){if(t.reader.takeSignificant(),i===`concept`){if(t.sourceOptions.numericMode===`legacy`&&o.content.startsWith("```")){t.skipFencedBody();continue}if(u!==void 0&&o.indent<=u&&(u=void 0),u!==void 0||x(o.content)===`implementation`){t.error(e.InvalidValidationRule,`Invalid validation rule '${o.content}'`,F(o)),u??=o.indent;continue}}if(x(o.content)===`require`){let e=n(i===`concept`?t.valueContext:t,o.content.substring(7).trim(),F(o),!1,t),r=null,a=`Error`,c=!1;for(let e=t.peekChild(o.indent);e!==void 0;e=t.peekChild(o.indent)){t.reader.takeSignificant();let n=B.exec(e.content);n!==null&&n.index===0?r=n[1]===void 0?n[2]:s(n[1]):x(e.content)===`severity`?(c||(a=K[e.content.substring(8).trim()]??`Error`),c=!0):t.skipOpaqueBlock(e.indent)}e!==null&&l.push({kind:`RequirementSyntax`,condition:e,message:r,severity:a,location:F(o)});continue}let r=parseValidationRule(t,i===`concept`?{...o,content:`value ${o.content}`}:o,i,a);r!==void 0&&c.push(r)}return{kind:`DeclarativeValidateSyntax`,rules:c,requirements:l,location:F(r)}}if(i===`concept`&&x(r.content.substring(8).trimStart())===`checksum`){let e=parseValidationRule(t,{...r,content:`value ${r.content.substring(8).trimStart()}`},i,a);return e===void 0?void 0:{kind:`DeclarativeValidateSyntax`,rules:[e],requirements:[],location:F(r)}}if(r.content===`validate csharp`){let e=g(t.valueContext,{...r,content:`csharp`});return e===null&&t.skipOpaqueBlock(r.indent),{kind:`CodeValidateSyntax`,code:e,location:F(r)}}t.error(e.InvalidValidateDeclaration,`Invalid validate declaration '${r.content}' - expected 'validate' or 'validate csharp'`,F(r)),t.skipBlock(r.indent)}function parseValidationRule(t,n,r,i){let a=x(V.exec(n.content)?.[2]??``)===`checksum`,o=r===`concept`&&!a?t.valueContext:t,{content:s,message:c}=splitMessage(n.content),l=splitSeverity(o,n,s);if(l===void 0)return;let u=V.exec(l.content);if(u===null){o.error(e.InvalidValidationRule,`Invalid validation rule '${n.content}'`,F(n));return}let d=parseRule(o,u[2],n);if(d===void 0)return;d.kind===`Matches`&&d.value!==null&&w(t,d.value,F(n),n.raw,C(t,r,i,u[1]));let f=d.kind===`Rule`?parseRuleImplementation(t,n,r===`command`):{file:null,code:null,implementation:null};return{kind:`ValidationRuleSyntax`,property:u[1],rule:d.kind,value:d.value,message:c,severity:l.severity,...f,location:F(n)}}function parseRuleImplementation(t,n,r){let i=t.peekChild(n.indent);if(i===void 0)return{file:null,code:null,implementation:null};t.reader.takeSignificant();let a=r&&x(i.content)===`implementation`,o=a?y(t,i):{file:h(i)?_(t,i):null,code:!h(i)&&m(t,i)?g(t,i):null,implementation:null};!a&&o.file===null&&o.code===null&&(t.error(e.UnknownRuleImplementationDirective,`Unexpected '${i.content}' in rule implementation - expected 'file <path>' or an inline code block`,F(i)),t.skipBlock(i.indent));for(let i=t.peekChild(n.indent);i!==void 0&&(a||r&&x(i.content)===`implementation`);i=t.peekChild(n.indent))t.reader.takeSignificant(),t.error(a&&x(i.content)===`implementation`?e.InvalidImplementationBlock:e.ConflictingImplementationSources,`A named rule has one implementation wrapper and cannot mix wrapped and direct sources.`,F(i)),m(t,i)?g(t,i):t.skipBlock(i.indent);return o}function splitMessage(e){let t=B.exec(e);if(t===null)return{content:e,message:null};let n=t[1]===void 0?t[2]:s(t[1]);return{content:e.substring(0,t.index).trimEnd(),message:n}}function splitSeverity(t,n,r){let i=z.exec(r);if(i===null)return{content:r,severity:`Error`};let a=K[i[1]];if(a===void 0)t.error(e.InvalidValidationSeverity,`Unknown validation severity '${i[1]}' - expected information, warning or error`,F(n));else return{content:r.substring(0,i.index).trimEnd(),severity:a}}function parseRule(t,n,r){if(n===`not empty`)return{kind:`NotEmpty`,value:null};if(x(n)===`checksum`){let i=n.substring(8).trim();if(i!==`luhn`&&i!==`mod11`&&i!==`mod97`){t.error(e.InvalidGenerationArgument,`Checksum validation requires luhn, mod11 or mod97.`,F(r));return}return{kind:`Checksum`,value:{kind:`LiteralExpressionSyntax`,value:i,location:F(r)}}}let i=H.exec(n);if(i===null){t.error(e.InvalidValidationRule,`Invalid validation rule '${r.content}'`,F(r));return}let a=i[1]??i[2];if(a===`rule`){let n=i[3].trim();if(!U.test(n)){t.error(e.InvalidRuleName,`Invalid rule name '${n}' in '${r.content}' - expected 'rule <Name>' with an identifier`,F(r));return}return{kind:`Rule`,value:{kind:`PathExpressionSyntax`,path:n,location:F(r)}}}return{kind:G[a],value:b(i[3],F(r),t)}}export{parseCommand,parseValidate};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{validateHandlerContracts as t}from"./CommandHandlerValidator.js";import{misplacedRuleHintForCommand as n}from"./MisplacedRuleHint.js";import{parseCondition as r}from"./ConditionParser.js";import{parseCommandStream as i}from"./EventSourceParser.js";import{pattern as a}from"../Text/patterns.js";import{sourceStreamPattern as o}from"../Text/SourceStreamNames.js";import{stringBodyPattern as s,unescapeString as c}from"../Text/StringLiteral.js";import{combineAuthorize as l,parseAuthorize as u}from"./AuthorizeParser.js";import{parseCommandResponse as d,scalarResponsePattern as f}from"./CommandResponseParser.js";import{parseDescription as p}from"./DescriptionParser.js";import{parseDocumentation as m}from"./DocumentationParser.js";import{isCode as h,isFile as g,parseCode as _,parseFile as v,parseHandler as y,parseImplementationWrapper as b}from"./ImplementationParser.js";import{parseMappingSource as x}from"./ExpressionParser.js";import{firstWord as S}from"./LineText.js";import{ParserContext as C}from"./ParserContext.js";import{matchSubject as w,validateMatchOperand as T}from"./MatchOperandValidation.js";import{isReactionIdentityLine as E,misplacedReactionIdentity as ee}from"./ReactionIdentityParser.js";import{commandReadSources as te}from"./CommandReadSources.js";import{dependencySources as D}from"../Syntax/DependencySources.js";import{captureConcurrency as O}from"./DependencySourceParser.js";import{parseReads as k}from"./ReadsParser.js";import{parseProduces as A}from"./ProducesParser.js";import{reportInvalidModifierOrder as j,reportLegacyOptionalSuffix as M,tryParseProperty as N}from"./PropertyLineParser.js";import{locationOf as P}from"./SourceLine.js";import{isFileDirectiveAmongProperties as F}from"./FileReferences.js";const ne=a(`^command\\s+([A-Za-z_]\\w*)$`),I=o(`^stream\\s+[A-Za-z_]\\w*\\.[A-Za-z_]\\w*$`),L=a(`^calendar\\s+(?:"|from\\s+\\$context\\.)`),R=a(`^calendar\\s+(?:"(${s})"|from\\s+\\$context\\.([A-Za-z_][A-Za-z0-9_]*(?:\\.[A-Za-z_][A-Za-z0-9_]*)*))$`),z=a(`\\bseverity\\s+(\\S+)$`),B=a(`\\bmessage\\s+(?:"(${s})"|(\\$strings\\.\\S*))$`),V=a(`^([\\w.]+)\\s+(.+)$`),H=a(`^(?:(not empty|matches|not contains|contains|starts with|ends with|max|min|rule)(?:\\s+|$)|(length ==|decimals <=|all >=|all >|>=|<=|==|!=|>|<)\\s*)(.*)$`),U=o(`^[A-Za-z_]\\w*$`),W=a(`^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 C(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(r,a,o,s){let h=ne.exec(a.content)?.[1]??``;h===``&&r.error(e.InvalidCommandDeclaration,`Invalid command declaration '${a.content}' - expected 'command <Name>'`,P(a));let g=[],_=[],v,b=[],x=[],C=[],w=[],T,M=null,F=null,z=null,B=!1,V=null,H=[],U=null,G=[],K=null;for(let t=r.peekChild(a.indent);t!==void 0;t=r.peekChild(a.indent)){r.reader.takeSignificant();let a=S(t.content),s=N(t);if(a===`calendar`&&L.test(t.content)){let n=R.exec(t.content);K!==null||n===null?r.error(e.InvalidCommandCalendar,`A command declares at most one 'calendar "<id>"' or 'calendar from $context.<member>'.`,P(t)):K={kind:`CommandCalendarSyntax`,id:n[1]===void 0?null:c(n[1]),contextMember:n[2]??null,location:P(t)}}else if(s!==void 0&&(J.has(a)||a===`validate`&&t.content!==`validate csharp`))v=addProperty(r,g,s,h,t,v);else if(a===`returns`){let e=f.exec(t.content);e!==null&&!e[1].startsWith(`@`)&&s!==void 0?o===void 0?(g.push(s),_.push({line:t,candidate:s,response:null})):o.has(s.type.name)?_.push({line:t,candidate:null,response:d(r,t)}):v=addProperty(r,g,s,h,t,v):s===void 0?j(r,t)?r.skipBlock(t.indent):_.push({line:t,candidate:null,response:d(r,t)}):v=addProperty(r,g,s,h,t,v)}else if(a===`stream`&&I.test(t.content)&&s!==void 0&&r.streamCandidates?.hasSource(s.type.name.split(`.`)[0])===!0){let[n,a]=s.type.name.split(`.`),o=r.streamCandidates.hasPropertyType(s.type.name)&&r.streamCandidates.hasUniqueStream(n,a),c=i(r,t,s,o);(U!==null||G.length>0)&&r.error(e.InvalidCommandStream,`A command declares at most one stream route.`,P(t)),o||U!==null?G.push(c):U=c}else if(a===`runs`&&E(t))ee(r,t);else if(a===`description`)M=p(r,t,M,`Command '${h}'`);else if(a===`documentation`)F=m(r,t,F,`Command '${h}'`);else if(a===`authorize`){let e=u(r,t);if(!B){let t=z;z=l(z,e,r),B=t!==null&&z===null}}else if(a===`validate`){let e=parseValidate(r,t,`command`,h);e!==void 0&&b.push(e)}else if(a===`produces`){let e=A(r,t,!0);e!==void 0&&x.push(e)}else if(a===`handler`)V=y(r,t),H.push({handler:V,location:P(t)});else if(q.has(a)){let n=a===`reads`?k(r,t):void 0;n!==void 0&&w.push(n),a===`concurrency`&&T===void 0&&(T=O(r,t));let i=/^reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?$/.exec(t.content);i!==null&&C.push({readModel:i[1],alias:i[2]??null}),W.test(t.content)&&r.error(e.OptionalReadsNotSupported,`Optional reads are not yet supported (see #308).`,P(t)),r.skipOpaqueBlock(t.indent)}else s===void 0?(j(r,t),r.error(e.UnknownCommandDirective,`Unexpected '${t.content}' in command body${n(t.content)}`,P(t)),r.skipBlock(t.indent)):v=addProperty(r,g,s,h,t,v)}let Y=new Set(_.flatMap(e=>e.candidate===null?[]:[e.candidate])),X=new Set(g.filter(e=>!Y.has(e)).map(e=>e.name));_.some(e=>e.candidate!==null&&!X.has(e.candidate.type.name)&&e.candidate.type.name!==`returns`)&&X.add(`returns`);for(let e of X)s?.add(e);let Z=null,Q=/* @__PURE__ */ new Set;for(let t of _){let n=t.response;if(t.candidate!==null){if(!X.has(t.candidate.type.name))continue;Q.add(t.candidate),n={kind:`ScalarCommandResponseSyntax`,source:{kind:`PropertyResponseSourceSyntax`,property:t.candidate.type.name,location:t.candidate.type.location},location:P(t.line)}}n!==null&&(Z===null?Z=n:r.error(e.InvalidCommandResponse,`A command declares at most one unconditional response.`,P(t.line)))}t(H,V,x.length>0,r);let $={kind:`CommandSyntax`,name:h,description:M,documentation:F,authorize:z,properties:g.filter(e=>!Q.has(e)),validations:b,produces:x,handler:V,response:Z,stream:U,streamCandidates:G,...K===null?{}:{calendar:K},location:P(a)};return te.set($,C),D.set($,{reads:w,concurrency:T}),$}function addProperty(t,n,r,i,a,o){return M(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 parseValidationFile(e,t,n){let r=v(e,n);return r===void 0?void 0:{kind:`FileValidateSyntax`,file:r,location:P(t)}}function hasValidationOperand(e){let t=V.exec(e.content);return t!==null&&startsWithRuleOperand(t[2])}function startsWithRuleOperand(e){return S(e)===`not`&&S(e.substring(3).trimStart())===`empty`||S(e)===`checksum`||H.test(e)}function isDeclarativePredicate(e){return startsWithRuleOperand(e)&&S(e)!==`rule`}function isValidationFileBody(e,t,n){if(!F(n)||hasValidationOperand(n))return!1;let r=e.reader.fork();r.takeSignificant();let i=r.peekSignificant();return i===void 0||i.indent<=t.indent}function parseValidate(t,n,i,a){if(n.content===`validate`){let o=t.peekChild(n.indent);if(o!==void 0&&isValidationFileBody(t,n,o))return t.reader.takeSignificant(),parseValidationFile(t,n,o);if(o!==void 0&&o.content.startsWith("```")){t.reader.takeSignificant();let e=_(t.valueContext,o);return e===null&&t.skipFencedBody(),{kind:`CodeValidateSyntax`,code:e,location:P(n)}}let s=[],l=[],u;for(let o=t.peekChild(n.indent);o!==void 0;o=t.peekChild(n.indent)){if(t.reader.takeSignificant(),i===`concept`){if(t.sourceOptions.numericMode===`legacy`&&o.content.startsWith("```")){t.skipFencedBody();continue}if(u!==void 0&&o.indent<=u&&(u=void 0),u!==void 0||S(o.content)===`implementation`){t.error(e.InvalidValidationRule,`Invalid validation rule '${o.content}'`,P(o)),u??=o.indent;continue}}if(S(o.content)===`require`){let e=r(i===`concept`?t.valueContext:t,o.content.substring(7).trim(),P(o),!1,t),n=null,a=`Error`,s=!1;for(let e=t.peekChild(o.indent);e!==void 0;e=t.peekChild(o.indent)){t.reader.takeSignificant();let r=B.exec(e.content);r!==null&&r.index===0?n=r[1]===void 0?r[2]:c(r[1]):S(e.content)===`severity`?(s||(a=K[e.content.substring(8).trim()]??`Error`),s=!0):t.skipOpaqueBlock(e.indent)}e!==null&&l.push({kind:`RequirementSyntax`,condition:e,message:n,severity:a,location:P(o)});continue}let n=parseValidationRule(t,i===`concept`?{...o,content:`value ${o.content}`}:o,i,a);n!==void 0&&s.push(n)}return{kind:`DeclarativeValidateSyntax`,rules:s,requirements:l,location:P(n)}}if(i===`concept`&&S(n.content.substring(8).trimStart())===`checksum`){let e=parseValidationRule(t,{...n,content:`value ${n.content.substring(8).trimStart()}`},i,a);return e===void 0?void 0:{kind:`DeclarativeValidateSyntax`,rules:[e],requirements:[],location:P(n)}}if(n.content===`validate csharp`){let e=_(t.valueContext,{...n,content:`csharp`});return e===null&&t.skipOpaqueBlock(n.indent),{kind:`CodeValidateSyntax`,code:e,location:P(n)}}t.error(e.InvalidValidateDeclaration,`Invalid validate declaration '${n.content}' - expected 'validate' or 'validate csharp'`,P(n)),t.skipBlock(n.indent)}function parseValidationRule(t,n,r,i){let a=S(V.exec(n.content)?.[2]??``)===`checksum`,o=r===`concept`&&!a?t.valueContext:t,{content:s,message:c}=splitMessage(n.content),l=splitSeverity(o,n,s);if(l===void 0)return;let u=V.exec(l.content);if(u===null){o.error(e.InvalidValidationRule,`Invalid validation rule '${n.content}'`,P(n));return}let d=parseRule(o,u[2],n);if(d===void 0)return;d.kind===`Matches`&&d.value!==null&&T(t,d.value,P(n),n.raw,w(t,r,i,u[1]));let f=d.kind===`Rule`?parseRuleImplementation(t,n,r===`command`):{file:null,code:null,implementation:null};return{kind:`ValidationRuleSyntax`,property:u[1],rule:d.kind,value:d.value,message:c,severity:l.severity,...f,location:P(n)}}function parseRuleImplementation(t,n,r){let i=t.peekChild(n.indent);if(i===void 0)return{file:null,code:null,implementation:null};t.reader.takeSignificant();let a=r&&S(i.content)===`implementation`,o=a?b(t,i):{file:g(i)?v(t,i):null,code:!g(i)&&h(t,i)?_(t,i):null,implementation:null};!a&&o.file===null&&o.code===null&&(t.error(e.UnknownRuleImplementationDirective,`Unexpected '${i.content}' in rule implementation - expected 'file <path>' or an inline code block`,P(i)),t.skipBlock(i.indent));for(let i=t.peekChild(n.indent);i!==void 0&&(a||r&&S(i.content)===`implementation`);i=t.peekChild(n.indent))t.reader.takeSignificant(),t.error(a&&S(i.content)===`implementation`?e.InvalidImplementationBlock:e.ConflictingImplementationSources,`A named rule has one implementation wrapper and cannot mix wrapped and direct sources.`,P(i)),h(t,i)?_(t,i):t.skipBlock(i.indent);return o}function splitMessage(e){let t=B.exec(e);if(t===null)return{content:e,message:null};let n=t[1]===void 0?t[2]:c(t[1]);return{content:e.substring(0,t.index).trimEnd(),message:n}}function splitSeverity(t,n,r){let i=z.exec(r);if(i===null)return{content:r,severity:`Error`};let a=K[i[1]];if(a===void 0)t.error(e.InvalidValidationSeverity,`Unknown validation severity '${i[1]}' - expected information, warning or error`,P(n));else return{content:r.substring(0,i.index).trimEnd(),severity:a}}function parseRule(t,n,r){if(n===`not empty`)return{kind:`NotEmpty`,value:null};if(S(n)===`checksum`){let i=n.substring(8).trim();if(i!==`luhn`&&i!==`mod11`&&i!==`mod97`){t.error(e.InvalidGenerationArgument,`Checksum validation requires luhn, mod11 or mod97.`,P(r));return}return{kind:`Checksum`,value:{kind:`LiteralExpressionSyntax`,value:i,location:P(r)}}}let i=H.exec(n);if(i===null){t.error(e.InvalidValidationRule,`Invalid validation rule '${r.content}'`,P(r));return}let a=i[1]??i[2];if(a===`rule`){let n=i[3].trim();if(!U.test(n)){t.error(e.InvalidRuleName,`Invalid rule name '${n}' in '${r.content}' - expected 'rule <Name>' with an identifier`,P(r));return}return{kind:`Rule`,value:{kind:`PathExpressionSyntax`,path:n,location:P(r)}}}return{kind:G[a],value:x(i[3],P(r),t)}}export{isDeclarativePredicate,parseCommand,parseValidate};
2
2
  //# sourceMappingURL=CommandParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CommandParser.js","names":["header","pattern","routeHeader","sourceStreamPattern","calendarPrefix","calendarPattern","stringBodyPattern","severityPattern","messagePattern","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","authorizationDepthExceeded","handler","handlers","stream","streamCandidates","calendar","child","keyword","firstWord","asProperty","tryParseProperty","match","unescapeString","scalar","scalarResponsePattern","responseNames","parseCommandResponse","reportInvalidModifierOrder","source","streamName","ambiguous","route","parseCommandStream","isReactionIdentityLine","misplacedReactionIdentity","parseDescription","parseDocumentation","next","parseAuthorize","previous","combineAuthorize","validate","production","parseProduces","parseHandler","reference","parseReads","captureConcurrency","read","candidates","entry","property","discoveredNames","response","removed","parsed","validateHandlerContracts","syntax","commandReadSources","dependencySources","reportLegacyOptionalSuffix","commandName","file","parseFile","body","rule","isFileDirectiveAmongProperties","fence","code","parseCode","rules","requirements","wrapperIndent","owner","condition","parseCondition","message","severity","hasSeverity","directive","matched","ownerName","checksum","valueContext","withSeverity","validateMatchOperand","matchSubject","wrapped","commandOwner","parseImplementationWrapper","isFile","isCode","extra","content","text","algorithm","operand","operator","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 { validateHandlerContracts } 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 { CommandCalendarSyntax } from '../Syntax/Calendar';\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';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\n\nconst header = pattern('^command\\\\s+([A-Za-z_]\\\\w*)$');\nconst routeHeader = sourceStreamPattern('^stream\\\\s+[A-Za-z_]\\\\w*\\\\.[A-Za-z_]\\\\w*$');\nconst calendarPrefix = pattern('^calendar\\\\s+(?:\"|from\\\\s+\\\\$context\\\\.)');\nconst calendarPattern = pattern(`^calendar\\\\s+(?:\"(${stringBodyPattern})\"|from\\\\s+\\\\$context\\\\.([A-Za-z_][A-Za-z0-9_]*(?:\\\\.[A-Za-z_][A-Za-z0-9_]*)*))$`);\nconst severityPattern = pattern('\\\\bseverity\\\\s+(\\\\S+)$');\nconst messagePattern = pattern(`\\\\bmessage\\\\s+(?:\"(${stringBodyPattern})\"|(\\\\$strings\\\\.\\\\S*))$`);\nconst rulePattern = pattern('^([\\\\w.]+)\\\\s+(.+)$');\nconst operandPattern = pattern('^(?:(not empty|matches|not contains|contains|starts with|ends with|max|min|rule)(?:\\\\s+|$)|(length ==|decimals <=|all >=|all >|>=|<=|==|!=|>|<)\\\\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 authorizationDepthExceeded = false;\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 let calendar: CommandCalendarSyntax | 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 const asProperty = tryParseProperty(child);\n if (keyword === 'calendar' && calendarPrefix.test(child.content)) {\n const match = calendarPattern.exec(child.content);\n if (calendar !== null || match === null) {\n context.error(DiagnosticCodes.InvalidCommandCalendar, 'A command declares at most one \\'calendar \"<id>\"\\' or \\'calendar from $context.<member>\\'.', locationOf(child));\n } else {\n calendar = { kind: 'CommandCalendarSyntax', id: match[1] === undefined ? null : unescapeString(match[1]), contextMember: match[2] ?? null, location: locationOf(child) };\n }\n } else 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 const next = parseAuthorize(context, child);\n if (!authorizationDepthExceeded) {\n const previous = authorize;\n authorize = combineAuthorize(authorize, next, context);\n authorizationDepthExceeded = previous !== null && authorize === null;\n }\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 validateHandlerContracts(handlers, handler, produces.length > 0, context);\n const syntax: CommandSyntax = { kind: 'CommandSyntax', name, description, documentation, authorize, properties: properties.filter(property => !removed.has(property)), validations, produces, handler, response, stream, streamCandidates, ...(calendar === null ? {} : { calendar }), 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\nfunction parseValidationFile(context: ParserContext, header: SourceLine, body: SourceLine): ValidateSyntax | undefined {\n const file = parseFile(context, body);\n return file === undefined ? undefined : { kind: 'FileValidateSyntax', file, location: locationOf(header) };\n}\n\nfunction hasValidationOperand(line: SourceLine): boolean {\n const match = rulePattern.exec(line.content);\n if (match === null) return false;\n const rule = match[2];\n return (firstWord(rule) === 'not' && firstWord(rule.substring('not'.length).trimStart()) === 'empty') ||\n firstWord(rule) === 'checksum' || operandPattern.test(rule);\n}\n\nfunction isValidationFileBody(context: ParserContext, header: SourceLine, body: SourceLine): boolean {\n if (!isFileDirectiveAmongProperties(body) || hasValidationOperand(body)) return false;\n const lookahead = context.reader.fork();\n lookahead.takeSignificant();\n const next = lookahead.peekSignificant();\n return next === undefined || next.indent <= header.indent;\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 && isValidationFileBody(context, line, fence)) {\n context.reader.takeSignificant();\n return parseValidationFile(context, line, fence);\n }\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 // Keep legacy operand enrichment quiet, but never discard the depth refusal.\n const condition = parseCondition(owner === 'concept' ? context.valueContext : context, child.content.substring('require'.length).trim(), locationOf(child), false, context);\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 const operator = operand[1] ?? operand[2];\n if (operator === 'rule') {\n const name = operand[3].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[operator], value: parseMappingSource(operand[3], locationOf(line), context) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommandParser.js","names":["header","pattern","routeHeader","sourceStreamPattern","calendarPrefix","calendarPattern","stringBodyPattern","severityPattern","messagePattern","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","authorizationDepthExceeded","handler","handlers","stream","streamCandidates","calendar","child","keyword","firstWord","asProperty","tryParseProperty","match","unescapeString","scalar","scalarResponsePattern","responseNames","parseCommandResponse","reportInvalidModifierOrder","source","streamName","ambiguous","route","parseCommandStream","isReactionIdentityLine","misplacedReactionIdentity","parseDescription","parseDocumentation","next","parseAuthorize","previous","combineAuthorize","validate","production","parseProduces","parseHandler","reference","parseReads","captureConcurrency","read","misplacedRuleHintForCommand","candidates","entry","property","discoveredNames","response","removed","parsed","validateHandlerContracts","syntax","commandReadSources","dependencySources","reportLegacyOptionalSuffix","commandName","file","parseFile","body","rule","isFileDirectiveAmongProperties","fence","code","parseCode","rules","requirements","wrapperIndent","owner","condition","parseCondition","message","severity","hasSeverity","directive","matched","ownerName","checksum","valueContext","withSeverity","validateMatchOperand","matchSubject","wrapped","commandOwner","parseImplementationWrapper","isFile","isCode","extra","content","text","algorithm","operand","operator","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 { validateHandlerContracts } from './CommandHandlerValidator';\nimport { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { RequirementSyntax } from '../Syntax/Conditions';\nimport { misplacedRuleHintForCommand } from './MisplacedRuleHint';\nimport { parseCondition } from './ConditionParser';\nimport { AuthorizeSyntax } from '../Syntax/Authorization';\nimport { CommandSyntax, ValidateSyntax, ValidationRuleKind, ValidationRuleSyntax, ValidationSeverity } from '../Syntax/Commands';\nimport { PropertySyntax } from '../Syntax/Declarations';\nimport { CommandCalendarSyntax } from '../Syntax/Calendar';\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';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\n\nconst header = pattern('^command\\\\s+([A-Za-z_]\\\\w*)$');\nconst routeHeader = sourceStreamPattern('^stream\\\\s+[A-Za-z_]\\\\w*\\\\.[A-Za-z_]\\\\w*$');\nconst calendarPrefix = pattern('^calendar\\\\s+(?:\"|from\\\\s+\\\\$context\\\\.)');\nconst calendarPattern = pattern(`^calendar\\\\s+(?:\"(${stringBodyPattern})\"|from\\\\s+\\\\$context\\\\.([A-Za-z_][A-Za-z0-9_]*(?:\\\\.[A-Za-z_][A-Za-z0-9_]*)*))$`);\nconst severityPattern = pattern('\\\\bseverity\\\\s+(\\\\S+)$');\nconst messagePattern = pattern(`\\\\bmessage\\\\s+(?:\"(${stringBodyPattern})\"|(\\\\$strings\\\\.\\\\S*))$`);\nconst rulePattern = pattern('^([\\\\w.]+)\\\\s+(.+)$');\nconst operandPattern = pattern('^(?:(not empty|matches|not contains|contains|starts with|ends with|max|min|rule)(?:\\\\s+|$)|(length ==|decimals <=|all >=|all >|>=|<=|==|!=|>|<)\\\\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 authorizationDepthExceeded = false;\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 let calendar: CommandCalendarSyntax | 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 const asProperty = tryParseProperty(child);\n if (keyword === 'calendar' && calendarPrefix.test(child.content)) {\n const match = calendarPattern.exec(child.content);\n if (calendar !== null || match === null) {\n context.error(DiagnosticCodes.InvalidCommandCalendar, 'A command declares at most one \\'calendar \"<id>\"\\' or \\'calendar from $context.<member>\\'.', locationOf(child));\n } else {\n calendar = { kind: 'CommandCalendarSyntax', id: match[1] === undefined ? null : unescapeString(match[1]), contextMember: match[2] ?? null, location: locationOf(child) };\n }\n } else 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 const next = parseAuthorize(context, child);\n if (!authorizationDepthExceeded) {\n const previous = authorize;\n authorize = combineAuthorize(authorize, next, context);\n authorizationDepthExceeded = previous !== null && authorize === null;\n }\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${misplacedRuleHintForCommand(child.content)}`, 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 validateHandlerContracts(handlers, handler, produces.length > 0, context);\n const syntax: CommandSyntax = { kind: 'CommandSyntax', name, description, documentation, authorize, properties: properties.filter(property => !removed.has(property)), validations, produces, handler, response, stream, streamCandidates, ...(calendar === null ? {} : { calendar }), 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\nfunction parseValidationFile(context: ParserContext, header: SourceLine, body: SourceLine): ValidateSyntax | undefined {\n const file = parseFile(context, body);\n return file === undefined ? undefined : { kind: 'FileValidateSyntax', file, location: locationOf(header) };\n}\n\nfunction hasValidationOperand(line: SourceLine): boolean {\n const match = rulePattern.exec(line.content);\n if (match === null) return false;\n return startsWithRuleOperand(match[2]);\n}\n\nfunction startsWithRuleOperand(rule: string): boolean {\n return (firstWord(rule) === 'not' && firstWord(rule.substring('not'.length).trimStart()) === 'empty') ||\n firstWord(rule) === 'checksum' || operandPattern.test(rule);\n}\n\n/** Recognizes a declarative predicate, with any message or severity suffix; a named 'rule <Name>' is not one. */\nexport function isDeclarativePredicate(rule: string): boolean {\n return startsWithRuleOperand(rule) && firstWord(rule) !== 'rule';\n}\n\nfunction isValidationFileBody(context: ParserContext, header: SourceLine, body: SourceLine): boolean {\n if (!isFileDirectiveAmongProperties(body) || hasValidationOperand(body)) return false;\n const lookahead = context.reader.fork();\n lookahead.takeSignificant();\n const next = lookahead.peekSignificant();\n return next === undefined || next.indent <= header.indent;\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 && isValidationFileBody(context, line, fence)) {\n context.reader.takeSignificant();\n return parseValidationFile(context, line, fence);\n }\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 // Keep legacy operand enrichment quiet, but never discard the depth refusal.\n const condition = parseCondition(owner === 'concept' ? context.valueContext : context, child.content.substring('require'.length).trim(), locationOf(child), false, context);\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 const operator = operand[1] ?? operand[2];\n if (operator === 'rule') {\n const name = operand[3].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[operator], value: parseMappingSource(operand[3], locationOf(line), context) };\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{pattern as e}from"../Text/patterns.js";import{isDeclarativePredicate as t}from"./CommandParser.js";const n=e(String.raw`^rule\s+(\S.*)$`);function misplacedPredicate(e){let r=n.exec(e)?.[1];return r!==void 0&&t(r)?r:void 0}function misplacedRuleHintForCommand(e){let t=misplacedPredicate(e);return t===void 0?``:` - to validate a property, declare 'validate' and put '<property> ${t}' on an indented line beneath it`}function misplacedRuleHintForConcept(e){let t=misplacedPredicate(e);return t===void 0?``:`. To validate the concept's value, declare 'validate' and put '${t}' on an indented line beneath it`}export{misplacedRuleHintForCommand,misplacedRuleHintForConcept};
2
+ //# sourceMappingURL=MisplacedRuleHint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MisplacedRuleHint.js","names":["misplacedRule","pattern","candidate","content","isDeclarativePredicate","rule"],"sources":["../../../../../../Compiler/Parsing/MisplacedRuleHint.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 { pattern } from '../Text/patterns';\nimport { isDeclarativePredicate } from './CommandParser';\n\n// Guidance appended to a rejected 'rule <predicate>' line that sits directly in a command or concept body instead\n// of inside a 'validate' block. Only a line whose predicate the validate-rule parser recognizes gets a hint\n// ('rule not empty', 'rule > 0', 'rule checksum luhn', with any message or severity suffix); a named\n// 'rule <Name>' and every other unknown directive keep the generic diagnostic. The hint never says the suggested\n// edit makes the application valid, and the line is still rejected.\nconst misplacedRule = pattern(String.raw`^rule\\s+(\\S.*)$`);\n\nfunction misplacedPredicate(content: string): string | undefined {\n const candidate = misplacedRule.exec(content)?.[1];\n return candidate !== undefined && isDeclarativePredicate(candidate) ? candidate : undefined;\n}\n\n/** Gets the hint to append to a rejected command body line, or an empty string when it is not a misplaced predicate. */\nexport function misplacedRuleHintForCommand(content: string): string {\n const rule = misplacedPredicate(content);\n return rule === undefined ? '' : ` - to validate a property, declare 'validate' and put '<property> ${rule}' on an indented line beneath it`;\n}\n\n/** Gets the hint to append to a rejected concept body line, or an empty string when it is not a misplaced predicate. */\nexport function misplacedRuleHintForConcept(content: string): string {\n const rule = misplacedPredicate(content);\n return rule === undefined ? '' : `. To validate the concept's value, declare 'validate' and put '${rule}' on an indented line beneath it`;\n}\n"],"mappings":"A,+JAWA,MAAMA,EAAgBC,EAAQ,OAAO,GAAG,iBAAiB,EAEzD,SAAS,mBAAmB,EAAqC,CAC7D,IAAMC,EAAYF,EAAc,KAAKG,CAAO,CAAC,GAAG,GAChD,OAAOD,IAAc,IAAA,IAAaE,EAAuBF,CAAS,EAAIA,EAAY,IAAA,EACtF,CAGA,SAAgB,4BAA4B,EAAyB,CACjE,IAAMG,EAAO,mBAAmBF,CAAO,EACvC,OAAOE,IAAS,IAAA,GAAY,GAAK,qEAAqEA,EAAK,iCAC/G,CAGA,SAAgB,4BAA4B,EAAyB,CACjE,IAAMA,EAAO,mBAAmBF,CAAO,EACvC,OAAOE,IAAS,IAAA,GAAY,GAAK,kEAAkEA,EAAK,iCAC5G,C"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{eventDeclarations as n}from"../Syntax/EventDeclarations.js";import{consumedEvents as r,isEventsSource as i}from"../Syntax/CaptureEventsSource.js";import{dependencySourcesOf as a}from"../Syntax/DependencySources.js";import{ParserContext as o}from"./ParserContext.js";import{PublicEventUsageCollector as s}from"./PublicEventUsageCollector.js";import{validatePublicEventMetadata as c}from"./PublicEventMetadataValidator.js";import{validateCaptureEventFixtures as l,validateEventSourceKeys as u}from"./CaptureEventFixturesValidator.js";function validatePublicEventUsage(n,r){c(n,r);let i=new t(n),a=new t(n,i.declarations.filter(e=>e.kind===`event`));for(let{slice:e,scope:t}of i.slices)validateOwnCaptureReactions(n,e,t,a,r),u(e,r);if(i.declarations.some(e=>e.node.kind===`EventSyntax`&&(e.node.visibility===`Public`||e.node.origin!=null))||n.imports.some(e=>e.visibility===`Public`||e.origin!=null)||i.slices.some(({slice:e})=>e.direction!=null||usesEventSource(e)||targetsEvent(e,i))){for(let{slice:e,scope:t}of i.slices)validateSlice(n,e,t,i,a,r);for(let t of n.seeds?.flatMap(e=>e.groups.flatMap(e=>e.events))??[]){let i=resolve(n,a,[],t.event,t,!0,r);if(i?.visibility!==`Public`)continue;let o=i.origin==null?e.PublicEventRequiresOutboundTranslation:e.ForeignPublicEventProduced;r.error(o,`Seed cannot append public event '${t.event}'; public production belongs to outbound translation, and foreign contracts cannot be produced locally.`,t.location)}}}function validateSlice(t,r,i,a,o,c){let u=new s;u.visitSlice(r);let d=[],f=r.type===`Translate`&&r.direction===`Outbound`,p=new Set(r.readModels.map(e=>e.name));for(let{target:n,node:a}of u.projectionTargets){let s=p.has(n)?void 0:resolve(t,o,i,n,a,!1,c);s!==void 0&&(f?(d.push({node:s,output:!0}),validateUse(r,n,a,!0,!1,s,c)):c.error(e.EventTargetOutsideOutboundTranslation,`'${n}' is an event: a projection or reducer may only target an event in an explicitly outbound Translate slice.`,a.location))}if((r.type!==`Translate`||r.direction!==`Inbound`)&&!f)for(let t of u.eventSources)c.error(e.EventsSourceOutsideInboundTranslation,`'source events' reads another application's public events and belongs to a Translate slice with 'direction inbound', not '${r.name}'.`,t.location);let m=/* @__PURE__ */ new Map;for(let e of u.uses){let n=resolve(t,e.node.kind===`ProducesSyntax`?a:o,i,e.name,e.node,e.output,c);n!==void 0&&(d.push({node:n,output:e.output}),validateUse(r,e.name,e.node,e.output,e.command,n,c),recordCaptureOrigin(e.node,n,m))}validateCaptureOrigins(r,m,c),l(r,i,o,c);for(let e of u.allEvents){let n=a.declarations.filter(e=>e.kind===`event`).map(e=>e.node);for(let i of[...n,...t.imports.filter(e=>e.visibility===`Public`)])d.push({node:i,output:!1}),validateUse(r,i.kind===`ImportSyntax`?i.qualifiedName:i.name,e,!1,!1,i,c)}if(r.type!==`Translate`||(r.direction==null&&(n(r).some(e=>e.visibility===`Public`)||d.some(e=>e.node.visibility===`Public`))&&c.error(e.PublicTranslationRequiresDirection,`A Translate slice using public events requires an explicit 'direction inbound' or 'direction outbound'. Legacy translations without public metadata remain inbound.`,r.location),r.direction!==`Outbound`))return;let h=new Set(d.filter(e=>e.output&&e.node.visibility===`Public`&&e.node.origin==null).map(e=>e.node)).size;h!==1&&c.error(e.OutboundPublicEventCount,`Outbound Translate slice '${r.name}' must produce exactly one local public event type; found ${h}.`,r.location);for(let t of r.captures)c.error(e.TranslationConstructDirection,`An outbound translation consumes private local events, not an external-data capture. Capture belongs to inbound translation.`,t.location)}function validateOwnCaptureReactions(t,n,r,i,a){if(n.type!==`Translate`||n.direction!=null)return;let c=new s;c.visitSlice(n);let l=new o(a.reader,a.path),u=new Set(c.uses.filter(e=>e.node.kind===`CaptureAppendSyntax`).map(e=>resolve(t,i,r,e.name,e.node,!0,l)).filter(e=>e!==void 0));for(let o of n.reactions.filter(e=>e.from==null)){let n=/* @__PURE__ */ new Map;for(let e of o.triggers){if(e.source.kind!==`NamedTriggerSourceSyntax`)continue;let a=e.source,o=resolve(t,i,r,a.name,a,!1,l);o!==void 0&&u.has(o)&&!n.has(o)&&n.set(o,a.name)}n.size!==0&&a.warning(e.DirectionlessTranslationReactsToOwnCapture,`Reaction '${o.name}' reacts to events appended by a capture in the same directionless Translate slice (${[...n.values()].join(`, `)}); keep the capture in this Translate slice and move the reaction to an Automation slice.`,o.location)}}function recordCaptureOrigin(e,t,n){if(e.kind!==`CaptureSourceSettingSyntax`)return;let r=publicOrigin(t);r!==void 0&&n.set(e,r)}function publicOrigin(e){if(e.visibility!==`Public`)return;let t=e.origin??``;return t.trim().length>0?t:void 0}function validateCaptureOrigins(t,n,a){for(let o of t.captures){let t=o.source;if(t==null||!i(t))continue;let s=[...new Set(r(t).flatMap(e=>{let t=n.get(e);return t==null?[]:[t]}))].sort();s.length<2||a.error(e.CaptureEventsFromSeveralOrigins,`The 'from' events of capture '${o.name}' originate from several event stores (${s.join(`, `)}); a capture reads one event store - split it into one capture per origin.`,t.location)}}function validateUse(t,n,r,i,a,o,s){let c=o.origin!=null,l=o.visibility===`Public`,error=(e,t)=>s.error(e,t,r.location);i?(a&&l&&error(e.CommandProducesPublicEvent,`Command cannot produce public event '${n}'; publish through an outbound Translate slice.`),t.type===`Translate`&&t.direction===`Outbound`&&!l&&error(e.OutboundTranslationOutput,`Outbound translation must produce its one local public event, not private event '${n}'.`),c&&error(e.ForeignPublicEventProduced,`Foreign public event '${n}' cannot be produced locally; translate it into a private local event.`),l&&!c&&(t.type!==`Translate`||t.direction!==`Outbound`)&&error(e.PublicEventRequiresOutboundTranslation,`Local public event '${n}' may only be produced by an explicitly outbound Translate slice.`),t.type===`Translate`&&(t.direction??`Inbound`)===`Inbound`&&(l||c)&&error(e.InboundTranslationOutput,`Inbound translation must produce private local events, not '${n}'.`)):(c&&(t.type!==`Translate`||t.direction!==`Inbound`)&&error(e.ForeignPublicEventConsumer,`Foreign public event '${n}' may only be consumed by an explicitly inbound Translate slice.`),t.type===`Translate`&&t.direction===`Outbound`&&(l||c)&&error(e.OutboundTranslationInput,`Outbound translation must consume private local events, not '${n}'.`),t.type!==`Translate`||t.direction!==`Inbound`||l&&c||error(e.InboundTranslationInput,`Explicitly inbound translation must consume foreign public events, not '${n}'.`))}function resolve(t,n,r,i,a,o,s){let c=n.resolveFromScope(i,r);if(c.declaration?.node.kind===`EventSyntax`)return c.declaration.node;if(c.kind===`operation`)return;if(c.kind===`ambiguous`){s.warning(e.AmbiguousReference,`Ambiguous event reference '${i}'; qualify it with its owning module, feature and slice.`,a.location);return}let l=t.imports.filter(e=>e.qualifiedName.split(`.`).at(-1)===i||e.qualifiedName===i);if(l.length===1){let t=l[0],o=n.resolveFromScope(t.qualifiedName,r);if(o.declaration?.node.kind===`EventSyntax`)return o.declaration.node;if(o.kind===`ambiguous`){s.warning(e.AmbiguousReference,`Ambiguous imported event reference '${i}'; qualify its declaration.`,a.location);return}return t.visibility===`Public`?t:void 0}l.length>1?s.warning(e.AmbiguousReference,`Ambiguous imported event reference '${i}'; use its qualified name.`,a.location):(o&&a.kind!==`CaptureAppendSyntax`||a.kind===`CaptureSourceSettingSyntax`)&&!s.diagnostics.some(t=>t.code===e.UnknownEvent&&t.location.path===a.location.path&&t.location.line===a.location.line&&t.location.column===a.location.column)&&s.warning(e.UnknownEvent,`Unknown event '${i}' - declare its contract before classifying its usage.`,a.location)}function usesEventSource(e){return e.captures.some(e=>e.source!=null&&i(e.source))}function targetsEvent(e,t){return[...e.projections.map(e=>e.readModel),...(a(e).reducers??[]).map(e=>e.readModel)].some(e=>e!=null&&t.declarations.some(t=>t.kind===`event`&&t.name===e))}export{validatePublicEventUsage};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{eventDeclarations as n}from"../Syntax/EventDeclarations.js";import{consumedEvents as r,isEventsSource as i}from"../Syntax/CaptureEventsSource.js";import{dependencySourcesOf as a}from"../Syntax/DependencySources.js";import{ParserContext as o}from"./ParserContext.js";import{PublicEventUsageCollector as s}from"./PublicEventUsageCollector.js";import{validatePublicEventMetadata as c}from"./PublicEventMetadataValidator.js";import{validateCaptureEventFixtures as l,validateEventSourceKeys as u}from"./CaptureEventFixturesValidator.js";function validatePublicEventUsage(n,r){c(n,r);let i=new t(n),a=new t(n,i.declarations.filter(e=>e.kind===`event`));for(let{slice:e,scope:t}of i.slices)validateOwnCaptureReactions(n,e,t,a,r),u(e,r);if(i.declarations.some(e=>e.node.kind===`EventSyntax`&&(e.node.visibility===`Public`||e.node.origin!=null))||n.imports.some(e=>e.visibility===`Public`||e.origin!=null)||i.slices.some(({slice:e})=>e.direction!=null||usesEventSource(e)||targetsEvent(e,i))){for(let{slice:e,scope:t}of i.slices)validateSlice(n,e,t,i,a,r);for(let t of n.seeds?.flatMap(e=>e.groups.flatMap(e=>e.events))??[]){let i=resolve(n,a,[],t.event,t,!0,r);if(i?.visibility!==`Public`)continue;let o=i.origin==null?e.PublicEventRequiresOutboundTranslation:e.ForeignPublicEventProduced;r.error(o,`Seed cannot append public event '${t.event}'; public production belongs to outbound translation, and foreign contracts cannot be produced locally.`,t.location)}}}function validateSlice(t,r,i,a,o,c){let u=new s;u.visitSlice(r);let d=[],f=r.type===`Translate`&&r.direction===`Outbound`,p=new Set(r.readModels.map(e=>e.name));for(let{target:n,node:a}of u.projectionTargets){let s=p.has(n)?void 0:resolve(t,o,i,n,a,!1,c);s!==void 0&&(f?(d.push({node:s,output:!0}),validateUse(r,n,a,!0,!1,s,c)):c.error(e.EventTargetOutsideOutboundTranslation,`'${n}' is an event: a projection or reducer may only target an event in an explicitly outbound Translate slice.`,a.location))}if((r.type!==`Translate`||r.direction!==`Inbound`)&&!f)for(let t of u.eventSources)c.error(e.EventsSourceOutsideInboundTranslation,`'source events' reads another application's public events and belongs to a Translate slice with 'direction inbound', not '${r.name}'.`,t.location);let m=/* @__PURE__ */ new Map;for(let e of u.uses){let n=resolve(t,e.node.kind===`ProducesSyntax`?a:o,i,e.name,e.node,e.output,c);n!==void 0&&(d.push({node:n,output:e.output}),validateUse(r,e.name,e.node,e.output,e.command,n,c),recordCaptureOrigin(e.node,n,m))}validateCaptureOrigins(r,m,c),l(r,i,o,c);for(let e of u.allEvents){let n=a.declarations.filter(e=>e.kind===`event`).map(e=>e.node);for(let i of[...n,...t.imports.filter(e=>e.visibility===`Public`)])d.push({node:i,output:!1}),validateUse(r,i.kind===`ImportSyntax`?i.qualifiedName:i.name,e,!1,!1,i,c)}if(r.type!==`Translate`||(r.direction==null&&(n(r).some(e=>e.visibility===`Public`)||d.some(e=>e.node.visibility===`Public`))&&c.error(e.PublicTranslationRequiresDirection,`A Translate slice using public events requires an explicit 'direction inbound' or 'direction outbound'. Legacy translations without public metadata remain inbound.`,r.location),r.direction!==`Outbound`))return;let h=new Set(d.filter(e=>e.output&&e.node.visibility===`Public`&&e.node.origin==null).map(e=>e.node)).size;h!==1&&c.error(e.OutboundPublicEventCount,`Outbound Translate slice '${r.name}' must produce exactly one local public event type; found ${h}.`,r.location);for(let t of r.captures)c.error(e.TranslationConstructDirection,`An outbound translation consumes private local events, not an external-data capture. Capture belongs to inbound translation.`,t.location)}function validateOwnCaptureReactions(t,n,r,i,a){if(n.type!==`Translate`||n.direction!=null)return;let c=new s;c.visitSlice(n);let l=new o(a.reader,a.path),u=new Set(c.uses.filter(e=>e.node.kind===`CaptureAppendSyntax`).map(e=>resolve(t,i,r,e.name,e.node,!0,l)).filter(e=>e!==void 0));for(let o of n.reactions.filter(e=>e.from==null)){let n=/* @__PURE__ */ new Map;for(let e of o.triggers){if(e.source.kind!==`NamedTriggerSourceSyntax`)continue;let a=e.source,o=resolve(t,i,r,a.name,a,!1,l);o!==void 0&&u.has(o)&&!n.has(o)&&n.set(o,a.name)}n.size!==0&&a.warning(e.DirectionlessTranslationReactsToOwnCapture,`Reaction '${o.name}' reacts to events appended by a capture in the same directionless Translate slice (${[...n.values()].join(`, `)}); keep the capture in this Translate slice and move the reaction to an Automation slice.`,o.location)}}function recordCaptureOrigin(e,t,n){if(e.kind!==`CaptureSourceSettingSyntax`)return;let r=publicOrigin(t);r!==void 0&&n.set(e,r)}function publicOrigin(e){if(e.visibility!==`Public`)return;let t=e.origin??``;return t.trim().length>0?t:void 0}function validateCaptureOrigins(t,n,a){for(let o of t.captures){let t=o.source;if(t==null||!i(t))continue;let s=[...new Set(r(t).flatMap(e=>{let t=n.get(e);return t==null?[]:[t]}))].sort();s.length<2||a.error(e.CaptureEventsFromSeveralOrigins,`The 'from' events of capture '${o.name}' originate from several event stores (${s.join(`, `)}); a capture reads one event store - split it into one capture per origin.`,t.location)}}function validateUse(t,n,r,i,a,o,s){let c=o.origin!=null,l=o.visibility===`Public`,error=(e,t)=>s.error(e,t,r.location);i?(a&&l&&error(e.CommandProducesPublicEvent,`Command cannot produce public event '${n}'; publish through an outbound Translate slice.`),t.type===`Translate`&&t.direction===`Outbound`&&!l&&error(e.OutboundTranslationOutput,`Outbound translation must produce its one local public event, not private event '${n}'.`),c&&error(e.ForeignPublicEventProduced,`Foreign public event '${n}' cannot be produced locally; translate it into a private local event.`),l&&!c&&(t.type!==`Translate`||t.direction!==`Outbound`)&&error(e.PublicEventRequiresOutboundTranslation,`Local public event '${n}' may only be produced by an explicitly outbound Translate slice.`),t.type===`Translate`&&(t.direction??`Inbound`)===`Inbound`&&(l||c)&&error(e.InboundTranslationOutput,`Inbound translation must produce private local events, not '${n}'.`)):(c&&(t.type!==`Translate`||t.direction!==`Inbound`)&&error(e.ForeignPublicEventConsumer,`Foreign public event '${n}' may only be consumed by an explicitly inbound Translate slice.`),t.type===`Translate`&&t.direction===`Outbound`&&(l||c)&&error(e.OutboundTranslationInput,`Outbound translation must consume private local events, not '${n}'.`),t.type!==`Translate`||t.direction!==`Inbound`||l&&c||error(e.InboundTranslationInput,`Explicitly inbound translation must consume foreign public events, not '${n}'.`))}function resolve(t,n,r,i,a,o,s){let c=n.resolveFromScope(i,r);if(c.declaration?.node.kind===`EventSyntax`)return c.declaration.node;if(c.kind===`operation`)return;if(c.kind===`ambiguous`){s.warning(e.AmbiguousReference,`Ambiguous event reference '${i}'; qualify it with its owning module, feature and slice.`,a.location);return}let l=t.imports.filter(e=>e.qualifiedName.split(`.`).at(-1)===i||e.qualifiedName===i);if(l.length===1){let t=l[0],o=n.resolveFromScope(t.qualifiedName,r);if(o.declaration?.node.kind===`EventSyntax`)return o.declaration.node;if(o.kind===`ambiguous`){s.warning(e.AmbiguousReference,`Ambiguous imported event reference '${i}'; qualify its declaration.`,a.location);return}return t.visibility===`Public`?t:void 0}l.length>1?s.warning(e.AmbiguousReference,`Ambiguous imported event reference '${i}'; use its qualified name.`,a.location):(o&&a.kind!==`CaptureAppendSyntax`||a.kind===`CaptureSourceSettingSyntax`)&&!s.diagnostics.some(t=>t.code===e.UnknownEvent&&t.location.path===a.location.path&&t.location.line===a.location.line&&t.location.column===a.location.column)&&reportUnknownEvent(i,a,s)}function reportUnknownEvent(t,n,r){let i=`Unknown event '${t}' - declare its contract before classifying its usage.`;n.kind===`CaptureSourceSettingSyntax`&&t.includes(`.`)?r.error(e.UnknownEvent,i,n.location):r.warning(e.UnknownEvent,i,n.location)}function usesEventSource(e){return e.captures.some(e=>e.source!=null&&i(e.source))}function targetsEvent(e,t){return[...e.projections.map(e=>e.readModel),...(a(e).reducers??[]).map(e=>e.readModel)].some(e=>e!=null&&t.declarations.some(t=>t.kind===`event`&&t.name===e))}export{validatePublicEventUsage};
2
2
  //# sourceMappingURL=PublicEventUsageValidator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PublicEventUsageValidator.js","names":["validatePublicEventMetadata","application","context","resolver","AuthoringProductionResolver","events","declaration","slice","scope","validateEventSourceKeys","imported","seed","group","contract","code","DiagnosticCodes","collector","PublicEventUsageCollector","contracts","explicitOutbound","readModels","readModel","target","node","source","captureOrigins","use","validateCaptureEventFixtures","all","declarations","eventDeclarations","event","outputs","capture","resolutionContext","ParserContext","appended","reaction","matching","trigger","origin","isEventsSource","origins","consumedEvents","setting","foreign","publicEvent","message","output","command","name","resolution","imports","local","diagnostic","projection","dependencySourcesOf","reducer"],"sources":["../../../../../../Compiler/Parsing/PublicEventUsageValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { AuthoringProductionKind, AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { EventSyntax, ImportSyntax } from '../Syntax/Declarations';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { consumedEvents, isEventsSource } from '../Syntax/CaptureEventsSource';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\nimport { TranslationDirection } from '../Syntax/TranslationDirection';\nimport { ParserContext } from './ParserContext';\nimport { PublicEventUsageCollector } from './PublicEventUsageCollector';\nimport { validatePublicEventMetadata } from './PublicEventMetadataValidator';\nimport { validateCaptureEventFixtures, validateEventSourceKeys } from './CaptureEventFixturesValidator';\n\n/** Validates public contract boundaries against the complete assembled declaration inventory. */\nexport function validatePublicEventUsage(application: ApplicationSyntax, context: ParserContext): void {\n validatePublicEventMetadata(application, context);\n const resolver = new AuthoringProductionResolver(application);\n const events = new AuthoringProductionResolver(application, resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event));\n for (const { slice, scope } of resolver.slices) {\n validateOwnCaptureReactions(application, slice, scope, events, context);\n validateEventSourceKeys(slice, context);\n }\n if (!resolver.declarations.some(declaration => declaration.node.kind === 'EventSyntax' && ((declaration.node as EventSyntax).visibility === EventVisibility.Public || (declaration.node as EventSyntax).origin != null)) &&\n !application.imports.some(imported => imported.visibility === EventVisibility.Public || imported.origin != null) &&\n !resolver.slices.some(({ slice }) => slice.direction != null || usesEventSource(slice) || targetsEvent(slice, resolver))) return;\n for (const { slice, scope } of resolver.slices) validateSlice(application, slice, scope, resolver, events, context);\n for (const seed of application.seeds?.flatMap(seed => seed.groups.flatMap(group => group.events)) ?? []) {\n const contract = resolve(application, events, [], seed.event, seed, true, context);\n if (contract?.visibility !== EventVisibility.Public) continue;\n const code = contract.origin == null ? DiagnosticCodes.PublicEventRequiresOutboundTranslation : DiagnosticCodes.ForeignPublicEventProduced;\n context.error(code, `Seed cannot append public event '${seed.event}'; public production belongs to outbound translation, and foreign contracts cannot be produced locally.`, seed.location);\n }\n}\n\nfunction validateSlice(application: ApplicationSyntax, slice: SliceSyntax, scope: readonly string[], resolver: AuthoringProductionResolver, events: AuthoringProductionResolver, context: ParserContext): void {\n const collector = new PublicEventUsageCollector();\n collector.visitSlice(slice);\n const contracts: { node: EventSyntax | ImportSyntax; output: boolean }[] = [];\n const explicitOutbound = slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound;\n const readModels = new Set(slice.readModels.map(readModel => readModel.name));\n for (const { target, node } of collector.projectionTargets) {\n // '=> Name' names a read model unless it resolves to an event: then the projection or reducer publishes that event.\n const contract = readModels.has(target) ? undefined : resolve(application, events, scope, target, node, false, context);\n if (contract === undefined) continue;\n if (!explicitOutbound) {\n context.error(DiagnosticCodes.EventTargetOutsideOutboundTranslation, `'${target}' is an event: a projection or reducer may only target an event in an explicitly outbound Translate slice.`, node.location);\n continue;\n }\n contracts.push({ node: contract, output: true });\n validateUse(slice, target, node, true, false, contract, context);\n }\n // An outbound slice with a capture is already refused as a whole by the translation-direction check below.\n if (!(slice.type === 'Translate' && slice.direction === TranslationDirection.Inbound) && !explicitOutbound) {\n for (const source of collector.eventSources) context.error(DiagnosticCodes.EventsSourceOutsideInboundTranslation, `'source events' reads another application's public events and belongs to a Translate slice with 'direction inbound', not '${slice.name}'.`, source.location);\n }\n const captureOrigins = new Map<SyntaxNode, string>();\n for (const use of collector.uses) {\n const contract = resolve(application, use.node.kind === 'ProducesSyntax' ? resolver : events, scope, use.name, use.node, use.output, context);\n if (contract === undefined) continue;\n contracts.push({ node: contract, output: use.output });\n validateUse(slice, use.name, use.node, use.output, use.command, contract, context);\n recordCaptureOrigin(use.node, contract, captureOrigins);\n }\n validateCaptureOrigins(slice, captureOrigins, context);\n validateCaptureEventFixtures(slice, scope, events, context);\n // 'all' subscribes to every event type; 'every' maps only the projection's existing inputs.\n for (const all of collector.allEvents) {\n const declarations = resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event).map(declaration => declaration.node as EventSyntax);\n for (const contract of [...declarations, ...application.imports.filter(imported => imported.visibility === EventVisibility.Public)]) {\n contracts.push({ node: contract, output: false });\n validateUse(slice, contract.kind === 'ImportSyntax' ? contract.qualifiedName : contract.name, all, false, false, contract, context);\n }\n }\n if (slice.type !== 'Translate') return;\n if (slice.direction == null && (eventDeclarations(slice).some(event => event.visibility === EventVisibility.Public) || contracts.some(contract => contract.node.visibility === EventVisibility.Public))) {\n context.error(DiagnosticCodes.PublicTranslationRequiresDirection, \"A Translate slice using public events requires an explicit 'direction inbound' or 'direction outbound'. Legacy translations without public metadata remain inbound.\", slice.location);\n }\n if (slice.direction !== TranslationDirection.Outbound) return;\n const outputs = new Set(contracts.filter(contract => contract.output && contract.node.visibility === EventVisibility.Public && contract.node.origin == null).map(contract => contract.node)).size;\n if (outputs !== 1) context.error(DiagnosticCodes.OutboundPublicEventCount, `Outbound Translate slice '${slice.name}' must produce exactly one local public event type; found ${outputs}.`, slice.location);\n for (const capture of slice.captures) context.error(DiagnosticCodes.TranslationConstructDirection, 'An outbound translation consumes private local events, not an external-data capture. Capture belongs to inbound translation.', capture.location);\n}\n\nfunction validateOwnCaptureReactions(application: ApplicationSyntax, slice: SliceSyntax, scope: readonly string[], events: AuthoringProductionResolver, context: ParserContext): void {\n if (slice.type !== 'Translate' || slice.direction != null) return;\n const collector = new PublicEventUsageCollector();\n collector.visitSlice(slice);\n // Resolution diagnostics belong to the existing reference validators, not this co-location warning.\n const resolutionContext = new ParserContext(context.reader, context.path);\n const appended = new Set(collector.uses.filter(use => use.node.kind === 'CaptureAppendSyntax')\n .map(use => resolve(application, events, scope, use.name, use.node, true, resolutionContext)).filter(node => node !== undefined));\n for (const reaction of slice.reactions.filter(reaction => reaction.from == null)) {\n const matching = new Map<EventSyntax | ImportSyntax, string>();\n for (const trigger of reaction.triggers) {\n if (trigger.source.kind !== 'NamedTriggerSourceSyntax') continue;\n const source = trigger.source;\n const node = resolve(application, events, scope, source.name, source, false, resolutionContext);\n if (node !== undefined && appended.has(node) && !matching.has(node)) matching.set(node, source.name);\n }\n if (matching.size === 0) continue;\n context.warning(DiagnosticCodes.DirectionlessTranslationReactsToOwnCapture,\n `Reaction '${reaction.name}' reacts to events appended by a capture in the same directionless Translate slice (${[...matching.values()].join(', ')}); keep the capture in this Translate slice and move the reaction to an Automation slice.`, reaction.location);\n }\n}\n\nfunction recordCaptureOrigin(node: SyntaxNode, contract: EventSyntax | ImportSyntax, captureOrigins: Map<SyntaxNode, string>): void {\n if (node.kind !== 'CaptureSourceSettingSyntax') return;\n const origin = publicOrigin(contract);\n if (origin !== undefined) captureOrigins.set(node, origin);\n}\n\nfunction publicOrigin(contract: EventSyntax | ImportSyntax): string | undefined {\n if (contract.visibility !== EventVisibility.Public) return undefined;\n const origin = contract.origin ?? '';\n return origin.trim().length > 0 ? origin : undefined;\n}\n\nfunction validateCaptureOrigins(slice: SliceSyntax, captureOrigins: Map<SyntaxNode, string>, context: ParserContext): void {\n for (const capture of slice.captures) {\n const source = capture.source;\n if (source == null || !isEventsSource(source)) continue;\n const origins = [...new Set(consumedEvents(source).flatMap(setting => {\n const origin = captureOrigins.get(setting);\n return origin == null ? [] : [origin];\n }))].sort();\n if (origins.length < 2) continue;\n context.error(DiagnosticCodes.CaptureEventsFromSeveralOrigins, `The 'from' events of capture '${capture.name}' originate from several event stores (${origins.join(', ')}); a capture reads one event store - split it into one capture per origin.`, source.location);\n }\n}\n\nfunction validateUse(slice: SliceSyntax, name: string, node: SyntaxNode, output: boolean, command: boolean, contract: EventSyntax | ImportSyntax, context: ParserContext): void {\n const foreign = contract.origin != null;\n const publicEvent = contract.visibility === EventVisibility.Public;\n const error = (code: string, message: string) => context.error(code, message, node.location);\n if (output) {\n if (command && publicEvent) error(DiagnosticCodes.CommandProducesPublicEvent, `Command cannot produce public event '${name}'; publish through an outbound Translate slice.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound && !publicEvent) error(DiagnosticCodes.OutboundTranslationOutput, `Outbound translation must produce its one local public event, not private event '${name}'.`);\n if (foreign) error(DiagnosticCodes.ForeignPublicEventProduced, `Foreign public event '${name}' cannot be produced locally; translate it into a private local event.`);\n if (publicEvent && !foreign && (slice.type !== 'Translate' || slice.direction !== TranslationDirection.Outbound)) error(DiagnosticCodes.PublicEventRequiresOutboundTranslation, `Local public event '${name}' may only be produced by an explicitly outbound Translate slice.`);\n if (slice.type === 'Translate' && (slice.direction ?? TranslationDirection.Inbound) === TranslationDirection.Inbound && (publicEvent || foreign)) error(DiagnosticCodes.InboundTranslationOutput, `Inbound translation must produce private local events, not '${name}'.`);\n } else {\n if (foreign && (slice.type !== 'Translate' || slice.direction !== TranslationDirection.Inbound)) error(DiagnosticCodes.ForeignPublicEventConsumer, `Foreign public event '${name}' may only be consumed by an explicitly inbound Translate slice.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound && (publicEvent || foreign)) error(DiagnosticCodes.OutboundTranslationInput, `Outbound translation must consume private local events, not '${name}'.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Inbound && (!publicEvent || !foreign)) error(DiagnosticCodes.InboundTranslationInput, `Explicitly inbound translation must consume foreign public events, not '${name}'.`);\n }\n}\n\nfunction resolve(application: ApplicationSyntax, resolver: AuthoringProductionResolver, scope: readonly string[], name: string, use: SyntaxNode, output: boolean, context: ParserContext): EventSyntax | ImportSyntax | undefined {\n const resolution = resolver.resolveFromScope(name, scope);\n if (resolution.declaration?.node.kind === 'EventSyntax') return resolution.declaration.node as EventSyntax;\n if (resolution.kind === AuthoringProductionKind.Operation) return undefined;\n if (resolution.kind === AuthoringProductionKind.Ambiguous) {\n context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous event reference '${name}'; qualify it with its owning module, feature and slice.`, use.location);\n return undefined;\n }\n const imports = application.imports.filter(imported => imported.qualifiedName.split('.').at(-1) === name || imported.qualifiedName === name);\n if (imports.length === 1) {\n const imported = imports[0];\n const local = resolver.resolveFromScope(imported.qualifiedName, scope);\n if (local.declaration?.node.kind === 'EventSyntax') return local.declaration.node as EventSyntax;\n if (local.kind === AuthoringProductionKind.Ambiguous) {\n context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous imported event reference '${name}'; qualify its declaration.`, use.location);\n return undefined;\n }\n return imported.visibility === EventVisibility.Public ? imported : undefined;\n }\n if (imports.length > 1) context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous imported event reference '${name}'; use its qualified name.`, use.location);\n else if (((output && use.kind !== 'CaptureAppendSyntax') || use.kind === 'CaptureSourceSettingSyntax') && !context.diagnostics.some(diagnostic => diagnostic.code === DiagnosticCodes.UnknownEvent && diagnostic.location.path === use.location.path && diagnostic.location.line === use.location.line && diagnostic.location.column === use.location.column)) {\n context.warning(DiagnosticCodes.UnknownEvent, `Unknown event '${name}' - declare its contract before classifying its usage.`, use.location);\n }\n return undefined;\n}\n\nfunction usesEventSource(slice: SliceSyntax): boolean {\n return slice.captures.some(capture => capture.source != null && isEventsSource(capture.source));\n}\n\nfunction targetsEvent(slice: SliceSyntax, resolver: AuthoringProductionResolver): boolean {\n const targets = [...slice.projections.map(projection => projection.readModel), ...(dependencySourcesOf(slice).reducers ?? []).map(reducer => reducer.readModel)];\n return targets.some(target => target != null && resolver.declarations.some(declaration => declaration.kind === AuthoringProductionKind.Event && declaration.name === target));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PublicEventUsageValidator.js","names":["validatePublicEventMetadata","application","context","resolver","AuthoringProductionResolver","events","declaration","slice","scope","validateEventSourceKeys","imported","seed","group","contract","code","DiagnosticCodes","collector","PublicEventUsageCollector","contracts","explicitOutbound","readModels","readModel","target","node","source","captureOrigins","use","validateCaptureEventFixtures","all","declarations","eventDeclarations","event","outputs","capture","resolutionContext","ParserContext","appended","reaction","matching","trigger","origin","isEventsSource","origins","consumedEvents","setting","foreign","publicEvent","message","output","command","name","resolution","imports","local","diagnostic","projection","dependencySourcesOf","reducer"],"sources":["../../../../../../Compiler/Parsing/PublicEventUsageValidator.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { AuthoringProductionKind, AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { EventSyntax, ImportSyntax } from '../Syntax/Declarations';\nimport { eventDeclarations } from '../Syntax/EventDeclarations';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { consumedEvents, isEventsSource } from '../Syntax/CaptureEventsSource';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { ApplicationSyntax, SliceSyntax } from '../Syntax/Structure';\nimport { SyntaxNode } from '../Syntax/SyntaxNode';\nimport { TranslationDirection } from '../Syntax/TranslationDirection';\nimport { ParserContext } from './ParserContext';\nimport { PublicEventUsageCollector } from './PublicEventUsageCollector';\nimport { validatePublicEventMetadata } from './PublicEventMetadataValidator';\nimport { validateCaptureEventFixtures, validateEventSourceKeys } from './CaptureEventFixturesValidator';\n\n/** Validates public contract boundaries against the complete assembled declaration inventory. */\nexport function validatePublicEventUsage(application: ApplicationSyntax, context: ParserContext): void {\n validatePublicEventMetadata(application, context);\n const resolver = new AuthoringProductionResolver(application);\n const events = new AuthoringProductionResolver(application, resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event));\n for (const { slice, scope } of resolver.slices) {\n validateOwnCaptureReactions(application, slice, scope, events, context);\n validateEventSourceKeys(slice, context);\n }\n if (!resolver.declarations.some(declaration => declaration.node.kind === 'EventSyntax' && ((declaration.node as EventSyntax).visibility === EventVisibility.Public || (declaration.node as EventSyntax).origin != null)) &&\n !application.imports.some(imported => imported.visibility === EventVisibility.Public || imported.origin != null) &&\n !resolver.slices.some(({ slice }) => slice.direction != null || usesEventSource(slice) || targetsEvent(slice, resolver))) return;\n for (const { slice, scope } of resolver.slices) validateSlice(application, slice, scope, resolver, events, context);\n for (const seed of application.seeds?.flatMap(seed => seed.groups.flatMap(group => group.events)) ?? []) {\n const contract = resolve(application, events, [], seed.event, seed, true, context);\n if (contract?.visibility !== EventVisibility.Public) continue;\n const code = contract.origin == null ? DiagnosticCodes.PublicEventRequiresOutboundTranslation : DiagnosticCodes.ForeignPublicEventProduced;\n context.error(code, `Seed cannot append public event '${seed.event}'; public production belongs to outbound translation, and foreign contracts cannot be produced locally.`, seed.location);\n }\n}\n\nfunction validateSlice(application: ApplicationSyntax, slice: SliceSyntax, scope: readonly string[], resolver: AuthoringProductionResolver, events: AuthoringProductionResolver, context: ParserContext): void {\n const collector = new PublicEventUsageCollector();\n collector.visitSlice(slice);\n const contracts: { node: EventSyntax | ImportSyntax; output: boolean }[] = [];\n const explicitOutbound = slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound;\n const readModels = new Set(slice.readModels.map(readModel => readModel.name));\n for (const { target, node } of collector.projectionTargets) {\n // '=> Name' names a read model unless it resolves to an event: then the projection or reducer publishes that event.\n const contract = readModels.has(target) ? undefined : resolve(application, events, scope, target, node, false, context);\n if (contract === undefined) continue;\n if (!explicitOutbound) {\n context.error(DiagnosticCodes.EventTargetOutsideOutboundTranslation, `'${target}' is an event: a projection or reducer may only target an event in an explicitly outbound Translate slice.`, node.location);\n continue;\n }\n contracts.push({ node: contract, output: true });\n validateUse(slice, target, node, true, false, contract, context);\n }\n // An outbound slice with a capture is already refused as a whole by the translation-direction check below.\n if (!(slice.type === 'Translate' && slice.direction === TranslationDirection.Inbound) && !explicitOutbound) {\n for (const source of collector.eventSources) context.error(DiagnosticCodes.EventsSourceOutsideInboundTranslation, `'source events' reads another application's public events and belongs to a Translate slice with 'direction inbound', not '${slice.name}'.`, source.location);\n }\n const captureOrigins = new Map<SyntaxNode, string>();\n for (const use of collector.uses) {\n const contract = resolve(application, use.node.kind === 'ProducesSyntax' ? resolver : events, scope, use.name, use.node, use.output, context);\n if (contract === undefined) continue;\n contracts.push({ node: contract, output: use.output });\n validateUse(slice, use.name, use.node, use.output, use.command, contract, context);\n recordCaptureOrigin(use.node, contract, captureOrigins);\n }\n validateCaptureOrigins(slice, captureOrigins, context);\n validateCaptureEventFixtures(slice, scope, events, context);\n // 'all' subscribes to every event type; 'every' maps only the projection's existing inputs.\n for (const all of collector.allEvents) {\n const declarations = resolver.declarations.filter(declaration => declaration.kind === AuthoringProductionKind.Event).map(declaration => declaration.node as EventSyntax);\n for (const contract of [...declarations, ...application.imports.filter(imported => imported.visibility === EventVisibility.Public)]) {\n contracts.push({ node: contract, output: false });\n validateUse(slice, contract.kind === 'ImportSyntax' ? contract.qualifiedName : contract.name, all, false, false, contract, context);\n }\n }\n if (slice.type !== 'Translate') return;\n if (slice.direction == null && (eventDeclarations(slice).some(event => event.visibility === EventVisibility.Public) || contracts.some(contract => contract.node.visibility === EventVisibility.Public))) {\n context.error(DiagnosticCodes.PublicTranslationRequiresDirection, \"A Translate slice using public events requires an explicit 'direction inbound' or 'direction outbound'. Legacy translations without public metadata remain inbound.\", slice.location);\n }\n if (slice.direction !== TranslationDirection.Outbound) return;\n const outputs = new Set(contracts.filter(contract => contract.output && contract.node.visibility === EventVisibility.Public && contract.node.origin == null).map(contract => contract.node)).size;\n if (outputs !== 1) context.error(DiagnosticCodes.OutboundPublicEventCount, `Outbound Translate slice '${slice.name}' must produce exactly one local public event type; found ${outputs}.`, slice.location);\n for (const capture of slice.captures) context.error(DiagnosticCodes.TranslationConstructDirection, 'An outbound translation consumes private local events, not an external-data capture. Capture belongs to inbound translation.', capture.location);\n}\n\nfunction validateOwnCaptureReactions(application: ApplicationSyntax, slice: SliceSyntax, scope: readonly string[], events: AuthoringProductionResolver, context: ParserContext): void {\n if (slice.type !== 'Translate' || slice.direction != null) return;\n const collector = new PublicEventUsageCollector();\n collector.visitSlice(slice);\n // Resolution diagnostics belong to the existing reference validators, not this co-location warning.\n const resolutionContext = new ParserContext(context.reader, context.path);\n const appended = new Set(collector.uses.filter(use => use.node.kind === 'CaptureAppendSyntax')\n .map(use => resolve(application, events, scope, use.name, use.node, true, resolutionContext)).filter(node => node !== undefined));\n for (const reaction of slice.reactions.filter(reaction => reaction.from == null)) {\n const matching = new Map<EventSyntax | ImportSyntax, string>();\n for (const trigger of reaction.triggers) {\n if (trigger.source.kind !== 'NamedTriggerSourceSyntax') continue;\n const source = trigger.source;\n const node = resolve(application, events, scope, source.name, source, false, resolutionContext);\n if (node !== undefined && appended.has(node) && !matching.has(node)) matching.set(node, source.name);\n }\n if (matching.size === 0) continue;\n context.warning(DiagnosticCodes.DirectionlessTranslationReactsToOwnCapture,\n `Reaction '${reaction.name}' reacts to events appended by a capture in the same directionless Translate slice (${[...matching.values()].join(', ')}); keep the capture in this Translate slice and move the reaction to an Automation slice.`, reaction.location);\n }\n}\n\nfunction recordCaptureOrigin(node: SyntaxNode, contract: EventSyntax | ImportSyntax, captureOrigins: Map<SyntaxNode, string>): void {\n if (node.kind !== 'CaptureSourceSettingSyntax') return;\n const origin = publicOrigin(contract);\n if (origin !== undefined) captureOrigins.set(node, origin);\n}\n\nfunction publicOrigin(contract: EventSyntax | ImportSyntax): string | undefined {\n if (contract.visibility !== EventVisibility.Public) return undefined;\n const origin = contract.origin ?? '';\n return origin.trim().length > 0 ? origin : undefined;\n}\n\nfunction validateCaptureOrigins(slice: SliceSyntax, captureOrigins: Map<SyntaxNode, string>, context: ParserContext): void {\n for (const capture of slice.captures) {\n const source = capture.source;\n if (source == null || !isEventsSource(source)) continue;\n const origins = [...new Set(consumedEvents(source).flatMap(setting => {\n const origin = captureOrigins.get(setting);\n return origin == null ? [] : [origin];\n }))].sort();\n if (origins.length < 2) continue;\n context.error(DiagnosticCodes.CaptureEventsFromSeveralOrigins, `The 'from' events of capture '${capture.name}' originate from several event stores (${origins.join(', ')}); a capture reads one event store - split it into one capture per origin.`, source.location);\n }\n}\n\nfunction validateUse(slice: SliceSyntax, name: string, node: SyntaxNode, output: boolean, command: boolean, contract: EventSyntax | ImportSyntax, context: ParserContext): void {\n const foreign = contract.origin != null;\n const publicEvent = contract.visibility === EventVisibility.Public;\n const error = (code: string, message: string) => context.error(code, message, node.location);\n if (output) {\n if (command && publicEvent) error(DiagnosticCodes.CommandProducesPublicEvent, `Command cannot produce public event '${name}'; publish through an outbound Translate slice.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound && !publicEvent) error(DiagnosticCodes.OutboundTranslationOutput, `Outbound translation must produce its one local public event, not private event '${name}'.`);\n if (foreign) error(DiagnosticCodes.ForeignPublicEventProduced, `Foreign public event '${name}' cannot be produced locally; translate it into a private local event.`);\n if (publicEvent && !foreign && (slice.type !== 'Translate' || slice.direction !== TranslationDirection.Outbound)) error(DiagnosticCodes.PublicEventRequiresOutboundTranslation, `Local public event '${name}' may only be produced by an explicitly outbound Translate slice.`);\n if (slice.type === 'Translate' && (slice.direction ?? TranslationDirection.Inbound) === TranslationDirection.Inbound && (publicEvent || foreign)) error(DiagnosticCodes.InboundTranslationOutput, `Inbound translation must produce private local events, not '${name}'.`);\n } else {\n if (foreign && (slice.type !== 'Translate' || slice.direction !== TranslationDirection.Inbound)) error(DiagnosticCodes.ForeignPublicEventConsumer, `Foreign public event '${name}' may only be consumed by an explicitly inbound Translate slice.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Outbound && (publicEvent || foreign)) error(DiagnosticCodes.OutboundTranslationInput, `Outbound translation must consume private local events, not '${name}'.`);\n if (slice.type === 'Translate' && slice.direction === TranslationDirection.Inbound && (!publicEvent || !foreign)) error(DiagnosticCodes.InboundTranslationInput, `Explicitly inbound translation must consume foreign public events, not '${name}'.`);\n }\n}\n\nfunction resolve(application: ApplicationSyntax, resolver: AuthoringProductionResolver, scope: readonly string[], name: string, use: SyntaxNode, output: boolean, context: ParserContext): EventSyntax | ImportSyntax | undefined {\n const resolution = resolver.resolveFromScope(name, scope);\n if (resolution.declaration?.node.kind === 'EventSyntax') return resolution.declaration.node as EventSyntax;\n if (resolution.kind === AuthoringProductionKind.Operation) return undefined;\n if (resolution.kind === AuthoringProductionKind.Ambiguous) {\n context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous event reference '${name}'; qualify it with its owning module, feature and slice.`, use.location);\n return undefined;\n }\n const imports = application.imports.filter(imported => imported.qualifiedName.split('.').at(-1) === name || imported.qualifiedName === name);\n if (imports.length === 1) {\n const imported = imports[0];\n const local = resolver.resolveFromScope(imported.qualifiedName, scope);\n if (local.declaration?.node.kind === 'EventSyntax') return local.declaration.node as EventSyntax;\n if (local.kind === AuthoringProductionKind.Ambiguous) {\n context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous imported event reference '${name}'; qualify its declaration.`, use.location);\n return undefined;\n }\n return imported.visibility === EventVisibility.Public ? imported : undefined;\n }\n if (imports.length > 1) context.warning(DiagnosticCodes.AmbiguousReference, `Ambiguous imported event reference '${name}'; use its qualified name.`, use.location);\n else if (((output && use.kind !== 'CaptureAppendSyntax') || use.kind === 'CaptureSourceSettingSyntax') && !context.diagnostics.some(diagnostic => diagnostic.code === DiagnosticCodes.UnknownEvent && diagnostic.location.path === use.location.path && diagnostic.location.line === use.location.line && diagnostic.location.column === use.location.column)) {\n reportUnknownEvent(name, use, context);\n }\n return undefined;\n}\n\nfunction reportUnknownEvent(name: string, use: SyntaxNode, context: ParserContext): void {\n const message = `Unknown event '${name}' - declare its contract before classifying its usage.`;\n if (use.kind === 'CaptureSourceSettingSyntax' && name.includes('.')) {\n context.error(DiagnosticCodes.UnknownEvent, message, use.location);\n } else {\n context.warning(DiagnosticCodes.UnknownEvent, message, use.location);\n }\n}\n\nfunction usesEventSource(slice: SliceSyntax): boolean {\n return slice.captures.some(capture => capture.source != null && isEventsSource(capture.source));\n}\n\nfunction targetsEvent(slice: SliceSyntax, resolver: AuthoringProductionResolver): boolean {\n const targets = [...slice.projections.map(projection => projection.readModel), ...(dependencySourcesOf(slice).reducers ?? []).map(reducer => reducer.readModel)];\n return targets.some(target => target != null && resolver.declarations.some(declaration => declaration.kind === AuthoringProductionKind.Event && declaration.name === target));\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{EnumerationMembers as e}from"./EnumerationMembers.js";import{parseGeneration as t}from"./GenerationParser.js";import{parseIdentity as n}from"./IdentityParser.js";import{parseApplicationContext as r}from"./ApplicationContextParser.js";import{misplacedReactionIdentity as i}from"./ReactionIdentityParser.js";import{DiagnosticCodes as a}from"../Diagnostics/DiagnosticCodes.js";import{recordAuthoredDocument as o}from"../Syntax/SourceOptions.js";import{describePlacement as s,documentPlacement as c,isDocumentPlacement as l}from"../Files/PlayPlacement.js";import{parseTriggerDeclaration as u}from"./TriggerDataParser.js";import{pattern as d}from"../Text/patterns.js";import{parseComplianceDirective as f,parseComplianceMarkers as p}from"./ConceptComplianceParser.js";import{parseType as m}from"./DeclarationParsers.js";import{parseValidate as h}from"./CommandParser.js";import{parseDescription as g}from"./DescriptionParser.js";import{FeatureBody as _,featureBodyExpected as v}from"./FeatureBody.js";import{isFileImport as y,parseFileImport as b}from"./FileImportParser.js";import{isFileDirective as x}from"./FileReferences.js";import{collectInputUses as ee}from"./InputUses.js";import{firstWord as S,unescapeIdentifier as C}from"./LineText.js";import{ModuleBody as te,moduleBodyExpected as w,modulePattern as T,parseModule as ne}from"./ModuleBody.js";import{parsePolicy as re}from"./PolicyParser.js";import{parsePurpose as E}from"./PurposeParser.js";import{parseSeed as D}from"./SeedParser.js";import{parseSystem as ie}from"./OperationParser.js";import{parseStateMachine as ae}from"./StateMachineParser.js";import{parseWorkflow as oe}from"./WorkflowParser.js";import{isBlankPublicEventOrigin as se}from"../Syntax/PublicEventInvariants.js";import{stringBodyPattern as O,unescapeString as k}from"../Text/StringLiteral.js";import{parseCanvasPair as A}from"./CanvasPlacement.js";import{parseEventSource as ce}from"./EventSourceParser.js";import{parseExposure as le,parseInstance as ue}from"./CompositionParser.js";import{parseExample as de}from"./SpecificationExampleParser.js";import{parseUiProfile as fe}from"./UiProfileLegacyLayout.js";import{locationOf as j,startOf as M}from"./SourceLine.js";const N=d(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),pe=d(`^time\\s+zone\\s+(configurable\\s+default\\s+)?"(${O})"$`),P=d(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${O})")?$`),F=d(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),I=d(`^@?[a-z_]\\w*$`),L=d(`^persona\\s+([A-Za-z_]\\w*)$`),R=d(`^policy\\s+([A-Za-z_]\\w*)$`),z=d(`^goal\\s+"(${O})"$`),B=d(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),V=d(`^colour\\s+(yellow|pink|green|blue)$`),H=/^[ ]*\t/,U=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],W=/* @__PURE__ */ new Set([`policy`,`authentication`,`onboarding`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),G=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(e,t,s=c){e.deferIdentityValidation=!0,warnOnTabIndentation(e,t);let d=s.length===1?new te(s[0]):void 0,f=s.length>1?new _(s[s.length-1]):void 0,p=d??f,h=null,g=null,v=null,x=!1,C=null,w=null,T=!1,O=!1,A=null,M=[],N=[],F=[],I=[],L=[],R=[],z=[],B=[],V=[],H=[],U=[],G=[],K=[],q=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let t=e.reader.peekSignificant();t!==void 0;t=e.reader.peekSignificant()){e.reader.takeSignificant();let o=S(t.content);if(o===`command`&&/^command\s+reads(?:\s|$)/.test(t.content))O||!l(s)||!/^command\s+reads\s+protected$/.test(t.content)?e.error(a.InvalidCommandReadsDeclaration,`Declare 'command reads protected' once at the application root.`,j(t)):C=`Protected`,O=!0;else if(o===`time`&&/^time\s+zone(?:\s|$)/.test(t.content)){let n=pe.exec(t.content);e.skipBlock(t.indent),T||!l(s)||n===null?e.error(a.InvalidTimeZoneDeclaration,`Declare 'time zone "<id>"' or 'time zone configurable default "<id>"' once at the application root.`,j(t)):w={kind:`TimeZoneSyntax`,id:k(n[2]),configurable:n[1]!==void 0,location:j(t)},T=!0}else if(o===`reaction`)x||!l(s)||!/^reaction\s+batches\s+atomic$/.test(t.content)?e.error(a.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,j(t)):v=`Atomic`,x=!0;else if(o===`runs`)i(e,t);else if(o===`domain`)e.authoredDeclarations=!0,A=parseDomain(e,t,A,Q);else if(Q||=declaresConstruct(o,t,s),e.authoredDeclarations||=o!==`import`&&declaresConstruct(o,t,s),o===`import`&&y(t.content))p===void 0?b(e,t,N):p.tryParse(e,t);else if(o===`import`){let n=P.exec(t.content);if(n===null)e.error(a.InvalidImportDeclaration,`Invalid import '${t.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,j(t));else{let r=n.groups?.origin===void 0?null:k(n.groups.origin);r!==null&&se(r)&&e.error(a.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,j(t)),M.push({kind:`ImportSyntax`,qualifiedName:n[1],origin:r,visibility:r===null?`Private`:`Public`,location:j(t)})}}else if(o===`example`)p===void 0?J.push(de(e,t)):p.tryParse(e,t);else if(o===`eventsource`)B.push(ce(e,t));else if(o===`system`)L.push(ie(e,t));else if(o===`statemachine`)R.push(ae(e,t));else if(o===`workflow`)z.push(oe(e,t));else if(o===`concept`)F.push(parseConcept(e,t));else if(o===`type`)I.push(m(e,t));else if(o===`module`&&!l(s))parseModuleInPlacedFile(e,t,s,d);else if(o===`module`)V.push(ne(e,t));else if(o===`persona`)H.push(parsePersona(e,t));else if(o===`sticky`){let n=parseStickyNote(e,t);n!==null&&U.push(n)}else if(o===`seed`)q.push(D(e.valueContext,t));else if(o===`purpose`&&p!==void 0)p.tryParse(e,t);else if(o===`purpose`)K.push(E(e,t));else if(o===`context`)g=r(e,t,g,s);else if(o===`identity`)h=n(e,t,h);else if(o===`policy`){let n=re(e,t);G.some(e=>e.name===n.name)&&e.error(a.DuplicateDeclaration,`Duplicate declaration of policy '${n.name}' - policy names must be unique`,n.location),G.push(n)}else if(o===`exposure`)X.push(le(e,t));else if(o===`instance`)Z.push(ue(e,t));else if(o===`trigger`){let n=u(e,t),r=/^trigger\s+([A-Za-z_]\w*)$/.exec(t.content)?.[1];r!==void 0&&Y.push({name:r,data:n})}else W.has(o)?o===`behavior`||o===`layout`?ee(e,t):o===`ui`?fe(e,t):e.skipOpaqueBlock(t.indent):p?.tryParse(e,t)!==!0&&reportUnexpectedTopLevel(e,t,s)}d===void 0?f!==void 0&&V.unshift(place(s,f.build(e.start,!0),e.start)):V.unshift(d.build(e.start,!0));let $={kind:`ApplicationSyntax`,...C===null?{}:{commandReadMode:C},...w===null?{}:{timeZone:w},...g===null?{}:{context:g},...v===null?{}:{reactionProductionMode:v},...h===null?{}:{identity:h},sourceOptions:e.sourceOptions,domain:A,imports:M,concepts:F,types:I,systems:L,...R.length>0?{stateMachines:R}:{},...z.length>0?{workflows:z}:{},eventSources:B,examples:J,modules:V,personas:H,policies:G,purposes:K,seeds:q,declaredTriggers:Y,fileImports:N,...X.length>0?{exposures:X}:{},...U.length>0?{stickyNotes:U}:{},...Z.length>0?{instanceContributions:Z}:{},location:e.start};return e.authoredDeclarations&&o($),$}function declaresConstruct(e,t,n){return e===`import`?P.test(t.content):e===`module`?l(n):e===`identity`?t.content===`identity`:e===`context`?t.content===`context`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`statemachine`||e===`workflow`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||W.has(e)}function parseModuleInPlacedFile(e,t,n,r){let i=T.exec(t.content)?.[1]??``;r!==void 0&&i===n[0]?(e.authoredDeclarations=!0,r.parseChildren(e,t)):(e.error(a.ModuleInPlacedFile,`This file is imported into ${s(n)}, so it cannot declare module '${i}' - import it at the top level of a document instead`,j(t)),e.skipBlock(t.indent))}function reportUnexpectedTopLevel(e,t,n){let r=S(t.content);if(l(n)){let n=G.has(r)?` - '${r}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, sticky note, authentication, onboarding, identity, context, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;e.error(a.UnknownTopLevelConstruct,`Unexpected '${r}' at the top level${n}`,j(t))}else{let i=n.length===1?w:v;e.error(a.UnexpectedInPlacedFile,`Unexpected '${r}' in a file imported into ${s(n)} - expected an application declaration or ${i}`,j(t))}e.skipBlock(t.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(e,t,n,r){let i=N.exec(t.content);return i===null?(e.error(a.InvalidDomainDeclaration,`Invalid domain declaration '${t.content}' - expected 'domain <Qualified.Name>'`,j(t)),n):n===null?(r&&e.error(a.DomainNotFirst,`'domain' must be declared before any other construct`,j(t)),{kind:`DomainSyntax`,name:i[1],location:j(t)}):(e.error(a.DuplicateDomain,`The document already declares a domain - a document can have at most one`,j(t)),n)}function warnOnTabIndentation(e,t){let n=!1;for(let r of t)r.raw.trimStart().startsWith("```")?n=!n:!n&&H.test(r.raw)&&e.warning(a.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,M(r))}function parseConcept(n,r){let i=F.exec(r.content);if(i===null)return n.error(a.InvalidConceptDeclaration,`Invalid concept declaration '${r.content}' - expected 'concept <Name> : <Type>'`,j(r)),n.skipBlock(r.indent),{kind:`ConceptSyntax`,name:S(r.content),type:``,attributes:[],values:[],location:j(r)};let[,o,s,c]=i,l=p(n,r,o,c);s!==`Enum`&&!U.includes(s)&&n.error(a.UnknownPrimitiveType,`Unknown primitive type '${s}' - expected ${U.join(`, `)} or Enum`,j(r));let u=[],d=new e,m=null,_=!1,v=null,y=[];for(let e=n.peekChild(r.indent);e!==void 0;e=n.peekChild(r.indent)){n.reader.takeSignificant();let r=s===`Enum`?d.tryNumbered(n,e):void 0;if(r!==void 0)u.push(r);else if(S(e.content)===`description`&&(s!==`Enum`||e.content!==`description`||n.peekChild(e.indent)?.content.startsWith("```")===!0))v=g(n,e,v,`Concept '${o}'`);else if(x(e))continue;else if(S(e.content)===`validate`){s===`Enum`&&e.content===`validate`&&n.peekChild(e.indent)===void 0&&n.warning(a.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${o}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,j(e));let t=h(n,e,`concept`,o);t!==void 0&&y.push(t)}else if(S(e.content)===`generate`&&(s!==`Enum`||e.content!==`generate`)){_&&n.error(a.DuplicateGeneration,`Concept '${o}' declares generation more than once.`,j(e));let r=t(n,e,s);_||(m=r),_=!0}else f(n,e,o,l)||(s===`Enum`&&I.test(e.content)?u.push(C(e.content)):s===`Enum`?n.error(a.InvalidEnumerationValue,`Invalid enum value '${e.content}' - expected an identifier`,j(e)):(n.error(a.UnknownConceptDirective,`Unexpected '${e.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'`,j(e)),n.skipBlock(e.indent)))}let b=d.finish(n,r,u.length);return{kind:`ConceptSyntax`,name:o,type:s,attributes:l,values:u,validations:y,description:v,...m===null?{}:{generation:m},...b===void 0?{}:{valueNumbers:b},location:j(r)}}function parsePersona(e,t){let n=L.exec(t.content)?.[1]??``;n===``&&e.error(a.InvalidPersonaDeclaration,`Invalid persona declaration '${t.content}' - expected 'persona <Name>'`,j(t));let r=null,i=[],o=[],s=null,c=null;for(let l=e.peekChild(t.indent);l!==void 0;l=e.peekChild(t.indent)){e.reader.takeSignificant();let t=S(l.content);if(t===`description`)r=g(e,l,r,`Persona '${n}'`);else if(t===`goal`){let t=z.exec(l.content);t===null?e.error(a.InvalidPersonaDeclaration,`Invalid goal '${l.content}' - expected 'goal "<text>"'`,j(l)):o.push(k(t[1]))}else if(t===`position`)s=A(e,l,`position`,`x`,`y`,s,!0)??s;else if(t===`size`)c=A(e,l,`size`,`width`,`height`,c,!1)??c;else if(t===`policy`){let t=R.exec(l.content);t===null?e.error(a.InvalidPersonaPolicyReference,`Invalid policy reference '${l.content}' - expected 'policy <Name>'`,j(l)):i.push(t[1])}else e.error(a.UnknownPersonaDirective,`Unexpected '${t}' in persona body - expected description, goal, policy, position or size`,j(l)),e.skipBlock(l.indent)}return{kind:`PersonaSyntax`,name:n,description:r,policies:i,...o.length>0?{goals:o}:{},...s===null?{}:{x:s[0],y:s[1]},...c===null?{}:{width:c[0],height:c[1]},location:j(t)}}function parseStickyNote(e,t){let n=B.exec(t.content);if(n===null)return e.error(a.InvalidPersonaDeclaration,`Invalid sticky note declaration '${t.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`,j(t)),e.skipBlock(t.indent),null;let r=null,i=null,o=null,s=null;for(let n=e.peekChild(t.indent);n!==void 0;n=e.peekChild(t.indent)){e.reader.takeSignificant();let t=S(n.content);if(t===`description`)r=g(e,n,r,`A sticky note`);else if(t===`colour`){let t=V.exec(n.content);t===null?e.error(a.InvalidPersonaDeclaration,`Invalid colour '${n.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`,j(n)):i=t[1]}else t===`position`?o=A(e,n,`position`,`x`,`y`,o,!0)??o:t===`size`?s=A(e,n,`size`,`width`,`height`,s,!1)??s:(e.error(a.UnknownPersonaDirective,`Unexpected '${t}' in sticky note body - expected description, colour, position or size`,j(n)),e.skipBlock(n.indent))}return r===null||o===null?(e.error(a.InvalidPersonaDeclaration,`A sticky note needs a description (the text on it) and a position`,j(t)),null):{kind:`StickyNoteSyntax`,canvas:n[1],text:r,colour:i,x:o[0],y:o[1],width:s===null?null:s[0],height:s===null?null:s[1],location:j(t)}}export{parseApplication};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{EnumerationMembers as e}from"./EnumerationMembers.js";import{misplacedRuleHintForConcept as t}from"./MisplacedRuleHint.js";import{parseGeneration as n}from"./GenerationParser.js";import{parseIdentity as r}from"./IdentityParser.js";import{parseApplicationContext as i}from"./ApplicationContextParser.js";import{misplacedReactionIdentity as a}from"./ReactionIdentityParser.js";import{DiagnosticCodes as o}from"../Diagnostics/DiagnosticCodes.js";import{recordAuthoredDocument as s}from"../Syntax/SourceOptions.js";import{describePlacement as c,documentPlacement as l,isDocumentPlacement as u}from"../Files/PlayPlacement.js";import{parseTriggerDeclaration as d}from"./TriggerDataParser.js";import{pattern as f}from"../Text/patterns.js";import{parseComplianceDirective as p,parseComplianceMarkers as m}from"./ConceptComplianceParser.js";import{parseType as h}from"./DeclarationParsers.js";import{parseValidate as g}from"./CommandParser.js";import{parseDescription as _}from"./DescriptionParser.js";import{FeatureBody as v,featureBodyExpected as y}from"./FeatureBody.js";import{isFileImport as b,parseFileImport as x}from"./FileImportParser.js";import{isFileDirective as S}from"./FileReferences.js";import{collectInputUses as ee}from"./InputUses.js";import{firstWord as C,unescapeIdentifier as w}from"./LineText.js";import{ModuleBody as te,moduleBodyExpected as T,modulePattern as E,parseModule as ne}from"./ModuleBody.js";import{parsePolicy as re}from"./PolicyParser.js";import{parsePurpose as ie}from"./PurposeParser.js";import{parseSeed as ae}from"./SeedParser.js";import{parseSystem as D}from"./OperationParser.js";import{parseStateMachine as oe}from"./StateMachineParser.js";import{parseWorkflow as se}from"./WorkflowParser.js";import{isBlankPublicEventOrigin as ce}from"../Syntax/PublicEventInvariants.js";import{stringBodyPattern as O,unescapeString as k}from"../Text/StringLiteral.js";import{parseCanvasPair as A}from"./CanvasPlacement.js";import{parseEventSource as le}from"./EventSourceParser.js";import{parseExposure as ue,parseInstance as de}from"./CompositionParser.js";import{parseExample as fe}from"./SpecificationExampleParser.js";import{parseUiProfile as pe}from"./UiProfileLegacyLayout.js";import{locationOf as j,startOf as M}from"./SourceLine.js";const N=f(`^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),P=f(`^time\\s+zone\\s+(configurable\\s+default\\s+)?"(${O})"$`),F=f(`^import\\s+([\\w.]+)(?:\\s+from\\s+"(?<origin>${O})")?$`),I=f(`^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@?\\w+)*)$`),L=f(`^@?[a-z_]\\w*$`),R=f(`^persona\\s+([A-Za-z_]\\w*)$`),z=f(`^policy\\s+([A-Za-z_]\\w*)$`),B=f(`^goal\\s+"(${O})"$`),V=f(`^sticky\\s+note\\s+on\\s+(personas|eventsources|givencontexts|seeddata)$`),H=f(`^colour\\s+(yellow|pink|green|blue)$`),U=/^[ ]*\t/,W=[`Uuid`,`String`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`],G=/* @__PURE__ */ new Set([`policy`,`authentication`,`onboarding`,`seed`,`ui`,`theme`,`trigger`,`layout`,`behavior`,`sample`]),K=/* @__PURE__ */ new Set([`slice`,`feature`,`description`,`documentation`,`authorize`,`screen`,`dialog`,`form`,`contribute`,`on`,`uses`]);function parseApplication(e,t,n=l){e.deferIdentityValidation=!0,warnOnTabIndentation(e,t);let c=n.length===1?new te(n[0]):void 0,f=n.length>1?new v(n[n.length-1]):void 0,p=c??f,m=null,g=null,_=null,y=!1,S=null,w=null,T=!1,E=!1,O=null,A=[],M=[],N=[],I=[],L=[],R=[],z=[],B=[],V=[],H=[],U=[],W=[],K=[],q=[],J=[],Y=[],X=[],Z=[],Q=!1;for(let t=e.reader.peekSignificant();t!==void 0;t=e.reader.peekSignificant()){e.reader.takeSignificant();let s=C(t.content);if(s===`command`&&/^command\s+reads(?:\s|$)/.test(t.content))E||!u(n)||!/^command\s+reads\s+protected$/.test(t.content)?e.error(o.InvalidCommandReadsDeclaration,`Declare 'command reads protected' once at the application root.`,j(t)):S=`Protected`,E=!0;else if(s===`time`&&/^time\s+zone(?:\s|$)/.test(t.content)){let r=P.exec(t.content);e.skipBlock(t.indent),T||!u(n)||r===null?e.error(o.InvalidTimeZoneDeclaration,`Declare 'time zone "<id>"' or 'time zone configurable default "<id>"' once at the application root.`,j(t)):w={kind:`TimeZoneSyntax`,id:k(r[2]),configurable:r[1]!==void 0,location:j(t)},T=!0}else if(s===`reaction`)y||!u(n)||!/^reaction\s+batches\s+atomic$/.test(t.content)?e.error(o.InvalidReactionBatchesDeclaration,`Declare 'reaction batches atomic' once at the application root.`,j(t)):_=`Atomic`,y=!0;else if(s===`runs`)a(e,t);else if(s===`domain`)e.authoredDeclarations=!0,O=parseDomain(e,t,O,Q);else if(Q||=declaresConstruct(s,t,n),e.authoredDeclarations||=s!==`import`&&declaresConstruct(s,t,n),s===`import`&&b(t.content))p===void 0?x(e,t,M):p.tryParse(e,t);else if(s===`import`){let n=F.exec(t.content);if(n===null)e.error(o.InvalidImportDeclaration,`Invalid import '${t.content}' - expected 'import <Qualified.Name> [from "<origin>"]'`,j(t));else{let r=n.groups?.origin===void 0?null:k(n.groups.origin);r!==null&&ce(r)&&e.error(o.InvalidImportDeclaration,`An import origin must be a nonblank quoted string`,j(t)),A.push({kind:`ImportSyntax`,qualifiedName:n[1],origin:r,visibility:r===null?`Private`:`Public`,location:j(t)})}}else if(s===`example`)p===void 0?J.push(fe(e,t)):p.tryParse(e,t);else if(s===`eventsource`)B.push(le(e,t));else if(s===`system`)L.push(D(e,t));else if(s===`statemachine`)R.push(oe(e,t));else if(s===`workflow`)z.push(se(e,t));else if(s===`concept`)N.push(parseConcept(e,t));else if(s===`type`)I.push(h(e,t));else if(s===`module`&&!u(n))parseModuleInPlacedFile(e,t,n,c);else if(s===`module`)V.push(ne(e,t));else if(s===`persona`)H.push(parsePersona(e,t));else if(s===`sticky`){let n=parseStickyNote(e,t);n!==null&&U.push(n)}else if(s===`seed`)q.push(ae(e.valueContext,t));else if(s===`purpose`&&p!==void 0)p.tryParse(e,t);else if(s===`purpose`)K.push(ie(e,t));else if(s===`context`)g=i(e,t,g,n);else if(s===`identity`)m=r(e,t,m);else if(s===`policy`){let n=re(e,t);W.some(e=>e.name===n.name)&&e.error(o.DuplicateDeclaration,`Duplicate declaration of policy '${n.name}' - policy names must be unique`,n.location),W.push(n)}else if(s===`exposure`)X.push(ue(e,t));else if(s===`instance`)Z.push(de(e,t));else if(s===`trigger`){let n=d(e,t),r=/^trigger\s+([A-Za-z_]\w*)$/.exec(t.content)?.[1];r!==void 0&&Y.push({name:r,data:n})}else G.has(s)?s===`behavior`||s===`layout`?ee(e,t):s===`ui`?pe(e,t):e.skipOpaqueBlock(t.indent):p?.tryParse(e,t)!==!0&&reportUnexpectedTopLevel(e,t,n)}c===void 0?f!==void 0&&V.unshift(place(n,f.build(e.start,!0),e.start)):V.unshift(c.build(e.start,!0));let $={kind:`ApplicationSyntax`,...S===null?{}:{commandReadMode:S},...w===null?{}:{timeZone:w},...g===null?{}:{context:g},..._===null?{}:{reactionProductionMode:_},...m===null?{}:{identity:m},sourceOptions:e.sourceOptions,domain:O,imports:A,concepts:N,types:I,systems:L,...R.length>0?{stateMachines:R}:{},...z.length>0?{workflows:z}:{},eventSources:B,examples:J,modules:V,personas:H,policies:W,purposes:K,seeds:q,declaredTriggers:Y,fileImports:M,...X.length>0?{exposures:X}:{},...U.length>0?{stickyNotes:U}:{},...Z.length>0?{instanceContributions:Z}:{},location:e.start};return e.authoredDeclarations&&s($),$}function declaresConstruct(e,t,n){return e===`import`?F.test(t.content):e===`module`?u(n):e===`identity`?t.content===`identity`:e===`context`?t.content===`context`:e===`purpose`||e===`example`||e===`exposure`||e===`instance`||e===`eventsource`||e===`system`||e===`statemachine`||e===`workflow`||e===`concept`||e===`type`||e===`persona`||e===`sticky`||G.has(e)}function parseModuleInPlacedFile(e,t,n,r){let i=E.exec(t.content)?.[1]??``;r!==void 0&&i===n[0]?(e.authoredDeclarations=!0,r.parseChildren(e,t)):(e.error(o.ModuleInPlacedFile,`This file is imported into ${c(n)}, so it cannot declare module '${i}' - import it at the top level of a document instead`,j(t)),e.skipBlock(t.indent))}function reportUnexpectedTopLevel(e,t,n){let r=C(t.content);if(u(n)){let n=K.has(r)?` - '${r}' belongs in a module or feature; wrap it in one, or import this file from inside one`:` - expected domain, import, concept, type, policy, persona, sticky note, authentication, onboarding, identity, context, module, seed, trigger, behavior, ui profile, theme, sample data or layout`;e.error(o.UnknownTopLevelConstruct,`Unexpected '${r}' at the top level${n}`,j(t))}else{let i=n.length===1?T:y;e.error(o.UnexpectedInPlacedFile,`Unexpected '${r}' in a file imported into ${c(n)} - expected an application declaration or ${i}`,j(t))}e.skipBlock(t.indent)}function place(e,t,n){let r=t;for(let t=e.length-2;t>=1;t--)r={kind:`FeatureSyntax`,name:e[t],description:null,authorize:null,features:[r],slices:[],fileImports:[],isPlacement:!0,location:n};return{kind:`ModuleSyntax`,name:e[0],description:null,authorize:null,features:[r],fileImports:[],isPlacement:!0,location:n}}function parseDomain(e,t,n,r){let i=N.exec(t.content);return i===null?(e.error(o.InvalidDomainDeclaration,`Invalid domain declaration '${t.content}' - expected 'domain <Qualified.Name>'`,j(t)),n):n===null?(r&&e.error(o.DomainNotFirst,`'domain' must be declared before any other construct`,j(t)),{kind:`DomainSyntax`,name:i[1],location:j(t)}):(e.error(o.DuplicateDomain,`The document already declares a domain - a document can have at most one`,j(t)),n)}function warnOnTabIndentation(e,t){let n=!1;for(let r of t)r.raw.trimStart().startsWith("```")?n=!n:!n&&U.test(r.raw)&&e.warning(o.TabIndentation,`Screenplay is indentation based - use spaces, not tabs`,M(r))}function parseConcept(r,i){let a=I.exec(i.content);if(a===null)return r.error(o.InvalidConceptDeclaration,`Invalid concept declaration '${i.content}' - expected 'concept <Name> : <Type>'`,j(i)),r.skipBlock(i.indent),{kind:`ConceptSyntax`,name:C(i.content),type:``,attributes:[],values:[],location:j(i)};let[,s,c,l]=a,u=m(r,i,s,l);c!==`Enum`&&!W.includes(c)&&r.error(o.UnknownPrimitiveType,`Unknown primitive type '${c}' - expected ${W.join(`, `)} or Enum`,j(i));let d=[],f=new e,h=null,v=!1,y=null,b=[];for(let e=r.peekChild(i.indent);e!==void 0;e=r.peekChild(i.indent)){r.reader.takeSignificant();let i=c===`Enum`?f.tryNumbered(r,e):void 0;if(i!==void 0)d.push(i);else if(C(e.content)===`description`&&(c!==`Enum`||e.content!==`description`||r.peekChild(e.indent)?.content.startsWith("```")===!0))y=_(r,e,y,`Concept '${s}'`);else if(S(e))continue;else if(C(e.content)===`validate`){c===`Enum`&&e.content===`validate`&&r.peekChild(e.indent)===void 0&&r.warning(o.ValidateReadAsEnumerationBlock,`'validate' in enumeration concept '${s}' declares an empty validate block, not a value named 'validate' - write '@validate' for the value`,j(e));let t=g(r,e,`concept`,s);t!==void 0&&b.push(t)}else if(C(e.content)===`generate`&&(c!==`Enum`||e.content!==`generate`)){v&&r.error(o.DuplicateGeneration,`Concept '${s}' declares generation more than once.`,j(e));let t=n(r,e,c);v||(h=t),v=!0}else p(r,e,s,u)||(c===`Enum`&&L.test(e.content)?d.push(w(e.content)):c===`Enum`?r.error(o.InvalidEnumerationValue,`Invalid enum value '${e.content}' - expected an identifier`,j(e)):(r.error(o.UnknownConceptDirective,`Unexpected '${e.content}' in concept body - expected validate, generate, 'file <path>' or '<attribute> reason "<text>"'${t(e.content)}`,j(e)),r.skipBlock(e.indent)))}let x=f.finish(r,i,d.length);return{kind:`ConceptSyntax`,name:s,type:c,attributes:u,values:d,validations:b,description:y,...h===null?{}:{generation:h},...x===void 0?{}:{valueNumbers:x},location:j(i)}}function parsePersona(e,t){let n=R.exec(t.content)?.[1]??``;n===``&&e.error(o.InvalidPersonaDeclaration,`Invalid persona declaration '${t.content}' - expected 'persona <Name>'`,j(t));let r=null,i=[],a=[],s=null,c=null;for(let l=e.peekChild(t.indent);l!==void 0;l=e.peekChild(t.indent)){e.reader.takeSignificant();let t=C(l.content);if(t===`description`)r=_(e,l,r,`Persona '${n}'`);else if(t===`goal`){let t=B.exec(l.content);t===null?e.error(o.InvalidPersonaDeclaration,`Invalid goal '${l.content}' - expected 'goal "<text>"'`,j(l)):a.push(k(t[1]))}else if(t===`position`)s=A(e,l,`position`,`x`,`y`,s,!0)??s;else if(t===`size`)c=A(e,l,`size`,`width`,`height`,c,!1)??c;else if(t===`policy`){let t=z.exec(l.content);t===null?e.error(o.InvalidPersonaPolicyReference,`Invalid policy reference '${l.content}' - expected 'policy <Name>'`,j(l)):i.push(t[1])}else e.error(o.UnknownPersonaDirective,`Unexpected '${t}' in persona body - expected description, goal, policy, position or size`,j(l)),e.skipBlock(l.indent)}return{kind:`PersonaSyntax`,name:n,description:r,policies:i,...a.length>0?{goals:a}:{},...s===null?{}:{x:s[0],y:s[1]},...c===null?{}:{width:c[0],height:c[1]},location:j(t)}}function parseStickyNote(e,t){let n=V.exec(t.content);if(n===null)return e.error(o.InvalidPersonaDeclaration,`Invalid sticky note declaration '${t.content}' - expected 'sticky note on personas', 'sticky note on eventsources', 'sticky note on givencontexts' or 'sticky note on seeddata'`,j(t)),e.skipBlock(t.indent),null;let r=null,i=null,a=null,s=null;for(let n=e.peekChild(t.indent);n!==void 0;n=e.peekChild(t.indent)){e.reader.takeSignificant();let t=C(n.content);if(t===`description`)r=_(e,n,r,`A sticky note`);else if(t===`colour`){let t=H.exec(n.content);t===null?e.error(o.InvalidPersonaDeclaration,`Invalid colour '${n.content}' - expected 'colour yellow', 'colour pink', 'colour green' or 'colour blue'`,j(n)):i=t[1]}else t===`position`?a=A(e,n,`position`,`x`,`y`,a,!0)??a:t===`size`?s=A(e,n,`size`,`width`,`height`,s,!1)??s:(e.error(o.UnknownPersonaDirective,`Unexpected '${t}' in sticky note body - expected description, colour, position or size`,j(n)),e.skipBlock(n.indent))}return r===null||a===null?(e.error(o.InvalidPersonaDeclaration,`A sticky note needs a description (the text on it) and a position`,j(t)),null):{kind:`StickyNoteSyntax`,canvas:n[1],text:r,colour:i,x:a[0],y:a[1],width:s===null?null:s[0],height:s===null?null:s[1],location:j(t)}}export{parseApplication};
2
2
  //# sourceMappingURL=ScreenplayParser.js.map