@cratis/screenplay-language 4.56.0 → 4.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles/chunk-IZGYM33T.js +14 -0
- package/dist/bundles/chunk-IZGYM33T.js.map +7 -0
- package/dist/bundles/index.js +3 -3
- package/dist/bundles/index.js.map +3 -3
- package/dist/bundles/sub-languages/projection/index.js +1 -1
- package/dist/completion-items.d.ts +1 -0
- package/dist/completion-items.d.ts.map +1 -1
- package/dist/completion-planner.d.ts.map +1 -1
- package/dist/diagnostic-codes.d.ts +3 -0
- package/dist/diagnostic-codes.d.ts.map +1 -1
- package/dist/hover-content.d.ts.map +1 -1
- package/dist/keyword-docs.d.ts +4 -0
- package/dist/keyword-docs.d.ts.map +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/bundles/chunk-TWF2T5S4.js +0 -13
- package/dist/bundles/chunk-TWF2T5S4.js.map +0 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{describeEventContext,describeEventContextMember,eventContextMemberAt,eventContextMembers,eventContextMembersAfter,fenceMap,validateEventContextPaths}from"../../chunk-TWF2T5S4.js";var languageId="pdl",KEYWORDS=["projection","sequence","all","every","on","from","key","parent","join","automap","no","children","nested","identified","by","add","subtract","remove","via","with","default","increment","decrement","count","set","unset","clear","events","id","exclude","variant","enters"],BUILTINS=["$eventSourceId","$causedBy","$eventContext"],OPERATORS=["=","+=","-=","=>","."],configuration={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}],indentationRules:{increaseIndentPattern:/^.*(:|\bon\b|\ball\b|\bevery\b|\bchildren\b|\bnested\b|\bparent\b|\bvariant\b)\s*$/,decreaseIndentPattern:/^.*\}.*$/},folding:{offSide:!0,markers:{start:/^\s*(projection|all|every|on|children|nested|parent|variant)/,end:/^\s*$/}},wordPattern:/@?[a-zA-Z_$][\w$-]*/},monarchLanguage={defaultToken:"",tokenPostfix:".pdl",keywords:KEYWORDS,builtins:BUILTINS,operators:OPERATORS,symbols:/[=><!~?:&|+\-*/^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[{include:"@whitespace"},[/`/,{token:"string.template",next:"@templateString"}],[/@[a-zA-Z_$][\w$]*/,"identifier.escape"],[/[A-Z][a-zA-Z_$][\w$]*/,{cases:{"@keywords":"invalid","@default":"identifier"}}],[/[a-z_$][\w$]*/,{cases:{"@keywords":"keyword","@builtins":"variable.predefined","@default":"identifier"}}],[/[{}()[\]]/,"@brackets"],[/=>/,"operator.arrow"],[/@symbols/,{cases:{"@operators":"operator","@default":""}}],[/\d*\.\d+([eE][-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F]+/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,{token:"string.quote",next:"@string"}]],whitespace:[[/[ \t\r\n]+/,""],[/#.*$/,"comment"]],templateString:[[/\$\{/,{token:"delimiter.bracket",next:"@templateExpression"}],[/[^\\`$]+/,"string.template"],[/@escapes/,"string.template.escape"],[/\\./,"string.template.escape.invalid"],[/`/,{token:"string.template",next:"@pop"}]],templateExpression:[[/\}/,{token:"delimiter.bracket",next:"@pop"}],{include:"@root"}],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,{token:"string.quote",next:"@pop"}]]}};var EVENT_CONTEXT_PATH=/\$eventContext\.((?:\w+\.)*)(\w*)$/,CompletionProvider=class{readModels=[];eventSchemas={};eventSequences=[];setReadModels(readModels){this.readModels=readModels||[]}setEventSequences(sequences){this.eventSequences=sequences||[]}setReadModelSchemas(schemas){this.readModels=schemas.map(schema=>({identifier:this.getSchemaName(schema)||"",displayName:this.getSchemaName(schema)||"",schema}))}setEventSchemas(schemas){if(!schemas){this.eventSchemas={};return}if(Array.isArray(schemas)){let map={};schemas.forEach((s,i)=>{if(!s)return;let name=this.getSchemaName(s)||`Event${i+1}`;map[name]=s}),this.eventSchemas=map;return}this.eventSchemas=schemas}provideCompletionItems(model,position){let context=this.buildContext(model,position),suggestions=[],activeSchema=this.getActiveReadModelSchema(model);return context.lineNumber===1?this.addProjectionLineCompletions(suggestions,context):this.isAfterKeyword(context,"sequence")?this.addEventSequenceCompletions(suggestions,context):this.isAfterKeyword(context,"from")||this.isAfterKeyword(context,"every")?this.addEventTypeCompletions(suggestions,context):/\benters\s+on\s+\w*$/.test(context.textBeforeCursor)?this.addEventTypeCompletions(suggestions,context):/\benters\s+\w*$/.test(context.textBeforeCursor)?suggestions.push({label:"on",kind:14,insertText:"on ",documentation:"Declares the event that activates this variant.",detail:"enters on <EventType>",range:this.getRangeForWord(context)}):this.isAfterKeyword(context,"variant")?this.addVariantNameCompletions(suggestions,context):this.isAfterKeyword(context,"key")?this.addKeyCompletions(suggestions,context,activeSchema):this.isAfterKeyword(context,"parent")?this.addParentCompletions(suggestions,context):this.isAfterKeyword(context,"children")?this.addChildrenCompletions(suggestions,context,activeSchema):this.isAfterKeyword(context,"join")?this.addJoinCompletions(suggestions,context,activeSchema):this.isAfterKeyword(context,"with")?this.addEventTypeCompletions(suggestions,context):this.isAfterNumericOperationKeyword(context)?this.addNumericPropertyCompletions(suggestions,context,activeSchema):this.isAfterAddOrSubtractBy(context)?this.addAssignmentValueCompletions(suggestions,context,model,position):this.isInAssignment(context)?this.addAssignmentValueCompletions(suggestions,context,model,position):this.isPropertyDotAccess(context)?this.addPropertyMemberCompletions(suggestions,context):(this.isStartOfLine(context)||this.isAfterIndent(context))&&this.addStatementCompletions(suggestions,context,activeSchema),{suggestions}}buildContext(model,position){let lineContent=model.getLineContent(position.lineNumber),textBeforeCursor=lineContent.substring(0,position.column-1),textAfterCursor=lineContent.substring(position.column-1),currentWord=model.getWordAtPosition(position)?.word||"",indentLevel=this.getIndentLevel(textBeforeCursor);return{lineContent,textBeforeCursor,textAfterCursor,currentWord,indentLevel,lineNumber:position.lineNumber}}getIndentLevel(text){let match=text.match(/^(\s*)/);return match?Math.floor(match[1].length/2):0}isStartOfLine(context){return context.textBeforeCursor.trim()===""}isAfterIndent(context){return/^\s+$/.test(context.textBeforeCursor)}isAfterKeyword(context,keyword){return new RegExp(`\\b${keyword}\\s+\\w*$`).test(context.textBeforeCursor)}isAfterNumericOperationKeyword(context){let countIncrDecrPattern=/\b(count|increment|decrement)\s+\w*$/,addSubtractPattern=/\b(add|subtract)\s+\w*$/;return countIncrDecrPattern.test(context.textBeforeCursor)?!0:addSubtractPattern.test(context.textBeforeCursor)?!this.isAfterAddOrSubtractBy(context):!1}isAfterAddOrSubtractBy(context){return/\b(add|subtract)\s+\w+\s+by\s+\w*$/.test(context.textBeforeCursor)}isInAssignment(context){return/\w+\s*=\s*\w*$/.test(context.textBeforeCursor)}isPropertyDotAccess(context){return/(\w+|\$\w+)\.(\w*)$/.test(context.textBeforeCursor)||EVENT_CONTEXT_PATH.test(context.textBeforeCursor)}addProjectionLineCompletions(suggestions,context){let trimmed=context.textBeforeCursor.trim();(trimmed===""||"projection".startsWith(trimmed))&&suggestions.push({label:"projection",kind:14,insertText:"projection ",documentation:"Define a projection that transforms events into a read model",detail:"projection <ProjectionName>",range:this.getRangeForWord(context)});let arrowMatch=trimmed.match(/^projection\s+[\w.]+\s*=>\s*([\w.]*)$/);if(arrowMatch){let partialReadModel=arrowMatch[1]||"";this.readModels.forEach(readModel=>{if(!partialReadModel||readModel.displayName.toLowerCase().startsWith(partialReadModel.toLowerCase())){let label=`${readModel.displayName} (${readModel.identifier})`;suggestions.push({label,kind:6,insertText:readModel.displayName,filterText:`${readModel.displayName} ${readModel.identifier}`,documentation:`Read model: ${readModel.displayName} (${readModel.identifier})`,detail:readModel.identifier,range:this.getRangeForWord(context)})}});return}if(trimmed.startsWith("projection ")&&!trimmed.includes("=>")){let afterProjection=trimmed.substring(11);this.readModels.forEach(readModel=>{if(!afterProjection||readModel.displayName.toLowerCase().startsWith(afterProjection.toLowerCase())){let label=`${readModel.displayName} (${readModel.identifier})`;suggestions.push({label,kind:6,insertText:`${readModel.displayName} => ${readModel.displayName}`,filterText:`${readModel.displayName} ${readModel.identifier}`,documentation:`Read model: ${readModel.displayName} (${readModel.identifier})`,detail:readModel.identifier,range:this.getRangeForWord(context)})}})}}addEventTypeCompletions(suggestions,context){Object.keys(this.eventSchemas).forEach(eventName=>{if(!context.currentWord||eventName.startsWith(context.currentWord)){let schema=this.eventSchemas[eventName];suggestions.push({label:eventName,kind:6,insertText:eventName,documentation:this.getSchemaDescription(schema)||`Event type: ${eventName}`,detail:"Event Type",range:this.getRangeForWord(context)})}})}addEventSequenceCompletions(suggestions,context){this.eventSequences.forEach(sequenceId=>{(!context.currentWord||sequenceId.startsWith(context.currentWord))&&suggestions.push({label:sequenceId,kind:13,insertText:sequenceId,documentation:`Event sequence: ${sequenceId}`,detail:"Event Sequence",range:this.getRangeForWord(context)})})}addKeyCompletions(suggestions,context,activeSchema){activeSchema?.definitions&&Object.keys(activeSchema.definitions).forEach(typeName=>{activeSchema.definitions[typeName].type==="object"&&suggestions.push({label:typeName,kind:6,insertText:typeName,documentation:`Composite key type: ${typeName}`,detail:"Composite Key Type",range:this.getRangeForWord(context)})}),this.addExpressionCompletions(suggestions,context)}addParentCompletions(suggestions,context){this.addExpressionCompletions(suggestions,context)}addNumericPropertyCompletions(suggestions,context,activeSchema){activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="integer"||propSchema.type==="number")&&(!context.currentWord||propName.startsWith(context.currentWord))&&suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Numeric property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})});let addSubtractMatch=context.textBeforeCursor.match(/\b(add|subtract)\s+(\w*)$/);if(addSubtractMatch){let partialProp=addSubtractMatch[2]||"";activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="integer"||propSchema.type==="number")&&(!partialProp||propName.startsWith(partialProp))&&suggestions.push({label:propName,kind:9,insertText:`${propName} by `,documentation:`Numeric property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}}addChildrenCompletions(suggestions,context,activeSchema){activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="array"||propSchema.items)&&suggestions.push({label:propName,kind:9,insertText:`${propName} id `,documentation:`Collection property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}addJoinCompletions(suggestions,context,activeSchema){let trimmed=context.textBeforeCursor.trim();trimmed==="join"||!trimmed.includes(" ")?activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="array"||propSchema.items)&&suggestions.push({label:propName,kind:9,insertText:`${propName} on `,documentation:`Join on collection: ${propName}`,range:this.getRangeForWord(context)})}):trimmed.match(/join\s+\w+\s+on\s+/)&&activeSchema?.properties&&Object.keys(activeSchema.properties).forEach(propName=>{suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Property: ${propName}`,range:this.getRangeForWord(context)})})}addVariantNameCompletions(suggestions,context){this.readModels.forEach(readModel=>{(!context.currentWord||readModel.displayName.toLowerCase().startsWith(context.currentWord.toLowerCase()))&&suggestions.push({label:readModel.displayName,kind:6,insertText:readModel.displayName,documentation:`Read model: ${readModel.displayName} (${readModel.identifier})`,detail:readModel.identifier,range:this.getRangeForWord(context)})})}addStatementCompletions(suggestions,context,activeSchema){[{label:"sequence",insertText:"sequence ",documentation:"Specify which event sequence to use for this projection",detail:"sequence <event-sequence-id>"},{label:"variant",insertText:"variant ",documentation:"Declare one of several mutually exclusive named read models sharing this projection's identity",detail:"variant <Name>"},{label:"enters on",insertText:"enters on ",documentation:"Declare the event that activates a variant",detail:"enters on <EventType>"},{label:"from",insertText:"from ",documentation:"Handle specific event types",detail:"from <EventType>"},{label:"all",insertText:"all",documentation:"Subscribe to all event types in the system \u2014 mappings run for every event system-wide, regardless of explicit from blocks",detail:"all"},{label:"every",insertText:"every",documentation:"Handle all events for automatic mapping (only events explicitly subscribed to via from blocks)",detail:"every"},{label:"key",insertText:"key ",documentation:"Define the projection key",detail:"key <expression>"},{label:"parent",insertText:"parent ",documentation:"Define parent relationship",detail:"parent <expression>"},{label:"join",insertText:"join ",documentation:"Join with child collection",detail:"join <collection> on <property>"},{label:"children",insertText:"children ",documentation:"Define child collection operations",detail:"children <collection> identified by <expression>"},{label:"remove with",insertText:"remove with ",documentation:"Remove items based on event",detail:"remove with <EventType>"},{label:"remove via",insertText:"remove via join on ",documentation:"Remove items via join",detail:"remove via join on <EventType>"},{label:"no automap",insertText:"no automap",documentation:"Disable automatic property mapping",detail:"no automap"},{label:"clear",insertText:"clear ",documentation:"Remove the value a property holds",detail:"clear <property>"},{label:"increment",insertText:"increment ",documentation:"Increment a numeric property",detail:"increment <property>"},{label:"decrement",insertText:"decrement ",documentation:"Decrement a numeric property",detail:"decrement <property>"},{label:"count",insertText:"count ",documentation:"Count occurrences",detail:"count <property>"},{label:"add",insertText:"add ",documentation:"Add value to property",detail:"add <property> by <expression>"},{label:"subtract",insertText:"subtract ",documentation:"Subtract value from property",detail:"subtract <property> by <expression>"},{label:"exclude children",insertText:"exclude children",documentation:"Exclude child collections from automap",detail:"exclude children"}].forEach(kw=>{(!context.currentWord||kw.label.startsWith(context.currentWord))&&suggestions.push({label:kw.label,kind:14,insertText:kw.insertText,documentation:kw.documentation,detail:kw.detail,range:this.getRangeForWord(context)})}),activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(!context.currentWord||propName.startsWith(context.currentWord))&&suggestions.push({label:propName,kind:9,insertText:`${propName} = `,documentation:`Assign value to property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}addAssignmentValueCompletions(suggestions,context,model,position){let eventType=this.getCurrentEventType(model,position.lineNumber);if(eventType&&this.eventSchemas[eventType]){let eventSchema=this.eventSchemas[eventType];eventSchema.properties&&Object.entries(eventSchema.properties).forEach(([propName,propSchema])=>{suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Event property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}this.addExpressionCompletions(suggestions,context)}addExpressionCompletions(suggestions,context){[{label:"$eventSourceId",insertText:"$eventSourceId",documentation:"The identifier of the event source (aggregate/entity)",detail:"Event Source Expression"},{label:"$causedBy",insertText:"$causedBy",documentation:"The identity that caused the event. Chronicle cannot yet evaluate this short form (Cratis/Chronicle#4119) - prefer $eventContext.causedBy.<property>.",detail:"Identity Expression"},{label:"$eventContext",insertText:"$eventContext.",documentation:`Metadata about the event: ${eventContextMembers.map(member=>member.name).join(", ")}`,detail:"Event Context Expression"}].forEach(expr=>{(!context.currentWord||expr.label.startsWith(context.currentWord)||expr.label.startsWith("$"+context.currentWord))&&suggestions.push({label:expr.label,kind:14,insertText:expr.insertText,documentation:expr.documentation,detail:expr.detail,range:this.getRangeForWord(context)})})}addPropertyMemberCompletions(suggestions,context){let eventContextMatch=context.textBeforeCursor.match(EVENT_CONTEXT_PATH);if(eventContextMatch){let segments=eventContextMatch[1].split(".").filter(segment=>segment.length>0);this.addEventContextMemberCompletions(suggestions,context,segments,eventContextMatch[2]);return}let match=context.textBeforeCursor.match(/(\w+|\$\w+)\.(\w*)$/);if(!match)return;let[,objectName,partialProp]=match,causedByMatch=context.textBeforeCursor.match(/\$causedBy\.((?:\w+\.)*)(\w*)$/);if(causedByMatch){let segments=causedByMatch[1].split(".").filter(segment=>segment.length>0);this.addEventContextMemberCompletions(suggestions,context,["causedBy",...segments],causedByMatch[2]);return}let eventSchema=this.eventSchemas[objectName];eventSchema?.properties&&Object.entries(eventSchema.properties).forEach(([propName,propSchema])=>{(!partialProp||propName.startsWith(partialProp))&&suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Event property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}addEventContextMemberCompletions(suggestions,context,segments,partial){(eventContextMembersAfter(segments)??[]).filter(member=>!partial||member.name.startsWith(partial)).forEach(member=>{suggestions.push({label:member.name,kind:member.kind==="function"?1:9,insertText:member.name,documentation:member.description,detail:member.type,range:this.getRangeForWord(context)})})}getCurrentEventType(model,lineNumber){for(let i=lineNumber;i>=1;i--){let line=model.getLineContent(i).trim(),fromMatch=line.match(/^from\s+([\w-]+)/);if(fromMatch)return fromMatch[1];if(line.match(/^every$/))return null}return null}getActiveReadModelSchema(model){let match=model.getLineContent(1).trim().match(/^projection\s+[\w.]+\s*=>\s*([\w.]+)/);if(!match)return;let readModelName=match[1];return this.resolveReadModelInfo(readModelName)?.schema}resolveReadModelInfo(readModelToken){return this.readModels.find(rm=>rm.identifier===readModelToken||rm.displayName===readModelToken)||null}getSchemaName(schema){if(schema.name)return schema.name;if(schema.title)return schema.title;if(typeof schema.$id=="string"){let parts=schema.$id.split("/");return parts[parts.length-1]||schema.$id}}getSchemaDescription(schema){return schema.description||void 0}getPropertyTypeDescription(propSchema){return propSchema.type==="array"&&propSchema.items?`${propSchema.items.type||propSchema.items.$id?.split("/").pop()||"unknown"}[]`:propSchema.type||propSchema.$ref?.split("/").pop()||"unknown"}getRangeForWord(context){let startColumn=context.textBeforeCursor.length-context.currentWord.length+1,endColumn=startColumn+context.currentWord.length;return{startLineNumber:context.lineNumber,startColumn:Math.max(1,startColumn),endLineNumber:context.lineNumber,endColumn:Math.max(1,endColumn)}}};var Validator=class{readModels=[];eventSchemas={};draftReadModel=null;setReadModels(readModels){this.readModels=readModels||[]}setDraftReadModel(draft){this.draftReadModel=draft}setReadModelSchemas(schemas){this.readModels=schemas.map(schema=>({identifier:this.getSchemaName(schema)||"",displayName:this.getSchemaName(schema)||"",schema}))}setEventSchemas(schemas){if(!schemas){this.eventSchemas={};return}if(Array.isArray(schemas)){let map={};schemas.forEach((s,i)=>{if(!s)return;let name=this.getSchemaName(s)||`Event${i+1}`;map[name]=s}),this.eventSchemas=map;return}this.eventSchemas=schemas}validate(model){let markers=[],content=model.getValue();if(!content.trim())return markers;let lines=content.replace(/\r\n/g,`
|
|
1
|
+
import{describeEventContext,describeEventContextMember,eventContextMemberAt,eventContextMembers,eventContextMembersAfter,fenceMap,validateEventContextPaths}from"../../chunk-IZGYM33T.js";var languageId="pdl",KEYWORDS=["projection","sequence","all","every","on","from","key","parent","join","automap","no","children","nested","identified","by","add","subtract","remove","via","with","default","increment","decrement","count","set","unset","clear","events","id","exclude","variant","enters"],BUILTINS=["$eventSourceId","$causedBy","$eventContext"],OPERATORS=["=","+=","-=","=>","."],configuration={comments:{lineComment:"#"},brackets:[["{","}"],["[","]"],["(",")"]],autoClosingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}],surroundingPairs:[{open:"{",close:"}"},{open:"[",close:"]"},{open:"(",close:")"},{open:'"',close:'"'},{open:"'",close:"'"},{open:"`",close:"`"}],indentationRules:{increaseIndentPattern:/^.*(:|\bon\b|\ball\b|\bevery\b|\bchildren\b|\bnested\b|\bparent\b|\bvariant\b)\s*$/,decreaseIndentPattern:/^.*\}.*$/},folding:{offSide:!0,markers:{start:/^\s*(projection|all|every|on|children|nested|parent|variant)/,end:/^\s*$/}},wordPattern:/@?[a-zA-Z_$][\w$-]*/},monarchLanguage={defaultToken:"",tokenPostfix:".pdl",keywords:KEYWORDS,builtins:BUILTINS,operators:OPERATORS,symbols:/[=><!~?:&|+\-*/^%]+/,escapes:/\\(?:[abfnrtv\\"']|x[0-9A-Fa-f]{1,4}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})/,tokenizer:{root:[{include:"@whitespace"},[/`/,{token:"string.template",next:"@templateString"}],[/@[a-zA-Z_$][\w$]*/,"identifier.escape"],[/[A-Z][a-zA-Z_$][\w$]*/,{cases:{"@keywords":"invalid","@default":"identifier"}}],[/[a-z_$][\w$]*/,{cases:{"@keywords":"keyword","@builtins":"variable.predefined","@default":"identifier"}}],[/[{}()[\]]/,"@brackets"],[/=>/,"operator.arrow"],[/@symbols/,{cases:{"@operators":"operator","@default":""}}],[/\d*\.\d+([eE][-+]?\d+)?/,"number.float"],[/0[xX][0-9a-fA-F]+/,"number.hex"],[/\d+/,"number"],[/[;,.]/,"delimiter"],[/"([^"\\]|\\.)*$/,"string.invalid"],[/"/,{token:"string.quote",next:"@string"}]],whitespace:[[/[ \t\r\n]+/,""],[/#.*$/,"comment"]],templateString:[[/\$\{/,{token:"delimiter.bracket",next:"@templateExpression"}],[/[^\\`$]+/,"string.template"],[/@escapes/,"string.template.escape"],[/\\./,"string.template.escape.invalid"],[/`/,{token:"string.template",next:"@pop"}]],templateExpression:[[/\}/,{token:"delimiter.bracket",next:"@pop"}],{include:"@root"}],string:[[/[^\\"]+/,"string"],[/@escapes/,"string.escape"],[/\\./,"string.escape.invalid"],[/"/,{token:"string.quote",next:"@pop"}]]}};var EVENT_CONTEXT_PATH=/\$eventContext\.((?:\w+\.)*)(\w*)$/,CompletionProvider=class{readModels=[];eventSchemas={};eventSequences=[];setReadModels(readModels){this.readModels=readModels||[]}setEventSequences(sequences){this.eventSequences=sequences||[]}setReadModelSchemas(schemas){this.readModels=schemas.map(schema=>({identifier:this.getSchemaName(schema)||"",displayName:this.getSchemaName(schema)||"",schema}))}setEventSchemas(schemas){if(!schemas){this.eventSchemas={};return}if(Array.isArray(schemas)){let map={};schemas.forEach((s,i)=>{if(!s)return;let name=this.getSchemaName(s)||`Event${i+1}`;map[name]=s}),this.eventSchemas=map;return}this.eventSchemas=schemas}provideCompletionItems(model,position){let context=this.buildContext(model,position),suggestions=[],activeSchema=this.getActiveReadModelSchema(model);return context.lineNumber===1?this.addProjectionLineCompletions(suggestions,context):this.isAfterKeyword(context,"sequence")?this.addEventSequenceCompletions(suggestions,context):this.isAfterKeyword(context,"from")||this.isAfterKeyword(context,"every")?this.addEventTypeCompletions(suggestions,context):/\benters\s+on\s+\w*$/.test(context.textBeforeCursor)?this.addEventTypeCompletions(suggestions,context):/\benters\s+\w*$/.test(context.textBeforeCursor)?suggestions.push({label:"on",kind:14,insertText:"on ",documentation:"Declares the event that activates this variant.",detail:"enters on <EventType>",range:this.getRangeForWord(context)}):this.isAfterKeyword(context,"variant")?this.addVariantNameCompletions(suggestions,context):this.isAfterKeyword(context,"key")?this.addKeyCompletions(suggestions,context,activeSchema):this.isAfterKeyword(context,"parent")?this.addParentCompletions(suggestions,context):this.isAfterKeyword(context,"children")?this.addChildrenCompletions(suggestions,context,activeSchema):this.isAfterKeyword(context,"join")?this.addJoinCompletions(suggestions,context,activeSchema):this.isAfterKeyword(context,"with")?this.addEventTypeCompletions(suggestions,context):this.isAfterNumericOperationKeyword(context)?this.addNumericPropertyCompletions(suggestions,context,activeSchema):this.isAfterAddOrSubtractBy(context)?this.addAssignmentValueCompletions(suggestions,context,model,position):this.isInAssignment(context)?this.addAssignmentValueCompletions(suggestions,context,model,position):this.isPropertyDotAccess(context)?this.addPropertyMemberCompletions(suggestions,context):(this.isStartOfLine(context)||this.isAfterIndent(context))&&this.addStatementCompletions(suggestions,context,activeSchema),{suggestions}}buildContext(model,position){let lineContent=model.getLineContent(position.lineNumber),textBeforeCursor=lineContent.substring(0,position.column-1),textAfterCursor=lineContent.substring(position.column-1),currentWord=model.getWordAtPosition(position)?.word||"",indentLevel=this.getIndentLevel(textBeforeCursor);return{lineContent,textBeforeCursor,textAfterCursor,currentWord,indentLevel,lineNumber:position.lineNumber}}getIndentLevel(text){let match=text.match(/^(\s*)/);return match?Math.floor(match[1].length/2):0}isStartOfLine(context){return context.textBeforeCursor.trim()===""}isAfterIndent(context){return/^\s+$/.test(context.textBeforeCursor)}isAfterKeyword(context,keyword){return new RegExp(`\\b${keyword}\\s+\\w*$`).test(context.textBeforeCursor)}isAfterNumericOperationKeyword(context){let countIncrDecrPattern=/\b(count|increment|decrement)\s+\w*$/,addSubtractPattern=/\b(add|subtract)\s+\w*$/;return countIncrDecrPattern.test(context.textBeforeCursor)?!0:addSubtractPattern.test(context.textBeforeCursor)?!this.isAfterAddOrSubtractBy(context):!1}isAfterAddOrSubtractBy(context){return/\b(add|subtract)\s+\w+\s+by\s+\w*$/.test(context.textBeforeCursor)}isInAssignment(context){return/\w+\s*=\s*\w*$/.test(context.textBeforeCursor)}isPropertyDotAccess(context){return/(\w+|\$\w+)\.(\w*)$/.test(context.textBeforeCursor)||EVENT_CONTEXT_PATH.test(context.textBeforeCursor)}addProjectionLineCompletions(suggestions,context){let trimmed=context.textBeforeCursor.trim();(trimmed===""||"projection".startsWith(trimmed))&&suggestions.push({label:"projection",kind:14,insertText:"projection ",documentation:"Define a projection that transforms events into a read model",detail:"projection <ProjectionName>",range:this.getRangeForWord(context)});let arrowMatch=trimmed.match(/^projection\s+[\w.]+\s*=>\s*([\w.]*)$/);if(arrowMatch){let partialReadModel=arrowMatch[1]||"";this.readModels.forEach(readModel=>{if(!partialReadModel||readModel.displayName.toLowerCase().startsWith(partialReadModel.toLowerCase())){let label=`${readModel.displayName} (${readModel.identifier})`;suggestions.push({label,kind:6,insertText:readModel.displayName,filterText:`${readModel.displayName} ${readModel.identifier}`,documentation:`Read model: ${readModel.displayName} (${readModel.identifier})`,detail:readModel.identifier,range:this.getRangeForWord(context)})}});return}if(trimmed.startsWith("projection ")&&!trimmed.includes("=>")){let afterProjection=trimmed.substring(11);this.readModels.forEach(readModel=>{if(!afterProjection||readModel.displayName.toLowerCase().startsWith(afterProjection.toLowerCase())){let label=`${readModel.displayName} (${readModel.identifier})`;suggestions.push({label,kind:6,insertText:`${readModel.displayName} => ${readModel.displayName}`,filterText:`${readModel.displayName} ${readModel.identifier}`,documentation:`Read model: ${readModel.displayName} (${readModel.identifier})`,detail:readModel.identifier,range:this.getRangeForWord(context)})}})}}addEventTypeCompletions(suggestions,context){Object.keys(this.eventSchemas).forEach(eventName=>{if(!context.currentWord||eventName.startsWith(context.currentWord)){let schema=this.eventSchemas[eventName];suggestions.push({label:eventName,kind:6,insertText:eventName,documentation:this.getSchemaDescription(schema)||`Event type: ${eventName}`,detail:"Event Type",range:this.getRangeForWord(context)})}})}addEventSequenceCompletions(suggestions,context){this.eventSequences.forEach(sequenceId=>{(!context.currentWord||sequenceId.startsWith(context.currentWord))&&suggestions.push({label:sequenceId,kind:13,insertText:sequenceId,documentation:`Event sequence: ${sequenceId}`,detail:"Event Sequence",range:this.getRangeForWord(context)})})}addKeyCompletions(suggestions,context,activeSchema){activeSchema?.definitions&&Object.keys(activeSchema.definitions).forEach(typeName=>{activeSchema.definitions[typeName].type==="object"&&suggestions.push({label:typeName,kind:6,insertText:typeName,documentation:`Composite key type: ${typeName}`,detail:"Composite Key Type",range:this.getRangeForWord(context)})}),this.addExpressionCompletions(suggestions,context)}addParentCompletions(suggestions,context){this.addExpressionCompletions(suggestions,context)}addNumericPropertyCompletions(suggestions,context,activeSchema){activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="integer"||propSchema.type==="number")&&(!context.currentWord||propName.startsWith(context.currentWord))&&suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Numeric property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})});let addSubtractMatch=context.textBeforeCursor.match(/\b(add|subtract)\s+(\w*)$/);if(addSubtractMatch){let partialProp=addSubtractMatch[2]||"";activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="integer"||propSchema.type==="number")&&(!partialProp||propName.startsWith(partialProp))&&suggestions.push({label:propName,kind:9,insertText:`${propName} by `,documentation:`Numeric property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}}addChildrenCompletions(suggestions,context,activeSchema){activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="array"||propSchema.items)&&suggestions.push({label:propName,kind:9,insertText:`${propName} id `,documentation:`Collection property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}addJoinCompletions(suggestions,context,activeSchema){let trimmed=context.textBeforeCursor.trim();trimmed==="join"||!trimmed.includes(" ")?activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(propSchema.type==="array"||propSchema.items)&&suggestions.push({label:propName,kind:9,insertText:`${propName} on `,documentation:`Join on collection: ${propName}`,range:this.getRangeForWord(context)})}):trimmed.match(/join\s+\w+\s+on\s+/)&&activeSchema?.properties&&Object.keys(activeSchema.properties).forEach(propName=>{suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Property: ${propName}`,range:this.getRangeForWord(context)})})}addVariantNameCompletions(suggestions,context){this.readModels.forEach(readModel=>{(!context.currentWord||readModel.displayName.toLowerCase().startsWith(context.currentWord.toLowerCase()))&&suggestions.push({label:readModel.displayName,kind:6,insertText:readModel.displayName,documentation:`Read model: ${readModel.displayName} (${readModel.identifier})`,detail:readModel.identifier,range:this.getRangeForWord(context)})})}addStatementCompletions(suggestions,context,activeSchema){[{label:"sequence",insertText:"sequence ",documentation:"Specify which event sequence to use for this projection",detail:"sequence <event-sequence-id>"},{label:"variant",insertText:"variant ",documentation:"Declare one of several mutually exclusive named read models sharing this projection's identity",detail:"variant <Name>"},{label:"enters on",insertText:"enters on ",documentation:"Declare the event that activates a variant",detail:"enters on <EventType>"},{label:"from",insertText:"from ",documentation:"Handle specific event types",detail:"from <EventType>"},{label:"all",insertText:"all",documentation:"Subscribe to all event types in the system \u2014 mappings run for every event system-wide, regardless of explicit from blocks",detail:"all"},{label:"every",insertText:"every",documentation:"Handle all events for automatic mapping (only events explicitly subscribed to via from blocks)",detail:"every"},{label:"key",insertText:"key ",documentation:"Define the projection key",detail:"key <expression>"},{label:"parent",insertText:"parent ",documentation:"Define parent relationship",detail:"parent <expression>"},{label:"join",insertText:"join ",documentation:"Join with child collection",detail:"join <collection> on <property>"},{label:"children",insertText:"children ",documentation:"Define child collection operations",detail:"children <collection> identified by <expression>"},{label:"remove with",insertText:"remove with ",documentation:"Remove items based on event",detail:"remove with <EventType>"},{label:"remove via",insertText:"remove via join on ",documentation:"Remove items via join",detail:"remove via join on <EventType>"},{label:"no automap",insertText:"no automap",documentation:"Disable automatic property mapping",detail:"no automap"},{label:"clear",insertText:"clear ",documentation:"Remove the value a property holds",detail:"clear <property>"},{label:"increment",insertText:"increment ",documentation:"Increment a numeric property",detail:"increment <property>"},{label:"decrement",insertText:"decrement ",documentation:"Decrement a numeric property",detail:"decrement <property>"},{label:"count",insertText:"count ",documentation:"Count occurrences",detail:"count <property>"},{label:"add",insertText:"add ",documentation:"Add value to property",detail:"add <property> by <expression>"},{label:"subtract",insertText:"subtract ",documentation:"Subtract value from property",detail:"subtract <property> by <expression>"},{label:"exclude children",insertText:"exclude children",documentation:"Exclude child collections from automap",detail:"exclude children"}].forEach(kw=>{(!context.currentWord||kw.label.startsWith(context.currentWord))&&suggestions.push({label:kw.label,kind:14,insertText:kw.insertText,documentation:kw.documentation,detail:kw.detail,range:this.getRangeForWord(context)})}),activeSchema?.properties&&Object.entries(activeSchema.properties).forEach(([propName,propSchema])=>{(!context.currentWord||propName.startsWith(context.currentWord))&&suggestions.push({label:propName,kind:9,insertText:`${propName} = `,documentation:`Assign value to property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}addAssignmentValueCompletions(suggestions,context,model,position){let eventType=this.getCurrentEventType(model,position.lineNumber);if(eventType&&this.eventSchemas[eventType]){let eventSchema=this.eventSchemas[eventType];eventSchema.properties&&Object.entries(eventSchema.properties).forEach(([propName,propSchema])=>{suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Event property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}this.addExpressionCompletions(suggestions,context)}addExpressionCompletions(suggestions,context){[{label:"$eventSourceId",insertText:"$eventSourceId",documentation:"The identifier of the event source (aggregate/entity)",detail:"Event Source Expression"},{label:"$causedBy",insertText:"$causedBy",documentation:"The identity that caused the event. Chronicle cannot yet evaluate this short form (Cratis/Chronicle#4119) - prefer $eventContext.causedBy.<property>.",detail:"Identity Expression"},{label:"$eventContext",insertText:"$eventContext.",documentation:`Metadata about the event: ${eventContextMembers.map(member=>member.name).join(", ")}`,detail:"Event Context Expression"}].forEach(expr=>{(!context.currentWord||expr.label.startsWith(context.currentWord)||expr.label.startsWith("$"+context.currentWord))&&suggestions.push({label:expr.label,kind:14,insertText:expr.insertText,documentation:expr.documentation,detail:expr.detail,range:this.getRangeForWord(context)})})}addPropertyMemberCompletions(suggestions,context){let eventContextMatch=context.textBeforeCursor.match(EVENT_CONTEXT_PATH);if(eventContextMatch){let segments=eventContextMatch[1].split(".").filter(segment=>segment.length>0);this.addEventContextMemberCompletions(suggestions,context,segments,eventContextMatch[2]);return}let match=context.textBeforeCursor.match(/(\w+|\$\w+)\.(\w*)$/);if(!match)return;let[,objectName,partialProp]=match,causedByMatch=context.textBeforeCursor.match(/\$causedBy\.((?:\w+\.)*)(\w*)$/);if(causedByMatch){let segments=causedByMatch[1].split(".").filter(segment=>segment.length>0);this.addEventContextMemberCompletions(suggestions,context,["causedBy",...segments],causedByMatch[2]);return}let eventSchema=this.eventSchemas[objectName];eventSchema?.properties&&Object.entries(eventSchema.properties).forEach(([propName,propSchema])=>{(!partialProp||propName.startsWith(partialProp))&&suggestions.push({label:propName,kind:9,insertText:propName,documentation:`Event property: ${propName}`,detail:this.getPropertyTypeDescription(propSchema),range:this.getRangeForWord(context)})})}addEventContextMemberCompletions(suggestions,context,segments,partial){(eventContextMembersAfter(segments)??[]).filter(member=>!partial||member.name.startsWith(partial)).forEach(member=>{suggestions.push({label:member.name,kind:member.kind==="function"?1:9,insertText:member.name,documentation:member.description,detail:member.type,range:this.getRangeForWord(context)})})}getCurrentEventType(model,lineNumber){for(let i=lineNumber;i>=1;i--){let line=model.getLineContent(i).trim(),fromMatch=line.match(/^from\s+([\w-]+)/);if(fromMatch)return fromMatch[1];if(line.match(/^every$/))return null}return null}getActiveReadModelSchema(model){let match=model.getLineContent(1).trim().match(/^projection\s+[\w.]+\s*=>\s*([\w.]+)/);if(!match)return;let readModelName=match[1];return this.resolveReadModelInfo(readModelName)?.schema}resolveReadModelInfo(readModelToken){return this.readModels.find(rm=>rm.identifier===readModelToken||rm.displayName===readModelToken)||null}getSchemaName(schema){if(schema.name)return schema.name;if(schema.title)return schema.title;if(typeof schema.$id=="string"){let parts=schema.$id.split("/");return parts[parts.length-1]||schema.$id}}getSchemaDescription(schema){return schema.description||void 0}getPropertyTypeDescription(propSchema){return propSchema.type==="array"&&propSchema.items?`${propSchema.items.type||propSchema.items.$id?.split("/").pop()||"unknown"}[]`:propSchema.type||propSchema.$ref?.split("/").pop()||"unknown"}getRangeForWord(context){let startColumn=context.textBeforeCursor.length-context.currentWord.length+1,endColumn=startColumn+context.currentWord.length;return{startLineNumber:context.lineNumber,startColumn:Math.max(1,startColumn),endLineNumber:context.lineNumber,endColumn:Math.max(1,endColumn)}}};var Validator=class{readModels=[];eventSchemas={};draftReadModel=null;setReadModels(readModels){this.readModels=readModels||[]}setDraftReadModel(draft){this.draftReadModel=draft}setReadModelSchemas(schemas){this.readModels=schemas.map(schema=>({identifier:this.getSchemaName(schema)||"",displayName:this.getSchemaName(schema)||"",schema}))}setEventSchemas(schemas){if(!schemas){this.eventSchemas={};return}if(Array.isArray(schemas)){let map={};schemas.forEach((s,i)=>{if(!s)return;let name=this.getSchemaName(s)||`Event${i+1}`;map[name]=s}),this.eventSchemas=map;return}this.eventSchemas=schemas}validate(model){let markers=[],content=model.getValue();if(!content.trim())return markers;let lines=content.replace(/\r\n/g,`
|
|
2
2
|
`).replace(/\r/g,`
|
|
3
3
|
`).split(`
|
|
4
4
|
`),firstNonEmptyLineIndex=0,firstLine="";for(let i=0;i<lines.length;i++){let trimmed=lines[i].trim();if(trimmed&&!trimmed.startsWith("#")){firstNonEmptyLineIndex=i,firstLine=trimmed;break}}if(!firstLine)return markers;let projectionWithReadModelMatch=firstLine.match(/^projection\s+([\w.]+)\s*=>\s*([\w.]+)\s*$/),projectionAdHocMatch=!projectionWithReadModelMatch&&firstLine.match(/^projection\s+([\w.]+)\s*$/);if(!projectionWithReadModelMatch&&!projectionAdHocMatch){let lineNumber=firstNonEmptyLineIndex+1;return markers.push(this.createError(lineNumber,1,firstLine.length+1,'Projection definition must start with "projection <ProjectionName>" or "projection <ProjectionName> => <ReadModelIdentifier>"')),markers}let activeSchema,readModelName=null;if(projectionWithReadModelMatch){readModelName=projectionWithReadModelMatch[2];let readModelExists=this.resolveReadModelIdentifier(readModelName)!==null,isDraftReadModel=this.isDraftReadModel(readModelName),readModelStartColumn=this.getReadModelStartColumn(firstLine,readModelName);if(!readModelExists&&!isDraftReadModel){let lineNumber=firstNonEmptyLineIndex+1,col=readModelStartColumn;markers.push(this.createError(lineNumber,col,col+readModelName.length,`Read model '${readModelName}' not found`))}else if(isDraftReadModel){let lineNumber=firstNonEmptyLineIndex+1,col=readModelStartColumn;markers.push(this.createInfo(lineNumber,col,col+readModelName.length,`Read model '${readModelName}' is a draft (not yet saved)`))}let isDraft=this.isDraftReadModel(readModelName),activeReadModel=isDraft?null:this.resolveReadModelInfo(readModelName);activeSchema=isDraft?this.draftReadModel.schema:activeReadModel?.schema}let contextStack=[activeSchema],indentStack=[0],lastIndent=0,eventContextStack=[new Map];for(let i=1;i<lines.length;i++){let lineNumber=i+1,line=lines[i],trimmed=line.trim();if(!trimmed||trimmed.startsWith("#"))continue;let currentIndent=line.search(/\S/);for(;currentIndent<lastIndent&&indentStack.length>1;){let poppedIndent=indentStack.pop();poppedIndent!==void 0&¤tIndent<poppedIndent&&(contextStack.pop(),eventContextStack.pop())}lastIndent=currentIndent;let currentEventContext=eventContextStack[eventContextStack.length-1],fromMatch=trimmed.match(/^from\s+([\w-]+)/);if(fromMatch){let eventType=fromMatch[1],col=line.indexOf(eventType)+1;Object.keys(this.eventSchemas).length>0&&!this.eventSchemas[eventType]&&markers.push(this.createError(lineNumber,col,col+eventType.length,`Event type '${eventType}' not found`)),currentEventContext.has(eventType)?markers.push(this.createError(lineNumber,col,col+eventType.length,`Duplicate event type '${eventType}' - event types can only be used once at each level`)):currentEventContext.set(eventType,{lineNumber,col})}let variantMatch=trimmed.match(/^variant\s+([\w.]+)\s*$/);if(variantMatch){let[,variantName]=variantMatch,col=line.indexOf(variantName)+1,isDraft=this.isDraftReadModel(variantName);!(this.resolveReadModelIdentifier(variantName)!==null)&&!isDraft?markers.push(this.createError(lineNumber,col,col+variantName.length,`Read model '${variantName}' not found`)):isDraft&&markers.push(this.createInfo(lineNumber,col,col+variantName.length,`Read model '${variantName}' is a draft (not yet saved)`));let variantSchema=isDraft?this.draftReadModel.schema:this.resolveReadModelInfo(variantName)?.schema;contextStack.push(variantSchema),indentStack.push(currentIndent),eventContextStack.push(new Map)}let entersOnMatch=trimmed.match(/^enters\s+on\s+([\w-]+)/);if(entersOnMatch){let eventType=entersOnMatch[1],col=line.indexOf(eventType)+1;Object.keys(this.eventSchemas).length>0&&!this.eventSchemas[eventType]&&markers.push(this.createError(lineNumber,col,col+eventType.length,`Event type '${eventType}' not found`)),currentEventContext.has(eventType)?markers.push(this.createError(lineNumber,col,col+eventType.length,`Duplicate event type '${eventType}' - event types can only be used once at each level`)):currentEventContext.set(eventType,{lineNumber,col})}let eventsMatch=trimmed.match(/^events\s+([\w-]+)/);if(eventsMatch){let eventType=eventsMatch[1],col=line.indexOf(eventType)+1;Object.keys(this.eventSchemas).length>0&&!this.eventSchemas[eventType]&&markers.push(this.createError(lineNumber,col,col+eventType.length,`Event type '${eventType}' not found`)),currentEventContext.has(eventType)?markers.push(this.createError(lineNumber,col,col+eventType.length,`Duplicate event type '${eventType}' - event types can only be used once at each level`)):currentEventContext.set(eventType,{lineNumber,col})}let removeWithMatch=trimmed.match(/^remove\s+(?:with|via\s+join\s+on)\s+([\w-]+)/);if(removeWithMatch){let eventType=removeWithMatch[1],col=line.indexOf(eventType)+1;Object.keys(this.eventSchemas).length>0&&!this.eventSchemas[eventType]&&markers.push(this.createError(lineNumber,col,col+eventType.length,`Event type '${eventType}' not found`)),currentEventContext.has(eventType)?markers.push(this.createError(lineNumber,col,col+eventType.length,`Duplicate event type '${eventType}' - event types can only be used once at each level`)):currentEventContext.set(eventType,{lineNumber,col})}let assignmentMatch=trimmed.match(/^(\w+)\s*=\s*(.+)$/);if(assignmentMatch){let currentSchema=contextStack[contextStack.length-1];if(currentSchema?.properties){let[,propertyName]=assignmentMatch;if(!currentSchema.properties[propertyName]){let col=line.indexOf(propertyName)+1,schemaName=this.getSchemaName(currentSchema)||"current schema";markers.push(this.createWarning(lineNumber,col,col+propertyName.length,`Property '${propertyName}' not found in ${schemaName}`))}}}let numericOpMatch=trimmed.match(/^(?:increment|decrement|count)\s+(\w+)$/);if(numericOpMatch){let currentSchema=contextStack[contextStack.length-1];if(currentSchema?.properties){let[,propertyName]=numericOpMatch;if(!currentSchema.properties[propertyName]){let col=line.indexOf(propertyName)+1,schemaName=this.getSchemaName(currentSchema)||"current schema";markers.push(this.createWarning(lineNumber,col,col+propertyName.length,`Property '${propertyName}' not found in ${schemaName}`))}}}let addSubMatch=trimmed.match(/^(?:add|subtract)\s+(\w+)\s+by\s+/);if(addSubMatch){let currentSchema=contextStack[contextStack.length-1];if(currentSchema?.properties){let[,propertyName]=addSubMatch;if(!currentSchema.properties[propertyName]){let col=line.indexOf(propertyName)+1,schemaName=this.getSchemaName(currentSchema)||"current schema";markers.push(this.createWarning(lineNumber,col,col+propertyName.length,`Property '${propertyName}' not found in ${schemaName}`))}}}let childrenMatch=trimmed.match(/^children\s+(\w+)\s+identified\s+by\s+/);if(childrenMatch){let currentSchema=contextStack[contextStack.length-1];if(currentSchema?.properties){let[,propertyName]=childrenMatch,prop=currentSchema.properties[propertyName];if(prop)if(prop.type!=="array"&&!prop.items){let col=line.indexOf(propertyName)+1;markers.push(this.createWarning(lineNumber,col,col+propertyName.length,`Property '${propertyName}' is not a collection (array) type`))}else{let childSchema=prop.items;childSchema&&(contextStack.push(childSchema),indentStack.push(currentIndent),eventContextStack.push(new Map))}else{let col=line.indexOf(propertyName)+1,schemaName=this.getSchemaName(currentSchema)||"current schema";markers.push(this.createWarning(lineNumber,col,col+propertyName.length,`Collection property '${propertyName}' not found in ${schemaName}`))}}}let joinMatch=trimmed.match(/^join\s+(\w+)\s+on\s+(\w+)/);if(joinMatch&&activeSchema?.properties){let[,collectionName,joinProperty]=joinMatch,collectionProp=activeSchema.properties[collectionName];if(collectionProp){if(collectionProp.type!=="array"&&!collectionProp.items){let col=line.indexOf(collectionName)+1;markers.push(this.createWarning(lineNumber,col,col+collectionName.length,`Property '${collectionName}' is not a collection (array) type`))}}else{let col=line.indexOf(collectionName)+1;markers.push(this.createWarning(lineNumber,col,col+collectionName.length,`Collection property '${collectionName}' not found in read model '${readModelName}'`))}if(!activeSchema.properties[joinProperty]){let col=line.indexOf(joinProperty,line.indexOf("on"))+1;markers.push(this.createWarning(lineNumber,col,col+joinProperty.length,`Property '${joinProperty}' not found in read model '${readModelName}'`))}eventContextStack.push(new Map),indentStack.push(currentIndent)}let keyMatch=trimmed.match(/^key\s+(\w+)\s*$/);if(keyMatch&&activeSchema){let[,keyName]=keyMatch,isInDefinitions=activeSchema.definitions&&activeSchema.definitions[keyName],isProperty=activeSchema.properties&&activeSchema.properties[keyName];if(!isInDefinitions&&!isProperty&&!this.isBuiltInExpression(keyName)){let col=line.indexOf(keyName)+1;markers.push(this.createWarning(lineNumber,col,col+keyName.length,`Composite key type '${keyName}' not found in read model schema`))}}}for(let issue of validateEventContextPaths(lines,fenceMap(lines)))markers.push({severity:issue.severity==="error"?8:4,startLineNumber:issue.line+1,endLineNumber:issue.line+1,startColumn:issue.startColumn,endColumn:issue.endColumn,message:issue.message,code:issue.code});return markers}resolveReadModelInfo(readModelToken){return this.readModels.find(rm=>rm.identifier===readModelToken||rm.displayName===readModelToken)||null}getReadModelStartColumn(firstLine,readModelName){let prefixMatch=firstLine.match(/^\s*projection\s+[\w.]+\s*=>\s*/);if(!prefixMatch){let fallbackIndex=firstLine.lastIndexOf(readModelName);return(fallbackIndex>=0?fallbackIndex:0)+1}return prefixMatch[0].length+1}resolveReadModelIdentifier(readModelToken){return this.isDraftReadModel(readModelToken)?this.draftReadModel.identifier:this.resolveReadModelInfo(readModelToken)?.identifier??null}isDraftReadModel(readModelToken){return!!this.draftReadModel&&(this.draftReadModel.identifier===readModelToken||this.draftReadModel.displayName===readModelToken)}isBuiltInExpression(text){return text.startsWith("$")||["true","false","null"].includes(text)}createError(line,startCol,endCol,message){return{severity:8,startLineNumber:line,startColumn:startCol,endLineNumber:line,endColumn:endCol,message}}createWarning(line,startCol,endCol,message){return{severity:4,startLineNumber:line,startColumn:startCol,endLineNumber:line,endColumn:endCol,message}}createInfo(line,startCol,endCol,message){return{severity:2,startLineNumber:line,startColumn:startCol,endLineNumber:line,endColumn:endCol,message}}getSchemaName(schema){if(schema.name)return schema.name;if(schema.title)return schema.title;if(typeof schema.$id=="string"){let parts=schema.$id.split("/");return parts[parts.length-1]||schema.$id}}};var HoverProvider=class{readModels=[];eventSchemas={};draftReadModel=null;setReadModels(readModels){this.readModels=readModels||[]}setReadModelSchemas(schemas){this.readModels=schemas.map(schema=>({identifier:this.getSchemaName(schema)||"",displayName:this.getSchemaName(schema)||"",schema}))}setEventSchemas(schemas){if(!schemas){this.eventSchemas={};return}if(Array.isArray(schemas)){let map={};schemas.forEach((s,i)=>{if(!s)return;let name=this.getSchemaName(s)||`Event${i+1}`;map[name]=s}),this.eventSchemas=map;return}this.eventSchemas=schemas}setDraftReadModel(draft){this.draftReadModel=draft}provideHover(model,position){let word=model.getWordAtPosition(position);if(!word)return null;let wordText=word.word,lineContent=model.getLineContent(position.lineNumber);if(this.getProjectionNameAtPosition(lineContent,position.column))return{contents:[{value:"The name of the projection"}],range:{startLineNumber:position.lineNumber,startColumn:word.startColumn,endLineNumber:position.lineNumber,endColumn:word.endColumn}};let eventContextInfo=this.getEventContextInfo(lineContent,word.startColumn);if(eventContextInfo)return{contents:[{value:eventContextInfo}],range:{startLineNumber:position.lineNumber,startColumn:word.startColumn,endLineNumber:position.lineNumber,endColumn:word.endColumn}};let keywordInfo=this.getKeywordInfo(wordText);if(keywordInfo)return{contents:[{value:keywordInfo}],range:{startLineNumber:position.lineNumber,startColumn:word.startColumn,endLineNumber:position.lineNumber,endColumn:word.endColumn}};let expressionInfo=this.getExpressionInfo(wordText);if(expressionInfo)return{contents:[{value:expressionInfo}],range:{startLineNumber:position.lineNumber,startColumn:word.startColumn,endLineNumber:position.lineNumber,endColumn:word.endColumn}};if(this.eventSchemas[wordText]){let schema=this.eventSchemas[wordText],description=this.getSchemaDescription(schema),properties=this.getSchemaProperties(schema),content=`**Event Type:** \`${wordText}\`
|
|
@@ -14,6 +14,7 @@ export declare const commandItems: CompletionEntry[];
|
|
|
14
14
|
export declare const eventItems: CompletionEntry[];
|
|
15
15
|
export declare const inlineEventItems: CompletionEntry[];
|
|
16
16
|
export declare const producesItems: CompletionEntry[];
|
|
17
|
+
export declare const implementationItems: CompletionEntry[];
|
|
17
18
|
export declare const handlerItems: CompletionEntry[];
|
|
18
19
|
export declare const queryItems: CompletionEntry[];
|
|
19
20
|
export declare const performerItems: CompletionEntry[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion-items.d.ts","sourceRoot":"","sources":["../completion-items.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,EAAE,eAAe,EAE9C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACzB;AAID,eAAO,MAAM,aAAa,EAAE,eAAe,EAS1C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAKzC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAAe,EAItC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,eAAe,EAIxC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAOzC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,eAAe,EAYvC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAazC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,eAAe,EAKvC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAAe,EAI7C,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,eAAe,EAE1C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"completion-items.d.ts","sourceRoot":"","sources":["../completion-items.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,iBAAiB,EAAE,eAAe,EAE9C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACzB;AAID,eAAO,MAAM,aAAa,EAAE,eAAe,EAS1C,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAKzC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAAe,EAItC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,eAAe,EAIxC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAOzC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,eAAe,EAYvC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAazC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,eAAe,EAKvC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAAe,EAI7C,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,eAAe,EAE1C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAAe,EAIhD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAIzC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,eAAe,EAOvC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,eAAe,EAI3C,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAAe,EAI5C,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,eAAe,EAM1C,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAAe,EAOjD,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,eAAe,EAIzC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAAe,EAmB/C,CAAC;AAGF,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,EAAE,eAAe,EAAE,CAwBvF,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,eAAe,EAGtC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,eAAe,EAKxC,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,eAAe,EAU1C,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,eAAe,EAYxC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,eAAe,EAGxC,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,eAAe,EAGvC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAAe,EAqBjD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completion-planner.d.ts","sourceRoot":"","sources":["../completion-planner.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AASrD,MAAM,MAAM,cAAc,GACpB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAExB,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"completion-planner.d.ts","sourceRoot":"","sources":["../completion-planner.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AASrD,MAAM,MAAM,cAAc,GACpB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,eAAe,EAAE,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAExB,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CA2DvE;AAID,wBAAgB,eAAe,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACnB,cAAc,CAsFhB"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export declare const diagnosticCodes: {
|
|
2
|
+
readonly invalidImplementationBlock: "PLAY0492";
|
|
3
|
+
readonly invalidImplementationHint: "PLAY0493";
|
|
4
|
+
readonly conflictingImplementationSources: "PLAY0494";
|
|
2
5
|
readonly eventSourceIdInPayload: "PLAY0469";
|
|
3
6
|
readonly explicitProducesTargetsRequired: "PLAY0470";
|
|
4
7
|
readonly redundantEventId: "PLAY0471";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostic-codes.d.ts","sourceRoot":"","sources":["../diagnostic-codes.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"diagnostic-codes.d.ts","sourceRoot":"","sources":["../diagnostic-codes.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8ClB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hover-content.d.ts","sourceRoot":"","sources":["../hover-content.ts"],"names":[],"mappings":"AAcA,wBAAgB,YAAY,CACxB,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"hover-content.d.ts","sourceRoot":"","sources":["../hover-content.ts"],"names":[],"mappings":"AAcA,wBAAgB,YAAY,CACxB,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,CA2Jf"}
|
package/dist/keyword-docs.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export declare const handlerIntentDocs: {
|
|
2
|
+
implementation: string;
|
|
3
|
+
hint: string;
|
|
4
|
+
};
|
|
1
5
|
export declare const keywordDocs: Record<string, string>;
|
|
2
6
|
export declare const specificationKeywordDocs: Record<string, string>;
|
|
3
7
|
export declare const attributeDocs: Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyword-docs.d.ts","sourceRoot":"","sources":["../keyword-docs.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keyword-docs.d.ts","sourceRoot":"","sources":["../keyword-docs.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,iBAAiB;;;CAG7B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA2G9C,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM3D,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAGhD,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuBtD,CAAC"}
|
package/dist/tokens.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../tokens.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAQ/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA0BzE,eAAO,MAAM,gBAAgB,EAAE,iBAa9B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,gBAAgB,
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../tokens.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAQ/C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA0BzE,eAAO,MAAM,gBAAgB,EAAE,iBAa9B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC,gBAAgB,CAoJ5F"}
|
package/package.json
CHANGED