@cratis/screenplay-language 4.51.0 → 4.53.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 (190) hide show
  1. package/dist/TypeReferenceSymbol.d.ts +8 -0
  2. package/dist/TypeReferenceSymbol.d.ts.map +1 -0
  3. package/dist/bundles/chunk-7WJEZ72S.js +4463 -0
  4. package/dist/bundles/chunk-7WJEZ72S.js.map +7 -0
  5. package/dist/bundles/index.js +1410 -0
  6. package/dist/bundles/index.js.map +7 -0
  7. package/dist/bundles/sub-languages/capture/index.js +677 -0
  8. package/dist/bundles/sub-languages/capture/index.js.map +7 -0
  9. package/dist/bundles/sub-languages/projection/index.js +1647 -0
  10. package/dist/bundles/sub-languages/projection/index.js.map +7 -0
  11. package/dist/code-actions.d.ts +3 -0
  12. package/dist/code-actions.d.ts.map +1 -0
  13. package/dist/completion-items.d.ts +1 -0
  14. package/dist/completion-items.d.ts.map +1 -1
  15. package/dist/completion-planner.d.ts.map +1 -1
  16. package/dist/completions.d.ts.map +1 -1
  17. package/dist/diagnostic-codes.d.ts +3 -0
  18. package/dist/diagnostic-codes.d.ts.map +1 -1
  19. package/dist/diagnostics.d.ts.map +1 -1
  20. package/dist/hover-content.d.ts.map +1 -1
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/keyword-docs.d.ts.map +1 -1
  24. package/dist/language.d.ts +1 -0
  25. package/dist/language.d.ts.map +1 -1
  26. package/dist/production-destinations.d.ts.map +1 -1
  27. package/dist/symbols.d.ts +4 -0
  28. package/dist/symbols.d.ts.map +1 -1
  29. package/dist/tokens.d.ts.map +1 -1
  30. package/dist/validation.d.ts +1 -0
  31. package/dist/validation.d.ts.map +1 -1
  32. package/package.json +13 -9
  33. package/DestinationHint.ts +0 -8
  34. package/ProductionSymbol.ts +0 -11
  35. package/completion-items.ts +0 -261
  36. package/completion-planner.ts +0 -167
  37. package/completions.ts +0 -156
  38. package/diagnostic-codes.ts +0 -43
  39. package/diagnostics.ts +0 -55
  40. package/dist/DestinationHint.js +0 -4
  41. package/dist/DestinationHint.js.map +0 -1
  42. package/dist/ProductionSymbol.js +0 -4
  43. package/dist/ProductionSymbol.js.map +0 -1
  44. package/dist/completion-items.js +0 -228
  45. package/dist/completion-items.js.map +0 -1
  46. package/dist/completion-planner.js +0 -143
  47. package/dist/completion-planner.js.map +0 -1
  48. package/dist/completions.js +0 -101
  49. package/dist/completions.js.map +0 -1
  50. package/dist/diagnostic-codes.js +0 -41
  51. package/dist/diagnostic-codes.js.map +0 -1
  52. package/dist/diagnostics.js +0 -50
  53. package/dist/diagnostics.js.map +0 -1
  54. package/dist/document-context.js +0 -85
  55. package/dist/document-context.js.map +0 -1
  56. package/dist/event-analysis-source.js +0 -19
  57. package/dist/event-analysis-source.js.map +0 -1
  58. package/dist/event-context-catalog.js +0 -116
  59. package/dist/event-context-catalog.js.map +0 -1
  60. package/dist/event-context.js +0 -88
  61. package/dist/event-context.js.map +0 -1
  62. package/dist/file-imports.js +0 -58
  63. package/dist/file-imports.js.map +0 -1
  64. package/dist/file-references.js +0 -70
  65. package/dist/file-references.js.map +0 -1
  66. package/dist/hover-content.js +0 -98
  67. package/dist/hover-content.js.map +0 -1
  68. package/dist/hover.js +0 -15
  69. package/dist/hover.js.map +0 -1
  70. package/dist/index.js +0 -61
  71. package/dist/index.js.map +0 -1
  72. package/dist/inlay-hints.js +0 -15
  73. package/dist/inlay-hints.js.map +0 -1
  74. package/dist/inline-event-validation.js +0 -131
  75. package/dist/inline-event-validation.js.map +0 -1
  76. package/dist/keyword-docs.js +0 -148
  77. package/dist/keyword-docs.js.map +0 -1
  78. package/dist/language.js +0 -196
  79. package/dist/language.js.map +0 -1
  80. package/dist/production-destinations.js +0 -32
  81. package/dist/production-destinations.js.map +0 -1
  82. package/dist/sub-language-registry.js +0 -18
  83. package/dist/sub-language-registry.js.map +0 -1
  84. package/dist/sub-languages/capture/CompletionProvider.js +0 -332
  85. package/dist/sub-languages/capture/CompletionProvider.js.map +0 -1
  86. package/dist/sub-languages/capture/HoverProvider.js +0 -87
  87. package/dist/sub-languages/capture/HoverProvider.js.map +0 -1
  88. package/dist/sub-languages/capture/Validator.js +0 -72
  89. package/dist/sub-languages/capture/Validator.js.map +0 -1
  90. package/dist/sub-languages/capture/index.js +0 -58
  91. package/dist/sub-languages/capture/index.js.map +0 -1
  92. package/dist/sub-languages/capture/language.js +0 -160
  93. package/dist/sub-languages/capture/language.js.map +0 -1
  94. package/dist/sub-languages/cdl.js +0 -74
  95. package/dist/sub-languages/cdl.js.map +0 -1
  96. package/dist/sub-languages/pdl.js +0 -73
  97. package/dist/sub-languages/pdl.js.map +0 -1
  98. package/dist/sub-languages/projection/CodeActionProvider.js +0 -93
  99. package/dist/sub-languages/projection/CodeActionProvider.js.map +0 -1
  100. package/dist/sub-languages/projection/CompletionProvider.js +0 -595
  101. package/dist/sub-languages/projection/CompletionProvider.js.map +0 -1
  102. package/dist/sub-languages/projection/HoverProvider.js +0 -333
  103. package/dist/sub-languages/projection/HoverProvider.js.map +0 -1
  104. package/dist/sub-languages/projection/Validator.js +0 -388
  105. package/dist/sub-languages/projection/Validator.js.map +0 -1
  106. package/dist/sub-languages/projection/index.js +0 -160
  107. package/dist/sub-languages/projection/index.js.map +0 -1
  108. package/dist/sub-languages/projection/language.js +0 -171
  109. package/dist/sub-languages/projection/language.js.map +0 -1
  110. package/dist/symbols.js +0 -275
  111. package/dist/symbols.js.map +0 -1
  112. package/dist/themes/screenplay-dark.js +0 -30
  113. package/dist/themes/screenplay-dark.js.map +0 -1
  114. package/dist/themes/screenplay-light.js +0 -30
  115. package/dist/themes/screenplay-light.js.map +0 -1
  116. package/dist/tokens.js +0 -147
  117. package/dist/tokens.js.map +0 -1
  118. package/dist/validation.js +0 -248
  119. package/dist/validation.js.map +0 -1
  120. package/document-context.ts +0 -93
  121. package/event-analysis-source.ts +0 -18
  122. package/event-context-catalog.ts +0 -135
  123. package/event-context.ts +0 -119
  124. package/file-imports.ts +0 -70
  125. package/file-references.ts +0 -87
  126. package/for_documentContext/when_stripping_comments.ts +0 -32
  127. package/for_eventContext/when_resolving_generated_catalog_vectors.ts +0 -15
  128. package/for_eventGenerations/when_editing_event_generations.ts +0 -57
  129. package/for_fileImports/when_finding_file_imports.ts +0 -38
  130. package/for_fileReferences/when_recognizing_an_absolute_path/with_paths_of_every_shape.ts +0 -26
  131. package/for_fileReferences/when_scanning_a_document/inside_a_code_fence.ts +0 -26
  132. package/for_fileReferences/when_scanning_a_document/with_a_bare_file_keyword.ts +0 -19
  133. package/for_fileReferences/when_scanning_a_document/with_a_file_directive.ts +0 -30
  134. package/for_fileReferences/when_scanning_a_document/with_a_property_named_file.ts +0 -25
  135. package/for_fileReferences/when_scanning_a_document/with_a_trailing_comment.ts +0 -25
  136. package/for_fileReferences/when_scanning_a_document/with_directives_on_several_constructs.ts +0 -41
  137. package/for_importablePaths/when_listing_what_a_document_can_import.ts +0 -34
  138. package/for_inlineEvents/when_analyzing_many_inline_events.ts +0 -59
  139. package/for_inlineEvents/when_authoring_inline_events.ts +0 -149
  140. package/for_inlineEvents/when_completing_many_events.ts +0 -49
  141. package/for_inlineEvents/when_indexing_command_production_ownership.ts +0 -79
  142. package/for_planCompletions/when_completing_a_file_import.ts +0 -26
  143. package/for_planCompletions/when_completing_a_specification_query.ts +0 -24
  144. package/for_planCompletions/when_completing_a_specification_step.ts +0 -42
  145. package/for_planCompletions/when_completing_an_absent_read_model.ts +0 -14
  146. package/for_planCompletions/when_completing_reaction_reads.ts +0 -36
  147. package/for_projectionCompletionProvider/when_completing_an_event_context_path.ts +0 -102
  148. package/for_projectionHoverProvider/when_hovering_an_event_context_path.ts +0 -44
  149. package/for_projectionValidator/when_validating_a_projection_with_variants.ts +0 -128
  150. package/for_projectionValidator/when_validating_event_context_paths.ts +0 -31
  151. package/for_scanDocument/when_scanning_a_query/with_a_dotted_return_type.ts +0 -34
  152. package/for_scanDocument/when_scanning_aliased_reads.ts +0 -33
  153. package/for_scanDocument/when_scanning_many_commands.ts +0 -47
  154. package/for_tokens/when_highlighting_a_file_import.ts +0 -18
  155. package/for_tokens/when_highlighting_event_metadata.ts +0 -63
  156. package/for_tokens/when_highlighting_specification_steps.ts +0 -28
  157. package/for_validateLines/when_validating_a_document/with_a_problem_of_every_coded_kind.ts +0 -77
  158. package/for_validateLines/when_validating_a_document/with_an_unknown_policy.ts +0 -33
  159. package/for_validateLines/when_validating_a_file_placed_by_an_import/with_names_declared_in_other_files.ts +0 -43
  160. package/for_validateLines/when_validating_event_context_paths/in_a_projection.ts +0 -97
  161. package/for_validateLines/when_validating_file_imports/at_every_level.ts +0 -36
  162. package/for_validateLines/when_validating_production_destinations/with_an_available_identifier.ts +0 -120
  163. package/hover-content.ts +0 -117
  164. package/hover.ts +0 -23
  165. package/index.ts +0 -125
  166. package/inlay-hints.ts +0 -17
  167. package/inline-event-validation.ts +0 -115
  168. package/keyword-docs.ts +0 -152
  169. package/language.ts +0 -212
  170. package/production-destinations.ts +0 -32
  171. package/sub-language-registry.ts +0 -42
  172. package/sub-languages/capture/CompletionProvider.ts +0 -365
  173. package/sub-languages/capture/HoverProvider.ts +0 -99
  174. package/sub-languages/capture/Validator.ts +0 -97
  175. package/sub-languages/capture/index.ts +0 -72
  176. package/sub-languages/capture/language.ts +0 -176
  177. package/sub-languages/cdl.ts +0 -76
  178. package/sub-languages/pdl.ts +0 -75
  179. package/sub-languages/projection/CodeActionProvider.ts +0 -123
  180. package/sub-languages/projection/CompletionProvider.ts +0 -660
  181. package/sub-languages/projection/HoverProvider.ts +0 -377
  182. package/sub-languages/projection/Validator.ts +0 -441
  183. package/sub-languages/projection/index.ts +0 -223
  184. package/sub-languages/projection/language.ts +0 -193
  185. package/symbols.ts +0 -374
  186. package/themes/screenplay-dark.ts +0 -33
  187. package/themes/screenplay-light.ts +0 -33
  188. package/tokens.ts +0 -174
  189. package/validation.ts +0 -443
  190. package/vitest.setup.ts +0 -5
@@ -1,377 +0,0 @@
1
- // Copyright (c) Cratis. All rights reserved.
2
- // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
-
4
- import type { editor, languages, Position } from 'monaco-editor';
5
- import type { JsonSchema, JsonSchemaProperty, ReadModelInfo, DraftReadModelInfo } from './index';
6
- import { describeEventContext, describeEventContextMember, eventContextMemberAt } from '../../event-context';
7
-
8
- export class HoverProvider implements languages.HoverProvider {
9
- private readModels: ReadModelInfo[] = [];
10
- private eventSchemas: Record<string, JsonSchema> = {};
11
- private draftReadModel: DraftReadModelInfo | null = null;
12
-
13
- setReadModels(readModels: ReadModelInfo[]): void {
14
- this.readModels = readModels || [];
15
- }
16
-
17
- // Keep for backwards compatibility
18
- setReadModelSchemas(schemas: JsonSchema[]): void {
19
- this.readModels = schemas.map(schema => ({
20
- identifier: this.getSchemaName(schema) || '',
21
- displayName: this.getSchemaName(schema) || '',
22
- schema
23
- }));
24
- }
25
-
26
- setEventSchemas(schemas: Record<string, JsonSchema> | JsonSchema[]): void {
27
- if (!schemas) {
28
- this.eventSchemas = {};
29
- return;
30
- }
31
-
32
- if (Array.isArray(schemas)) {
33
- const map: Record<string, JsonSchema> = {};
34
- schemas.forEach((s, i) => {
35
- if (!s) return;
36
- const name = this.getSchemaName(s) || `Event${i + 1}`;
37
- map[name] = s;
38
- });
39
- this.eventSchemas = map;
40
- return;
41
- }
42
-
43
- this.eventSchemas = schemas;
44
- }
45
-
46
- setDraftReadModel(draft: DraftReadModelInfo | null): void {
47
- this.draftReadModel = draft;
48
- }
49
-
50
- provideHover(model: editor.ITextModel, position: Position): languages.ProviderResult<languages.Hover> {
51
- const word = model.getWordAtPosition(position);
52
- if (!word) return null;
53
-
54
- const wordText = word.word;
55
-
56
- // Check if we're on the projection name (before '=>')
57
- const lineContent = model.getLineContent(position.lineNumber);
58
- const projectionNameMatch = this.getProjectionNameAtPosition(lineContent, position.column);
59
- if (projectionNameMatch) {
60
- return {
61
- contents: [{ value: 'The name of the projection' }],
62
- range: {
63
- startLineNumber: position.lineNumber,
64
- startColumn: word.startColumn,
65
- endLineNumber: position.lineNumber,
66
- endColumn: word.endColumn,
67
- },
68
- };
69
- }
70
-
71
- // A segment of an $eventContext path - before keywords, since a member such as 'id' is also a keyword
72
- const eventContextInfo = this.getEventContextInfo(lineContent, word.startColumn);
73
- if (eventContextInfo) {
74
- return {
75
- contents: [{ value: eventContextInfo }],
76
- range: {
77
- startLineNumber: position.lineNumber,
78
- startColumn: word.startColumn,
79
- endLineNumber: position.lineNumber,
80
- endColumn: word.endColumn,
81
- },
82
- };
83
- }
84
-
85
- // Check if it's a keyword
86
- const keywordInfo = this.getKeywordInfo(wordText);
87
- if (keywordInfo) {
88
- return {
89
- contents: [{ value: keywordInfo }],
90
- range: {
91
- startLineNumber: position.lineNumber,
92
- startColumn: word.startColumn,
93
- endLineNumber: position.lineNumber,
94
- endColumn: word.endColumn,
95
- },
96
- };
97
- }
98
-
99
- // Check if it's a built-in expression
100
- const expressionInfo = this.getExpressionInfo(wordText);
101
- if (expressionInfo) {
102
- return {
103
- contents: [{ value: expressionInfo }],
104
- range: {
105
- startLineNumber: position.lineNumber,
106
- startColumn: word.startColumn,
107
- endLineNumber: position.lineNumber,
108
- endColumn: word.endColumn,
109
- },
110
- };
111
- }
112
-
113
- // Check if it's an event type
114
- if (this.eventSchemas[wordText]) {
115
- const schema = this.eventSchemas[wordText];
116
- const description = this.getSchemaDescription(schema);
117
- const properties = this.getSchemaProperties(schema);
118
-
119
- let content = `**Event Type:** \`${wordText}\`\n\n`;
120
- if (description) {
121
- content += `${description}\n\n`;
122
- }
123
- if (properties.length > 0) {
124
- content += `**Properties:**\n\n${properties.map(p => `- \`${p.name}\`: ${p.type}`).join('\n')}`;
125
- }
126
-
127
- return {
128
- contents: [{ value: content }],
129
- range: {
130
- startLineNumber: position.lineNumber,
131
- startColumn: word.startColumn,
132
- endLineNumber: position.lineNumber,
133
- endColumn: word.endColumn,
134
- },
135
- };
136
- }
137
-
138
- // Check if it's a draft read model
139
- if (this.isDraftReadModel(wordText)) {
140
- const description = this.getSchemaDescription(this.draftReadModel!.schema);
141
- const properties = this.getSchemaProperties(this.draftReadModel!.schema);
142
- const identifier = this.draftReadModel!.identifier;
143
- const displayName = this.draftReadModel!.displayName;
144
-
145
- let content = `**Read Model (Draft):** \`${displayName}\`\n\n**Identifier:** \`${identifier}\`\n\n`;
146
- if (description) {
147
- content += `${description}\n\n`;
148
- }
149
- if (properties.length > 0) {
150
- content += `**Properties:**\n\n${properties.map(p => `- \`${p.name}\`: ${p.type}`).join('\n')}`;
151
- }
152
-
153
- return {
154
- contents: [{ value: content }],
155
- range: {
156
- startLineNumber: position.lineNumber,
157
- startColumn: word.startColumn,
158
- endLineNumber: position.lineNumber,
159
- endColumn: word.endColumn,
160
- },
161
- };
162
- }
163
-
164
- // Check if it's a read model
165
- const readModel = this.resolveReadModelInfo(wordText);
166
- if (readModel) {
167
- const description = this.getSchemaDescription(readModel.schema);
168
- const properties = this.getSchemaProperties(readModel.schema);
169
-
170
- let content = `**Read Model:** \`${readModel.displayName}\`\n\n**Identifier:** \`${readModel.identifier}\`\n\n`;
171
- if (description) {
172
- content += `${description}\n\n`;
173
- }
174
- if (properties.length > 0) {
175
- content += `**Properties:**\n\n${properties.map(p => `- \`${p.name}\`: ${p.type}`).join('\n')}`;
176
- }
177
-
178
- return {
179
- contents: [{ value: content }],
180
- range: {
181
- startLineNumber: position.lineNumber,
182
- startColumn: word.startColumn,
183
- endLineNumber: position.lineNumber,
184
- endColumn: word.endColumn,
185
- },
186
- };
187
- }
188
-
189
- // Check if it's a property in the current context
190
- const propertyInfo = this.getPropertyInfo(model, position, wordText);
191
- if (propertyInfo) {
192
- return {
193
- contents: [{ value: propertyInfo }],
194
- range: {
195
- startLineNumber: position.lineNumber,
196
- startColumn: word.startColumn,
197
- endLineNumber: position.lineNumber,
198
- endColumn: word.endColumn,
199
- },
200
- };
201
- }
202
-
203
- return null;
204
- }
205
-
206
- private getKeywordInfo(word: string): string | null {
207
- const keywords: Record<string, string> = {
208
- 'projection': '**projection** - Defines a projection that transforms events into a read model',
209
- 'from': '**from** *<EventType>*\n\nHandles specific event types and maps their properties to the read model.',
210
- 'all': '**all**\n\nSubscribes to **all event types in the system**, regardless of explicit `from` blocks. Mappings inside `all` run for every event that arrives system-wide.',
211
- 'every': '**every**\n\nHandles all events the projection **explicitly subscribes to** through `from` blocks, with automatic property mapping.',
212
- 'key': '**key** *<expression>*\n\nDefines the projection key or composite key type.',
213
- 'parent': '**parent** *<expression>*\n\nDefines a parent relationship for hierarchical projections.',
214
- 'join': '**join** *<collection>* **on** *<property>*\n\nJoins with a child collection based on a property.',
215
- 'children': '**children** *<collection>* **id** *<expression>*\n\nDefines operations on child collections.',
216
- 'remove': '**remove with** *<EventType>* or **remove via join on** *<EventType>*\n\nRemoves items from the read model based on events.',
217
- 'clear': '**clear** *<property>*\n\nRemoves the value a property holds. **clear with** *<EventType>* nulls a whole nested object instead.',
218
- 'automap': '**automap** or **no automap**\n\nControls automatic property mapping from events to the read model.',
219
- 'increment': '**increment** *<property>*\n\nIncrements a numeric property by 1.',
220
- 'decrement': '**decrement** *<property>*\n\nDecrements a numeric property by 1.',
221
- 'count': '**count** *<property>*\n\nCounts occurrences and stores in a property.',
222
- 'add': '**add** *<property>* **by** *<expression>*\n\nAdds a value to a property.',
223
- 'subtract': '**subtract** *<property>* **by** *<expression>*\n\nSubtracts a value from a property.',
224
- 'exclude': '**exclude children**\n\nExcludes child collections from automatic mapping.',
225
- 'events': '**events** *<EventType>*, ...\n\nSpecifies which event types to include in a join.',
226
- 'via': 'Used with **remove via join on** to remove items via a join relationship.',
227
- 'with': 'Used with **remove with** to specify which event type triggers removal.',
228
- 'on': 'Used with **join** to specify the join property.',
229
- 'by': 'Used with **add** or **subtract** to specify the value.',
230
- 'id': 'Used with **children** to specify the child identifier expression.',
231
- 'no': 'Used with **no automap** to disable automatic property mapping.',
232
- 'variant': '**variant** *<Name>*\n\nDeclares one of several mutually exclusive named read models sharing the projection\'s identity. Entering one variant removes the entity from every other variant of the same projection.',
233
- 'enters': '**enters on** *<EventType>*\n\nDeclares the event that activates this variant - the only event allowed to create it. Every other event the variant subscribes to is update-only.',
234
- };
235
-
236
- return keywords[word] || null;
237
- }
238
-
239
- private getExpressionInfo(word: string): string | null {
240
- const expressions: Record<string, string> = {
241
- '$eventSourceId': '**$eventSourceId**\n\nThe identifier of the event source (aggregate/entity) that generated the event.',
242
- '$causedBy': '**$causedBy**\n\nThe identity that caused the event - `subject`, `name`, `userName` or `onBehalfOf`, itself an identity.\n\nChronicle cannot yet evaluate this short form (Cratis/Chronicle#4119); prefer **$eventContext.causedBy**.*property*.',
243
- '$eventContext': describeEventContext(),
244
- };
245
-
246
- return expressions[word] || null;
247
- }
248
-
249
- // Describes the $eventContext path segment starting at the given column, if the word there is one.
250
- private getEventContextInfo(lineContent: string, startColumn: number): string | null {
251
- for (const match of lineContent.matchAll(/\$eventContext((?:\.\w+(?:\(\))?)*)/g)) {
252
- let column = (match.index ?? 0) + 1;
253
- if (startColumn === column) return describeEventContext();
254
-
255
- column += '$eventContext'.length;
256
- const segments = match[1].split('.').slice(1);
257
- for (let index = 0; index < segments.length; index++) {
258
- column += 1;
259
- if (startColumn === column) {
260
- const path = segments.slice(0, index + 1);
261
- const member = eventContextMemberAt(path);
262
- return member ? describeEventContextMember(path.join('.'), member) : null;
263
- }
264
-
265
- column += segments[index].length;
266
- }
267
- }
268
-
269
- return null;
270
- }
271
-
272
- private getPropertyInfo(model: editor.ITextModel, position: Position, propertyName: string): string | null {
273
- // Try to find the active read model
274
- const firstLine = model.getLineContent(1).trim();
275
- const match = firstLine.match(/^projection\s+[\w.]+\s*=>\s*([\w.]+)/);
276
- if (!match) return null;
277
-
278
- const readModelName = match[1];
279
- const draftMatch = this.isDraftReadModel(readModelName) ? this.draftReadModel : null;
280
- const resolvedReadModel = draftMatch ? null : this.resolveReadModelInfo(readModelName);
281
- const activeSchema = draftMatch?.schema || resolvedReadModel?.schema;
282
-
283
- if (activeSchema?.properties && activeSchema.properties[propertyName]) {
284
- const prop = activeSchema.properties[propertyName];
285
- const type = this.getPropertyTypeDescription(prop);
286
- const description = prop.description;
287
-
288
- let content = `**Property:** \`${propertyName}\`\n\n**Type:** \`${type}\``;
289
- if (description) {
290
- content += `\n\n${description}`;
291
- }
292
- return content;
293
- }
294
-
295
- // Check if it's an event property
296
- const eventType = this.getCurrentEventType(model, position.lineNumber);
297
- if (eventType && this.eventSchemas[eventType]) {
298
- const eventSchema = this.eventSchemas[eventType];
299
- if (eventSchema.properties && eventSchema.properties[propertyName]) {
300
- const prop = eventSchema.properties[propertyName];
301
- const type = this.getPropertyTypeDescription(prop);
302
- const description = prop.description;
303
-
304
- let content = `**Event Property:** \`${propertyName}\`\n\n**Type:** \`${type}\``;
305
- if (description) {
306
- content += `\n\n${description}`;
307
- }
308
- return content;
309
- }
310
- }
311
-
312
- return null;
313
- }
314
-
315
- private resolveReadModelInfo(readModelToken: string): ReadModelInfo | null {
316
- return this.readModels.find(rm => rm.identifier === readModelToken || rm.displayName === readModelToken) || null;
317
- }
318
-
319
- private isDraftReadModel(readModelToken: string): boolean {
320
- return !!this.draftReadModel && (this.draftReadModel.identifier === readModelToken || this.draftReadModel.displayName === readModelToken);
321
- }
322
-
323
- private getCurrentEventType(model: editor.ITextModel, lineNumber: number): string | null {
324
- for (let i = lineNumber; i >= 1; i--) {
325
- const line = model.getLineContent(i).trim();
326
- const fromMatch = line.match(/^from\s+([\w-]+)/);
327
- if (fromMatch) {
328
- return fromMatch[1];
329
- }
330
- }
331
- return null;
332
- }
333
-
334
- private getProjectionNameAtPosition(lineContent: string, column: number): boolean {
335
- // Check if we're on line 1 (projection declaration line)
336
- const projectionMatch = lineContent.match(/^\s*projection\s+(\S+)\s*=>/);
337
- if (!projectionMatch) return false;
338
-
339
- const projectionKeywordEnd = lineContent.indexOf('projection') + 'projection'.length;
340
- const arrowStart = lineContent.indexOf('=>');
341
-
342
- // Check if cursor is between 'projection' keyword and '=>'
343
- // and is on the projection name itself
344
- return column > projectionKeywordEnd && column <= arrowStart;
345
- }
346
-
347
- private getSchemaName(schema: JsonSchema): string | undefined {
348
- if (schema.name) return schema.name;
349
- if (schema.title) return schema.title;
350
- if (typeof schema.$id === 'string') {
351
- const parts = schema.$id.split('/');
352
- return parts[parts.length - 1] || schema.$id;
353
- }
354
- return undefined;
355
- }
356
-
357
- private getSchemaDescription(schema: JsonSchema): string | undefined {
358
- return schema.description || undefined;
359
- }
360
-
361
- private getSchemaProperties(schema: JsonSchema): Array<{ name: string; type: string }> {
362
- if (!schema.properties) return [];
363
-
364
- return Object.entries(schema.properties).map(([name, prop]) => ({
365
- name,
366
- type: this.getPropertyTypeDescription(prop),
367
- }));
368
- }
369
-
370
- private getPropertyTypeDescription(propSchema: JsonSchemaProperty): string {
371
- if (propSchema.type === 'array' && propSchema.items) {
372
- const itemType = propSchema.items.type || propSchema.items.$ref?.split('/').pop() || 'unknown';
373
- return `${itemType}[]`;
374
- }
375
- return propSchema.type || propSchema.$ref?.split('/').pop() || 'unknown';
376
- }
377
- }