@cratis/screenplay-language 4.128.0 → 4.130.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/AuthoredReadModelKeys.d.ts +13 -0
  2. package/dist/AuthoredReadModelKeys.d.ts.map +1 -0
  3. package/dist/EventSourceAnalysis.d.ts +11 -0
  4. package/dist/EventSourceAnalysis.d.ts.map +1 -1
  5. package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js +1 -1
  6. package/dist/bundles/compiler/Diagnostics/DiagnosticCodes.js.map +1 -1
  7. package/dist/bundles/compiler/Files/PlayApplicationAssembly.js +1 -1
  8. package/dist/bundles/compiler/Files/PlayApplicationAssembly.js.map +1 -1
  9. package/dist/bundles/compiler/Parsing/CommandParser.js +1 -1
  10. package/dist/bundles/compiler/Parsing/CommandParser.js.map +1 -1
  11. package/dist/bundles/compiler/Parsing/DeclarationParsers.js +1 -1
  12. package/dist/bundles/compiler/Parsing/DeclarationParsers.js.map +1 -1
  13. package/dist/bundles/compiler/Parsing/DependencySourceParser.js +1 -1
  14. package/dist/bundles/compiler/Parsing/DependencySourceParser.js.map +1 -1
  15. package/dist/bundles/compiler/Parsing/EventSourceValidator.js +1 -1
  16. package/dist/bundles/compiler/Parsing/EventSourceValidator.js.map +1 -1
  17. package/dist/bundles/compiler/Parsing/IdentifierComplianceValidator.js +1 -1
  18. package/dist/bundles/compiler/Parsing/IdentifierComplianceValidator.js.map +1 -1
  19. package/dist/bundles/compiler/Parsing/ObserverFilterParser.js +2 -0
  20. package/dist/bundles/compiler/Parsing/ObserverFilterParser.js.map +1 -0
  21. package/dist/bundles/compiler/Parsing/ObserverFilterValidator.js +2 -0
  22. package/dist/bundles/compiler/Parsing/ObserverFilterValidator.js.map +1 -0
  23. package/dist/bundles/compiler/Parsing/ProducesParser.js +1 -1
  24. package/dist/bundles/compiler/Parsing/ProducesParser.js.map +1 -1
  25. package/dist/bundles/compiler/Parsing/PropertyLineParser.js +1 -1
  26. package/dist/bundles/compiler/Parsing/PropertyLineParser.js.map +1 -1
  27. package/dist/bundles/compiler/Parsing/QueryParser.js +1 -1
  28. package/dist/bundles/compiler/Parsing/QueryParser.js.map +1 -1
  29. package/dist/bundles/compiler/Parsing/ReactionParser.js +1 -1
  30. package/dist/bundles/compiler/Parsing/ReactionParser.js.map +1 -1
  31. package/dist/bundles/compiler/Parsing/ReadModelKeyValidator.js +2 -0
  32. package/dist/bundles/compiler/Parsing/ReadModelKeyValidator.js.map +1 -0
  33. package/dist/bundles/compiler/Parsing/ReadsParser.js +2 -0
  34. package/dist/bundles/compiler/Parsing/ReadsParser.js.map +1 -0
  35. package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js +1 -1
  36. package/dist/bundles/compiler/Parsing/SpecificationStreamValidator.js.map +1 -1
  37. package/dist/bundles/compiler/Parsing/TriggerDataParser.js +1 -1
  38. package/dist/bundles/compiler/Parsing/TriggerDataParser.js.map +1 -1
  39. package/dist/bundles/compiler/ScreenplayCompiler.js +1 -1
  40. package/dist/bundles/compiler/ScreenplayCompiler.js.map +1 -1
  41. package/dist/bundles/compiler/Syntax/EventSourceCatalog.js +1 -1
  42. package/dist/bundles/compiler/Syntax/EventSourceCatalog.js.map +1 -1
  43. package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js +1 -1
  44. package/dist/bundles/compiler/Syntax/ScreenplaySyntaxWalker.js.map +1 -1
  45. package/dist/bundles/compiler/Syntax/SyntaxCollections.js +1 -1
  46. package/dist/bundles/compiler/Syntax/SyntaxCollections.js.map +1 -1
  47. package/dist/bundles/compiler/Syntax/SyntaxInvariants.js +1 -1
  48. package/dist/bundles/compiler/Syntax/SyntaxInvariants.js.map +1 -1
  49. package/dist/bundles/compiler/Syntax/SyntaxJson.js +1 -1
  50. package/dist/bundles/compiler/Syntax/SyntaxJson.js.map +1 -1
  51. package/dist/bundles/compiler/Syntax/index.js +1 -1
  52. package/dist/bundles/compiler/index.js +1 -1
  53. package/dist/bundles/completion-items.js +2 -2
  54. package/dist/bundles/completion-items.js.map +1 -1
  55. package/dist/bundles/completion-planner.js +2 -2
  56. package/dist/bundles/completion-planner.js.map +1 -1
  57. package/dist/bundles/diagnostic-codes.js +1 -1
  58. package/dist/bundles/diagnostic-codes.js.map +1 -1
  59. package/dist/bundles/event-source-authoring.js +10 -10
  60. package/dist/bundles/event-source-authoring.js.map +1 -1
  61. package/dist/bundles/keyword-docs.js +1 -1
  62. package/dist/bundles/keyword-docs.js.map +1 -1
  63. package/dist/bundles/read-model-key-completions.js +2 -0
  64. package/dist/bundles/read-model-key-completions.js.map +1 -0
  65. package/dist/bundles/response-analysis.js +6 -6
  66. package/dist/bundles/response-analysis.js.map +1 -1
  67. package/dist/bundles/scope-items.js +1 -1
  68. package/dist/bundles/scope-items.js.map +1 -1
  69. package/dist/bundles/tokens.js +1 -1
  70. package/dist/bundles/tokens.js.map +1 -1
  71. package/dist/bundles/validation.js +1 -1
  72. package/dist/bundles/validation.js.map +1 -1
  73. package/dist/completion-items.d.ts.map +1 -1
  74. package/dist/completion-planner.d.ts.map +1 -1
  75. package/dist/diagnostic-codes.d.ts +7 -0
  76. package/dist/diagnostic-codes.d.ts.map +1 -1
  77. package/dist/event-source-authoring.d.ts.map +1 -1
  78. package/dist/keyword-docs.d.ts.map +1 -1
  79. package/dist/read-model-key-completions.d.ts +4 -0
  80. package/dist/read-model-key-completions.d.ts.map +1 -0
  81. package/dist/response-analysis.d.ts +2 -0
  82. package/dist/response-analysis.d.ts.map +1 -1
  83. package/dist/scope-items.d.ts.map +1 -1
  84. package/dist/tokens.d.ts.map +1 -1
  85. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i}from"./SourceLine.js";import{parseMappingSource as a}from"./ExpressionParser.js";import{firstWord as o}from"./LineText.js";import{parseProperty as s,tryParseProperty as c}from"./PropertyLineParser.js";import{parseDescription as l}from"./DescriptionParser.js";import{parseDocumentation as u}from"./DocumentationParser.js";import{isFileDirectiveAmongProperties as d}from"./FileReferences.js";import{isBlankPublicEventOrigin as f}from"../Syntax/PublicEventInvariants.js";import{eventBodyReservedWords as p}from"../Text/ReservedWords.js";import{EventMetadataParser as m}from"./EventMetadataParser.js";const h=r(`^type\\s+([A-Za-z_]\\w*)$`),g=r(`^(?:(?<public>public)\\s+)?event\\s+(?<name>[A-Za-z_]\\w*)(?:\\s+generation\\s+(?<generation>[0-9]+))?(?:\\s+from\\s+"(?<origin>${t})")?$`),_=r(`^readmodel\\s+([A-Za-z_]\\w*)$`),v=r(`^[A-Z]\\w*(?:\\[\\])?(?:\\?|\\s+optional)?$`),y=r(`^[A-Za-z_]\\w*$`),isDescription=e=>o(e.content)===`description`&&c(e)===void 0;function withoutIdentifier(e,t,n,r,a){return t.isIdentifier?(e.error(r,a,i(n)),{...t,isIdentifier:!1}):t}function parseType(t,n){let r=h.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidTypeDeclaration,`Invalid type declaration '${n.content}' - expected 'type <Name>'`,i(n));let a=[],o=null;for(let c=t.peekChild(n.indent);c!==void 0;c=t.peekChild(n.indent)){if(t.reader.takeSignificant(),isDescription(c)){o=l(t,c,o,`Type '${r}'`);continue}if(d(c))continue;let n=s(t,c);n===void 0?t.error(e.InvalidPropertyDeclaration,`Invalid property '${c.content}' - expected '<name> <Type>'`,i(c)):a.push(withoutIdentifier(t,n,c,e.IdentifierOutsideCommand,`Property '${n.name}' of type '${r}' cannot be marked identifier - only a command property can be`))}return a.length===0&&t.error(e.TypeWithoutProperties,`Type '${r}' must declare at least one property`,i(n)),{kind:`TypeSyntax`,name:r,properties:a,description:o,location:i(n)}}function parseEvent(t,r){let a=g.exec(r.content),c=a?.groups?.name??``;a===null&&t.error(e.InvalidEventDeclaration,`Invalid event declaration '${r.content}' - expected '[public] event <Name> [generation <N>] [from "<origin>"]'`,i(r));let l=a?.groups?.origin===void 0?null:n(a.groups.origin),u=a?.groups?.public!==void 0||l!==null?`Public`:`Private`;l!==null&&f(l)&&t.error(e.InvalidEventDeclaration,`An event origin must be a nonblank quoted string`,i(r));let h=a?.groups?.generation!==void 0,_=1;if(h){let n=Number(a.groups.generation);!Number.isSafeInteger(n)||n===0||n>=4294967295?t.error(e.InvalidEventGeneration,`Event '${c}' must declare a generation between 1 and 4294967294`,i(r)):_=n}let v=[],y=[],b=new m(c);for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent)){if(t.reader.takeSignificant(),d(n))continue;if(p.includes(o(n.content))){let e=parseTag(t,n);e!==void 0&&y.push(e);continue}let r=s(t,n);r===void 0?b.tryParse(t,n)||t.error(e.InvalidPropertyDeclaration,`Invalid property '${n.content}' - expected '<name> <Type>'`,i(n)):v.push(withoutIdentifier(t,r,n,e.IdentifierOnEventProperty,`Property '${r.name}' of event '${c}' cannot be marked identifier - an event never carries its event source id`))}return{kind:`EventSyntax`,name:c,properties:v,tags:y,visibility:u,origin:l,generation:_,hasGenerationMarker:h,...b.value,location:i(r)}}function parseTag(t,n,r=!0){let o=n.content.substring(3).trim();if(r&&v.test(o)&&t.warning(e.TagPropertyReadAsTag,`'${n.content}' declares a static tag with the value '${o}', not a property named 'tag' - write 'tag "${o}"' for the tag, or '@${n.content}' for the property`,i(n)),o.length===0){t.error(e.TagWithoutValue,`Expected a value after 'tag' - an identifier, a string literal or a context expression`,i(n));return}if(y.test(o))return{kind:`TagSyntax`,value:{kind:`LiteralExpressionSyntax`,value:o,location:i(n)},location:i(n)};let s=a(o,i(n),t);if(s.kind===`RawExpressionSyntax`)t.error(e.InvalidTagValue,`Invalid tag value '${o}' - expected an identifier, a string literal or a context expression`,i(n));else return{kind:`TagSyntax`,value:s,location:i(n)}}function parseReadModel(t,n){let r=_.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidReadModelDeclaration,`Invalid read model declaration '${n.content}' - expected 'readmodel <Name>'`,i(n));let a=[],f=null,p=null;for(let m=t.peekChild(n.indent);m!==void 0;m=t.peekChild(n.indent))if(t.reader.takeSignificant(),isDescription(m))f=l(t,m,f,`Read model '${r}'`);else if(o(m.content)===`documentation`&&c(m)===void 0)p=u(t,m,p,`Read model '${r}'`);else if(d(m))continue;else{let n=s(t,m);if(n===void 0){t.error(e.InvalidPropertyDeclaration,`Invalid property '${m.content}' - expected '<name> <Type>'`,i(m));continue}a.push(withoutIdentifier(t,n,m,e.IdentifierOutsideCommand,`Property '${n.name}' of read model '${r}' cannot be marked identifier - only a command property can be`))}return{kind:`ReadModelSyntax`,name:r,properties:a,description:f,documentation:p,location:i(n)}}export{parseEvent,parseReadModel,parseTag,parseType};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{stringBodyPattern as t,unescapeString as n}from"../Text/StringLiteral.js";import{pattern as r}from"../Text/patterns.js";import{locationOf as i}from"./SourceLine.js";import{parseMappingSource as a}from"./ExpressionParser.js";import{firstWord as o}from"./LineText.js";import{parseProperty as s,tryParseProperty as c}from"./PropertyLineParser.js";import{parseDescription as l}from"./DescriptionParser.js";import{parseDocumentation as u}from"./DocumentationParser.js";import{isFileDirectiveAmongProperties as d}from"./FileReferences.js";import{isBlankPublicEventOrigin as f}from"../Syntax/PublicEventInvariants.js";import{eventBodyReservedWords as p}from"../Text/ReservedWords.js";import{EventMetadataParser as m}from"./EventMetadataParser.js";const h=r(`^type\\s+([A-Za-z_]\\w*)$`),g=r(`^(?:(?<public>public)\\s+)?event\\s+(?<name>[A-Za-z_]\\w*)(?:\\s+generation\\s+(?<generation>[0-9]+))?(?:\\s+from\\s+"(?<origin>${t})")?$`),_=r(`^readmodel\\s+([A-Za-z_]\\w*)$`),v=r(`^[A-Z]\\w*(?:\\[\\])?(?:\\?|\\s+optional)?$`),y=r(`^[A-Za-z_]\\w*$`),isDescription=e=>o(e.content)===`description`&&c(e)===void 0;function withoutIdentifier(e,t,n,r,a){return t.isIdentifier?(e.error(r,a,i(n)),{...t,isIdentifier:!1}):t}function parseType(t,n){let r=h.exec(n.content)?.[1]??``;r===``&&t.error(e.InvalidTypeDeclaration,`Invalid type declaration '${n.content}' - expected 'type <Name>'`,i(n));let a=[],o=null;for(let c=t.peekChild(n.indent);c!==void 0;c=t.peekChild(n.indent)){if(t.reader.takeSignificant(),isDescription(c)){o=l(t,c,o,`Type '${r}'`);continue}if(d(c))continue;let n=s(t,c);n===void 0?t.error(e.InvalidPropertyDeclaration,`Invalid property '${c.content}' - expected '<name> <Type>'`,i(c)):a.push(withoutIdentifier(t,n,c,e.IdentifierOutsideCommand,`Property '${n.name}' of type '${r}' cannot be marked identifier - only a command property can be`))}return a.length===0&&t.error(e.TypeWithoutProperties,`Type '${r}' must declare at least one property`,i(n)),{kind:`TypeSyntax`,name:r,properties:a,description:o,location:i(n)}}function parseEvent(t,r){let a=g.exec(r.content),c=a?.groups?.name??``;a===null&&t.error(e.InvalidEventDeclaration,`Invalid event declaration '${r.content}' - expected '[public] event <Name> [generation <N>] [from "<origin>"]'`,i(r));let l=a?.groups?.origin===void 0?null:n(a.groups.origin),u=a?.groups?.public!==void 0||l!==null?`Public`:`Private`;l!==null&&f(l)&&t.error(e.InvalidEventDeclaration,`An event origin must be a nonblank quoted string`,i(r));let h=a?.groups?.generation!==void 0,_=1;if(h){let n=Number(a.groups.generation);!Number.isSafeInteger(n)||n===0||n>=4294967295?t.error(e.InvalidEventGeneration,`Event '${c}' must declare a generation between 1 and 4294967294`,i(r)):_=n}let v=[],y=[],b=new m(c);for(let n=t.peekChild(r.indent);n!==void 0;n=t.peekChild(r.indent)){if(t.reader.takeSignificant(),d(n))continue;if(p.includes(o(n.content))){let e=parseTag(t,n);e!==void 0&&y.push(e);continue}let r=s(t,n);r===void 0?b.tryParse(t,n)||t.error(e.InvalidPropertyDeclaration,`Invalid property '${n.content}' - expected '<name> <Type>'`,i(n)):v.push(withoutIdentifier(t,r,n,e.IdentifierOnEventProperty,`Property '${r.name}' of event '${c}' cannot be marked identifier - an event never carries its event source id`))}return{kind:`EventSyntax`,name:c,properties:v,tags:y,visibility:u,origin:l,generation:_,hasGenerationMarker:h,...b.value,location:i(r)}}function parseTag(t,n,r=!0){let o=n.content.substring(3).trim();if(r&&v.test(o)&&t.warning(e.TagPropertyReadAsTag,`'${n.content}' declares a static tag with the value '${o}', not a property named 'tag' - write 'tag "${o}"' for the tag, or '@${n.content}' for the property`,i(n)),o.length===0){t.error(e.TagWithoutValue,`Expected a value after 'tag' - an identifier, a string literal or a context expression`,i(n));return}if(y.test(o))return{kind:`TagSyntax`,value:{kind:`LiteralExpressionSyntax`,value:o,location:i(n)},location:i(n)};let s=a(o,i(n),t);if(s.kind===`RawExpressionSyntax`)t.error(e.InvalidTagValue,`Invalid tag value '${o}' - expected an identifier, a string literal or a context expression`,i(n));else return{kind:`TagSyntax`,value:s,location:i(n)}}function parseReadModel(t,n){let r,a=_.exec(n.content)?.[1]??``;a===``&&t.error(e.InvalidReadModelDeclaration,`Invalid read model declaration '${n.content}' - expected 'readmodel <Name>'`,i(n));let f=[],p=null,m=null;for(let h=t.peekChild(n.indent);h!==void 0;h=t.peekChild(n.indent))if(t.reader.takeSignificant(),r??=h.indent,isDescription(h))p=l(t,h,p,`Read model '${a}'`);else if(o(h.content)===`documentation`&&c(h)===void 0)m=u(t,h,m,`Read model '${a}'`);else if(d(h))continue;else{let n=s(t,h);if(n===void 0){t.error(e.InvalidPropertyDeclaration,`Invalid property '${h.content}' - expected '<name> <Type>'`,i(h));continue}n.isKey&&h.indent>r&&t.error(e.InvalidReadModelKey,`The key modifier is only valid on top-level read-model properties.`,n.location),f.push(withoutIdentifier(t,h.indent>r?{...n,isKey:!1}:n,h,e.IdentifierOutsideCommand,`Property '${n.name}' of read model '${a}' cannot be marked identifier - only a command property can be`))}return{kind:`ReadModelSyntax`,name:a,properties:f,description:p,documentation:m,location:i(n)}}export{parseEvent,parseReadModel,parseTag,parseType};
2
2
  //# sourceMappingURL=DeclarationParsers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DeclarationParsers.js","names":["typeHeader","pattern","eventHeader","stringBodyPattern","readModelHeader","typeShapedPattern","tagIdentifierPattern","firstWord","line","tryParseProperty","property","context","code","message","locationOf","name","header","DiagnosticCodes","properties","description","parseDescription","isFileDirectiveAmongProperties","parseProperty","match","origin","unescapeString","visibility","isBlankPublicEventOrigin","hasGenerationMarker","generation","declared","tags","metadata","EventMetadataParser","eventBodyReservedWords","tag","value","eventDeclaration","expression","parseMappingSource","documentation","parseDocumentation"],"sources":["../../../../../../Compiler/Parsing/DeclarationParsers.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 { EventSyntax, PropertySyntax, ReadModelSyntax, TagSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { pattern } from '../Text/patterns';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { eventBodyReservedWords } from '../Text/ReservedWords';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { EventMetadataParser } from './EventMetadataParser';\nimport { parseMappingSource } from './ExpressionParser';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst typeHeader = pattern('^type\\\\s+([A-Za-z_]\\\\w*)$');\nconst eventHeader = pattern(`^(?:(?<public>public)\\\\s+)?event\\\\s+(?<name>[A-Za-z_]\\\\w*)(?:\\\\s+generation\\\\s+(?<generation>[0-9]+))?(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst readModelHeader = pattern('^readmodel\\\\s+([A-Za-z_]\\\\w*)$');\nconst maximumGeneration = 4294967295;\nconst typeShapedPattern = pattern('^[A-Z]\\\\w*(?:\\\\[\\\\])?(?:\\\\?|\\\\s+optional)?$');\nconst tagIdentifierPattern = pattern('^[A-Za-z_]\\\\w*$');\n\n// 'description' takes no type reference, so a line with property shape is a property named description.\nconst isDescription = (line: SourceLine): boolean => firstWord(line.content) === 'description' && tryParseProperty(line) === undefined;\n\nfunction withoutIdentifier(context: ParserContext, property: PropertySyntax, line: SourceLine, code: string, message: string): PropertySyntax {\n if (!property.isIdentifier) {\n return property;\n }\n context.error(code, message, locationOf(line));\n return { ...property, isIdentifier: false };\n}\n\nexport function parseType(context: ParserContext, header: SourceLine): TypeSyntax {\n const name = typeHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidTypeDeclaration, `Invalid type declaration '${header.content}' - expected 'type <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Type '${name}'`);\n continue;\n }\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of type '${name}' cannot be marked identifier - only a command property can be`));\n }\n if (properties.length === 0) {\n context.error(DiagnosticCodes.TypeWithoutProperties, `Type '${name}' must declare at least one property`, locationOf(header));\n }\n return { kind: 'TypeSyntax', name, properties, description, location: locationOf(header) };\n}\n\nexport function parseEvent(context: ParserContext, header: SourceLine): EventSyntax {\n const match = eventHeader.exec(header.content);\n const name = match?.groups?.name ?? '';\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, `Invalid event declaration '${header.content}' - expected '[public] event <Name> [generation <N>] [from \"<origin>\"]'`, locationOf(header));\n }\n const origin = match?.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n const visibility = match?.groups?.public !== undefined || origin !== null ? EventVisibility.Public : EventVisibility.Private;\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, 'An event origin must be a nonblank quoted string', locationOf(header));\n }\n const hasGenerationMarker = match?.groups?.generation !== undefined;\n let generation = 1;\n if (hasGenerationMarker) {\n const declared = Number(match!.groups!.generation);\n if (!Number.isSafeInteger(declared) || declared === 0 || declared >= maximumGeneration) {\n context.error(DiagnosticCodes.InvalidEventGeneration, `Event '${name}' must declare a generation between 1 and ${maximumGeneration - 1}`, locationOf(header));\n } else {\n generation = declared;\n }\n }\n const properties: PropertySyntax[] = [];\n const tags: TagSyntax[] = [];\n const metadata = new EventMetadataParser(name);\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n if (eventBodyReservedWords.includes(firstWord(line.content))) {\n const tag = parseTag(context, line);\n if (tag !== undefined) {\n tags.push(tag);\n }\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n if (!metadata.tryParse(context, line)) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n }\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOnEventProperty,\n `Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`));\n }\n return { kind: 'EventSyntax', name, properties, tags, visibility, origin, generation, hasGenerationMarker, ...metadata.value, location: locationOf(header) };\n}\n\n// 'tag <value>' - the port of the C# TagParser, with the warning the C# EventParser gives for a tag whose\n// value looks like a type, which is almost always a property named tag written without its '@'.\nexport function parseTag(context: ParserContext, line: SourceLine, eventDeclaration = true): TagSyntax | undefined {\n const value = line.content.substring('tag'.length).trim();\n if (eventDeclaration && typeShapedPattern.test(value)) {\n context.warning(DiagnosticCodes.TagPropertyReadAsTag,\n `'${line.content}' declares a static tag with the value '${value}', not a property named 'tag' - write 'tag \"${value}\"' for the tag, or '@${line.content}' for the property`,\n locationOf(line));\n }\n if (value.length === 0) {\n context.error(DiagnosticCodes.TagWithoutValue, 'Expected a value after \\'tag\\' - an identifier, a string literal or a context expression', locationOf(line));\n return undefined;\n }\n if (tagIdentifierPattern.test(value)) {\n return { kind: 'TagSyntax', value: { kind: 'LiteralExpressionSyntax', value, location: locationOf(line) }, location: locationOf(line) };\n }\n const expression = parseMappingSource(value, locationOf(line), context);\n if (expression.kind === 'RawExpressionSyntax') {\n context.error(DiagnosticCodes.InvalidTagValue, `Invalid tag value '${value}' - expected an identifier, a string literal or a context expression`, locationOf(line));\n return undefined;\n }\n return { kind: 'TagSyntax', value: expression, location: locationOf(line) };\n}\n\nexport function parseReadModel(context: ParserContext, header: SourceLine): ReadModelSyntax {\n const name = readModelHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidReadModelDeclaration, `Invalid read model declaration '${header.content}' - expected 'readmodel <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n let documentation: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Read model '${name}'`);\n } else if (firstWord(line.content) === 'documentation' && tryParseProperty(line) === undefined) {\n documentation = parseDocumentation(context, line, documentation, `Read model '${name}'`);\n } else if (isFileDirectiveAmongProperties(line)) {\n continue;\n } else {\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of read model '${name}' cannot be marked identifier - only a command property can be`));\n }\n }\n return { kind: 'ReadModelSyntax', name, properties, description, documentation, location: locationOf(header) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DeclarationParsers.js","names":["typeHeader","pattern","eventHeader","stringBodyPattern","readModelHeader","typeShapedPattern","tagIdentifierPattern","firstWord","line","tryParseProperty","property","context","code","message","locationOf","name","header","DiagnosticCodes","properties","description","parseDescription","isFileDirectiveAmongProperties","parseProperty","match","origin","unescapeString","visibility","isBlankPublicEventOrigin","hasGenerationMarker","generation","declared","tags","metadata","EventMetadataParser","eventBodyReservedWords","tag","value","eventDeclaration","expression","parseMappingSource","bodyIndent","documentation","parseDocumentation"],"sources":["../../../../../../Compiler/Parsing/DeclarationParsers.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 { EventSyntax, PropertySyntax, ReadModelSyntax, TagSyntax, TypeSyntax } from '../Syntax/Declarations';\nimport { pattern } from '../Text/patterns';\nimport { EventVisibility } from '../Syntax/EventVisibility';\nimport { isBlankPublicEventOrigin } from '../Syntax/PublicEventInvariants';\nimport { stringBodyPattern, unescapeString } from '../Text/StringLiteral';\nimport { eventBodyReservedWords } from '../Text/ReservedWords';\nimport { parseDescription } from './DescriptionParser';\nimport { parseDocumentation } from './DocumentationParser';\nimport { EventMetadataParser } from './EventMetadataParser';\nimport { parseMappingSource } from './ExpressionParser';\nimport { isFileDirectiveAmongProperties } from './FileReferences';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseProperty, tryParseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst typeHeader = pattern('^type\\\\s+([A-Za-z_]\\\\w*)$');\nconst eventHeader = pattern(`^(?:(?<public>public)\\\\s+)?event\\\\s+(?<name>[A-Za-z_]\\\\w*)(?:\\\\s+generation\\\\s+(?<generation>[0-9]+))?(?:\\\\s+from\\\\s+\"(?<origin>${stringBodyPattern})\")?$`);\nconst readModelHeader = pattern('^readmodel\\\\s+([A-Za-z_]\\\\w*)$');\nconst maximumGeneration = 4294967295;\nconst typeShapedPattern = pattern('^[A-Z]\\\\w*(?:\\\\[\\\\])?(?:\\\\?|\\\\s+optional)?$');\nconst tagIdentifierPattern = pattern('^[A-Za-z_]\\\\w*$');\n\n// 'description' takes no type reference, so a line with property shape is a property named description.\nconst isDescription = (line: SourceLine): boolean => firstWord(line.content) === 'description' && tryParseProperty(line) === undefined;\n\nfunction withoutIdentifier(context: ParserContext, property: PropertySyntax, line: SourceLine, code: string, message: string): PropertySyntax {\n if (!property.isIdentifier) {\n return property;\n }\n context.error(code, message, locationOf(line));\n return { ...property, isIdentifier: false };\n}\n\nexport function parseType(context: ParserContext, header: SourceLine): TypeSyntax {\n const name = typeHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidTypeDeclaration, `Invalid type declaration '${header.content}' - expected 'type <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Type '${name}'`);\n continue;\n }\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of type '${name}' cannot be marked identifier - only a command property can be`));\n }\n if (properties.length === 0) {\n context.error(DiagnosticCodes.TypeWithoutProperties, `Type '${name}' must declare at least one property`, locationOf(header));\n }\n return { kind: 'TypeSyntax', name, properties, description, location: locationOf(header) };\n}\n\nexport function parseEvent(context: ParserContext, header: SourceLine): EventSyntax {\n const match = eventHeader.exec(header.content);\n const name = match?.groups?.name ?? '';\n if (match === null) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, `Invalid event declaration '${header.content}' - expected '[public] event <Name> [generation <N>] [from \"<origin>\"]'`, locationOf(header));\n }\n const origin = match?.groups?.origin === undefined ? null : unescapeString(match.groups.origin);\n const visibility = match?.groups?.public !== undefined || origin !== null ? EventVisibility.Public : EventVisibility.Private;\n if (origin !== null && isBlankPublicEventOrigin(origin)) {\n context.error(DiagnosticCodes.InvalidEventDeclaration, 'An event origin must be a nonblank quoted string', locationOf(header));\n }\n const hasGenerationMarker = match?.groups?.generation !== undefined;\n let generation = 1;\n if (hasGenerationMarker) {\n const declared = Number(match!.groups!.generation);\n if (!Number.isSafeInteger(declared) || declared === 0 || declared >= maximumGeneration) {\n context.error(DiagnosticCodes.InvalidEventGeneration, `Event '${name}' must declare a generation between 1 and ${maximumGeneration - 1}`, locationOf(header));\n } else {\n generation = declared;\n }\n }\n const properties: PropertySyntax[] = [];\n const tags: TagSyntax[] = [];\n const metadata = new EventMetadataParser(name);\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n if (isFileDirectiveAmongProperties(line)) {\n continue;\n }\n if (eventBodyReservedWords.includes(firstWord(line.content))) {\n const tag = parseTag(context, line);\n if (tag !== undefined) {\n tags.push(tag);\n }\n continue;\n }\n const property = parseProperty(context, line);\n if (property === undefined) {\n if (!metadata.tryParse(context, line)) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n }\n continue;\n }\n properties.push(withoutIdentifier(context, property, line, DiagnosticCodes.IdentifierOnEventProperty,\n `Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`));\n }\n return { kind: 'EventSyntax', name, properties, tags, visibility, origin, generation, hasGenerationMarker, ...metadata.value, location: locationOf(header) };\n}\n\n// 'tag <value>' - the port of the C# TagParser, with the warning the C# EventParser gives for a tag whose\n// value looks like a type, which is almost always a property named tag written without its '@'.\nexport function parseTag(context: ParserContext, line: SourceLine, eventDeclaration = true): TagSyntax | undefined {\n const value = line.content.substring('tag'.length).trim();\n if (eventDeclaration && typeShapedPattern.test(value)) {\n context.warning(DiagnosticCodes.TagPropertyReadAsTag,\n `'${line.content}' declares a static tag with the value '${value}', not a property named 'tag' - write 'tag \"${value}\"' for the tag, or '@${line.content}' for the property`,\n locationOf(line));\n }\n if (value.length === 0) {\n context.error(DiagnosticCodes.TagWithoutValue, 'Expected a value after \\'tag\\' - an identifier, a string literal or a context expression', locationOf(line));\n return undefined;\n }\n if (tagIdentifierPattern.test(value)) {\n return { kind: 'TagSyntax', value: { kind: 'LiteralExpressionSyntax', value, location: locationOf(line) }, location: locationOf(line) };\n }\n const expression = parseMappingSource(value, locationOf(line), context);\n if (expression.kind === 'RawExpressionSyntax') {\n context.error(DiagnosticCodes.InvalidTagValue, `Invalid tag value '${value}' - expected an identifier, a string literal or a context expression`, locationOf(line));\n return undefined;\n }\n return { kind: 'TagSyntax', value: expression, location: locationOf(line) };\n}\n\nexport function parseReadModel(context: ParserContext, header: SourceLine): ReadModelSyntax {\n let bodyIndent: number | undefined;\n const name = readModelHeader.exec(header.content)?.[1] ?? '';\n if (name === '') {\n context.error(DiagnosticCodes.InvalidReadModelDeclaration, `Invalid read model declaration '${header.content}' - expected 'readmodel <Name>'`, locationOf(header));\n }\n const properties: PropertySyntax[] = [];\n let description: string | null = null;\n let documentation: string | null = null;\n for (let line = context.peekChild(header.indent); line !== undefined; line = context.peekChild(header.indent)) {\n context.reader.takeSignificant();\n bodyIndent ??= line.indent;\n if (isDescription(line)) {\n description = parseDescription(context, line, description, `Read model '${name}'`);\n } else if (firstWord(line.content) === 'documentation' && tryParseProperty(line) === undefined) {\n documentation = parseDocumentation(context, line, documentation, `Read model '${name}'`);\n } else if (isFileDirectiveAmongProperties(line)) {\n continue;\n } else {\n const property = parseProperty(context, line);\n if (property === undefined) {\n context.error(DiagnosticCodes.InvalidPropertyDeclaration, `Invalid property '${line.content}' - expected '<name> <Type>'`, locationOf(line));\n continue;\n }\n if (property.isKey && line.indent > bodyIndent) {\n context.error(DiagnosticCodes.InvalidReadModelKey, 'The key modifier is only valid on top-level read-model properties.', property.location);\n }\n properties.push(withoutIdentifier(context, line.indent > bodyIndent ? { ...property, isKey: false } : property, line, DiagnosticCodes.IdentifierOutsideCommand,\n `Property '${property.name}' of read model '${name}' cannot be marked identifier - only a command property can be`));\n }\n }\n return { kind: 'ReadModelSyntax', name, properties, description, documentation, location: locationOf(header) };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{dotNetWhitespace as e,nativePattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{firstWord as r}from"./LineText.js";import{parseDescription as i}from"./DescriptionParser.js";import{ParserContext as a}from"./ParserContext.js";function captureReads(r){let i=t(`^reads${e}+([A-Z]\\w*)(?:${e}+as${e}+([a-z_]\\w*))?(?:${e}+by${e}+([a-z_]\\w*))?$`).exec(r.content);if(!(i===null||[`as`,`by`,`reads`].includes(i[2])))return{kind:`ReadsSyntax`,readModel:i[1],alias:i[2]??null,by:i[3]??null,location:n(r)}}function fork(e){return new a(e.reader.fork(),e.path,e.languages)}function captureConcurrency(i,a){if(a.content!==`concurrency`)return;let o=fork(i),s=!1,c={},l;for(let n=o.peekChild(a.indent);n!==void 0;n=o.peekChild(a.indent))switch(o.reader.takeSignificant(),r(n.content)){case`eventSource`:n.content===`eventSource`&&(s=!0);break;case`sourceType`:case`streamType`:case`streamId`:{let r=t(`^(sourceType|streamType|streamId)${e}+([A-Za-z_]\\w*)$`).exec(n.content);r!==null&&(c[r[1]]??=r[2]);break}case`events`:{if(l!==void 0)break;let r=n.content.slice(6).split(`,`).map(t=>t.replace(RegExp(`^${e}+|${e}+$`,`gu`),``)).filter(Boolean);r.length>0&&r.every(e=>t(`^[A-Z]\\w*$`).test(e))&&(l=r);break}default:o.skipBlock(n.indent)}return{kind:`ConcurrencySyntax`,eventSource:s,eventSourceType:c.sourceType??null,eventStreamType:c.streamType??null,eventStreamId:c.streamId??null,eventTypes:l??[],location:n(a)}}function captureReducer(a,o){let s=t(`^reducer${e}+([A-Za-z_]\\w*)${e}*=>${e}*([A-Za-z_]\\w*)$`).exec(o.content),c=fork(a),l=[];for(let a=c.peekChild(o.indent);a!==void 0;a=c.peekChild(o.indent)){if(c.reader.takeSignificant(),r(a.content)===`description`){i(c,a,null,`Reducer`);continue}let o=t(`^on${e}+([A-Z]\\w*)$`).exec(a.content);o!==null&&l.push({kind:`ReducerRuleSyntax`,event:o[1],file:null,code:null,description:null,location:n(a)}),c.skipOpaqueBlock(a.indent)}return{kind:`ReducerSyntax`,name:s?.[1]??``,readModel:s?.[2]??``,rules:l,description:null,location:n(o)}}export{captureConcurrency,captureReads,captureReducer};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{dotNetWhitespace as t,nativePattern as n}from"../Text/patterns.js";import{locationOf as r}from"./SourceLine.js";import{firstWord as i}from"./LineText.js";import{parseDescription as a}from"./DescriptionParser.js";import{ParserContext as o}from"./ParserContext.js";import{parseObserverFilter as s}from"./ObserverFilterParser.js";function captureReads(e){let i=n(`^reads${t}+([A-Z]\\w*)(?:${t}+as${t}+([a-z_]\\w*))?(?:${t}+by${t}+([a-z_]\\w*))?$`).exec(e.content);if(!(i===null||[`as`,`by`,`reads`].includes(i[2])))return{kind:`ReadsSyntax`,readModel:i[1],alias:i[2]??null,by:i[3]??null,location:r(e)}}function fork(e){return new o(e.reader.fork(),e.path,e.languages)}function captureConcurrency(e,a){if(a.content!==`concurrency`)return;let o=fork(e),s=!1,c={},l;for(let e=o.peekChild(a.indent);e!==void 0;e=o.peekChild(a.indent))switch(o.reader.takeSignificant(),i(e.content)){case`eventSource`:e.content===`eventSource`&&(s=!0);break;case`sourceType`:case`streamType`:case`streamId`:{let r=n(`^(sourceType|streamType|streamId)${t}+([A-Za-z_]\\w*)$`).exec(e.content);r!==null&&(c[r[1]]??=r[2]);break}case`events`:{if(l!==void 0)break;let r=e.content.slice(6).split(`,`).map(e=>e.replace(RegExp(`^${t}+|${t}+$`,`gu`),``)).filter(Boolean);r.length>0&&r.every(e=>n(`^[A-Z]\\w*$`).test(e))&&(l=r);break}default:o.skipBlock(e.indent)}return{kind:`ConcurrencySyntax`,eventSource:s,eventSourceType:c.sourceType??null,eventStreamType:c.streamType??null,eventStreamId:c.streamId??null,eventTypes:l??[],location:r(a)}}function captureReducer(o,c){let l=n(`^reducer${t}+([A-Za-z_]\\w*)${t}*=>${t}*([A-Za-z_]\\w*)$`).exec(c.content),u=fork(o),d=[],f=null;for(let e=u.peekChild(c.indent);e!==void 0;e=u.peekChild(c.indent)){if(u.reader.takeSignificant(),i(e.content)===`description`){a(u,e,null,`Reducer`);continue}if(i(e.content)===`from`){f=s(u,e,f);continue}let o=n(`^on${t}+([A-Z]\\w*)$`).exec(e.content);o!==null&&d.push({kind:`ReducerRuleSyntax`,event:o[1],file:null,code:null,description:null,location:r(e)}),u.skipOpaqueBlock(e.indent)}for(let t of u.diagnostics.filter(t=>t.code===e.InvalidObserverFilter))o.error(t.code,t.message,t.location);return{kind:`ReducerSyntax`,from:f,name:l?.[1]??``,readModel:l?.[2]??``,rules:d,description:null,location:r(c)}}export{captureConcurrency,captureReads,captureReducer};
2
2
  //# sourceMappingURL=DependencySourceParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DependencySourceParser.js","names":["match","nativePattern","dotNetWhitespace","line","locationOf","ParserContext","context","body","eventSource","dimensions","eventTypes","child","firstWord","dimension","names","name","rules","parseDescription","rule"],"sources":["../../../../../../Compiler/Parsing/DependencySourceParser.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 { ConcurrencySyntax, ReadsSyntax, ReducerRuleSyntax, ReducerSyntax } from '../Syntax/DependencySources';\nimport { dotNetWhitespace, nativePattern } from '../Text/patterns';\nimport { parseDescription } from './DescriptionParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\n// Reference-only capture does not change the committed parser's diagnostics or opaque-block skipping.\n// Fork before reading a body: code, malformed operands and unsupported realization stay opaque.\nexport function captureReads(line: SourceLine): ReadsSyntax | undefined {\n const match = nativePattern(`^reads${dotNetWhitespace}+([A-Z]\\\\w*)(?:${dotNetWhitespace}+as${dotNetWhitespace}+([a-z_]\\\\w*))?(?:${dotNetWhitespace}+by${dotNetWhitespace}+([a-z_]\\\\w*))?$`).exec(line.content);\n if (match === null || ['as', 'by', 'reads'].includes(match[2])) return undefined;\n return { kind: 'ReadsSyntax', readModel: match[1], alias: match[2] ?? null, by: match[3] ?? null, location: locationOf(line) };\n}\n\nfunction fork(context: ParserContext): ParserContext {\n return new ParserContext(context.reader.fork(), context.path, context.languages);\n}\n\nexport function captureConcurrency(context: ParserContext, line: SourceLine): ConcurrencySyntax | undefined {\n if (line.content !== 'concurrency') return undefined;\n const body = fork(context);\n let eventSource = false;\n const dimensions: Record<string, string> = {};\n let eventTypes: string[] | undefined;\n for (let child = body.peekChild(line.indent); child !== undefined; child = body.peekChild(line.indent)) {\n body.reader.takeSignificant();\n // C# keeps walking every descendant of the header for recognized dimensions, even malformed\n // or duplicate ones. Only an unknown dimension skips its own descendants during recovery.\n switch (firstWord(child.content)) {\n case 'eventSource':\n if (child.content === 'eventSource') eventSource = true;\n break;\n case 'sourceType':\n case 'streamType':\n case 'streamId': {\n const dimension = nativePattern(`^(sourceType|streamType|streamId)${dotNetWhitespace}+([A-Za-z_]\\\\w*)$`).exec(child.content);\n if (dimension !== null) dimensions[dimension[1]] ??= dimension[2];\n break;\n }\n case 'events': {\n if (eventTypes !== undefined) break;\n const names = child.content.slice('events'.length).split(',').map(name => name.replace(new RegExp(`^${dotNetWhitespace}+|${dotNetWhitespace}+$`, 'gu'), '')).filter(Boolean);\n if (names.length > 0 && names.every(name => nativePattern('^[A-Z]\\\\w*$').test(name))) eventTypes = names;\n break;\n }\n default:\n body.skipBlock(child.indent);\n break;\n }\n }\n return { kind: 'ConcurrencySyntax', eventSource, eventSourceType: dimensions.sourceType ?? null, eventStreamType: dimensions.streamType ?? null, eventStreamId: dimensions.streamId ?? null, eventTypes: eventTypes ?? [], location: locationOf(line) };\n}\n\nexport function captureReducer(context: ParserContext, line: SourceLine): ReducerSyntax {\n const match = nativePattern(`^reducer${dotNetWhitespace}+([A-Za-z_]\\\\w*)${dotNetWhitespace}*=>${dotNetWhitespace}*([A-Za-z_]\\\\w*)$`).exec(line.content);\n const body = fork(context);\n const rules: ReducerRuleSyntax[] = [];\n for (let child = body.peekChild(line.indent); child !== undefined; child = body.peekChild(line.indent)) {\n body.reader.takeSignificant();\n if (firstWord(child.content) === 'description') {\n // Descriptions consume only their fenced text, never the following descendants. Diagnostics\n // stay on the fork, so reference capture does not change the committed parser's behavior.\n parseDescription(body, child, null, 'Reducer');\n continue;\n }\n const rule = nativePattern(`^on${dotNetWhitespace}+([A-Z]\\\\w*)$`).exec(child.content);\n if (rule !== null) rules.push({ kind: 'ReducerRuleSyntax', event: rule[1], file: null, code: null, description: null, location: locationOf(child) });\n body.skipOpaqueBlock(child.indent);\n }\n return { kind: 'ReducerSyntax', name: match?.[1] ?? '', readModel: match?.[2] ?? '', rules, description: null, location: locationOf(line) };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DependencySourceParser.js","names":["match","nativePattern","dotNetWhitespace","line","locationOf","ParserContext","context","body","eventSource","dimensions","eventTypes","child","firstWord","dimension","names","name","rules","from","parseDescription","parseObserverFilter","rule","diagnostic","DiagnosticCodes"],"sources":["../../../../../../Compiler/Parsing/DependencySourceParser.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 { ConcurrencySyntax, ReadsSyntax, ReducerRuleSyntax, ReducerSyntax } from '../Syntax/DependencySources';\nimport { DiagnosticCodes } from '../Diagnostics/DiagnosticCodes';\nimport { dotNetWhitespace, nativePattern } from '../Text/patterns';\nimport { parseDescription } from './DescriptionParser';\nimport { ObserverFilterSyntax } from '../Syntax/ObserverFilterSyntax';\nimport { parseObserverFilter } from './ObserverFilterParser';\nimport { firstWord } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\n// Reference-only capture does not change the committed parser's diagnostics or opaque-block skipping.\n// Fork before reading a body: code, malformed operands and unsupported realization stay opaque.\nexport function captureReads(line: SourceLine): ReadsSyntax | undefined {\n const match = nativePattern(`^reads${dotNetWhitespace}+([A-Z]\\\\w*)(?:${dotNetWhitespace}+as${dotNetWhitespace}+([a-z_]\\\\w*))?(?:${dotNetWhitespace}+by${dotNetWhitespace}+([a-z_]\\\\w*))?$`).exec(line.content);\n if (match === null || ['as', 'by', 'reads'].includes(match[2])) return undefined;\n return { kind: 'ReadsSyntax', readModel: match[1], alias: match[2] ?? null, by: match[3] ?? null, location: locationOf(line) };\n}\n\nfunction fork(context: ParserContext): ParserContext {\n return new ParserContext(context.reader.fork(), context.path, context.languages);\n}\n\nexport function captureConcurrency(context: ParserContext, line: SourceLine): ConcurrencySyntax | undefined {\n if (line.content !== 'concurrency') return undefined;\n const body = fork(context);\n let eventSource = false;\n const dimensions: Record<string, string> = {};\n let eventTypes: string[] | undefined;\n for (let child = body.peekChild(line.indent); child !== undefined; child = body.peekChild(line.indent)) {\n body.reader.takeSignificant();\n // C# keeps walking every descendant of the header for recognized dimensions, even malformed\n // or duplicate ones. Only an unknown dimension skips its own descendants during recovery.\n switch (firstWord(child.content)) {\n case 'eventSource':\n if (child.content === 'eventSource') eventSource = true;\n break;\n case 'sourceType':\n case 'streamType':\n case 'streamId': {\n const dimension = nativePattern(`^(sourceType|streamType|streamId)${dotNetWhitespace}+([A-Za-z_]\\\\w*)$`).exec(child.content);\n if (dimension !== null) dimensions[dimension[1]] ??= dimension[2];\n break;\n }\n case 'events': {\n if (eventTypes !== undefined) break;\n const names = child.content.slice('events'.length).split(',').map(name => name.replace(new RegExp(`^${dotNetWhitespace}+|${dotNetWhitespace}+$`, 'gu'), '')).filter(Boolean);\n if (names.length > 0 && names.every(name => nativePattern('^[A-Z]\\\\w*$').test(name))) eventTypes = names;\n break;\n }\n default:\n body.skipBlock(child.indent);\n break;\n }\n }\n return { kind: 'ConcurrencySyntax', eventSource, eventSourceType: dimensions.sourceType ?? null, eventStreamType: dimensions.streamType ?? null, eventStreamId: dimensions.streamId ?? null, eventTypes: eventTypes ?? [], location: locationOf(line) };\n}\n\nexport function captureReducer(context: ParserContext, line: SourceLine): ReducerSyntax {\n const match = nativePattern(`^reducer${dotNetWhitespace}+([A-Za-z_]\\\\w*)${dotNetWhitespace}*=>${dotNetWhitespace}*([A-Za-z_]\\\\w*)$`).exec(line.content);\n const body = fork(context);\n const rules: ReducerRuleSyntax[] = [];\n let from: ObserverFilterSyntax | null = null;\n for (let child = body.peekChild(line.indent); child !== undefined; child = body.peekChild(line.indent)) {\n body.reader.takeSignificant();\n if (firstWord(child.content) === 'description') {\n // Descriptions consume only their fenced text, never the following descendants. Diagnostics\n // stay on the fork, so reference capture does not change the committed parser's behavior.\n parseDescription(body, child, null, 'Reducer');\n continue;\n }\n if (firstWord(child.content) === 'from') {\n from = parseObserverFilter(body, child, from);\n continue;\n }\n const rule = nativePattern(`^on${dotNetWhitespace}+([A-Z]\\\\w*)$`).exec(child.content);\n if (rule !== null) rules.push({ kind: 'ReducerRuleSyntax', event: rule[1], file: null, code: null, description: null, location: locationOf(child) });\n body.skipOpaqueBlock(child.indent);\n }\n for (const diagnostic of body.diagnostics.filter(diagnostic => diagnostic.code === DiagnosticCodes.InvalidObserverFilter))\n context.error(diagnostic.code, diagnostic.message, diagnostic.location);\n return { kind: 'ReducerSyntax', from, name: match?.[1] ?? '', readModel: match?.[2] ?? '', rules, description: null, location: locationOf(line) };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{EventSourceCatalog as n}from"../Syntax/EventSourceCatalog.js";import{compatibleValue as r,uniqueByName as i}from"./ResponseValidator.js";import{commandDestinationType as a}from"./CommandDestinationTypes.js";import{streamIdFailureMessage as o,tryFormatInteger as s,tryFormatText as c,tryFormatUuidText as l}from"../Syntax/StreamIdFormatter.js";import{validateStreamIdParts as u}from"./CompositeStreamIdValidator.js";import{validateSpecificationStreams as d}from"./SpecificationStreamValidator.js";const f=/* @__PURE__ */ new Set([`String`,`Uuid`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`]);function supportsStreamIdentity(e,t){let n=t.concepts.filter(t=>t.name===e.name),r=n.length===1?n[0].type:n.length===0&&f.has(e.name)?e.name:null;return r===`String`||r===`Uuid`||r===`Int`&&n.length===1&&n[0].values.length===0}function formatStreamIdLiteral(e,t,n){if(e?.kind!==`LiteralExpressionSyntax`)return null;let r=e.value,a=t===null?null:i(n.concepts).get(t.name)?.type??t.name;return typeof r==`string`?a===`Uuid`?l(r):c(r):typeof r==`number`?s(r):typeof r==`object`&&r&&r.literalType===`ExactNumber`?r.value.includes(`.`)?s(NaN):s(BigInt(r.value),!1):null}function validateEventSources(s,c){let l=i(s.concepts),p=i(s.types),m=/* @__PURE__ */ new Set([...f,...l.keys(),...p.keys()]),h=new Map([...p].map(([e,t])=>[e,i(t.properties)])),compatible=(e,t)=>m.has(e.name)&&m.has(t.name)?e.name===t.name&&e.isCollection===t.isCollection&&(!e.isOptional||t.isOptional):null,validateType=(t,n)=>{if(t===null)return;if(t.isOptional||t.isCollection||s.types.some(e=>e.name===t.name)){c.error(e.InvalidEventSourceDeclaration,`Identifier and streamId declarations require a nonoptional scalar value type.`,t.location);return}let r=s.concepts.filter(e=>e.name===t.name),i=r.length===1?r[0].type:r.length===0&&f.has(t.name)?t.name:null;n&&i!==null&&!supportsStreamIdentity(t,s)&&c.error(e.UnsupportedStreamIdType,`Stream ids support text and UUID values and their nominal concepts, plus integer-backed concepts; other types need a future portable formatter.`,t.location),i===null&&!s.imports.some(e=>e.qualifiedName===t.name||e.qualifiedName.split(`.`).at(-1)===t.name)&&c.warning(e.UnknownType,`Unknown type '${t.name}' in event source declaration.`,t.location)},g=/* @__PURE__ */ new Set;for(let t of s.eventSources??[]){g.has(t.name)&&c.error(e.InvalidEventSourceDeclaration,`Event source '${t.name}' has multiple physical declarations.`,t.location),g.add(t.name),validateType(t.identifier,!1);let n=/* @__PURE__ */ new Set;for(let r of t.streams){n.has(r.name)&&c.error(e.InvalidEventSourceDeclaration,`Stream '${t.name}.${r.name}' has multiple declarations under this source.`,r.location),n.add(r.name),validateType(r.streamId,!0);let i=r.streamIdParts;if(i.length>0){i.length<2&&c.error(e.InvalidEventSourceDeclaration,`A composite stream id requires at least two named parts.`,r.directiveLocations?.streamId??r.location);for(let t of new Set(i.map(e=>e.name)))for(let n of i.filter(e=>e.name===t).slice(1))c.error(e.InvalidEventSourceDeclaration,`Stream id part '${n.name}' is declared more than once.`,n.location);for(let e of i)validateType(e.type,!0)}}}let pathProperty=(e,t)=>{let[n,...r]=t.split(`.`);if(e===null)return{property:null,missing:!1};let i=e.filter(e=>e.name===n);if(i.length!==1)return{property:null,missing:i.length===0};let a=i[0];if(r.length===0)return{property:a,missing:!1};if(f.has(a.type.name)||l.has(a.type.name)&&!p.has(a.type.name))return{property:null,missing:!0};let o=pathProperty(p.get(a.type.name)?.properties??null,r.join(`.`));return o.property===null?o:{property:{...o.property,type:{...o.property.type,isCollection:a.type.isCollection||o.property.type.isCollection,isOptional:a.type.isOptional||o.property.type.isOptional}},missing:!1}},_=new n(s),v=new t(s);for(let{slice:t}of v.slices)for(let n of t.commands){let i=n.stream;if(i==null||i.propertyCandidate!==null)continue;let d=_.resolve(i.eventSource,i.stream);if(d.kind!==`unique`){let t={ambiguous:`Ambiguous`,notFound:`NotFound`,wrongKind:`WrongKind`}[d.kind];c.error(e.InvalidCommandStream,`Stream '${i.eventSource}.${i.stream}' is ${t}; routing requires one physical source and stream.`,i.location);continue}let p=d.sources[0],m=d.streams[0],g=n.properties.filter(e=>e.isIdentifier);p.identifier!==null&&g.length===1&&compatible(g[0].type,p.identifier)===!1&&c.error(e.InvalidCommandStream,`Command identifier '${g[0].name}' does not have the source's nominal identifier type '${p.identifier.name}'. The stream does not supply a destination.`,g[0].location);for(let r of n.produces.filter(e=>v.isEventProduction(e,t))){if(p.identifier===null)continue;let i=a(n,r,s,{resolver:v,slice:t});if(i===null||r.for===null&&r.inlineEvent!==null&&g.length===1&&compatible(g[0].type,p.identifier)===!1)continue;let o=r.for===null&&r.inlineEvent===null&&!n.properties.some(e=>e.isGenerated&&e.isIdentifier),u=l.get(p.identifier.name)?.type??(f.has(p.identifier.name)?p.identifier.name:null);(o?u===null?null:u===`Uuid`:compatible(i,p.identifier))===!1&&c.error(e.InvalidCommandStream,`Command production destination does not have the source's nominal identifier type '${p.identifier.name}'. The stream does not supply a destination.`,r.for?.location??r.location)}let validateMapping=(t,i)=>{let a=t.source;if(a.kind===`PathExpressionSyntax`){let t=pathProperty(n.properties,a.path);(t.missing||t.property!==null&&compatible(t.property.type,i)===!1)&&c.error(e.InvalidCommandStream,`Stream id source '${a.path}' is absent or incompatible with nominal type '${i.name}'.`,a.location)}else if(a.kind===`LiteralExpressionSyntax`&&a.value!==null){let t=formatStreamIdLiteral(a,i,s);t?.failure==null?r(a,i,l,h)||c.error(e.InvalidCommandStream,`Stream id value is incompatible with nominal type '${i.name}'.`,a.location):c.error(e.InvalidCommandStream,o(t.failure),a.location)}else([`RawExpressionSyntax`,`ObjectExpressionSyntax`,`ListExpressionSyntax`].includes(a.kind)||a.kind===`LiteralExpressionSyntax`&&a.value===null)&&c.error(e.InvalidCommandStream,`A stream id needs a scalar value source, not a raw expression, collection or absence.`,a.location)};m.streamIdParts.length>0?u(m,i.streamIdParts,i.streamId!==null,i.location,e.InvalidCommandStream,c,validateMapping):i.streamIdParts.length>0?c.error(e.InvalidCommandStream,`A streamId part block requires a composite stream.`,i.location):((m.streamId===null&&i.streamId!==null||m.streamId!==null&&i.streamId===null)&&c.error(e.InvalidCommandStream,m.streamId===null?`An unkeyed stream cannot take a streamId mapping.`:`This keyed stream requires a streamId mapping.`,i.location),m.streamId!==null&&i.streamId!==null&&validateMapping(i.streamId,m.streamId))}d(s,c)}export{formatStreamIdLiteral,supportsStreamIdentity,validateEventSources};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{EventSourceCatalog as n}from"../Syntax/EventSourceCatalog.js";import{compatibleValue as r,uniqueByName as i}from"./ResponseValidator.js";import{commandDestinationType as a}from"./CommandDestinationTypes.js";import{validateObserverFilters as o}from"./ObserverFilterValidator.js";import{streamIdFailureMessage as s,tryFormatInteger as c,tryFormatText as l,tryFormatUuidText as u}from"../Syntax/StreamIdFormatter.js";import{validateStreamIdParts as d}from"./CompositeStreamIdValidator.js";import{validateSpecificationStreams as f}from"./SpecificationStreamValidator.js";const sameExpression=(e,t)=>e==null&&t==null||e?.kind===`PathExpressionSyntax`&&t?.kind===`PathExpressionSyntax`&&e.path===t.path||e?.kind===`LiteralExpressionSyntax`&&t?.kind===`LiteralExpressionSyntax`&&JSON.stringify(e.value)===JSON.stringify(t.value),sameRoute=(e,t)=>e.eventSource===t.eventSource&&e.stream===t.stream&&sameExpression(e.streamId?.source,t.streamId?.source)&&e.streamIdParts.length===t.streamIdParts.length&&e.streamIdParts.every(e=>t.streamIdParts.some(t=>e.property===t.property&&sameExpression(e.source,t.source))),p=/* @__PURE__ */ new Set([`String`,`Uuid`,`Int`,`Decimal`,`Bool`,`Date`,`DateTime`]);function supportsStreamIdentity(e,t){let n=t.concepts.filter(t=>t.name===e.name),r=n.length===1?n[0].type:n.length===0&&p.has(e.name)?e.name:null;return r===`String`||r===`Uuid`||r===`Int`&&n.length===1&&n[0].values.length===0}function formatStreamIdLiteral(e,t,n){if(e?.kind!==`LiteralExpressionSyntax`)return null;let r=e.value,a=t===null?null:i(n.concepts).get(t.name)?.type??t.name;return typeof r==`string`?a===`Uuid`?u(r):l(r):typeof r==`number`?c(r):typeof r==`object`&&r&&r.literalType===`ExactNumber`?r.value.includes(`.`)?c(NaN):c(BigInt(r.value),!1):null}function validateEventSources(c,l){let u=i(c.concepts),m=i(c.types),h=/* @__PURE__ */ new Set([...p,...u.keys(),...m.keys()]),g=new Map([...m].map(([e,t])=>[e,i(t.properties)])),compatible=(e,t)=>h.has(e.name)&&h.has(t.name)?e.name===t.name&&e.isCollection===t.isCollection&&(!e.isOptional||t.isOptional):null,validateType=(t,n)=>{if(t===null)return;if(t.isOptional||t.isCollection||c.types.some(e=>e.name===t.name)){l.error(e.InvalidEventSourceDeclaration,`Identifier and streamId declarations require a nonoptional scalar value type.`,t.location);return}let r=c.concepts.filter(e=>e.name===t.name),i=r.length===1?r[0].type:r.length===0&&p.has(t.name)?t.name:null;n&&i!==null&&!supportsStreamIdentity(t,c)&&l.error(e.UnsupportedStreamIdType,`Stream ids support text and UUID values and their nominal concepts, plus integer-backed concepts; other types need a future portable formatter.`,t.location),i===null&&!c.imports.some(e=>e.qualifiedName===t.name||e.qualifiedName.split(`.`).at(-1)===t.name)&&l.warning(e.UnknownType,`Unknown type '${t.name}' in event source declaration.`,t.location)},_=/* @__PURE__ */ new Set;for(let t of c.eventSources??[]){_.has(t.name)&&l.error(e.InvalidEventSourceDeclaration,`Event source '${t.name}' has multiple physical declarations.`,t.location),_.add(t.name),validateType(t.identifier,!1);let n=/* @__PURE__ */ new Set;for(let r of t.streams){n.has(r.name)&&l.error(e.InvalidEventSourceDeclaration,`Stream '${t.name}.${r.name}' has multiple declarations under this source.`,r.location),n.add(r.name),validateType(r.streamId,!0);let i=r.streamIdParts;if(i.length>0){i.length<2&&l.error(e.InvalidEventSourceDeclaration,`A composite stream id requires at least two named parts.`,r.directiveLocations?.streamId??r.location);for(let t of new Set(i.map(e=>e.name)))for(let n of i.filter(e=>e.name===t).slice(1))l.error(e.InvalidEventSourceDeclaration,`Stream id part '${n.name}' is declared more than once.`,n.location);for(let e of i)validateType(e.type,!0)}}}let pathProperty=(e,t)=>{let[n,...r]=t.split(`.`);if(e===null)return{property:null,missing:!1};let i=e.filter(e=>e.name===n);if(i.length!==1)return{property:null,missing:i.length===0};let a=i[0];if(r.length===0)return{property:a,missing:!1};if(p.has(a.type.name)||u.has(a.type.name)&&!m.has(a.type.name))return{property:null,missing:!0};let o=pathProperty(m.get(a.type.name)?.properties??null,r.join(`.`));return o.property===null?o:{property:{...o.property,type:{...o.property.type,isCollection:a.type.isCollection||o.property.type.isCollection,isOptional:a.type.isOptional||o.property.type.isOptional}},missing:!1}},v=new n(c),y=new t(c);o(c,l,y);for(let{slice:t}of y.slices)for(let n of t.commands)for(let{route:i,production:o}of[...n.stream==null?[]:[{route:n.stream,production:null}],...n.produces.filter(e=>e.stream!=null).map(e=>({route:e.stream,production:e}))]){if(i.propertyCandidate!==null)continue;o!==null&&n.stream!=null&&sameRoute(i,n.stream)&&l.warning(e.RedundantProductionRoute,`The production route repeats its command route; omit the override.`,i.location);let f=v.resolve(i.eventSource,i.stream);if(f.kind!==`unique`){let t={ambiguous:`Ambiguous`,notFound:`NotFound`,wrongKind:`WrongKind`}[f.kind];l.error(e.InvalidCommandStream,`Stream '${i.eventSource}.${i.stream}' is ${t}; routing requires one physical source and stream.`,i.location);continue}let m=f.sources[0],h=f.streams[0],_=n.properties.filter(e=>e.isIdentifier);o===null&&m.identifier!==null&&_.length===1&&compatible(_[0].type,m.identifier)===!1&&l.error(e.InvalidCommandStream,`Command identifier '${_[0].name}' does not have the source's nominal identifier type '${m.identifier.name}'. The stream does not supply a destination.`,_[0].location);for(let r of n.produces.filter(e=>y.isEventProduction(e,t)&&(o===null?e.stream==null:e===o))){if(m.identifier===null)continue;let i=a(n,r,c,{resolver:y,slice:t});if(i===null||o===null&&r.for===null&&r.inlineEvent!==null&&_.length===1&&compatible(_[0].type,m.identifier)===!1)continue;let s=r.for===null&&r.inlineEvent===null&&!n.properties.some(e=>e.isGenerated&&e.isIdentifier),d=u.get(m.identifier.name)?.type??(p.has(m.identifier.name)?m.identifier.name:null);(s?d===null?null:d===`Uuid`:compatible(i,m.identifier))===!1&&l.error(e.InvalidCommandStream,`Command production destination does not have the source's nominal identifier type '${m.identifier.name}'. The stream does not supply a destination.`,o?.stream?.location??r.for?.location??r.location)}let validateMapping=(t,i)=>{let a=t.source;if(a.kind===`PathExpressionSyntax`){let t=pathProperty(n.properties,a.path);(t.missing||t.property!==null&&compatible(t.property.type,i)===!1)&&l.error(e.InvalidCommandStream,`Stream id source '${a.path}' is absent or incompatible with nominal type '${i.name}'.`,a.location)}else if(a.kind===`LiteralExpressionSyntax`&&a.value!==null){let t=formatStreamIdLiteral(a,i,c);t?.failure==null?r(a,i,u,g)||l.error(e.InvalidCommandStream,`Stream id value is incompatible with nominal type '${i.name}'.`,a.location):l.error(e.InvalidCommandStream,s(t.failure),a.location)}else([`RawExpressionSyntax`,`ObjectExpressionSyntax`,`ListExpressionSyntax`].includes(a.kind)||a.kind===`LiteralExpressionSyntax`&&a.value===null)&&l.error(e.InvalidCommandStream,`A stream id needs a scalar value source, not a raw expression, collection or absence.`,a.location)};h.streamIdParts.length>0?d(h,i.streamIdParts,i.streamId!==null,i.location,e.InvalidCommandStream,l,validateMapping):i.streamIdParts.length>0?l.error(e.InvalidCommandStream,`A streamId part block requires a composite stream.`,i.location):((h.streamId===null&&i.streamId!==null||h.streamId!==null&&i.streamId===null)&&l.error(e.InvalidCommandStream,h.streamId===null?`An unkeyed stream cannot take a streamId mapping.`:`This keyed stream requires a streamId mapping.`,i.location),h.streamId!==null&&i.streamId!==null&&validateMapping(i.streamId,h.streamId))}f(c,l)}export{formatStreamIdLiteral,supportsStreamIdentity,validateEventSources};
2
2
  //# sourceMappingURL=EventSourceValidator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EventSourceValidator.js","names":["primitives","concepts","application","concept","type","primitive","expression","value","uniqueByName","tryFormatUuidText","tryFormatText","tryFormatInteger","composites","known","compositeProperties","name","source","target","composite","context","DiagnosticCodes","named","streamId","imported","names","streams","stream","parts","part","duplicate","remaining","path","properties","matches","property","resolved","catalog","EventSourceCatalog","resolver","AuthoringProductionResolver","command","slice","route","resolution","state","identifiers","produced","destination","commandDestinationType","allocated","mapping","formatted","compatibleValue","streamIdFailureMessage","validateStreamIdParts","validateSpecificationStreams"],"sources":["../../../../../../Compiler/Parsing/EventSourceValidator.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 { AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax, TypeRefSyntax } from '../Syntax/Declarations';\nimport { EventSourceCatalog } from '../Syntax/EventSourceCatalog';\nimport { EventSourceResolutionKind } from '../Syntax/EventSources';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { StreamIdFormatResult, streamIdFailureMessage, tryFormatInteger, tryFormatText, tryFormatUuidText } from '../Syntax/StreamIdFormatter';\nimport { commandDestinationType } from './CommandDestinationTypes';\nimport { validateStreamIdParts } from './CompositeStreamIdValidator';\nimport { ParserContext } from './ParserContext';\nimport { compatibleValue, uniqueByName } from './ResponseValidator';\nimport { validateSpecificationStreams } from './SpecificationStreamValidator';\n\nconst primitives = new Set(['String', 'Uuid', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime']);\n\nexport function supportsStreamIdentity(type: TypeRefSyntax, application: ApplicationSyntax): boolean {\n const concepts = application.concepts.filter(concept => concept.name === type.name);\n const primitive = concepts.length === 1 ? concepts[0].type : concepts.length === 0 && primitives.has(type.name) ? type.name : null;\n return primitive === 'String' || primitive === 'Uuid' || primitive === 'Int' && concepts.length === 1 && concepts[0].values.length === 0;\n}\n\nexport function formatStreamIdLiteral(expression: ExpressionSyntax | null | undefined, type: TypeRefSyntax | null, application: ApplicationSyntax): StreamIdFormatResult | null {\n if (expression?.kind !== 'LiteralExpressionSyntax') return null;\n const value = expression.value;\n const primitive = type === null ? null : uniqueByName(application.concepts).get(type.name)?.type ?? type.name;\n if (typeof value === 'string') return primitive === 'Uuid' ? tryFormatUuidText(value) : tryFormatText(value);\n if (typeof value === 'number') return tryFormatInteger(value);\n if (typeof value === 'object' && value !== null && value.literalType === 'ExactNumber') {\n if (value.value.includes('.')) return tryFormatInteger(NaN);\n return tryFormatInteger(BigInt(value.value), false);\n }\n return null;\n}\n\nexport function validateEventSources(application: ApplicationSyntax, context: ParserContext): void {\n const concepts = uniqueByName(application.concepts);\n const composites = uniqueByName(application.types);\n const known = new Set([...primitives, ...concepts.keys(), ...composites.keys()]);\n const compositeProperties = new Map([...composites].map(([name, type]) => [name, uniqueByName(type.properties)]));\n const compatible = (source: TypeRefSyntax, target: TypeRefSyntax): boolean | null => known.has(source.name) && known.has(target.name)\n ? source.name === target.name && source.isCollection === target.isCollection && (!source.isOptional || target.isOptional) : null;\n const validateType = (type: TypeRefSyntax | null, streamId: boolean): void => {\n if (type === null) return;\n if (type.isOptional || type.isCollection || application.types.some(composite => composite.name === type.name)) {\n context.error(DiagnosticCodes.InvalidEventSourceDeclaration, 'Identifier and streamId declarations require a nonoptional scalar value type.', type.location);\n return;\n }\n const named = application.concepts.filter(concept => concept.name === type.name);\n const primitive = named.length === 1 ? named[0].type : named.length === 0 && primitives.has(type.name) ? type.name : null;\n if (streamId && primitive !== null && !supportsStreamIdentity(type, application))\n context.error(DiagnosticCodes.UnsupportedStreamIdType, 'Stream ids support text and UUID values and their nominal concepts, plus integer-backed concepts; other types need a future portable formatter.', type.location);\n if (primitive === null && !application.imports.some(imported => imported.qualifiedName === type.name || imported.qualifiedName.split('.').at(-1) === type.name))\n context.warning(DiagnosticCodes.UnknownType, `Unknown type '${type.name}' in event source declaration.`, type.location);\n };\n const names = new Set<string>();\n for (const source of application.eventSources ?? []) {\n if (names.has(source.name)) context.error(DiagnosticCodes.InvalidEventSourceDeclaration, `Event source '${source.name}' has multiple physical declarations.`, source.location);\n names.add(source.name);\n validateType(source.identifier, false);\n const streams = new Set<string>();\n for (const stream of source.streams) {\n if (streams.has(stream.name)) context.error(DiagnosticCodes.InvalidEventSourceDeclaration, `Stream '${source.name}.${stream.name}' has multiple declarations under this source.`, stream.location);\n streams.add(stream.name);\n validateType(stream.streamId, true);\n const parts = stream.streamIdParts;\n if (parts.length > 0) {\n if (parts.length < 2) context.error(DiagnosticCodes.InvalidEventSourceDeclaration, 'A composite stream id requires at least two named parts.', stream.directiveLocations?.streamId ?? stream.location);\n for (const name of new Set(parts.map(part => part.name))) {\n for (const duplicate of parts.filter(part => part.name === name).slice(1))\n context.error(DiagnosticCodes.InvalidEventSourceDeclaration, `Stream id part '${duplicate.name}' is declared more than once.`, duplicate.location);\n }\n for (const part of parts) validateType(part.type, true);\n }\n }\n }\n const pathProperty = (properties: readonly PropertySyntax[] | null, path: string): { property: PropertySyntax | null; missing: boolean } => {\n const [name, ...remaining] = path.split('.');\n if (properties === null) return { property: null, missing: false };\n const matches = properties.filter(property => property.name === name);\n if (matches.length !== 1) return { property: null, missing: matches.length === 0 };\n const property = matches[0];\n if (remaining.length === 0) return { property, missing: false };\n if (primitives.has(property.type.name) || concepts.has(property.type.name) && !composites.has(property.type.name)) return { property: null, missing: true };\n const resolved = pathProperty(composites.get(property.type.name)?.properties ?? null, remaining.join('.'));\n return resolved.property === null ? resolved : { property: { ...resolved.property, type: { ...resolved.property.type, isCollection: property.type.isCollection || resolved.property.type.isCollection, isOptional: property.type.isOptional || resolved.property.type.isOptional } }, missing: false };\n };\n const catalog = new EventSourceCatalog(application);\n const resolver = new AuthoringProductionResolver(application);\n for (const { slice } of resolver.slices) for (const command of slice.commands) {\n const route = command.stream;\n if (route == null || route.propertyCandidate !== null) continue;\n const resolution = catalog.resolve(route.eventSource, route.stream);\n if (resolution.kind !== EventSourceResolutionKind.Unique) {\n const state = { ambiguous: 'Ambiguous', notFound: 'NotFound', wrongKind: 'WrongKind' }[resolution.kind];\n context.error(DiagnosticCodes.InvalidCommandStream, `Stream '${route.eventSource}.${route.stream}' is ${state}; routing requires one physical source and stream.`, route.location);\n continue;\n }\n const source = resolution.sources[0];\n const stream = resolution.streams[0];\n const identifiers = command.properties.filter(property => property.isIdentifier);\n if (source.identifier !== null && identifiers.length === 1 && compatible(identifiers[0].type, source.identifier) === false)\n context.error(DiagnosticCodes.InvalidCommandStream, `Command identifier '${identifiers[0].name}' does not have the source's nominal identifier type '${source.identifier.name}'. The stream does not supply a destination.`, identifiers[0].location);\n for (const produced of command.produces.filter(produced => resolver.isEventProduction(produced, slice))) {\n if (source.identifier === null) continue;\n const destination = commandDestinationType(command, produced, application, { resolver, slice });\n if (destination === null) continue;\n if (produced.for === null && produced.inlineEvent !== null && identifiers.length === 1 && compatible(identifiers[0].type, source.identifier) === false) continue;\n const allocated = produced.for === null && produced.inlineEvent === null && !command.properties.some(property => property.isGenerated && property.isIdentifier);\n const primitive = concepts.get(source.identifier.name)?.type ?? (primitives.has(source.identifier.name) ? source.identifier.name : null);\n const matches = allocated ? primitive === null ? null : primitive === 'Uuid' : compatible(destination, source.identifier);\n if (matches === false) context.error(DiagnosticCodes.InvalidCommandStream, `Command production destination does not have the source's nominal identifier type '${source.identifier.name}'. The stream does not supply a destination.`, produced.for?.location ?? produced.location);\n }\n const validateMapping = (mapping: PropertyMappingSyntax, target: TypeRefSyntax): void => {\n const expression = mapping.source;\n if (expression.kind === 'PathExpressionSyntax') {\n const resolved = pathProperty(command.properties, expression.path);\n if (resolved.missing || resolved.property !== null && compatible(resolved.property.type, target) === false)\n context.error(DiagnosticCodes.InvalidCommandStream, `Stream id source '${expression.path}' is absent or incompatible with nominal type '${target.name}'.`, expression.location);\n } else if (expression.kind === 'LiteralExpressionSyntax' && expression.value !== null) {\n const formatted = formatStreamIdLiteral(expression, target, application);\n if (formatted?.failure != null) context.error(DiagnosticCodes.InvalidCommandStream, streamIdFailureMessage(formatted.failure), expression.location);\n else if (!compatibleValue(expression, target, concepts, compositeProperties)) context.error(DiagnosticCodes.InvalidCommandStream, `Stream id value is incompatible with nominal type '${target.name}'.`, expression.location);\n } else if (['RawExpressionSyntax', 'ObjectExpressionSyntax', 'ListExpressionSyntax'].includes(expression.kind) || expression.kind === 'LiteralExpressionSyntax' && expression.value === null)\n context.error(DiagnosticCodes.InvalidCommandStream, 'A stream id needs a scalar value source, not a raw expression, collection or absence.', expression.location);\n };\n if (stream.streamIdParts.length > 0) {\n validateStreamIdParts(stream, route.streamIdParts, route.streamId !== null, route.location, DiagnosticCodes.InvalidCommandStream, context, validateMapping);\n continue;\n }\n if (route.streamIdParts.length > 0) {\n context.error(DiagnosticCodes.InvalidCommandStream, 'A streamId part block requires a composite stream.', route.location);\n continue;\n }\n if (stream.streamId === null && route.streamId !== null || stream.streamId !== null && route.streamId === null)\n context.error(DiagnosticCodes.InvalidCommandStream, stream.streamId === null ? 'An unkeyed stream cannot take a streamId mapping.' : 'This keyed stream requires a streamId mapping.', route.location);\n if (stream.streamId === null || route.streamId === null) continue;\n validateMapping(route.streamId, stream.streamId);\n }\n validateSpecificationStreams(application, context);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EventSourceValidator.js","names":["left","right","part","other","primitives","concepts","application","concept","type","primitive","expression","value","uniqueByName","tryFormatUuidText","tryFormatText","tryFormatInteger","composites","known","compositeProperties","name","source","target","composite","context","DiagnosticCodes","named","streamId","imported","names","streams","stream","parts","duplicate","remaining","path","properties","matches","property","resolved","catalog","EventSourceCatalog","resolver","AuthoringProductionResolver","validateObserverFilters","command","slice","produced","route","production","resolution","state","identifiers","destination","commandDestinationType","allocated","mapping","formatted","compatibleValue","streamIdFailureMessage","validateStreamIdParts","validateSpecificationStreams"],"sources":["../../../../../../Compiler/Parsing/EventSourceValidator.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 { AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax, TypeRefSyntax } from '../Syntax/Declarations';\nimport { EventSourceCatalog } from '../Syntax/EventSourceCatalog';\nimport { CommandStreamSyntax, EventSourceResolutionKind } from '../Syntax/EventSources';\nimport { validateObserverFilters } from './ObserverFilterValidator';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { StreamIdFormatResult, streamIdFailureMessage, tryFormatInteger, tryFormatText, tryFormatUuidText } from '../Syntax/StreamIdFormatter';\nimport { commandDestinationType } from './CommandDestinationTypes';\nimport { validateStreamIdParts } from './CompositeStreamIdValidator';\nimport { ParserContext } from './ParserContext';\nimport { compatibleValue, uniqueByName } from './ResponseValidator';\nimport { validateSpecificationStreams } from './SpecificationStreamValidator';\n\nconst sameExpression = (left: ExpressionSyntax | null | undefined, right: ExpressionSyntax | null | undefined): boolean =>\n left == null && right == null || left?.kind === 'PathExpressionSyntax' && right?.kind === 'PathExpressionSyntax' && left.path === right.path ||\n left?.kind === 'LiteralExpressionSyntax' && right?.kind === 'LiteralExpressionSyntax' && JSON.stringify(left.value) === JSON.stringify(right.value);\nconst sameRoute = (left: CommandStreamSyntax, right: CommandStreamSyntax): boolean => left.eventSource === right.eventSource && left.stream === right.stream &&\n sameExpression(left.streamId?.source, right.streamId?.source) && left.streamIdParts.length === right.streamIdParts.length &&\n left.streamIdParts.every(part => right.streamIdParts.some(other => part.property === other.property && sameExpression(part.source, other.source)));\n\nconst primitives = new Set(['String', 'Uuid', 'Int', 'Decimal', 'Bool', 'Date', 'DateTime']);\n\nexport function supportsStreamIdentity(type: TypeRefSyntax, application: ApplicationSyntax): boolean {\n const concepts = application.concepts.filter(concept => concept.name === type.name);\n const primitive = concepts.length === 1 ? concepts[0].type : concepts.length === 0 && primitives.has(type.name) ? type.name : null;\n return primitive === 'String' || primitive === 'Uuid' || primitive === 'Int' && concepts.length === 1 && concepts[0].values.length === 0;\n}\n\nexport function formatStreamIdLiteral(expression: ExpressionSyntax | null | undefined, type: TypeRefSyntax | null, application: ApplicationSyntax): StreamIdFormatResult | null {\n if (expression?.kind !== 'LiteralExpressionSyntax') return null;\n const value = expression.value;\n const primitive = type === null ? null : uniqueByName(application.concepts).get(type.name)?.type ?? type.name;\n if (typeof value === 'string') return primitive === 'Uuid' ? tryFormatUuidText(value) : tryFormatText(value);\n if (typeof value === 'number') return tryFormatInteger(value);\n if (typeof value === 'object' && value !== null && value.literalType === 'ExactNumber') {\n if (value.value.includes('.')) return tryFormatInteger(NaN);\n return tryFormatInteger(BigInt(value.value), false);\n }\n return null;\n}\n\nexport function validateEventSources(application: ApplicationSyntax, context: ParserContext): void {\n const concepts = uniqueByName(application.concepts);\n const composites = uniqueByName(application.types);\n const known = new Set([...primitives, ...concepts.keys(), ...composites.keys()]);\n const compositeProperties = new Map([...composites].map(([name, type]) => [name, uniqueByName(type.properties)]));\n const compatible = (source: TypeRefSyntax, target: TypeRefSyntax): boolean | null => known.has(source.name) && known.has(target.name)\n ? source.name === target.name && source.isCollection === target.isCollection && (!source.isOptional || target.isOptional) : null;\n const validateType = (type: TypeRefSyntax | null, streamId: boolean): void => {\n if (type === null) return;\n if (type.isOptional || type.isCollection || application.types.some(composite => composite.name === type.name)) {\n context.error(DiagnosticCodes.InvalidEventSourceDeclaration, 'Identifier and streamId declarations require a nonoptional scalar value type.', type.location);\n return;\n }\n const named = application.concepts.filter(concept => concept.name === type.name);\n const primitive = named.length === 1 ? named[0].type : named.length === 0 && primitives.has(type.name) ? type.name : null;\n if (streamId && primitive !== null && !supportsStreamIdentity(type, application))\n context.error(DiagnosticCodes.UnsupportedStreamIdType, 'Stream ids support text and UUID values and their nominal concepts, plus integer-backed concepts; other types need a future portable formatter.', type.location);\n if (primitive === null && !application.imports.some(imported => imported.qualifiedName === type.name || imported.qualifiedName.split('.').at(-1) === type.name))\n context.warning(DiagnosticCodes.UnknownType, `Unknown type '${type.name}' in event source declaration.`, type.location);\n };\n const names = new Set<string>();\n for (const source of application.eventSources ?? []) {\n if (names.has(source.name)) context.error(DiagnosticCodes.InvalidEventSourceDeclaration, `Event source '${source.name}' has multiple physical declarations.`, source.location);\n names.add(source.name);\n validateType(source.identifier, false);\n const streams = new Set<string>();\n for (const stream of source.streams) {\n if (streams.has(stream.name)) context.error(DiagnosticCodes.InvalidEventSourceDeclaration, `Stream '${source.name}.${stream.name}' has multiple declarations under this source.`, stream.location);\n streams.add(stream.name);\n validateType(stream.streamId, true);\n const parts = stream.streamIdParts;\n if (parts.length > 0) {\n if (parts.length < 2) context.error(DiagnosticCodes.InvalidEventSourceDeclaration, 'A composite stream id requires at least two named parts.', stream.directiveLocations?.streamId ?? stream.location);\n for (const name of new Set(parts.map(part => part.name))) {\n for (const duplicate of parts.filter(part => part.name === name).slice(1))\n context.error(DiagnosticCodes.InvalidEventSourceDeclaration, `Stream id part '${duplicate.name}' is declared more than once.`, duplicate.location);\n }\n for (const part of parts) validateType(part.type, true);\n }\n }\n }\n const pathProperty = (properties: readonly PropertySyntax[] | null, path: string): { property: PropertySyntax | null; missing: boolean } => {\n const [name, ...remaining] = path.split('.');\n if (properties === null) return { property: null, missing: false };\n const matches = properties.filter(property => property.name === name);\n if (matches.length !== 1) return { property: null, missing: matches.length === 0 };\n const property = matches[0];\n if (remaining.length === 0) return { property, missing: false };\n if (primitives.has(property.type.name) || concepts.has(property.type.name) && !composites.has(property.type.name)) return { property: null, missing: true };\n const resolved = pathProperty(composites.get(property.type.name)?.properties ?? null, remaining.join('.'));\n return resolved.property === null ? resolved : { property: { ...resolved.property, type: { ...resolved.property.type, isCollection: property.type.isCollection || resolved.property.type.isCollection, isOptional: property.type.isOptional || resolved.property.type.isOptional } }, missing: false };\n };\n const catalog = new EventSourceCatalog(application);\n const resolver = new AuthoringProductionResolver(application);\n validateObserverFilters(application, context, resolver);\n for (const { slice } of resolver.slices) for (const command of slice.commands) for (const { route, production } of [\n ...(command.stream == null ? [] : [{ route: command.stream, production: null }]),\n ...command.produces.filter(produced => produced.stream != null).map(produced => ({ route: produced.stream!, production: produced }))\n ]) {\n if (route.propertyCandidate !== null) continue;\n if (production !== null && command.stream != null && sameRoute(route, command.stream))\n context.warning(DiagnosticCodes.RedundantProductionRoute, 'The production route repeats its command route; omit the override.', route.location);\n const resolution = catalog.resolve(route.eventSource, route.stream);\n if (resolution.kind !== EventSourceResolutionKind.Unique) {\n const state = { ambiguous: 'Ambiguous', notFound: 'NotFound', wrongKind: 'WrongKind' }[resolution.kind];\n context.error(DiagnosticCodes.InvalidCommandStream, `Stream '${route.eventSource}.${route.stream}' is ${state}; routing requires one physical source and stream.`, route.location);\n continue;\n }\n const source = resolution.sources[0];\n const stream = resolution.streams[0];\n const identifiers = command.properties.filter(property => property.isIdentifier);\n if (production === null && source.identifier !== null && identifiers.length === 1 && compatible(identifiers[0].type, source.identifier) === false)\n context.error(DiagnosticCodes.InvalidCommandStream, `Command identifier '${identifiers[0].name}' does not have the source's nominal identifier type '${source.identifier.name}'. The stream does not supply a destination.`, identifiers[0].location);\n for (const produced of command.produces.filter(produced => resolver.isEventProduction(produced, slice) && (production === null ? produced.stream == null : produced === production))) {\n if (source.identifier === null) continue;\n const destination = commandDestinationType(command, produced, application, { resolver, slice });\n if (destination === null) continue;\n if (production === null && produced.for === null && produced.inlineEvent !== null && identifiers.length === 1 && compatible(identifiers[0].type, source.identifier) === false) continue;\n const allocated = produced.for === null && produced.inlineEvent === null && !command.properties.some(property => property.isGenerated && property.isIdentifier);\n const primitive = concepts.get(source.identifier.name)?.type ?? (primitives.has(source.identifier.name) ? source.identifier.name : null);\n const matches = allocated ? primitive === null ? null : primitive === 'Uuid' : compatible(destination, source.identifier);\n if (matches === false) context.error(DiagnosticCodes.InvalidCommandStream, `Command production destination does not have the source's nominal identifier type '${source.identifier.name}'. The stream does not supply a destination.`, production?.stream?.location ?? produced.for?.location ?? produced.location);\n }\n const validateMapping = (mapping: PropertyMappingSyntax, target: TypeRefSyntax): void => {\n const expression = mapping.source;\n if (expression.kind === 'PathExpressionSyntax') {\n const resolved = pathProperty(command.properties, expression.path);\n if (resolved.missing || resolved.property !== null && compatible(resolved.property.type, target) === false)\n context.error(DiagnosticCodes.InvalidCommandStream, `Stream id source '${expression.path}' is absent or incompatible with nominal type '${target.name}'.`, expression.location);\n } else if (expression.kind === 'LiteralExpressionSyntax' && expression.value !== null) {\n const formatted = formatStreamIdLiteral(expression, target, application);\n if (formatted?.failure != null) context.error(DiagnosticCodes.InvalidCommandStream, streamIdFailureMessage(formatted.failure), expression.location);\n else if (!compatibleValue(expression, target, concepts, compositeProperties)) context.error(DiagnosticCodes.InvalidCommandStream, `Stream id value is incompatible with nominal type '${target.name}'.`, expression.location);\n } else if (['RawExpressionSyntax', 'ObjectExpressionSyntax', 'ListExpressionSyntax'].includes(expression.kind) || expression.kind === 'LiteralExpressionSyntax' && expression.value === null)\n context.error(DiagnosticCodes.InvalidCommandStream, 'A stream id needs a scalar value source, not a raw expression, collection or absence.', expression.location);\n };\n if (stream.streamIdParts.length > 0) {\n validateStreamIdParts(stream, route.streamIdParts, route.streamId !== null, route.location, DiagnosticCodes.InvalidCommandStream, context, validateMapping);\n continue;\n }\n if (route.streamIdParts.length > 0) {\n context.error(DiagnosticCodes.InvalidCommandStream, 'A streamId part block requires a composite stream.', route.location);\n continue;\n }\n if (stream.streamId === null && route.streamId !== null || stream.streamId !== null && route.streamId === null)\n context.error(DiagnosticCodes.InvalidCommandStream, stream.streamId === null ? 'An unkeyed stream cannot take a streamId mapping.' : 'This keyed stream requires a streamId mapping.', route.location);\n if (stream.streamId === null || route.streamId === null) continue;\n validateMapping(route.streamId, stream.streamId);\n }\n validateSpecificationStreams(application, context);\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{dependencySourcesOf as n}from"../Syntax/DependencySources.js";import{EventSourceCatalog as r}from"../Syntax/EventSourceCatalog.js";import{uniqueByName as i}from"./ResponseValidator.js";function validateIdentifierCompliance(a,o){let s=new Set(a.concepts.filter(e=>e.attributes.some(e=>e.name===`pii`)).map(e=>e.name)),c=new Set(a.concepts.filter(e=>e.attributes.some(e=>e.name===`sensitive`)).map(e=>e.name)),l=i(a.types),u=new t(a),d=new Set(a.imports.map(e=>e.qualifiedName.split(`.`).at(-1))),f=/* @__PURE__ */ new Map;for(let e of a.declaredTriggers??[]){let t=f.get(e.name)??[];t.push(e.data),f.set(e.name,t)}let validate=(t,n,r=`an event source identifier`)=>{if(s.has(t.name)||c.has(t.name)){let i=s.has(t.name)?`pii`:`secret`;o.error(e.PiiNotSupportedOnIdentifier,`Concept '${t.name}' is ${i} and cannot be ${r} - use a surrogate Uuid identifier and keep the ${i} value as a property`,n)}},property=(e,t)=>{let[n,...r]=t.split(`.`),i=e.filter(e=>e.name===n);if(i.length!==1)return null;let a=i[0];return r.length===0?a:property(l.get(a.type.name)?.properties??[],r.join(`.`))};for(let e of a.eventSources??[]){e.identifier!=null&&validate(e.identifier,e.identifier.location);for(let t of e.streams){t.streamId!==null&&validate(t.streamId,t.streamId.location,`a stream id`);for(let e of t.streamIdParts)validate(e.type,e.type.location,`a stream id part '${e.name}'`)}}let p=new r(a);for(let{slice:e}of u.slices){for(let t of e.commands){for(let e of t.properties.filter(e=>e.isIdentifier))validate(e.type,e.location);for(let e of[...t.stream?[t.stream]:[],...t.streamCandidates??[]].filter(e=>e.propertyCandidate===null)){let n=p.resolve(e.eventSource,e.stream),r=n.kind===`unique`?n.streams[0]:void 0,i=[...e.streamId===null?[]:[{mapping:e.streamId,target:r?.streamId}],...e.streamIdParts.map(e=>({mapping:e,target:r?.streamIdParts.find(t=>t.name===e.property)?.type}))];for(let{mapping:e,target:n}of i){if(e.source.kind!==`PathExpressionSyntax`)continue;let r=property(t.properties,e.source.path);r!==null&&(r.type.name!==n?.name||!s.has(r.type.name)&&!c.has(r.type.name))&&validate(r.type,e.source.location,`a stream id route mapping`)}}for(let n of t.produces.filter(t=>u.isEventProduction(t,e))){if(n.for?.kind!==`PathExpressionSyntax`)continue;let e=property(t.properties,n.for.path);e!==null&&!e.isIdentifier&&validate(e.type,n.for.location)}}for(let t of e.reactions.flatMap(e=>e.triggers)){if(t.source.kind!==`NamedTriggerSourceSyntax`)continue;let r=u.resolve(t.source.name,e).declaration?.node,i=(n(t).data??[]).flatMap(e=>e.type===null?[]:[{kind:`PropertySyntax`,name:e.name,type:e.type,isIdentifier:!1,location:e.location}]),a=[r?.kind===`EventSyntax`?r.properties:[],i];r?.kind!==`EventSyntax`&&!d.has(t.source.name)&&a.push(...f.get(t.source.name)??[]);for(let n of t.produces.filter(t=>u.isEventProduction(t,e))){if(n.for?.kind!==`PathExpressionSyntax`)continue;let e=n.for.path,t=a.map(t=>property(t,e)).find(e=>e!==null&&(s.has(e.type.name)||c.has(e.type.name)));t!=null&&validate(t.type,n.for.location)}}}}export{validateIdentifierCompliance};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{AuthoringProductionResolver as t}from"../Syntax/AuthoringProductionResolver.js";import{dependencySourcesOf as n}from"../Syntax/DependencySources.js";import{EventSourceCatalog as r}from"../Syntax/EventSourceCatalog.js";import{uniqueByName as i}from"./ResponseValidator.js";function validateIdentifierCompliance(a,o){let s=new Set(a.concepts.filter(e=>e.attributes.some(e=>e.name===`pii`)).map(e=>e.name)),c=new Set(a.concepts.filter(e=>e.attributes.some(e=>e.name===`sensitive`)).map(e=>e.name)),l=i(a.types),u=new t(a),d=new Set(a.imports.map(e=>e.qualifiedName.split(`.`).at(-1))),f=/* @__PURE__ */ new Map;for(let e of a.declaredTriggers??[]){let t=f.get(e.name)??[];t.push(e.data),f.set(e.name,t)}let validate=(t,n,r=`an event source identifier`)=>{if(s.has(t.name)||c.has(t.name)){let i=s.has(t.name)?`pii`:`secret`;o.error(e.PiiNotSupportedOnIdentifier,`Concept '${t.name}' is ${i} and cannot be ${r} - use a surrogate Uuid identifier and keep the ${i} value as a property`,n)}},property=(e,t)=>{let[n,...r]=t.split(`.`),i=e.filter(e=>e.name===n);if(i.length!==1)return null;let a=i[0];return r.length===0?a:property(l.get(a.type.name)?.properties??[],r.join(`.`))};for(let e of a.eventSources??[]){e.identifier!=null&&validate(e.identifier,e.identifier.location);for(let t of e.streams){t.streamId!==null&&validate(t.streamId,t.streamId.location,`a stream id`);for(let e of t.streamIdParts)validate(e.type,e.type.location,`a stream id part '${e.name}'`)}}let p=new r(a);for(let{slice:e}of u.slices){for(let t of e.commands){for(let e of t.properties.filter(e=>e.isIdentifier))validate(e.type,e.location);for(let e of[...t.stream?[t.stream]:[],...t.streamCandidates??[],...t.produces.flatMap(e=>e.stream==null?[]:[e.stream])].filter(e=>e.propertyCandidate===null)){let n=p.resolve(e.eventSource,e.stream),r=n.kind===`unique`?n.streams[0]:void 0,i=[...e.streamId===null?[]:[{mapping:e.streamId,target:r?.streamId}],...e.streamIdParts.map(e=>({mapping:e,target:r?.streamIdParts.find(t=>t.name===e.property)?.type}))];for(let{mapping:e,target:n}of i){if(e.source.kind!==`PathExpressionSyntax`)continue;let r=property(t.properties,e.source.path);r!==null&&(r.type.name!==n?.name||!s.has(r.type.name)&&!c.has(r.type.name))&&validate(r.type,e.source.location,`a stream id route mapping`)}}for(let n of t.produces.filter(t=>u.isEventProduction(t,e))){if(n.for?.kind!==`PathExpressionSyntax`)continue;let e=property(t.properties,n.for.path);e!==null&&!e.isIdentifier&&validate(e.type,n.for.location)}}for(let t of e.reactions.flatMap(e=>e.triggers)){if(t.source.kind!==`NamedTriggerSourceSyntax`)continue;let r=u.resolve(t.source.name,e).declaration?.node,i=(n(t).data??[]).flatMap(e=>e.type===null?[]:[{kind:`PropertySyntax`,name:e.name,type:e.type,isIdentifier:!1,location:e.location}]),a=[r?.kind===`EventSyntax`?r.properties:[],i];r?.kind!==`EventSyntax`&&!d.has(t.source.name)&&a.push(...f.get(t.source.name)??[]);for(let n of t.produces.filter(t=>u.isEventProduction(t,e))){if(n.for?.kind!==`PathExpressionSyntax`)continue;let e=n.for.path,t=a.map(t=>property(t,e)).find(e=>e!==null&&(s.has(e.type.name)||c.has(e.type.name)));t!=null&&validate(t.type,n.for.location)}}}}export{validateIdentifierCompliance};
2
2
  //# sourceMappingURL=IdentifierComplianceValidator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IdentifierComplianceValidator.js","names":["personal","application","concept","attribute","sensitive","types","uniqueByName","resolver","AuthoringProductionResolver","imports","imported","declaredTriggers","declared","shapes","type","context","DiagnosticCodes","position","location","name","rest","path","matches","properties","entry","value","source","stream","part","catalog","EventSourceCatalog","command","slice","route","resolution","mappings","mapping","target","production","trigger","reaction","event","clauseData","dependencySourcesOf","datum"],"sources":["../../../../../../Compiler/Parsing/IdentifierComplianceValidator.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 { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax, TypeRefSyntax } from '../Syntax/Declarations';\nimport { EventSourceCatalog } from '../Syntax/EventSourceCatalog';\nimport { EventSourceResolutionKind } from '../Syntax/EventSources';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { ParserContext } from './ParserContext';\nimport { uniqueByName } from './ResponseValidator';\n\nexport function validateIdentifierCompliance(application: ApplicationSyntax, context: ParserContext): void {\n const personal = new Set(application.concepts.filter(concept => concept.attributes.some(attribute => attribute.name === 'pii')).map(concept => concept.name));\n const sensitive = new Set(application.concepts.filter(concept => concept.attributes.some(attribute => attribute.name === 'sensitive')).map(concept => concept.name));\n const types = uniqueByName(application.types);\n const resolver = new AuthoringProductionResolver(application);\n const imports = new Set(application.imports.map(imported => imported.qualifiedName.split('.').at(-1)!));\n const declaredTriggers = new Map<string, (readonly PropertySyntax[])[]>();\n for (const declared of application.declaredTriggers ?? []) {\n const shapes = declaredTriggers.get(declared.name) ?? [];\n shapes.push(declared.data);\n declaredTriggers.set(declared.name, shapes);\n }\n const validate = (type: TypeRefSyntax, location: SourceLocation, position = 'an event source identifier'): void => {\n if (personal.has(type.name) || sensitive.has(type.name)) {\n const attribute = personal.has(type.name) ? 'pii' : 'secret';\n context.error(DiagnosticCodes.PiiNotSupportedOnIdentifier, `Concept '${type.name}' is ${attribute} and cannot be ${position} - use a surrogate Uuid identifier and keep the ${attribute} value as a property`, location);\n }\n };\n const property = (properties: readonly PropertySyntax[], path: string): PropertySyntax | null => {\n const [name, ...rest] = path.split('.');\n const matches = properties.filter(entry => entry.name === name);\n if (matches.length !== 1) return null;\n const value = matches[0];\n if (rest.length === 0) return value;\n return property(types.get(value.type.name)?.properties ?? [], rest.join('.'));\n };\n for (const source of application.eventSources ?? []) {\n if (source.identifier != null) validate(source.identifier, source.identifier.location);\n for (const stream of source.streams) {\n if (stream.streamId !== null) validate(stream.streamId, stream.streamId.location, 'a stream id');\n for (const part of stream.streamIdParts) validate(part.type, part.type.location, `a stream id part '${part.name}'`);\n }\n }\n const catalog = new EventSourceCatalog(application);\n for (const { slice } of resolver.slices) {\n for (const command of slice.commands) {\n for (const entry of command.properties.filter(entry => entry.isIdentifier)) validate(entry.type, entry.location);\n for (const route of [...(command.stream ? [command.stream] : []), ...command.streamCandidates ?? []].filter(route => route.propertyCandidate === null)) {\n const resolution = catalog.resolve(route.eventSource, route.stream);\n const stream = resolution.kind === EventSourceResolutionKind.Unique ? resolution.streams[0] : undefined;\n const mappings = [\n ...(route.streamId === null ? [] : [{ mapping: route.streamId, target: stream?.streamId }]),\n ...route.streamIdParts.map(mapping => ({ mapping, target: stream?.streamIdParts.find(part => part.name === mapping.property)?.type })),\n ];\n for (const { mapping, target } of mappings) {\n if (mapping.source.kind !== 'PathExpressionSyntax') continue;\n const entry = property(command.properties, mapping.source.path);\n if (entry === null) continue;\n // The same protected concept has already been reported at its resolved declaration.\n if (entry.type.name === target?.name && (personal.has(entry.type.name) || sensitive.has(entry.type.name))) continue;\n validate(entry.type, mapping.source.location, 'a stream id route mapping');\n }\n }\n for (const production of command.produces.filter(production => resolver.isEventProduction(production, slice))) {\n if (production.for?.kind !== 'PathExpressionSyntax') continue;\n const entry = property(command.properties, production.for.path);\n if (entry !== null && !entry.isIdentifier) validate(entry.type, production.for.location);\n }\n }\n for (const trigger of slice.reactions.flatMap(reaction => reaction.triggers)) {\n if (trigger.source.kind !== 'NamedTriggerSourceSyntax') continue;\n const resolution = resolver.resolve(trigger.source.name, slice);\n const event = resolution.declaration?.node;\n const clauseData = (dependencySourcesOf(trigger).data ?? []).flatMap<PropertySyntax>(datum => datum.type === null ? [] : [{ kind: 'PropertySyntax', name: datum.name, type: datum.type, isIdentifier: false, location: datum.location }]);\n const shapes = [event?.kind === 'EventSyntax' ? event.properties : [], clauseData];\n if (event?.kind !== 'EventSyntax' && !imports.has(trigger.source.name)) {\n shapes.push(...declaredTriggers.get(trigger.source.name) ?? []);\n }\n for (const production of trigger.produces.filter(production => resolver.isEventProduction(production, slice))) {\n if (production.for?.kind !== 'PathExpressionSyntax') continue;\n // Check clause-local types alongside the occurrence selected by event-first reaction resolution.\n const path = production.for.path;\n const entry = shapes.map(properties => property(properties, path)).find(entry => entry !== null && (personal.has(entry.type.name) || sensitive.has(entry.type.name)));\n if (entry != null) validate(entry.type, production.for.location);\n }\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"IdentifierComplianceValidator.js","names":["personal","application","concept","attribute","sensitive","types","uniqueByName","resolver","AuthoringProductionResolver","imports","imported","declaredTriggers","declared","shapes","type","context","DiagnosticCodes","position","location","name","rest","path","matches","properties","entry","value","source","stream","part","catalog","EventSourceCatalog","command","slice","route","produced","resolution","mappings","mapping","target","production","trigger","reaction","event","clauseData","dependencySourcesOf","datum"],"sources":["../../../../../../Compiler/Parsing/IdentifierComplianceValidator.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 { SourceLocation } from '../Diagnostics/SourceLocation';\nimport { AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { PropertySyntax, TypeRefSyntax } from '../Syntax/Declarations';\nimport { EventSourceCatalog } from '../Syntax/EventSourceCatalog';\nimport { EventSourceResolutionKind } from '../Syntax/EventSources';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { ParserContext } from './ParserContext';\nimport { uniqueByName } from './ResponseValidator';\n\nexport function validateIdentifierCompliance(application: ApplicationSyntax, context: ParserContext): void {\n const personal = new Set(application.concepts.filter(concept => concept.attributes.some(attribute => attribute.name === 'pii')).map(concept => concept.name));\n const sensitive = new Set(application.concepts.filter(concept => concept.attributes.some(attribute => attribute.name === 'sensitive')).map(concept => concept.name));\n const types = uniqueByName(application.types);\n const resolver = new AuthoringProductionResolver(application);\n const imports = new Set(application.imports.map(imported => imported.qualifiedName.split('.').at(-1)!));\n const declaredTriggers = new Map<string, (readonly PropertySyntax[])[]>();\n for (const declared of application.declaredTriggers ?? []) {\n const shapes = declaredTriggers.get(declared.name) ?? [];\n shapes.push(declared.data);\n declaredTriggers.set(declared.name, shapes);\n }\n const validate = (type: TypeRefSyntax, location: SourceLocation, position = 'an event source identifier'): void => {\n if (personal.has(type.name) || sensitive.has(type.name)) {\n const attribute = personal.has(type.name) ? 'pii' : 'secret';\n context.error(DiagnosticCodes.PiiNotSupportedOnIdentifier, `Concept '${type.name}' is ${attribute} and cannot be ${position} - use a surrogate Uuid identifier and keep the ${attribute} value as a property`, location);\n }\n };\n const property = (properties: readonly PropertySyntax[], path: string): PropertySyntax | null => {\n const [name, ...rest] = path.split('.');\n const matches = properties.filter(entry => entry.name === name);\n if (matches.length !== 1) return null;\n const value = matches[0];\n if (rest.length === 0) return value;\n return property(types.get(value.type.name)?.properties ?? [], rest.join('.'));\n };\n for (const source of application.eventSources ?? []) {\n if (source.identifier != null) validate(source.identifier, source.identifier.location);\n for (const stream of source.streams) {\n if (stream.streamId !== null) validate(stream.streamId, stream.streamId.location, 'a stream id');\n for (const part of stream.streamIdParts) validate(part.type, part.type.location, `a stream id part '${part.name}'`);\n }\n }\n const catalog = new EventSourceCatalog(application);\n for (const { slice } of resolver.slices) {\n for (const command of slice.commands) {\n for (const entry of command.properties.filter(entry => entry.isIdentifier)) validate(entry.type, entry.location);\n for (const route of [...(command.stream ? [command.stream] : []), ...command.streamCandidates ?? [], ...command.produces.flatMap(produced => produced.stream == null ? [] : [produced.stream])].filter(route => route.propertyCandidate === null)) {\n const resolution = catalog.resolve(route.eventSource, route.stream);\n const stream = resolution.kind === EventSourceResolutionKind.Unique ? resolution.streams[0] : undefined;\n const mappings = [\n ...(route.streamId === null ? [] : [{ mapping: route.streamId, target: stream?.streamId }]),\n ...route.streamIdParts.map(mapping => ({ mapping, target: stream?.streamIdParts.find(part => part.name === mapping.property)?.type })),\n ];\n for (const { mapping, target } of mappings) {\n if (mapping.source.kind !== 'PathExpressionSyntax') continue;\n const entry = property(command.properties, mapping.source.path);\n if (entry === null) continue;\n // The same protected concept has already been reported at its resolved declaration.\n if (entry.type.name === target?.name && (personal.has(entry.type.name) || sensitive.has(entry.type.name))) continue;\n validate(entry.type, mapping.source.location, 'a stream id route mapping');\n }\n }\n for (const production of command.produces.filter(production => resolver.isEventProduction(production, slice))) {\n if (production.for?.kind !== 'PathExpressionSyntax') continue;\n const entry = property(command.properties, production.for.path);\n if (entry !== null && !entry.isIdentifier) validate(entry.type, production.for.location);\n }\n }\n for (const trigger of slice.reactions.flatMap(reaction => reaction.triggers)) {\n if (trigger.source.kind !== 'NamedTriggerSourceSyntax') continue;\n const resolution = resolver.resolve(trigger.source.name, slice);\n const event = resolution.declaration?.node;\n const clauseData = (dependencySourcesOf(trigger).data ?? []).flatMap<PropertySyntax>(datum => datum.type === null ? [] : [{ kind: 'PropertySyntax', name: datum.name, type: datum.type, isIdentifier: false, location: datum.location }]);\n const shapes = [event?.kind === 'EventSyntax' ? event.properties : [], clauseData];\n if (event?.kind !== 'EventSyntax' && !imports.has(trigger.source.name)) {\n shapes.push(...declaredTriggers.get(trigger.source.name) ?? []);\n }\n for (const production of trigger.produces.filter(production => resolver.isEventProduction(production, slice))) {\n if (production.for?.kind !== 'PathExpressionSyntax') continue;\n // Check clause-local types alongside the occurrence selected by event-first reaction resolution.\n const path = production.for.path;\n const entry = shapes.map(properties => property(properties, path)).find(entry => entry !== null && (personal.has(entry.type.name) || sensitive.has(entry.type.name)));\n if (entry != null) validate(entry.type, production.for.location);\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{locationOf as t}from"./SourceLine.js";import{sourceStreamPattern as n}from"../Text/SourceStreamNames.js";const r=n(`^from\\s+([A-Za-z_]\\w*)(?:\\.([A-Za-z_]\\w*))?$`);function parseObserverFilter(n,i,a){let o=r.exec(i.content);o===null||a!==null?n.error(e.InvalidObserverFilter,`Declare at most one 'from <Source>[.<Stream>]' observer filter.`,t(i)):a={kind:`ObserverFilterSyntax`,eventSource:o[1],stream:o[2]??null,location:t(i)};let s=n.peekChild(i.indent);return s!==void 0&&(n.error(e.InvalidObserverFilter,`An observer filter cannot have children or filter stream ids.`,t(s)),n.skipBlock(i.indent)),a}export{parseObserverFilter};
2
+ //# sourceMappingURL=ObserverFilterParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObserverFilterParser.js","names":["header","sourceStreamPattern","match","line","previous","context","DiagnosticCodes","locationOf","child"],"sources":["../../../../../../Compiler/Parsing/ObserverFilterParser.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 { ObserverFilterSyntax } from '../Syntax/ObserverFilterSyntax';\nimport { sourceStreamPattern } from '../Text/SourceStreamNames';\nimport { ParserContext } from './ParserContext';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst header = sourceStreamPattern('^from\\\\s+([A-Za-z_]\\\\w*)(?:\\\\.([A-Za-z_]\\\\w*))?$');\n\nexport function parseObserverFilter(context: ParserContext, line: SourceLine, previous: ObserverFilterSyntax | null): ObserverFilterSyntax | null {\n const match = header.exec(line.content);\n if (match === null || previous !== null) {\n context.error(DiagnosticCodes.InvalidObserverFilter, \"Declare at most one 'from <Source>[.<Stream>]' observer filter.\", locationOf(line));\n } else {\n previous = { kind: 'ObserverFilterSyntax', eventSource: match[1], stream: match[2] ?? null, location: locationOf(line) };\n }\n const child = context.peekChild(line.indent);\n if (child !== undefined) {\n context.error(DiagnosticCodes.InvalidObserverFilter, 'An observer filter cannot have children or filter stream ids.', locationOf(child));\n context.skipBlock(line.indent);\n }\n return previous;\n}\n"],"mappings":"yOASA,MAAMA,EAASC,EAAoB,kDAAkD,EAErF,SAAgB,oBAAoB,EAAwB,EAAkB,EAAoE,CAC9I,IAAMC,EAAQF,EAAO,KAAKG,EAAK,OAAO,EAClCD,IAAU,MAAQE,IAAa,KAC/BC,EAAQ,MAAMC,EAAgB,sBAAuB,kEAAmEC,EAAWJ,CAAI,CAAC,EAExI,EAAW,CAAE,KAAM,uBAAwB,YAAaD,EAAM,GAAI,OAAQA,EAAM,IAAM,KAAM,SAAUK,EAAWJ,CAAI,CAAE,EAE3H,IAAMK,EAAQH,EAAQ,UAAUF,EAAK,MAAM,EAK3C,OAJIK,IAAU,IAAA,KACVH,EAAQ,MAAMC,EAAgB,sBAAuB,gEAAiEC,EAAWC,CAAK,CAAC,EACvIH,EAAQ,UAAUF,EAAK,MAAM,GAE1BC,CACX"}
@@ -0,0 +1,2 @@
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{dependencySourcesOf as t}from"../Syntax/DependencySources.js";import{EventSourceCatalog as n}from"../Syntax/EventSourceCatalog.js";function validateObserverFilters(r,i,a){let o=new n(r),resolve=t=>o.resolve(t.eventSource,t.stream??void 0).kind===`unique`||(i.error(e.InvalidObserverFilter,`An observer filter must name one physical event source and, when supplied, one stream belonging to it.`,t.location),!1);for(let{slice:n}of a.slices){for(let t of n.reactions)if(t.from!=null&&resolve(t.from))for(let r of t.triggers)(r.source.kind!==`NamedTriggerSourceSyntax`||a.resolve(r.source.name,n).declaration?.node.kind!==`EventSyntax`)&&i.error(e.InvalidObserverFilter,`A filtered reaction requires only 'when <Event>' triggers on declared events.`,r.location);for(let e of t(n).reducers??[])e.from!=null&&resolve(e.from)}}export{validateObserverFilters};
2
+ //# sourceMappingURL=ObserverFilterValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObserverFilterValidator.js","names":["catalog","EventSourceCatalog","application","filter","context","DiagnosticCodes","resolver","reaction","slice","trigger","reducer","dependencySourcesOf"],"sources":["../../../../../../Compiler/Parsing/ObserverFilterValidator.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 { AuthoringProductionResolver } from '../Syntax/AuthoringProductionResolver';\nimport { dependencySourcesOf } from '../Syntax/DependencySources';\nimport { EventSourceCatalog, EventSourceResolutionKind } from '../Syntax/EventSourceCatalog';\nimport { ObserverFilterSyntax } from '../Syntax/ObserverFilterSyntax';\nimport { ApplicationSyntax } from '../Syntax/Structure';\nimport { ParserContext } from './ParserContext';\n\nexport function validateObserverFilters(application: ApplicationSyntax, context: ParserContext, resolver: AuthoringProductionResolver): void {\n const catalog = new EventSourceCatalog(application);\n const resolve = (filter: ObserverFilterSyntax): boolean => {\n const resolution = catalog.resolve(filter.eventSource, filter.stream ?? undefined);\n if (resolution.kind === EventSourceResolutionKind.Unique) return true;\n context.error(DiagnosticCodes.InvalidObserverFilter, 'An observer filter must name one physical event source and, when supplied, one stream belonging to it.', filter.location);\n return false;\n };\n for (const { slice } of resolver.slices) {\n for (const reaction of slice.reactions) {\n if (reaction.from == null || !resolve(reaction.from)) continue;\n for (const trigger of reaction.triggers) {\n if (trigger.source.kind !== 'NamedTriggerSourceSyntax' || resolver.resolve(trigger.source.name, slice).declaration?.node.kind !== 'EventSyntax')\n context.error(DiagnosticCodes.InvalidObserverFilter, \"A filtered reaction requires only 'when <Event>' triggers on declared events.\", trigger.location);\n }\n }\n for (const reducer of dependencySourcesOf(slice).reducers ?? []) {\n if (reducer.from != null) resolve(reducer.from);\n }\n }\n}\n"],"mappings":"mQAWA,SAAgB,wBAAwB,EAAgC,EAAwB,EAA6C,CACzI,IAAMA,EAAU,IAAIC,EAAmBC,CAAW,EAC5C,QAAW,GACMF,EAAQ,QAAQG,EAAO,YAAaA,EAAO,QAAU,IAAA,EAC3D,CAAC,CAAC,OAAA,WACfC,EAAQ,MAAMC,EAAgB,sBAAuB,yGAA0GF,EAAO,QAAQ,EACvK,IAEX,IAAK,GAAM,CAAE,WAAWG,EAAS,OAAQ,CACrC,IAAK,IAAMC,KAAYC,EAAM,UACzB,GAAID,EAAS,MAAQ,MAAS,QAAQA,EAAS,IAAI,EACnD,IAAK,IAAME,KAAWF,EAAS,UACvBE,EAAQ,OAAO,OAAS,4BAA8BH,EAAS,QAAQG,EAAQ,OAAO,KAAMD,CAAK,CAAC,CAAC,aAAa,KAAK,OAAS,gBAC9HJ,EAAQ,MAAMC,EAAgB,sBAAuB,gFAAiFI,EAAQ,QAAQ,EAGlK,IAAK,IAAMC,KAAWC,EAAoBH,CAAK,CAAC,CAAC,UAAY,CAAC,EACtDE,EAAQ,MAAQ,MAAM,QAAQA,EAAQ,IAAI,CAEtD,CACJ"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{parseMappingSource as r}from"./ExpressionParser.js";import{firstWord as i,unescapeIdentifier as a}from"./LineText.js";import{parseProperty as o}from"./PropertyLineParser.js";import{parseCondition as s}from"./ConditionParser.js";import{parseOperation as c}from"./OperationParser.js";import{EventMetadataParser as l}from"./EventMetadataParser.js";import{parseTag as u}from"./DeclarationParsers.js";const d=t(`^produces\\s+operation(?:\\s|$)`),f=t(`^produces\\s+event\\s+([A-Za-z_]\\w*)(?:\\s+(generation)(?:\\s+.*)?)?$`),p=t(`^produces\\s+([A-Z]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),m=t(`^produces\\s+when\\s+(.+)$`),h=t(`^[A-Z]\\w*(?:\\.[A-Za-z_]\\w*)*$`),g=t(`^for\\s+(\\S.*)$`),_=t(`^(@?[\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),v=t(`^(.+?)\\s*=(?!=|>)\\s*(.+)$`),y=/* @__PURE__ */ new Set([`namespace`,`sequence`,`correlation`,`causation`,`causedBy`,`occurred`]);function parseProduces(t,b,x=!1){if(d.test(b.content)){if(!x){t.error(e.OperationOutsideCommand,`Operations can only be produced by commands.`,n(b)),t.skipOpaqueBlock(b.indent);return}let r=c(t,b,!0);return{kind:`ProducesSyntax`,when:null,event:r.operation.name,targetLocation:{...n(b),column:b.indent+b.content.match(/^produces\s+operation(?:\s+|$)/)[0].length+1},inlineEvent:null,inlineOperation:r.operation,mappings:r.mappings,for:null,tags:[],location:n(b)}}let S=f.exec(b.content),C=b,w=null,T,E;if(S!==null){if(!x){t.error(e.InlineEventOutsideCommand,`Inline events can only be declared inside commands`,n(b)),t.skipOpaqueBlock(b.indent);return}S[2]!==void 0&&t.error(e.InlineEventGeneration,`Inline events are generation 1 - extract the event before declaring generations`,n(b)),T=S[1],E=b.indent+b.content.match(/^produces\s+event\s+/)[0].length+1}else if(m.test(b.content)){w=s(t,m.exec(b.content)[1],n(b));let r=t.peekChild(b.indent);if(r===void 0||!h.test(r.content)){t.error(e.ProducesWhenWithoutEvent,`Expected an event name on the line after 'produces when'`,n(b)),t.skipOpaqueBlock(b.indent);return}t.reader.takeSignificant(),C=r,T=r.content,E=r.indent+1}else{let r=p.exec(b.content);if(r===null){t.error(e.InvalidProducesDeclaration,`Invalid produces declaration '${b.content}' - expected 'produces <EventType>' or 'produces when <condition>'`,n(b)),t.skipOpaqueBlock(b.indent);return}T=r[1],E=b.indent+b.content.match(/^produces\s+/)[0].length+1}let D=[],O=/* @__PURE__ */ new Set,k=[],A=[],j=new l(T),M=null;for(let s=t.peekChild(C.indent);s!==void 0;s=t.peekChild(C.indent)){t.reader.takeSignificant();let c=i(s.content),l=n(s);if(y.has(c)){t.error(e.ReservedProductionMetadata,`'${c}' is system-assigned production metadata and cannot be supplied here`,l),t.skipOpaqueBlock(s.indent);continue}if(S!==null&&(c===`generation`||c===`origin`)){t.error(c===`generation`?e.InlineEventGeneration:e.ReservedProductionMetadata,c===`generation`?`Inline events are generation 1 - extract the event before declaring generations`:`An inline event is local to its command and cannot declare origin`,l),t.skipOpaqueBlock(s.indent);continue}if(c===`tag`){let e=u(t,s,!1);e!==void 0&&A.push(e);continue}let d=g.exec(s.content);if(d!==null){M===null?M=r(d[1],l,t):t.error(e.DuplicateProducesTarget,`'${C.content}' already declares where it lands - an event is appended to one event source`,l);continue}let f=(S===null?_:v).exec(s.content),p=f===null||S===null?void 0:o(t,{...s,content:f[1].trimEnd()});if(f!==null&&(S===null||p!==void 0)){if(p!==void 0){p.isIdentifier&&(t.error(e.IdentifierOnEventProperty,`Property '${p.name}' of event '${T}' cannot be marked identifier - an event never carries its event source id`,l),p={...p,isIdentifier:!1});let n=p.name;O.has(n)&&t.error(e.DuplicateDeclaration,`Event '${T}' already declares property '${p.name}'`,l),O.add(n),D.push(p)}k.push({kind:`PropertyMappingSyntax`,property:p?.name??a(f[1]),source:r(f[2],{...l,column:s.indent+s.content.length-f[2].length+1},t),location:l})}else(S===null||!j.tryParse(t,s))&&t.error(e.InvalidPropertyMapping,`Invalid ${S===null?``:`inline `}property mapping '${s.content}' - expected '<property>${S===null?``:` <Type>`} = <source>'`,l)}return C!==b&&t.skipBlock(b.indent),{kind:`ProducesSyntax`,when:w,event:T,targetLocation:{...n(C),column:E},inlineOperation:null,mappings:k,for:M,tags:S===null?A:[],location:n(b),inlineEvent:S===null?null:{kind:`EventSyntax`,name:T,properties:D,tags:A,generation:1,hasGenerationMarker:!1,...j.value,location:n(b)}}}export{parseProduces};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{parseMappingSource as r}from"./ExpressionParser.js";import{firstWord as i,unescapeIdentifier as a}from"./LineText.js";import{parseProperty as o}from"./PropertyLineParser.js";import{parseCondition as s}from"./ConditionParser.js";import{sourceStreamPattern as c}from"../Text/SourceStreamNames.js";import{parseCommandStream as l}from"./EventSourceParser.js";import{parseOperation as u}from"./OperationParser.js";import{EventMetadataParser as d}from"./EventMetadataParser.js";import{parseTag as f}from"./DeclarationParsers.js";const p=t(`^produces\\s+operation(?:\\s|$)`),m=t(`^produces\\s+event\\s+([A-Za-z_]\\w*)(?:\\s+(generation)(?:\\s+.*)?)?$`),h=t(`^produces\\s+([A-Z]\\w*(?:\\.[A-Za-z_]\\w*)*)$`),g=t(`^produces\\s+when\\s+(.+)$`),_=t(`^[A-Z]\\w*(?:\\.[A-Za-z_]\\w*)*$`),v=t(`^for\\s+(\\S.*)$`),y=t(`^(@?[\\w.]+)\\s*=(?!=|>)\\s*(.+)$`),b=t(`^(.+?)\\s*=(?!=|>)\\s*(.+)$`),x=/* @__PURE__ */ new Set([`namespace`,`sequence`,`correlation`,`causation`,`causedBy`,`occurred`]);function parseProduces(t,S,C=!1){if(p.test(S.content)){if(!C){t.error(e.OperationOutsideCommand,`Operations can only be produced by commands.`,n(S)),t.skipOpaqueBlock(S.indent);return}let r=u(t,S,!0);return{kind:`ProducesSyntax`,when:null,event:r.operation.name,targetLocation:{...n(S),column:S.indent+S.content.match(/^produces\s+operation(?:\s+|$)/)[0].length+1},inlineEvent:null,inlineOperation:r.operation,mappings:r.mappings,for:null,tags:[],location:n(S)}}let w=m.exec(S.content),T=S,E=null,D,O;if(w!==null){if(!C){t.error(e.InlineEventOutsideCommand,`Inline events can only be declared inside commands`,n(S)),t.skipOpaqueBlock(S.indent);return}w[2]!==void 0&&t.error(e.InlineEventGeneration,`Inline events are generation 1 - extract the event before declaring generations`,n(S)),D=w[1],O=S.indent+S.content.match(/^produces\s+event\s+/)[0].length+1}else if(g.test(S.content)){E=s(t,g.exec(S.content)[1],n(S));let r=t.peekChild(S.indent);if(r===void 0||!_.test(r.content)){t.error(e.ProducesWhenWithoutEvent,`Expected an event name on the line after 'produces when'`,n(S)),t.skipOpaqueBlock(S.indent);return}t.reader.takeSignificant(),T=r,D=r.content,O=r.indent+1}else{let r=h.exec(S.content);if(r===null){t.error(e.InvalidProducesDeclaration,`Invalid produces declaration '${S.content}' - expected 'produces <EventType>' or 'produces when <condition>'`,n(S)),t.skipOpaqueBlock(S.indent);return}D=r[1],O=S.indent+S.content.match(/^produces\s+/)[0].length+1}let k=[],A=/* @__PURE__ */ new Set,j=[],M=[],N=new d(D),P=null,F=null;for(let s=t.peekChild(T.indent);s!==void 0;s=t.peekChild(T.indent)){t.reader.takeSignificant();let u=i(s.content),d=n(s);if(x.has(u)){t.error(e.ReservedProductionMetadata,`'${u}' is system-assigned production metadata and cannot be supplied here`,d),t.skipOpaqueBlock(s.indent);continue}if(w!==null&&(u===`generation`||u===`origin`)){t.error(u===`generation`?e.InlineEventGeneration:e.ReservedProductionMetadata,u===`generation`?`Inline events are generation 1 - extract the event before declaring generations`:`An inline event is local to its command and cannot declare origin`,d),t.skipOpaqueBlock(s.indent);continue}if(u===`stream`&&!s.content.includes(`=`)){let n=c(`^stream\\s+([A-Za-z_]\\w*\\.[A-Za-z_]\\w*)$`).exec(s.content);if(!C)t.error(e.ProductionRouteOutsideCommand,`Only command event productions can declare a stream route.`,d),t.skipBlock(s.indent);else if(F!==null)t.error(e.InvalidCommandStream,`A production can declare at most one stream route.`,d),t.skipBlock(s.indent);else if(n===null)t.error(e.InvalidCommandStream,`Expected 'stream <Source>.<Stream>'.`,d),t.skipBlock(s.indent);else{let e={...d,column:s.indent+s.content.indexOf(n[1])+1},r={kind:`PropertySyntax`,name:`stream`,type:{kind:`TypeRefSyntax`,name:n[1],isCollection:!1,isOptional:!1,location:e},isIdentifier:!1,location:d};F=l(t,s,r,!1)}continue}if(u===`tag`){let e=f(t,s,!1);e!==void 0&&M.push(e);continue}let p=v.exec(s.content);if(p!==null){P===null?P=r(p[1],d,t):t.error(e.DuplicateProducesTarget,`'${T.content}' already declares where it lands - an event is appended to one event source`,d);continue}let m=(w===null?y:b).exec(s.content),h=m===null||w===null?void 0:o(t,{...s,content:m[1].trimEnd()});if(m!==null&&(w===null||h!==void 0)){if(h!==void 0){h.isIdentifier&&(t.error(e.IdentifierOnEventProperty,`Property '${h.name}' of event '${D}' cannot be marked identifier - an event never carries its event source id`,d),h={...h,isIdentifier:!1});let n=h.name;A.has(n)&&t.error(e.DuplicateDeclaration,`Event '${D}' already declares property '${h.name}'`,d),A.add(n),k.push(h)}j.push({kind:`PropertyMappingSyntax`,property:h?.name??a(m[1]),source:r(m[2],{...d,column:s.indent+s.content.length-m[2].length+1},t),location:d})}else(w===null||!N.tryParse(t,s))&&t.error(e.InvalidPropertyMapping,`Invalid ${w===null?``:`inline `}property mapping '${s.content}' - expected '<property>${w===null?``:` <Type>`} = <source>'`,d)}return T!==S&&t.skipBlock(S.indent),{kind:`ProducesSyntax`,when:E,event:D,stream:F,targetLocation:{...n(T),column:O},inlineOperation:null,mappings:j,for:P,tags:w===null?M:[],location:n(S),inlineEvent:w===null?null:{kind:`EventSyntax`,name:D,properties:k,tags:M,generation:1,hasGenerationMarker:!1,...N.value,location:n(S)}}}export{parseProduces};
2
2
  //# sourceMappingURL=ProducesParser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProducesParser.js","names":["inlineOperationPrefix","pattern","inlineHeader","plainHeader","conditional","eventName","targetPattern","mappingPattern","typedMappingPattern","reserved","header","inCommand","context","DiagnosticCodes","locationOf","parsed","parseOperation","inline","parent","when","name","targetColumn","parseCondition","child","plain","properties","propertyNames","mappings","tags","metadata","EventMetadataParser","target","line","keyword","firstWord","location","tag","parseTag","forMatch","parseMappingSource","match","property","parseProperty","propertyName","unescapeIdentifier"],"sources":["../../../../../../Compiler/Parsing/ProducesParser.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 { ConditionSyntax } from '../Syntax/Conditions';\nimport { parseCondition } from './ConditionParser';\nimport { PropertySyntax, TagSyntax } from '../Syntax/Declarations';\nimport { ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { ProducesSyntax } from '../Syntax/Reactions';\nimport { pattern } from '../Text/patterns';\nimport { parseTag } from './DeclarationParsers';\nimport { EventMetadataParser } from './EventMetadataParser';\nimport { parseMappingSource } from './ExpressionParser';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseOperation } from './OperationParser';\nimport { parseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst inlineOperationPrefix = pattern('^produces\\\\s+operation(?:\\\\s|$)');\nconst inlineHeader = pattern('^produces\\\\s+event\\\\s+([A-Za-z_]\\\\w*)(?:\\\\s+(generation)(?:\\\\s+.*)?)?$');\nconst plainHeader = pattern('^produces\\\\s+([A-Z]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst conditional = pattern('^produces\\\\s+when\\\\s+(.+)$');\nconst eventName = pattern('^[A-Z]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*$');\nconst targetPattern = pattern('^for\\\\s+(\\\\S.*)$');\nconst mappingPattern = pattern('^(@?[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst typedMappingPattern = pattern('^(.+?)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst reserved = new Set(['namespace', 'sequence', 'correlation', 'causation', 'causedBy', 'occurred']);\n\nexport function parseProduces(context: ParserContext, header: SourceLine, inCommand = false): ProducesSyntax | undefined {\n if (inlineOperationPrefix.test(header.content)) {\n if (!inCommand) {\n context.error(DiagnosticCodes.OperationOutsideCommand, 'Operations can only be produced by commands.', locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n const parsed = parseOperation(context, header, true);\n return { kind: 'ProducesSyntax', when: null, event: parsed.operation.name, targetLocation: { ...locationOf(header), column: header.indent + header.content.match(/^produces\\s+operation(?:\\s+|$)/)![0].length + 1 }, inlineEvent: null, inlineOperation: parsed.operation, mappings: parsed.mappings, for: null, tags: [], location: locationOf(header) };\n }\n const inline = inlineHeader.exec(header.content);\n let parent = header;\n let when: ConditionSyntax | null = null;\n let name: string;\n let targetColumn: number;\n if (inline !== null) {\n if (!inCommand) {\n context.error(DiagnosticCodes.InlineEventOutsideCommand, 'Inline events can only be declared inside commands', locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n if (inline[2] !== undefined) {\n context.error(DiagnosticCodes.InlineEventGeneration, 'Inline events are generation 1 - extract the event before declaring generations', locationOf(header));\n }\n name = inline[1];\n targetColumn = header.indent + header.content.match(/^produces\\s+event\\s+/)![0].length + 1;\n } else if (conditional.test(header.content)) {\n when = parseCondition(context, conditional.exec(header.content)![1], locationOf(header));\n const child = context.peekChild(header.indent);\n if (child === undefined || !eventName.test(child.content)) {\n context.error(DiagnosticCodes.ProducesWhenWithoutEvent, \"Expected an event name on the line after 'produces when'\", locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n context.reader.takeSignificant();\n parent = child;\n name = child.content;\n targetColumn = child.indent + 1;\n } else {\n const plain = plainHeader.exec(header.content);\n if (plain === null) {\n context.error(DiagnosticCodes.InvalidProducesDeclaration, `Invalid produces declaration '${header.content}' - expected 'produces <EventType>' or 'produces when <condition>'`, locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n name = plain[1];\n targetColumn = header.indent + header.content.match(/^produces\\s+/)![0].length + 1;\n }\n const properties: PropertySyntax[] = [];\n const propertyNames = new Set<string>();\n const mappings: PropertyMappingSyntax[] = [];\n const tags: TagSyntax[] = [];\n const metadata = new EventMetadataParser(name);\n let target: ExpressionSyntax | null = null;\n for (let line = context.peekChild(parent.indent); line !== undefined; line = context.peekChild(parent.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n const location = locationOf(line);\n if (reserved.has(keyword)) {\n context.error(DiagnosticCodes.ReservedProductionMetadata, `'${keyword}' is system-assigned production metadata and cannot be supplied here`, location);\n context.skipOpaqueBlock(line.indent);\n continue;\n }\n if (inline !== null && (keyword === 'generation' || keyword === 'origin')) {\n context.error(keyword === 'generation' ? DiagnosticCodes.InlineEventGeneration : DiagnosticCodes.ReservedProductionMetadata,\n keyword === 'generation' ? 'Inline events are generation 1 - extract the event before declaring generations' : 'An inline event is local to its command and cannot declare origin', location);\n context.skipOpaqueBlock(line.indent);\n continue;\n }\n if (keyword === 'tag') {\n const tag = parseTag(context, line, false);\n if (tag !== undefined) tags.push(tag);\n continue;\n }\n const forMatch = targetPattern.exec(line.content);\n if (forMatch !== null) {\n if (target !== null) {\n context.error(DiagnosticCodes.DuplicateProducesTarget, `'${parent.content}' already declares where it lands - an event is appended to one event source`, location);\n } else {\n target = parseMappingSource(forMatch[1], location, context);\n }\n continue;\n }\n const match = (inline === null ? mappingPattern : typedMappingPattern).exec(line.content);\n let property = match === null || inline === null ? undefined : parseProperty(context, { ...line, content: match[1].trimEnd() });\n if (match !== null && (inline === null || property !== undefined)) {\n if (property !== undefined) {\n if (property.isIdentifier) {\n context.error(DiagnosticCodes.IdentifierOnEventProperty, `Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`, location);\n property = { ...property, isIdentifier: false };\n }\n const propertyName = property.name;\n if (propertyNames.has(propertyName)) {\n context.error(DiagnosticCodes.DuplicateDeclaration, `Event '${name}' already declares property '${property.name}'`, location);\n }\n propertyNames.add(propertyName);\n properties.push(property);\n }\n mappings.push({ kind: 'PropertyMappingSyntax', property: property?.name ?? unescapeIdentifier(match[1]), source: parseMappingSource(match[2], { ...location, column: line.indent + line.content.length - match[2].length + 1 }, context), location });\n } else if (inline === null || !metadata.tryParse(context, line)) {\n context.error(DiagnosticCodes.InvalidPropertyMapping, `Invalid ${inline === null ? '' : 'inline '}property mapping '${line.content}' - expected '<property>${inline === null ? '' : ' <Type>'} = <source>'`, location);\n }\n }\n if (parent !== header) context.skipBlock(header.indent);\n return {\n kind: 'ProducesSyntax', when, event: name, targetLocation: { ...locationOf(parent), column: targetColumn }, inlineOperation: null, mappings, for: target, tags: inline === null ? tags : [], location: locationOf(header),\n inlineEvent: inline === null ? null : { kind: 'EventSyntax', name, properties, tags, generation: 1, hasGenerationMarker: false, ...metadata.value, location: locationOf(header) },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProducesParser.js","names":["inlineOperationPrefix","pattern","inlineHeader","plainHeader","conditional","eventName","targetPattern","mappingPattern","typedMappingPattern","reserved","header","inCommand","context","DiagnosticCodes","locationOf","parsed","parseOperation","inline","parent","when","name","targetColumn","parseCondition","child","plain","properties","propertyNames","mappings","tags","metadata","EventMetadataParser","target","stream","line","keyword","firstWord","location","route","sourceStreamPattern","typeLocation","candidate","parseCommandStream","tag","parseTag","forMatch","parseMappingSource","match","property","parseProperty","propertyName","unescapeIdentifier"],"sources":["../../../../../../Compiler/Parsing/ProducesParser.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 { CommandStreamSyntax } from '../Syntax/CommandStreamSyntax';\nimport { sourceStreamPattern } from '../Text/SourceStreamNames';\nimport { parseCommandStream } from './EventSourceParser';\nimport { ConditionSyntax } from '../Syntax/Conditions';\nimport { parseCondition } from './ConditionParser';\nimport { PropertySyntax, TagSyntax } from '../Syntax/Declarations';\nimport { ExpressionSyntax, PropertyMappingSyntax } from '../Syntax/Expressions';\nimport { ProducesSyntax } from '../Syntax/Reactions';\nimport { pattern } from '../Text/patterns';\nimport { parseTag } from './DeclarationParsers';\nimport { EventMetadataParser } from './EventMetadataParser';\nimport { parseMappingSource } from './ExpressionParser';\nimport { firstWord, unescapeIdentifier } from './LineText';\nimport { ParserContext } from './ParserContext';\nimport { parseOperation } from './OperationParser';\nimport { parseProperty } from './PropertyLineParser';\nimport { locationOf, SourceLine } from './SourceLine';\n\nconst inlineOperationPrefix = pattern('^produces\\\\s+operation(?:\\\\s|$)');\nconst inlineHeader = pattern('^produces\\\\s+event\\\\s+([A-Za-z_]\\\\w*)(?:\\\\s+(generation)(?:\\\\s+.*)?)?$');\nconst plainHeader = pattern('^produces\\\\s+([A-Z]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*)$');\nconst conditional = pattern('^produces\\\\s+when\\\\s+(.+)$');\nconst eventName = pattern('^[A-Z]\\\\w*(?:\\\\.[A-Za-z_]\\\\w*)*$');\nconst targetPattern = pattern('^for\\\\s+(\\\\S.*)$');\nconst mappingPattern = pattern('^(@?[\\\\w.]+)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst typedMappingPattern = pattern('^(.+?)\\\\s*=(?!=|>)\\\\s*(.+)$');\nconst reserved = new Set(['namespace', 'sequence', 'correlation', 'causation', 'causedBy', 'occurred']);\n\nexport function parseProduces(context: ParserContext, header: SourceLine, inCommand = false): ProducesSyntax | undefined {\n if (inlineOperationPrefix.test(header.content)) {\n if (!inCommand) {\n context.error(DiagnosticCodes.OperationOutsideCommand, 'Operations can only be produced by commands.', locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n const parsed = parseOperation(context, header, true);\n return { kind: 'ProducesSyntax', when: null, event: parsed.operation.name, targetLocation: { ...locationOf(header), column: header.indent + header.content.match(/^produces\\s+operation(?:\\s+|$)/)![0].length + 1 }, inlineEvent: null, inlineOperation: parsed.operation, mappings: parsed.mappings, for: null, tags: [], location: locationOf(header) };\n }\n const inline = inlineHeader.exec(header.content);\n let parent = header;\n let when: ConditionSyntax | null = null;\n let name: string;\n let targetColumn: number;\n if (inline !== null) {\n if (!inCommand) {\n context.error(DiagnosticCodes.InlineEventOutsideCommand, 'Inline events can only be declared inside commands', locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n if (inline[2] !== undefined) {\n context.error(DiagnosticCodes.InlineEventGeneration, 'Inline events are generation 1 - extract the event before declaring generations', locationOf(header));\n }\n name = inline[1];\n targetColumn = header.indent + header.content.match(/^produces\\s+event\\s+/)![0].length + 1;\n } else if (conditional.test(header.content)) {\n when = parseCondition(context, conditional.exec(header.content)![1], locationOf(header));\n const child = context.peekChild(header.indent);\n if (child === undefined || !eventName.test(child.content)) {\n context.error(DiagnosticCodes.ProducesWhenWithoutEvent, \"Expected an event name on the line after 'produces when'\", locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n context.reader.takeSignificant();\n parent = child;\n name = child.content;\n targetColumn = child.indent + 1;\n } else {\n const plain = plainHeader.exec(header.content);\n if (plain === null) {\n context.error(DiagnosticCodes.InvalidProducesDeclaration, `Invalid produces declaration '${header.content}' - expected 'produces <EventType>' or 'produces when <condition>'`, locationOf(header));\n context.skipOpaqueBlock(header.indent);\n return undefined;\n }\n name = plain[1];\n targetColumn = header.indent + header.content.match(/^produces\\s+/)![0].length + 1;\n }\n const properties: PropertySyntax[] = [];\n const propertyNames = new Set<string>();\n const mappings: PropertyMappingSyntax[] = [];\n const tags: TagSyntax[] = [];\n const metadata = new EventMetadataParser(name);\n let target: ExpressionSyntax | null = null;\n let stream: CommandStreamSyntax | null = null;\n for (let line = context.peekChild(parent.indent); line !== undefined; line = context.peekChild(parent.indent)) {\n context.reader.takeSignificant();\n const keyword = firstWord(line.content);\n const location = locationOf(line);\n if (reserved.has(keyword)) {\n context.error(DiagnosticCodes.ReservedProductionMetadata, `'${keyword}' is system-assigned production metadata and cannot be supplied here`, location);\n context.skipOpaqueBlock(line.indent);\n continue;\n }\n if (inline !== null && (keyword === 'generation' || keyword === 'origin')) {\n context.error(keyword === 'generation' ? DiagnosticCodes.InlineEventGeneration : DiagnosticCodes.ReservedProductionMetadata,\n keyword === 'generation' ? 'Inline events are generation 1 - extract the event before declaring generations' : 'An inline event is local to its command and cannot declare origin', location);\n context.skipOpaqueBlock(line.indent);\n continue;\n }\n if (keyword === 'stream' && !line.content.includes('=')) {\n const route = sourceStreamPattern('^stream\\\\s+([A-Za-z_]\\\\w*\\\\.[A-Za-z_]\\\\w*)$').exec(line.content);\n if (!inCommand) {\n context.error(DiagnosticCodes.ProductionRouteOutsideCommand, 'Only command event productions can declare a stream route.', location);\n context.skipBlock(line.indent);\n } else if (stream !== null) {\n context.error(DiagnosticCodes.InvalidCommandStream, 'A production can declare at most one stream route.', location);\n context.skipBlock(line.indent);\n } else if (route === null) {\n context.error(DiagnosticCodes.InvalidCommandStream, \"Expected 'stream <Source>.<Stream>'.\", location);\n context.skipBlock(line.indent);\n } else {\n const typeLocation = { ...location, column: line.indent + line.content.indexOf(route[1]) + 1 };\n const candidate: PropertySyntax = { kind: 'PropertySyntax', name: 'stream', type: { kind: 'TypeRefSyntax', name: route[1], isCollection: false, isOptional: false, location: typeLocation }, isIdentifier: false, location };\n stream = parseCommandStream(context, line, candidate, false);\n }\n continue;\n }\n if (keyword === 'tag') {\n const tag = parseTag(context, line, false);\n if (tag !== undefined) tags.push(tag);\n continue;\n }\n const forMatch = targetPattern.exec(line.content);\n if (forMatch !== null) {\n if (target !== null) {\n context.error(DiagnosticCodes.DuplicateProducesTarget, `'${parent.content}' already declares where it lands - an event is appended to one event source`, location);\n } else {\n target = parseMappingSource(forMatch[1], location, context);\n }\n continue;\n }\n const match = (inline === null ? mappingPattern : typedMappingPattern).exec(line.content);\n let property = match === null || inline === null ? undefined : parseProperty(context, { ...line, content: match[1].trimEnd() });\n if (match !== null && (inline === null || property !== undefined)) {\n if (property !== undefined) {\n if (property.isIdentifier) {\n context.error(DiagnosticCodes.IdentifierOnEventProperty, `Property '${property.name}' of event '${name}' cannot be marked identifier - an event never carries its event source id`, location);\n property = { ...property, isIdentifier: false };\n }\n const propertyName = property.name;\n if (propertyNames.has(propertyName)) {\n context.error(DiagnosticCodes.DuplicateDeclaration, `Event '${name}' already declares property '${property.name}'`, location);\n }\n propertyNames.add(propertyName);\n properties.push(property);\n }\n mappings.push({ kind: 'PropertyMappingSyntax', property: property?.name ?? unescapeIdentifier(match[1]), source: parseMappingSource(match[2], { ...location, column: line.indent + line.content.length - match[2].length + 1 }, context), location });\n } else if (inline === null || !metadata.tryParse(context, line)) {\n context.error(DiagnosticCodes.InvalidPropertyMapping, `Invalid ${inline === null ? '' : 'inline '}property mapping '${line.content}' - expected '<property>${inline === null ? '' : ' <Type>'} = <source>'`, location);\n }\n }\n if (parent !== header) context.skipBlock(header.indent);\n return {\n kind: 'ProducesSyntax', when, event: name, stream, targetLocation: { ...locationOf(parent), column: targetColumn }, inlineOperation: null, mappings, for: target, tags: inline === null ? tags : [], location: locationOf(header),\n inlineEvent: inline === null ? null : { kind: 'EventSyntax', name, properties, tags, generation: 1, hasGenerationMarker: false, ...metadata.value, location: locationOf(header) },\n };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{unescapeIdentifier as r}from"./LineText.js";const i=t(`^(@?[a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+(generated))?(?:\\s+(identifier))?(?:\\s+(subject))?$`),a=t(`^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\??\\s+((?:optional|generated|identifier|subject)(?:\\s+(?:optional|generated|identifier|subject))*)$`),o=t(`^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\s+identifier\\s+optional(?:\\s*=.*)?$`);function tryParseProperty(e){let t=i.exec(e.content);if(t===null)return;let a=n(e);return{kind:`PropertySyntax`,name:r(t[1]),type:parseTypeRef(t[2],{...a,column:a.column+e.content.indexOf(t[2],t[1].length)}),isGenerated:t[3]!==void 0,nameWasEscaped:t[1].startsWith(`@`),isIdentifier:t[4]!==void 0,...t[5]===void 0?{}:{isSubject:!0},location:a}}function parseTypeRef(e,t){let n=e.endsWith(`?`),r=/\soptional$/.test(e),i=n||r;i&&(e=e.substring(0,e.length-(n?1:8)).trimEnd());let a=e.endsWith(`[]`);return a&&(e=e.substring(0,e.length-2)),{kind:`TypeRefSyntax`,name:e,isCollection:a,isOptional:i,location:t}}function parseProperty(e,t){let n=tryParseProperty(t);return n===void 0?reportInvalidModifierOrder(e,t):reportLegacyOptionalSuffix(e,n.type,t),n}function reportLegacyOptionalSuffix(t,n,r){t.claimField(r);let i=n.name.length+(n.isCollection?2:0),a=n.location.column-r.indent-1+i;if(n.isOptional&&r.content[a]===`?`){let r=n.name+(n.isCollection?`[]`:``);t.information(e.LegacyOptionalSuffix,`Write '${r} optional' instead of '${r}?'.`,n.location)}}function reportInvalidModifierOrder(t,r){let i=a.exec(r.content);if(i!==null&&i[1].split(/\s+/).includes(`subject`))return t.error(e.InvalidSubjectModifierOrder,`Write each modifier once in order: '<name> <Type> optional generated identifier subject'.`,n(r)),!0;if(o.test(r.content))return t.error(e.InvalidOptionalModifierOrder,`Write 'optional' before 'identifier': '<name> <Type> optional identifier'.`,n(r)),!0;{let i=a.exec(r.content);if(i!==null&&i[1].split(/\s+/).some(e=>e===`generated`||e===`identifier`))return t.error(e.InvalidGeneratedModifierOrder,`Write each modifier once in order: '<name> <Type> optional generated identifier'.`,n(r)),!0}return!1}export{parseProperty,parseTypeRef,reportInvalidModifierOrder,reportLegacyOptionalSuffix,tryParseProperty};
1
+ import"../../_virtual/_virtual/_rolldown/runtime.js";import{DiagnosticCodes as e}from"../Diagnostics/DiagnosticCodes.js";import{pattern as t}from"../Text/patterns.js";import{locationOf as n}from"./SourceLine.js";import{unescapeIdentifier as r}from"./LineText.js";const i=t(`^(@?[a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+(generated))?(?:\\s+(identifier))?(?:\\s+(subject))?(?:\\s+(key))?$`),a=t(`^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\??\\s+((?:optional|generated|identifier|subject|key)(?:\\s+(?:optional|generated|identifier|subject|key))*)$`),o=t(`^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\s+identifier\\s+optional(?:\\s*=.*)?$`);function tryParseProperty(e){let t=i.exec(e.content);if(t===null)return;let a=n(e);return{kind:`PropertySyntax`,name:r(t[1]),type:parseTypeRef(t[2],{...a,column:a.column+e.content.indexOf(t[2],t[1].length)}),isGenerated:t[3]!==void 0,nameWasEscaped:t[1].startsWith(`@`),isIdentifier:t[4]!==void 0,...t[5]===void 0?{}:{isSubject:!0},...t[6]===void 0?{}:{isKey:!0},location:a}}function parseTypeRef(e,t){let n=e.endsWith(`?`),r=/\soptional$/.test(e),i=n||r;i&&(e=e.substring(0,e.length-(n?1:8)).trimEnd());let a=e.endsWith(`[]`);return a&&(e=e.substring(0,e.length-2)),{kind:`TypeRefSyntax`,name:e,isCollection:a,isOptional:i,location:t}}function parseProperty(t,r){let i=tryParseProperty(r);return i===void 0?reportInvalidModifierOrder(t,r):(reportLegacyOptionalSuffix(t,i.type,r),i.isKey&&(i.type.isOptional||i.type.isCollection||i.isGenerated||i.isIdentifier||i.isSubject)&&t.error(e.InvalidReadModelKey,`A read-model key part must be required, not a collection, and cannot combine key with generated, identifier or subject.`,n(r))),i}function reportLegacyOptionalSuffix(t,n,r){t.claimField(r);let i=n.name.length+(n.isCollection?2:0),a=n.location.column-r.indent-1+i;if(n.isOptional&&r.content[a]===`?`){let r=n.name+(n.isCollection?`[]`:``);t.information(e.LegacyOptionalSuffix,`Write '${r} optional' instead of '${r}?'.`,n.location)}}function reportInvalidModifierOrder(t,r){let i=a.exec(r.content);if(i!==null&&i[1].split(/\s+/).includes(`key`))return t.error(e.InvalidReadModelKey,`Write 'key' once, without other modifiers: '<name> <Type> key'.`,n(r)),!0;let s=a.exec(r.content);if(s!==null&&s[1].split(/\s+/).includes(`subject`))return t.error(e.InvalidSubjectModifierOrder,`Write each modifier once in order: '<name> <Type> optional generated identifier subject'.`,n(r)),!0;if(o.test(r.content))return t.error(e.InvalidOptionalModifierOrder,`Write 'optional' before 'identifier': '<name> <Type> optional identifier'.`,n(r)),!0;{let i=a.exec(r.content);if(i!==null&&i[1].split(/\s+/).some(e=>e===`generated`||e===`identifier`))return t.error(e.InvalidGeneratedModifierOrder,`Write each modifier once in order: '<name> <Type> optional generated identifier'.`,n(r)),!0}return!1}export{parseProperty,parseTypeRef,reportInvalidModifierOrder,reportLegacyOptionalSuffix,tryParseProperty};
2
2
  //# sourceMappingURL=PropertyLineParser.js.map