@cratis/screenplay-language 4.55.0 → 4.55.1

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.
@@ -261,531 +261,50 @@ function nearestEnclosingLine(lines, fences, lineIndex, indent) {
261
261
  return void 0;
262
262
  }
263
263
 
264
- // event-analysis-source.ts
265
- function eventAnalysisSource(lines) {
266
- let fenced = false;
267
- return lines.map((line) => {
268
- if (fenced) {
269
- if (line.trim() === "```") fenced = false;
270
- return line;
271
- }
272
- const text = withoutComment(line);
273
- if (/^\s*```(?:[a-z]+)?\s*$/.test(text)) fenced = true;
274
- return text.trimEnd();
275
- });
276
- }
277
-
278
- // symbols.ts
279
- var conceptPattern = /^concept\s+(\w+)\s*:\s*(\w+)((?:\s+@\w+)*)\s*$/;
280
- var propertyPattern = /^\s*(@?[a-z_]\w*)\s+([\w.]+(?:\[\])?(?:\?|\s+optional)?)(\s+identifier)?\s*$/;
281
- var attributeReasonPattern = /^([a-z_]\w*)\s+reason\s+"((?:[^"\\]|\\.)*)"\s*$/;
282
- var readPattern = /^\s*reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?\s*$/;
283
- var commandReserved = ["authorize", "produces", "reads"];
284
- var authorizationContinuation = /^(?:(?:or|and)\s+)?[A-Za-z_(][\p{L}\p{Mn}\p{Nd}\p{Pc}\s()]*$/u;
285
- var eventReserved = clauseKeywords.filter((keyword) => !["id", "description", "documentation"].includes(keyword));
286
- var queryParameterPattern = /^\s*(?:by|filter)\s+([a-z_]\w*)\s+([\w.]+(?:\[\])?(?:\?|\s+optional)?)(?:\s+from\s+.+)?\s*$/;
287
- function propertyTypeReference(property) {
288
- return property.typeReference ?? typeReferenceSymbol(property.type);
289
- }
290
- function propertiesIn(lines, body, reserved3) {
291
- return body.map((index) => ({ index, match: lines[index].match(propertyPattern) })).filter((entry) => entry.match !== null).filter(({ match }) => match[1].startsWith("@") || match[1] === "as" || !reserved3.includes(match[1])).map(({ index, match }) => ({
292
- name: match[1].replace(/^@/, ""),
293
- type: match[2],
294
- typeReference: typeReferenceSymbol(match[2]),
295
- isIdentifier: match[3] !== void 0,
296
- line: index
297
- }));
298
- }
299
- function collectBody(lines, fences, start, indent) {
300
- const body = [];
301
- for (let index = start + 1; index < lines.length; index++) {
302
- if (fences[index]) {
303
- continue;
264
+ // file-references.ts
265
+ var fileReferenceKeyword = "file";
266
+ var typeReferencePattern = /^[A-Za-z_]\w*(?:\[\])?(?:\?|\s+optional)?$/;
267
+ var absolutePathPattern = /^(?:[/\\]|[A-Za-z]:[/\\]|~[/\\])/;
268
+ function isAbsoluteFileReferencePath(path) {
269
+ return absolutePathPattern.test(path);
270
+ }
271
+ function withoutComment2(text) {
272
+ let inString = false;
273
+ let inTemplate = false;
274
+ for (let index = 0; index < text.length; index++) {
275
+ const current = text[index];
276
+ if (current === "\\" && inString && index + 1 < text.length) {
277
+ index++;
278
+ } else if (current === '"' && !inTemplate) {
279
+ inString = !inString;
280
+ } else if (current === "`" && !inString) {
281
+ inTemplate = !inTemplate;
282
+ } else if (!inString && !inTemplate && current === "/" && text[index + 1] === "/") {
283
+ return text.slice(0, index);
304
284
  }
305
- const line = lines[index];
306
- if (line.trim().length === 0) continue;
307
- if (indentOf(line) <= indent) break;
308
- body.push(index);
309
285
  }
310
- return body;
311
- }
312
- function directBody(lines, fences, start, indent) {
313
- const body = collectBody(lines, fences, start, indent).filter((index) => !fences[index] && !/^\s*(?:\/\/|#)/.test(lines[index]));
314
- if (!/^\s*command\b/.test(lines[start])) return body;
315
- let blockIndent;
316
- let authorization = false;
317
- return body.filter((index) => {
318
- const childIndent = indentOf(lines[index]);
319
- const text = lines[index].trim();
320
- if (blockIndent !== void 0 && childIndent > blockIndent && (!authorization || authorizationContinuation.test(text))) return false;
321
- const property = text !== "validate csharp" && propertiesIn(lines, [index], commandReserved).length > 0;
322
- const leaf = property || /^description(?:\s|$)/.test(text);
323
- blockIndent = leaf ? void 0 : childIndent;
324
- authorization = /^authorize(?:\s|$)/.test(text);
325
- return true;
326
- });
286
+ return text;
327
287
  }
328
- function scanDocument(lines) {
329
- const symbols = {
330
- imports: [],
331
- concepts: [],
332
- types: [],
333
- policies: [],
334
- events: [],
335
- commands: [],
336
- queries: [],
337
- screens: [],
338
- triggers: []
339
- };
340
- lines = eventAnalysisSource(lines);
288
+ function fileReferenceOn(line, lineIndex) {
289
+ const indent = indentOf(line);
290
+ const content = withoutComment2(line.slice(indent)).trimEnd();
291
+ if (firstWord(content) !== fileReferenceKeyword) return void 0;
292
+ const afterKeyword = content.slice(fileReferenceKeyword.length);
293
+ const path = afterKeyword.trim();
294
+ if (path.length === 0 || typeReferencePattern.test(path)) return void 0;
295
+ const separatorLength = afterKeyword.length - afterKeyword.trimStart().length;
296
+ const startColumn = indent + fileReferenceKeyword.length + separatorLength + 1;
297
+ return { path, line: lineIndex, startColumn, endColumn: startColumn + path.length };
298
+ }
299
+ function fileReferences(lines) {
341
300
  const fences = fenceMap(lines);
342
- const eventLines = lines;
343
- const eventFences = fences;
344
- const eventPropertyLines = lines.map((line) => line.replace(/\s*=(?!=|>).*/, ""));
301
+ const references = [];
345
302
  for (let index = 0; index < lines.length; index++) {
346
303
  if (fences[index]) continue;
347
- const line = lines[index];
348
- const trimmed = line.trim();
349
- const indent = indentOf(line);
350
- const importMatch = eventLines[index].trim().match(/^import\s+([\w.]+)\s*$/);
351
- if (importMatch && indent === 0) {
352
- const qualifiedName = importMatch[1];
353
- const shortName = qualifiedName.split(".").pop() ?? qualifiedName;
354
- symbols.imports.push({ qualifiedName, shortName, line: index });
355
- continue;
356
- }
357
- const conceptMatch = trimmed.match(conceptPattern);
358
- if (conceptMatch) {
359
- const body = collectBody(lines, fences, index, indent).map((i) => lines[i].trim());
360
- const attributeReasons = {};
361
- for (const line2 of body) {
362
- const reason = line2.match(attributeReasonPattern);
363
- if (reason && attributeReasons[reason[1]] === void 0) {
364
- attributeReasons[reason[1]] = reason[2];
365
- }
366
- }
367
- const enumValues = conceptMatch[2] === "Enum" ? body.filter((line2) => !attributeReasonPattern.test(line2)) : [];
368
- symbols.concepts.push({
369
- name: conceptMatch[1],
370
- primitive: conceptMatch[2],
371
- attributes: conceptMatch[3].trim().split(/\s+/).filter(Boolean),
372
- attributeReasons,
373
- enumValues,
374
- line: index
375
- });
376
- continue;
377
- }
378
- const typeMatch = trimmed.match(/^type\s+(\w+)\s*$/);
379
- if (typeMatch) {
380
- symbols.types.push({
381
- name: typeMatch[1],
382
- properties: propertiesIn(lines, collectBody(lines, fences, index, indent), clauseKeywords),
383
- line: index
384
- });
385
- continue;
386
- }
387
- const policyMatch = trimmed.match(/^policy\s+(\w+)\s*$/);
388
- if (policyMatch) {
389
- const requires = collectBody(lines, fences, index, indent).filter((i) => !fences[i]).map((i) => lines[i].trim());
390
- symbols.policies.push({ name: policyMatch[1], requires, line: index });
391
- continue;
392
- }
393
- const eventMatch = eventLines[index].trim().match(/^(?:produces\s+)?event\s+(\w+)(?:\s+generation\s+(\d+))?\s*$/);
394
- if (eventMatch) {
395
- symbols.events.push({
396
- name: eventMatch[1],
397
- ...eventMatch[2] ? { generation: Number(eventMatch[2]) } : {},
398
- inline: trimmed.startsWith("produces "),
399
- properties: propertiesIn(
400
- trimmed.startsWith("produces ") ? eventPropertyLines : eventLines,
401
- directBody(eventLines, eventFences, index, indent),
402
- eventReserved
403
- ),
404
- line: index
405
- });
406
- continue;
407
- }
408
- const commandMatch = eventLines[index].trim().match(/^command\s+(\w+)\s*$/);
409
- if (commandMatch) {
410
- const body = directBody(lines, fences, index, indent);
411
- const productionHeaders = body.filter((line2) => /^\s*produces\b/.test(lines[line2]));
412
- symbols.commands.push({
413
- name: commandMatch[1],
414
- properties: propertiesIn(lines, body.filter((line2) => lines[line2].trim() !== "validate csharp"), commandReserved),
415
- productionHeaders,
416
- produces: productionHeaders.flatMap((line2) => {
417
- const header10 = eventLines[line2].trim();
418
- const inline = /^produces\s+event\b/.test(header10);
419
- const conditional2 = /^produces\s+when\b/.test(header10);
420
- const eventLine = conditional2 ? directBody(eventLines, eventFences, line2, indentOf(eventLines[line2]))[0] : line2;
421
- if (eventLine === void 0) return [];
422
- const name = conditional2 ? eventLines[eventLine].trim() : header10.match(inline ? /^produces\s+event\s+([A-Za-z_]\w*)(?:\s+generation\s+\d+)?\s*$/ : /^produces\s+([A-Z]\w*)\s*$/)?.[1];
423
- if (name === void 0 || !/^[A-Za-z_]\w*$/.test(name)) return [];
424
- const children = directBody(eventLines, eventFences, eventLine, indentOf(eventLines[eventLine]));
425
- const targets = children.map((index2) => eventLines[index2].trim().match(/^for(?:\s+(.*))?$/)).filter((match) => match !== null);
426
- const target = targets.length === 0 ? void 0 : targets.length === 1 ? targets[0][1] ?? "" : "";
427
- const mappings = children.flatMap((index2) => {
428
- const match = eventLines[index2].trim().match(inline ? /^(@?[a-z_]\w*)\s+[\w.]+(?:\[\])?(?:\?|\s+optional)?\s*=(?!=|>)\s*(.+)$/ : /^(@?[\w.]+)\s*=(?!=|>)\s*(.+)$/);
429
- return match === null ? [] : [{ name: match[1].replace(/^@/, ""), source: match[2], line: index2 }];
430
- });
431
- return [{ name, inline, conditional: conditional2, line: line2, target, mappings }];
432
- }),
433
- reads: body.filter((line2) => !fences[line2]).map((line2) => ({ line: line2, match: lines[line2].match(readPattern) })).filter((entry) => entry.match !== null).map(({ line: line2, match }) => ({
434
- view: match[1],
435
- ...match[2] ? { alias: match[2] } : {},
436
- ...match[3] ? { by: match[3] } : {},
437
- line: line2
438
- })),
439
- line: index
440
- });
441
- continue;
442
- }
443
- const queryMatch = trimmed.match(/^query\s+(\w+)\s*=>\s*(?:observable\s+)?([\w.]+(?:\[\])?(?:\?|\s+optional)?)\s*$/);
444
- if (queryMatch) {
445
- const parameters = collectBody(lines, fences, index, indent).map((i) => ({ index: i, match: lines[i].match(queryParameterPattern) })).filter(
446
- (entry) => entry.match !== null
447
- ).map(({ index: line2, match }) => ({
448
- name: match[1],
449
- type: match[2],
450
- typeReference: typeReferenceSymbol(match[2]),
451
- isIdentifier: false,
452
- line: line2
453
- }));
454
- symbols.queries.push({
455
- name: queryMatch[1],
456
- returnType: queryMatch[2],
457
- returnTypeReference: typeReferenceSymbol(queryMatch[2]),
458
- parameters,
459
- line: index
460
- });
461
- continue;
462
- }
463
- const screenMatch = trimmed.match(/^screen\s+(\w+)\s*$/);
464
- if (screenMatch) {
465
- symbols.screens.push({ name: screenMatch[1], line: index });
466
- continue;
467
- }
468
- const triggerMatch = trimmed.match(/^trigger\s+(\w+)\s*$/);
469
- if (triggerMatch && indent === 0) {
470
- symbols.triggers.push({ name: triggerMatch[1], line: index });
471
- }
304
+ const reference = fileReferenceOn(lines[index], index);
305
+ if (reference) references.push(reference);
472
306
  }
473
- return symbols;
474
- }
475
- function mergeSymbols(...documents) {
476
- return {
477
- imports: documents.flatMap((document) => document.imports),
478
- concepts: documents.flatMap((document) => document.concepts),
479
- types: documents.flatMap((document) => document.types),
480
- policies: documents.flatMap((document) => document.policies),
481
- events: documents.flatMap((document) => document.events),
482
- commands: documents.flatMap((document) => document.commands),
483
- queries: documents.flatMap((document) => document.queries),
484
- screens: documents.flatMap((document) => document.screens),
485
- triggers: documents.flatMap((document) => document.triggers)
486
- };
487
- }
488
- function knownEventNames(symbols) {
489
- return [
490
- ...symbols.events.map((event) => event.name),
491
- ...symbols.imports.map((imported) => imported.shortName)
492
- ];
493
- }
494
- var builtInTriggerNames = ["Startup", "Shutdown"];
495
- function knownTriggerNames(symbols) {
496
- return [
497
- ...knownEventNames(symbols),
498
- ...symbols.triggers.map((trigger) => trigger.name),
499
- ...builtInTriggerNames
500
- ];
501
- }
502
- function knownTypeNames(symbols, primitives) {
503
- return [
504
- ...primitives,
505
- ...symbols.concepts.map((concept) => concept.name),
506
- ...symbols.types.map((type) => type.name),
507
- ...symbols.imports.map((imported) => imported.shortName)
508
- ];
509
- }
510
-
511
- // event-context-catalog.ts
512
- var eventContextRootType = "EventContext";
513
- var eventContextTypes = {
514
- "EventContext": [
515
- { name: "eventType", type: "EventType", kind: "composite", description: "The type of the event - its identifier, generation and whether it is a tombstone." },
516
- { name: "eventSourceType", type: "EventSourceType", kind: "value", description: "The type of the event source the event was appended to." },
517
- { name: "eventSourceId", type: "EventSourceId", kind: "value", description: "The identifier of the event source the event was appended to - the value $eventSourceId resolves." },
518
- { name: "eventStreamType", type: "EventStreamType", kind: "value", description: "The type of the event stream the event belongs to." },
519
- { name: "eventStreamId", type: "EventStreamId", kind: "value", description: "The identifier of the event stream the event belongs to." },
520
- { name: "sequenceNumber", type: "EventSequenceNumber", kind: "value", description: "The position of the event in its event sequence." },
521
- { name: "occurred", type: "DateTimeOffset", kind: "value", description: "When the event occurred - the time it was appended unless one was given." },
522
- { name: "eventStore", type: "EventStoreName", kind: "value", description: "The name of the event store the event belongs to." },
523
- { name: "namespace", type: "EventStoreNamespaceName", kind: "value", description: "The namespace within the event store the event belongs to." },
524
- { name: "correlationId", type: "CorrelationId", kind: "value", description: "The correlation identifier the event was appended with." },
525
- { name: "causation", type: "IEnumerable<Causation>", kind: "collection", description: "The chain of causes that led to the event - a collection, not addressable below." },
526
- { name: "causedBy", type: "Identity", kind: "composite", description: "The identity that caused the event." },
527
- { name: "tags", type: "IEnumerable<Tag>", kind: "collection", description: "The tags the event was appended with - a collection, not addressable below." },
528
- { name: "hash", type: "EventHash", kind: "value", description: "The hash of the event content." },
529
- { name: "observationState", type: "EventObservationState", kind: "value", description: "Whether the observer sees the event for the first time or again on replay - differs between live processing and replay." },
530
- { name: "subject", type: "Subject", kind: "value", description: "The compliance subject the event is about - the event source identifier unless one was given." },
531
- { name: "subjectIsEventSourceId", type: "bool", kind: "value", description: "Whether the subject is the event source identifier." }
532
- ],
533
- "EventType": [
534
- { name: "id", type: "EventTypeId", kind: "value", description: "The identifier of the event type." },
535
- { name: "generation", type: "EventTypeGeneration", kind: "value", description: "The generation of the event type." },
536
- { name: "tombstone", type: "bool", kind: "value", description: "Whether the event is a tombstone event." }
537
- ],
538
- "EventSourceType": [
539
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
540
- ],
541
- "EventSourceId": [
542
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
543
- ],
544
- "EventStreamType": [
545
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
546
- ],
547
- "EventStreamId": [
548
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
549
- ],
550
- "EventSequenceNumber": [
551
- { name: "value", type: "ulong", kind: "value", description: "The underlying ulong value." }
552
- ],
553
- "DateTimeOffset": [
554
- { name: "Week", type: "int", kind: "function", description: "The ISO 8601 week of the year the value falls in." }
555
- ],
556
- "EventStoreName": [
557
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
558
- ],
559
- "EventStoreNamespaceName": [
560
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
561
- ],
562
- "CorrelationId": [
563
- { name: "value", type: "Guid", kind: "value", description: "The underlying Guid value." }
564
- ],
565
- "Identity": [
566
- { name: "subject", type: "string", kind: "value", description: "The subject identifier of the identity." },
567
- { name: "name", type: "string", kind: "value", description: "The display name of the identity." },
568
- { name: "userName", type: "string", kind: "value", description: "The user name of the identity." },
569
- { name: "onBehalfOf", type: "Identity", kind: "composite", description: "The identity this identity acted on behalf of, if any - an identity with the same members." }
570
- ],
571
- "EventHash": [
572
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
573
- ],
574
- "Subject": [
575
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
576
- ],
577
- "EventTypeId": [
578
- { name: "value", type: "string", kind: "value", description: "The underlying string value." }
579
- ],
580
- "EventTypeGeneration": [
581
- { name: "value", type: "uint", kind: "value", description: "The underlying uint value." }
582
- ]
583
- };
584
- var eventContextPaths = [
585
- { path: "eventType", name: "eventType", type: "EventType", kind: "composite", description: "The type of the event - its identifier, generation and whether it is a tombstone." },
586
- { path: "eventType.id", name: "id", type: "EventTypeId", kind: "value", description: "The identifier of the event type." },
587
- { path: "eventType.id.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
588
- { path: "eventType.generation", name: "generation", type: "EventTypeGeneration", kind: "value", description: "The generation of the event type." },
589
- { path: "eventType.generation.value", name: "value", type: "uint", kind: "value", description: "The underlying uint value." },
590
- { path: "eventType.tombstone", name: "tombstone", type: "bool", kind: "value", description: "Whether the event is a tombstone event." },
591
- { path: "eventSourceType", name: "eventSourceType", type: "EventSourceType", kind: "value", description: "The type of the event source the event was appended to." },
592
- { path: "eventSourceType.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
593
- { path: "eventSourceId", name: "eventSourceId", type: "EventSourceId", kind: "value", description: "The identifier of the event source the event was appended to - the value $eventSourceId resolves." },
594
- { path: "eventSourceId.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
595
- { path: "eventStreamType", name: "eventStreamType", type: "EventStreamType", kind: "value", description: "The type of the event stream the event belongs to." },
596
- { path: "eventStreamType.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
597
- { path: "eventStreamId", name: "eventStreamId", type: "EventStreamId", kind: "value", description: "The identifier of the event stream the event belongs to." },
598
- { path: "eventStreamId.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
599
- { path: "sequenceNumber", name: "sequenceNumber", type: "EventSequenceNumber", kind: "value", description: "The position of the event in its event sequence." },
600
- { path: "sequenceNumber.value", name: "value", type: "ulong", kind: "value", description: "The underlying ulong value." },
601
- { path: "occurred", name: "occurred", type: "DateTimeOffset", kind: "value", description: "When the event occurred - the time it was appended unless one was given." },
602
- { path: "occurred.Week", name: "Week", type: "int", kind: "function", description: "The ISO 8601 week of the year the value falls in." },
603
- { path: "eventStore", name: "eventStore", type: "EventStoreName", kind: "value", description: "The name of the event store the event belongs to." },
604
- { path: "eventStore.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
605
- { path: "namespace", name: "namespace", type: "EventStoreNamespaceName", kind: "value", description: "The namespace within the event store the event belongs to." },
606
- { path: "namespace.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
607
- { path: "correlationId", name: "correlationId", type: "CorrelationId", kind: "value", description: "The correlation identifier the event was appended with." },
608
- { path: "correlationId.value", name: "value", type: "Guid", kind: "value", description: "The underlying Guid value." },
609
- { path: "causation", name: "causation", type: "IEnumerable<Causation>", kind: "collection", description: "The chain of causes that led to the event - a collection, not addressable below." },
610
- { path: "causedBy", name: "causedBy", type: "Identity", kind: "composite", description: "The identity that caused the event." },
611
- { path: "causedBy.subject", name: "subject", type: "string", kind: "value", description: "The subject identifier of the identity." },
612
- { path: "causedBy.name", name: "name", type: "string", kind: "value", description: "The display name of the identity." },
613
- { path: "causedBy.userName", name: "userName", type: "string", kind: "value", description: "The user name of the identity." },
614
- { path: "causedBy.onBehalfOf", name: "onBehalfOf", type: "Identity", kind: "composite", description: "The identity this identity acted on behalf of, if any - an identity with the same members." },
615
- { path: "tags", name: "tags", type: "IEnumerable<Tag>", kind: "collection", description: "The tags the event was appended with - a collection, not addressable below." },
616
- { path: "hash", name: "hash", type: "EventHash", kind: "value", description: "The hash of the event content." },
617
- { path: "hash.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
618
- { path: "observationState", name: "observationState", type: "EventObservationState", kind: "value", description: "Whether the observer sees the event for the first time or again on replay - differs between live processing and replay." },
619
- { path: "subject", name: "subject", type: "Subject", kind: "value", description: "The compliance subject the event is about - the event source identifier unless one was given." },
620
- { path: "subject.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
621
- { path: "subjectIsEventSourceId", name: "subjectIsEventSourceId", type: "bool", kind: "value", description: "Whether the subject is the event source identifier." }
622
- ];
623
-
624
- // event-context.ts
625
- function namesEventContextMember(member, segment) {
626
- if (member.kind === "function") {
627
- return segment === member.name || segment === `${member.name}()`;
628
- }
629
- const declared = member.name[0].toUpperCase() + member.name.slice(1);
630
- return segment === declared || segment.length > 0 && segment[0].toUpperCase() + segment.slice(1) === declared;
631
- }
632
- var eventContextMembers = eventContextTypes[eventContextRootType];
633
- function eventContextMembersAfter(segments) {
634
- let members = eventContextMembers;
635
- for (const segment of segments) {
636
- const member = members.find((candidate) => namesEventContextMember(candidate, segment));
637
- if (!member || member.kind === "collection" || member.kind === "function") {
638
- return void 0;
639
- }
640
- members = eventContextTypes[member.type] ?? [];
641
- }
642
- return members;
643
- }
644
- function eventContextMemberAt(segments) {
645
- if (segments.length === 0) {
646
- return void 0;
647
- }
648
- const members = eventContextMembersAfter(segments.slice(0, -1));
649
- return members?.find((member) => namesEventContextMember(member, segments[segments.length - 1]));
650
- }
651
- function resolveEventContextPath(path) {
652
- let current;
653
- let expected = eventContextMembers;
654
- for (const segment of path.split(".")) {
655
- if (segment.length === 0) {
656
- return { status: "missing", member: current, expected };
657
- }
658
- if (current?.kind === "collection") {
659
- return { status: "belowCollection", member: current, segment, expected: [] };
660
- }
661
- const next = expected.find((member) => namesEventContextMember(member, segment));
662
- if (!next) {
663
- return { status: current ? "unknownSubPath" : "unknownMember", member: current, segment, expected };
664
- }
665
- current = next;
666
- expected = next.kind === "function" ? [] : eventContextTypes[next.type] ?? [];
667
- }
668
- return { status: "known", member: current, expected: [] };
669
- }
670
- function describeEventContext() {
671
- return [
672
- "**$eventContext**",
673
- "",
674
- "Metadata about the event being projected. Paths are checked against the event-context catalog; `causation` and `tags` are collections and cannot be addressed below.",
675
- "",
676
- "**Members:**",
677
- ...eventContextMembers.map((member) => `- \`${member.name}\` (${member.type}) - ${member.description}`)
678
- ].join("\n");
679
- }
680
- function describeEventContextMember(path, member) {
681
- const below = member.kind === "collection" || member.kind === "function" ? [] : eventContextTypes[member.type] ?? [];
682
- const lines = [`**$eventContext.${path}**: \`${member.type}\``, "", member.description];
683
- if (below.length > 0) {
684
- lines.push("", `**Members:** ${below.map((child) => `\`${child.name}\``).join(", ")}`);
685
- }
686
- return lines.join("\n");
687
- }
688
-
689
- // production-destinations.ts
690
- function productionDestinations(command) {
691
- const identifiers = command.properties.filter((property) => property.isIdentifier && !propertyTypeReference(property).isOptional && !propertyTypeReference(property).isCollection);
692
- const identifier = identifiers.length === 1 ? identifiers[0].name : void 0;
693
- const productions = command.produces ?? [];
694
- const mixed = productions.some((production) => production.target !== void 0 && production.target !== identifier) || productions.some((production) => production.inline && production.target === void 0) && productions.some((production) => !production.inline && production.target === void 0);
695
- return { identifier, mixed };
696
- }
697
- function destinationHints(lines) {
698
- const source = eventAnalysisSource(lines);
699
- return scanDocument(source).commands.flatMap((command) => {
700
- const { identifier, mixed } = productionDestinations(command);
701
- if (mixed || command.productionHeaders?.length !== command.produces?.length) return [];
702
- const hasPromotedDestination = command.produces?.some((sibling) => sibling.target !== void 0 || sibling.inline);
703
- return (command.produces ?? []).flatMap((production) => {
704
- if (production.target !== void 0 || production.inline && (identifier === void 0 || /\bgeneration\b/.test(source[production.line]))) return [];
705
- if (!production.inline && hasPromotedDestination) return [];
706
- return [{ line: production.line, column: source[production.line].length + 1, label: production.inline ? `for ${identifier}` : "for <new event source>" }];
707
- });
708
- });
709
- }
710
-
711
- // diagnostic-codes.ts
712
- var diagnosticCodes = {
713
- eventSourceIdInPayload: "PLAY0469",
714
- explicitProducesTargetsRequired: "PLAY0470",
715
- redundantEventId: "PLAY0471",
716
- invalidEventId: "PLAY0472",
717
- inlineEventCollision: "PLAY0473",
718
- inlineEventOutsideCommand: "PLAY0474",
719
- inlineEventGeneration: "PLAY0475",
720
- reservedProductionMetadata: "PLAY0476",
721
- invalidEventDocumentation: "PLAY0477",
722
- tabIndentation: "PLAY0006",
723
- unknownPrimitiveType: "PLAY0008",
724
- unknownSliceType: "PLAY0028",
725
- duplicateCommandIdentifier: "PLAY0036",
726
- unknownContextPath: "PLAY0153",
727
- unknownContextCausedByProperty: "PLAY0154",
728
- unknownContextIdentityProperty: "PLAY0155",
729
- unclosedCodeBlock: "PLAY0164",
730
- unknownType: "PLAY0165",
731
- unknownEvent: "PLAY0166",
732
- unknownPolicy: "PLAY0167",
733
- duplicateDeclaration: "PLAY0168",
734
- unknownEventContextMember: "PLAY0295",
735
- unknownEventContextPath: "PLAY0296",
736
- eventContextPathBelowCollection: "PLAY0297",
737
- missingEventContextPath: "PLAY0298",
738
- unresolvedDynamicKeySource: "PLAY0299",
739
- invalidFileImport: "PLAY0454",
740
- omittedProductionDestination: "PLAY0478",
741
- legacyOptionalSuffix: "PLAY0479",
742
- invalidOptionalModifierOrder: "PLAY0480",
743
- optionalReadsNotSupported: "PLAY0481"
744
- };
745
-
746
- // file-imports.ts
747
- var fileImportPattern = /^import(\s+)"([^"\\]+)"\s*(?:\/\/.*)?$/;
748
- var quotedImportPattern = /^import\s+"/;
749
- function isFileImportLine(line) {
750
- return quotedImportPattern.test(line.trim());
751
- }
752
- function fileImportOn(line, lineIndex) {
753
- const indent = indentOf(line);
754
- const match = line.slice(indent).match(fileImportPattern);
755
- if (!match) return void 0;
756
- const startColumn = indent + "import".length + match[1].length + 2;
757
- return { pattern: match[2], line: lineIndex, startColumn, endColumn: startColumn + match[2].length };
758
- }
759
- function fileImports(lines) {
760
- const fences = fenceMap(lines);
761
- const found = [];
762
- for (let index = 0; index < lines.length; index++) {
763
- if (fences[index]) continue;
764
- const fileImport = fileImportOn(lines[index], index);
765
- if (fileImport) found.push(fileImport);
766
- }
767
- return found;
768
- }
769
- var folderOf = (path) => path.split("/").slice(0, -1);
770
- function relativeTo(from, path) {
771
- const segments = path.split("/");
772
- let common = 0;
773
- while (common < from.length && common < segments.length - 1 && from[common] === segments[common]) common++;
774
- return [...from.slice(common).map(() => ".."), ...segments.slice(common)].join("/");
775
- }
776
- function importablePaths(documentPath, files) {
777
- const from = folderOf(documentPath);
778
- const paths = /* @__PURE__ */ new Set();
779
- for (const file of files.filter((candidate) => candidate !== documentPath && candidate.toLowerCase().endsWith(".play"))) {
780
- const relative = relativeTo(from, file);
781
- const folders = folderOf(relative);
782
- paths.add(relative);
783
- paths.add([...folders, "*.play"].join("/"));
784
- for (let depth = 0; depth <= folders.length; depth++) {
785
- paths.add([...folders.slice(0, depth), "**", "*.play"].join("/"));
786
- }
787
- }
788
- return [...paths].sort();
307
+ return references;
789
308
  }
790
309
 
791
310
  // ../../Compiler/dist/Diagnostics/DiagnosticCodes.js
@@ -1221,11 +740,11 @@ function keep(context, line, existing, owner, description) {
1221
740
  }
1222
741
 
1223
742
  // ../../Compiler/dist/Parsing/FileImportParser.js
1224
- var fileImportPattern2 = pattern('^import\\s+"([^"\\\\]+)"$');
743
+ var fileImportPattern = pattern('^import\\s+"([^"\\\\]+)"$');
1225
744
  var quotedPattern = pattern('^import\\s+"');
1226
745
  var isFileImport = (content) => quotedPattern.test(content);
1227
746
  function tryParseFileImport(line) {
1228
- const match = fileImportPattern2.exec(line.content);
747
+ const match = fileImportPattern.exec(line.content);
1229
748
  return match === null ? void 0 : { kind: "FileImportSyntax", pattern: match[1], location: locationOf(line) };
1230
749
  }
1231
750
  function parseFileImport(context, line, imports) {
@@ -1560,6 +1079,9 @@ function parseLiteral(text, location) {
1560
1079
  return void 0;
1561
1080
  }
1562
1081
 
1082
+ // ../../Compiler/dist/Text/ReservedWords.js
1083
+ var eventBodyReservedWords = ["tag"];
1084
+
1563
1085
  // ../../Compiler/dist/Parsing/EventMetadataParser.js
1564
1086
  var idPattern = pattern(`^id\\s+"(${stringBodyPattern})"$`);
1565
1087
  var EventMetadataParser = class {
@@ -1608,16 +1130,16 @@ var EventMetadataParser = class {
1608
1130
  };
1609
1131
 
1610
1132
  // ../../Compiler/dist/Parsing/FileReferences.js
1611
- var typeReferencePattern = pattern("^[A-Za-z_]\\w*(?:\\[\\])?(?:\\?|\\s+optional)?$");
1133
+ var typeReferencePattern2 = pattern("^[A-Za-z_]\\w*(?:\\[\\])?(?:\\?|\\s+optional)?$");
1612
1134
  var pathOf = (line) => firstWord2(line.content) === "file" ? line.content.substring("file".length).trim() : "";
1613
1135
  var isFileDirective = (line) => pathOf(line).length > 0;
1614
- var isFileDirectiveAmongProperties = (line) => isFileDirective(line) && !typeReferencePattern.test(pathOf(line));
1136
+ var isFileDirectiveAmongProperties = (line) => isFileDirective(line) && !typeReferencePattern2.test(pathOf(line));
1615
1137
 
1616
1138
  // ../../Compiler/dist/Parsing/PropertyLineParser.js
1617
- var propertyPattern2 = pattern("^(@?[a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+(identifier))?$");
1139
+ var propertyPattern = pattern("^(@?[a-z_]\\w*)\\s+([\\w.]+(?:\\[\\])?(?:\\?|\\s+optional)?)(?:\\s+(identifier))?$");
1618
1140
  var reversedModifiers = pattern("^@?[a-z_]\\w*\\s+[\\w.]+(?:\\[\\])?\\s+identifier\\s+optional(?:\\s*=.*)?$");
1619
1141
  function tryParseProperty(line) {
1620
- const match = propertyPattern2.exec(line.content);
1142
+ const match = propertyPattern.exec(line.content);
1621
1143
  if (match === null) {
1622
1144
  return void 0;
1623
1145
  }
@@ -1733,7 +1255,7 @@ function parseEvent(context, header10) {
1733
1255
  if (isFileDirectiveAmongProperties(line)) {
1734
1256
  continue;
1735
1257
  }
1736
- if (firstWord2(line.content) === "tag") {
1258
+ if (eventBodyReservedWords.includes(firstWord2(line.content))) {
1737
1259
  const tag = parseTag(context, line);
1738
1260
  if (tag !== void 0) {
1739
1261
  tags.push(tag);
@@ -3638,9 +3160,9 @@ var ParserContext = class {
3638
3160
  // ../../Compiler/dist/Parsing/ScreenplayParser.js
3639
3161
  var domainPattern = pattern("^domain\\s+([A-Za-z_]\\w*(?:\\.[A-Za-z_]\\w*)*)$");
3640
3162
  var importPattern = pattern("^import\\s+([\\w.]+)$");
3641
- var conceptPattern2 = pattern("^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@\\w+)*)$");
3163
+ var conceptPattern = pattern("^concept\\s+(\\w+)\\s*:\\s*(\\w+)((?:\\s+@\\w+)*)$");
3642
3164
  var enumValuePattern = pattern("^@?[a-z_]\\w*$");
3643
- var attributeReasonPattern2 = pattern(`^([a-z_]\\w*)\\s+reason\\s+"(${stringBodyPattern})"$`);
3165
+ var attributeReasonPattern = pattern(`^([a-z_]\\w*)\\s+reason\\s+"(${stringBodyPattern})"$`);
3644
3166
  var personaPattern = pattern("^persona\\s+([A-Za-z_]\\w*)$");
3645
3167
  var personaPolicyPattern = pattern("^policy\\s+([A-Za-z_]\\w*)$");
3646
3168
  var tabIndentPattern = /^[ ]*\t/;
@@ -3789,7 +3311,7 @@ function warnOnTabIndentation(context, lines) {
3789
3311
  }
3790
3312
  }
3791
3313
  function parseConcept(context, line) {
3792
- const match = conceptPattern2.exec(line.content);
3314
+ const match = conceptPattern.exec(line.content);
3793
3315
  if (match === null) {
3794
3316
  context.error(DiagnosticCodes.InvalidConceptDeclaration, `Invalid concept declaration '${line.content}' - expected 'concept <Name> : <Type>'`, locationOf(line));
3795
3317
  context.skipBlock(line.indent);
@@ -3808,7 +3330,7 @@ function parseConcept(context, line) {
3808
3330
  const values = [];
3809
3331
  for (let child = context.peekChild(line.indent); child !== void 0; child = context.peekChild(line.indent)) {
3810
3332
  context.reader.takeSignificant();
3811
- const reason = attributeReasonPattern2.exec(child.content);
3333
+ const reason = attributeReasonPattern.exec(child.content);
3812
3334
  if (isFileDirective(child)) {
3813
3335
  continue;
3814
3336
  } else if (firstWord2(child.content) === "validate") {
@@ -4094,258 +3616,789 @@ var ScreenplaySyntaxWalker = class {
4094
3616
  visitTriggerSource(syntax) {
4095
3617
  this.visitNode(syntax);
4096
3618
  }
4097
- visitScreen(syntax) {
4098
- this.visitNode(syntax);
4099
- syntax.directives.forEach((node) => this.visitScreenDirective(node));
3619
+ visitScreen(syntax) {
3620
+ this.visitNode(syntax);
3621
+ syntax.directives.forEach((node) => this.visitScreenDirective(node));
3622
+ }
3623
+ visitScreenDirective(syntax) {
3624
+ this.visitNode(syntax);
3625
+ switch (syntax.kind) {
3626
+ case "ScreenDataSyntax":
3627
+ this.visitTypeRef(syntax.type);
3628
+ break;
3629
+ case "ScreenActionSyntax":
3630
+ if (syntax.navigate !== null)
3631
+ this.visitScreenDirective(syntax.navigate);
3632
+ break;
3633
+ case "ScreenTemplateReferenceSyntax":
3634
+ syntax.slots.forEach((slot2) => {
3635
+ this.visitNode(slot2);
3636
+ slot2.directives.forEach((node) => this.visitScreenDirective(node));
3637
+ });
3638
+ break;
3639
+ case "ScreenSectionSyntax":
3640
+ syntax.directives.forEach((node) => this.visitScreenDirective(node));
3641
+ break;
3642
+ case "ScreenTableSyntax":
3643
+ syntax.columns.forEach((node) => this.visitNode(node));
3644
+ if (syntax.rowClick !== null)
3645
+ this.visitScreenDirective(syntax.rowClick);
3646
+ break;
3647
+ case "ScreenSummarySyntax":
3648
+ syntax.fields.forEach((node) => this.visitNode(node));
3649
+ break;
3650
+ case "ScreenCodeSyntax":
3651
+ this.visitNode(syntax.code);
3652
+ break;
3653
+ }
3654
+ }
3655
+ visitSpecification(syntax) {
3656
+ this.visitNode(syntax);
3657
+ if (syntax.givenClock !== null)
3658
+ this.visitSpecificationClock(syntax.givenClock);
3659
+ syntax.given.forEach((node) => this.visitSpecificationEvent(node));
3660
+ syntax.givenReadModels.forEach((node) => this.visitSpecificationReadModel(node));
3661
+ if (syntax.when !== null)
3662
+ this.visitSpecificationCommand(syntax.when);
3663
+ syntax.givenCaptures.forEach((node) => this.visitSpecificationCapture(node));
3664
+ if (syntax.whenAppended !== null)
3665
+ this.visitSpecificationEvent(syntax.whenAppended);
3666
+ if (syntax.whenClock !== null)
3667
+ this.visitSpecificationClock(syntax.whenClock);
3668
+ if (syntax.whenTrigger !== null)
3669
+ this.visitSpecificationTrigger(syntax.whenTrigger);
3670
+ if (syntax.whenCapture !== null)
3671
+ this.visitSpecificationCapture(syntax.whenCapture);
3672
+ if (syntax.whenQuery !== null)
3673
+ this.visitSpecificationWhenQuery(syntax.whenQuery);
3674
+ syntax.thenEvents.forEach((node) => this.visitSpecificationEvent(node));
3675
+ syntax.thenReadModels.forEach((node) => this.visitSpecificationReadModel(node));
3676
+ syntax.thenResults.forEach((node) => this.visitSpecificationQueryResult(node));
3677
+ if (syntax.thenNoResult !== null)
3678
+ this.visitNode(syntax.thenNoResult);
3679
+ syntax.thenErrors.forEach((node) => this.visitNode(node));
3680
+ }
3681
+ visitSpecificationClock(syntax) {
3682
+ this.visitNode(syntax);
3683
+ }
3684
+ visitSpecificationTrigger(syntax) {
3685
+ this.visitNode(syntax);
3686
+ syntax.values.forEach((node) => this.visitPropertyMapping(node));
3687
+ }
3688
+ visitSpecificationCapture(syntax) {
3689
+ this.visitNode(syntax);
3690
+ syntax.record.forEach((node) => this.visitPropertyMapping(node));
3691
+ }
3692
+ visitSpecificationWhenQuery(syntax) {
3693
+ this.visitNode(syntax);
3694
+ syntax.arguments.forEach((node) => this.visitPropertyMapping(node));
3695
+ }
3696
+ visitSpecificationQueryResult(syntax) {
3697
+ this.visitNode(syntax);
3698
+ syntax.properties.forEach((node) => this.visitPropertyMapping(node));
3699
+ }
3700
+ visitSpecificationEvent(syntax) {
3701
+ this.visitNode(syntax);
3702
+ syntax.values.forEach((node) => this.visitPropertyMapping(node));
3703
+ if (syntax.for !== null)
3704
+ this.visitExpression(syntax.for);
3705
+ }
3706
+ visitSpecificationCommand(syntax) {
3707
+ this.visitNode(syntax);
3708
+ syntax.values.forEach((node) => this.visitPropertyMapping(node));
3709
+ if (syntax.for !== null)
3710
+ this.visitExpression(syntax.for);
3711
+ }
3712
+ visitSpecificationReadModel(syntax) {
3713
+ this.visitNode(syntax);
3714
+ syntax.properties.forEach((node) => this.visitPropertyMapping(node));
3715
+ }
3716
+ visitPropertyMapping(syntax) {
3717
+ this.visitNode(syntax);
3718
+ this.visitExpression(syntax.source);
3719
+ }
3720
+ visitProperty(syntax) {
3721
+ this.visitNode(syntax);
3722
+ this.visitTypeRef(syntax.type);
3723
+ }
3724
+ visitTypeRef(syntax) {
3725
+ this.visitNode(syntax);
3726
+ }
3727
+ visitExpression(syntax) {
3728
+ this.visitNode(syntax);
3729
+ if (syntax.kind === "ListExpressionSyntax") {
3730
+ syntax.items.forEach((item) => this.visitExpression(item));
3731
+ } else if (syntax.kind === "ObjectExpressionSyntax") {
3732
+ syntax.members.forEach((member) => this.visitObjectMember(member));
3733
+ }
3734
+ }
3735
+ visitObjectMember(syntax) {
3736
+ this.visitNode(syntax);
3737
+ this.visitExpression(syntax.value);
3738
+ }
3739
+ };
3740
+
3741
+ // ../../Compiler/dist/Authoring/QuickFixes.js
3742
+ function isQuickFixDiagnostic(code) {
3743
+ return code === DiagnosticCodes.LegacyOptionalSuffix || code === DiagnosticCodes.RedundantEventId;
3744
+ }
3745
+ function legacyOptionalTypeLength(line, diagnostic) {
3746
+ if (diagnostic.code !== DiagnosticCodes.LegacyOptionalSuffix)
3747
+ return 0;
3748
+ return /^[\p{L}\p{Mn}\p{Nd}\p{Pc}.]+(?:\[\])?\?/u.exec(line.slice(diagnostic.location.column - 1))?.[0].length ?? 0;
3749
+ }
3750
+ function prepareQuickFixes(source, options = {}) {
3751
+ const original = parseForAuthoring(source, void 0, options.placement);
3752
+ if (!original.success)
3753
+ return () => [];
3754
+ const lines = splitLines(source);
3755
+ const eventsByLine = /* @__PURE__ */ new Map();
3756
+ const walker = new class extends ScreenplaySyntaxWalker {
3757
+ visitEvent(event2) {
3758
+ eventsByLine.set(event2.location.line, event2);
3759
+ }
3760
+ }();
3761
+ walker.visitApplication(original.value);
3762
+ const counts = /* @__PURE__ */ new Map();
3763
+ const byLine = /* @__PURE__ */ new Map();
3764
+ const events = /* @__PURE__ */ new Map();
3765
+ let event;
3766
+ for (const line of lines) {
3767
+ event = eventsByLine.get(line.number) ?? event;
3768
+ if (event !== void 0)
3769
+ events.set(line.number, event);
3770
+ }
3771
+ for (const diagnostic of original.diagnostics) {
3772
+ counts.set(diagnostic.code, (counts.get(diagnostic.code) ?? 0) + 1);
3773
+ const line = lines[diagnostic.location.line - 1];
3774
+ const length = legacyOptionalTypeLength(line.raw, diagnostic);
3775
+ if (length > 0) {
3776
+ byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: "Use 'optional' instead of '?'", scope: "occurrence", edits: [{ start: line.startOffset + diagnostic.location.column + length - 2, length: 1, text: " optional" }] } });
3777
+ } else if (diagnostic.code === DiagnosticCodes.RedundantEventId && commentStart(line.raw) < 0) {
3778
+ const declaration = events.get(line.number);
3779
+ if (declaration?.id !== declaration?.name || declaration === void 0)
3780
+ continue;
3781
+ byLine.set(line.number, {
3782
+ line: line.number,
3783
+ fix: { diagnosticCode: diagnostic.code, title: "Remove the redundant event id", scope: "occurrence", edits: [{ start: line.startOffset, length: (lines[line.number]?.startOffset ?? source.length) - line.startOffset, text: "" }] },
3784
+ change: { node: declaration, replacement: { ...declaration, id: null } }
3785
+ });
3786
+ }
3787
+ }
3788
+ const optional = [...byLine.values()].filter((candidate) => candidate.fix.diagnosticCode === DiagnosticCodes.LegacyOptionalSuffix);
3789
+ const syntax = verificationShape(original);
3790
+ const verified = /* @__PURE__ */ new Map();
3791
+ let rangeVerdicts;
3792
+ let documentChecked = false;
3793
+ let documentFix;
3794
+ const verify = (fix, change) => {
3795
+ const candidate = applyQuickFixEdits(source, fix.edits);
3796
+ if (candidate === void 0)
3797
+ return void 0;
3798
+ const parsed = parseForAuthoring(candidate, void 0, options.placement);
3799
+ if (!parsed.success || verificationShape(parsed) !== (change === void 0 ? syntax : verificationShape(original, [change])))
3800
+ return void 0;
3801
+ return parsed.diagnostics.filter((diagnostic) => diagnostic.code === fix.diagnosticCode).length === (counts.get(fix.diagnosticCode) ?? 0) - fix.edits.length ? fix : void 0;
3802
+ };
3803
+ return (line, diagnosticCode) => {
3804
+ const requests = typeof line === "number" || line === void 0 ? void 0 : line;
3805
+ const includeDocument = requests === void 0 ? diagnosticCode === void 0 || diagnosticCode === DiagnosticCodes.LegacyOptionalSuffix : requests.some((request) => request.diagnosticCode === DiagnosticCodes.LegacyOptionalSuffix);
3806
+ if (includeDocument && !documentChecked) {
3807
+ if (optional.length > 0)
3808
+ documentFix = verify({ diagnosticCode: DiagnosticCodes.LegacyOptionalSuffix, title: "Use 'optional' throughout this document", scope: "document", edits: optional.flatMap((candidate) => candidate.fix.edits) });
3809
+ documentChecked = true;
3810
+ }
3811
+ if (requests !== void 0) {
3812
+ if (rangeVerdicts === void 0) {
3813
+ rangeVerdicts = /* @__PURE__ */ new Map();
3814
+ const candidates = lines.flatMap((line2) => byLine.has(line2.number) ? [byLine.get(line2.number)] : []);
3815
+ const edits = candidates.flatMap((candidate) => candidate.fix.edits);
3816
+ const candidateSource = applyQuickFixEdits(source, edits);
3817
+ if (edits.length > 0 && candidateSource !== void 0) {
3818
+ const parsed = parseForAuthoring(candidateSource, void 0, options.placement);
3819
+ const changes = candidates.flatMap((candidate) => candidate.change === void 0 ? [] : [candidate.change]);
3820
+ if (parsed.success && verificationShape(parsed) === verificationShape(original, changes)) {
3821
+ const remaining = /* @__PURE__ */ new Map();
3822
+ const removed = /* @__PURE__ */ new Map();
3823
+ for (const diagnostic of parsed.diagnostics)
3824
+ remaining.set(diagnostic.code, (remaining.get(diagnostic.code) ?? 0) + 1);
3825
+ for (const candidate of candidates)
3826
+ removed.set(candidate.fix.diagnosticCode, (removed.get(candidate.fix.diagnosticCode) ?? 0) + candidate.fix.edits.length);
3827
+ if ([...removed].every(([code, count]) => (remaining.get(code) ?? 0) === (counts.get(code) ?? 0) - count)) {
3828
+ for (const candidate of candidates)
3829
+ rangeVerdicts.set(candidate.line, candidate.fix);
3830
+ }
3831
+ }
3832
+ }
3833
+ }
3834
+ const selected2 = /* @__PURE__ */ new Map();
3835
+ for (const request of requests) {
3836
+ const fix = rangeVerdicts.get(request.line);
3837
+ if (fix?.diagnosticCode === request.diagnosticCode)
3838
+ selected2.set(request.line, fix);
3839
+ }
3840
+ return [...selected2.values(), ...includeDocument && documentFix !== void 0 ? [documentFix] : []];
3841
+ }
3842
+ const occurrenceLine = typeof line === "number" ? line : void 0;
3843
+ const selected = occurrenceLine === void 0 ? void 0 : byLine.get(occurrenceLine);
3844
+ let occurrenceFix;
3845
+ if (selected !== void 0 && occurrenceLine !== void 0 && (diagnosticCode === void 0 || selected.fix.diagnosticCode === diagnosticCode)) {
3846
+ if (!verified.has(occurrenceLine)) {
3847
+ if (verified.size === 32)
3848
+ verified.delete(verified.keys().next().value);
3849
+ verified.set(occurrenceLine, verify(selected.fix, selected.change));
3850
+ }
3851
+ occurrenceFix = verified.get(occurrenceLine);
3852
+ }
3853
+ return [occurrenceFix, includeDocument ? documentFix : void 0].filter((fix) => fix !== void 0);
3854
+ };
3855
+ }
3856
+ function verificationShape(parsed, changes = []) {
3857
+ const replacements = new Map(changes.map((change) => [change.node, change.replacement]));
3858
+ return JSON.stringify([parsed.value, parsed.triggerData], (key, value) => key === "location" ? void 0 : replacements.get(value) ?? value);
3859
+ }
3860
+ function applyQuickFixEdits(source, edits) {
3861
+ const parts = [];
3862
+ let end = 0;
3863
+ for (const edit of edits) {
3864
+ if (edit.start < end || edit.start < 0 || edit.length < 0 || edit.start + edit.length > source.length)
3865
+ return void 0;
3866
+ parts.push(source.slice(end, edit.start), edit.text);
3867
+ end = edit.start + edit.length;
3868
+ }
3869
+ parts.push(source.slice(end));
3870
+ return parts.join("");
3871
+ }
3872
+
3873
+ // event-analysis-source.ts
3874
+ function eventAnalysisSource(lines) {
3875
+ let fenced = false;
3876
+ return lines.map((line) => {
3877
+ if (fenced) {
3878
+ if (line.trim() === "```") fenced = false;
3879
+ return line;
3880
+ }
3881
+ const text = withoutComment(line);
3882
+ if (/^\s*```(?:[a-z]+)?\s*$/.test(text)) fenced = true;
3883
+ return text.trimEnd();
3884
+ });
3885
+ }
3886
+
3887
+ // symbols.ts
3888
+ var conceptPattern2 = /^concept\s+(\w+)\s*:\s*(\w+)((?:\s+@\w+)*)\s*$/;
3889
+ var propertyPattern2 = /^\s*(@?[a-z_]\w*)\s+([\w.]+(?:\[\])?(?:\?|\s+optional)?)(\s+identifier)?\s*$/;
3890
+ var attributeReasonPattern2 = /^([a-z_]\w*)\s+reason\s+"((?:[^"\\]|\\.)*)"\s*$/;
3891
+ var readPattern = /^\s*reads\s+([A-Z]\w*)(?:\s+as\s+([a-z_]\w*))?(?:\s+by\s+([a-z_]\w*))?\s*$/;
3892
+ var commandReserved = ["authorize", "produces", "reads"];
3893
+ var authorizationContinuation = /^(?:(?:or|and)\s+)?[A-Za-z_(][\p{L}\p{Mn}\p{Nd}\p{Pc}\s()]*$/u;
3894
+ var eventReserved = eventBodyReservedWords;
3895
+ var inlineEventReserved = ["tag", "for", "generation", "origin", "namespace", "sequence", "correlation", "causation", "causedBy", "occurred"];
3896
+ var queryParameterPattern = /^\s*(?:by|filter)\s+([a-z_]\w*)\s+([\w.]+(?:\[\])?(?:\?|\s+optional)?)(?:\s+from\s+.+)?\s*$/;
3897
+ function propertyTypeReference(property) {
3898
+ return property.typeReference ?? typeReferenceSymbol(property.type);
3899
+ }
3900
+ function propertiesIn(lines, body, reserved3) {
3901
+ return body.map((index) => ({ index, match: lines[index].match(propertyPattern2) })).filter((entry) => entry.match !== null).filter(({ match }) => match[1].startsWith("@") || match[1] === "as" || !reserved3.includes(match[1])).map(({ index, match }) => ({
3902
+ name: match[1].replace(/^@/, ""),
3903
+ type: match[2],
3904
+ typeReference: typeReferenceSymbol(match[2]),
3905
+ isIdentifier: match[3] !== void 0,
3906
+ line: index
3907
+ }));
3908
+ }
3909
+ function collectBody(lines, fences, start, indent) {
3910
+ const body = [];
3911
+ for (let index = start + 1; index < lines.length; index++) {
3912
+ if (fences[index]) {
3913
+ continue;
3914
+ }
3915
+ const line = lines[index];
3916
+ if (line.trim().length === 0) continue;
3917
+ if (indentOf(line) <= indent) break;
3918
+ body.push(index);
4100
3919
  }
4101
- visitScreenDirective(syntax) {
4102
- this.visitNode(syntax);
4103
- switch (syntax.kind) {
4104
- case "ScreenDataSyntax":
4105
- this.visitTypeRef(syntax.type);
4106
- break;
4107
- case "ScreenActionSyntax":
4108
- if (syntax.navigate !== null)
4109
- this.visitScreenDirective(syntax.navigate);
4110
- break;
4111
- case "ScreenTemplateReferenceSyntax":
4112
- syntax.slots.forEach((slot2) => {
4113
- this.visitNode(slot2);
4114
- slot2.directives.forEach((node) => this.visitScreenDirective(node));
4115
- });
4116
- break;
4117
- case "ScreenSectionSyntax":
4118
- syntax.directives.forEach((node) => this.visitScreenDirective(node));
4119
- break;
4120
- case "ScreenTableSyntax":
4121
- syntax.columns.forEach((node) => this.visitNode(node));
4122
- if (syntax.rowClick !== null)
4123
- this.visitScreenDirective(syntax.rowClick);
4124
- break;
4125
- case "ScreenSummarySyntax":
4126
- syntax.fields.forEach((node) => this.visitNode(node));
4127
- break;
4128
- case "ScreenCodeSyntax":
4129
- this.visitNode(syntax.code);
4130
- break;
3920
+ return body;
3921
+ }
3922
+ function directBody(lines, fences, start, indent) {
3923
+ const body = collectBody(lines, fences, start, indent).filter((index) => !fences[index] && !/^\s*(?:\/\/|#)/.test(lines[index]));
3924
+ if (!/^\s*command\b/.test(lines[start])) return body;
3925
+ let blockIndent;
3926
+ let authorization = false;
3927
+ return body.filter((index) => {
3928
+ const childIndent = indentOf(lines[index]);
3929
+ const text = lines[index].trim();
3930
+ if (blockIndent !== void 0 && childIndent > blockIndent && (!authorization || authorizationContinuation.test(text))) return false;
3931
+ const property = text !== "validate csharp" && propertiesIn(lines, [index], commandReserved).length > 0;
3932
+ const leaf = property || /^description(?:\s|$)/.test(text);
3933
+ blockIndent = leaf ? void 0 : childIndent;
3934
+ authorization = /^authorize(?:\s|$)/.test(text);
3935
+ return true;
3936
+ });
3937
+ }
3938
+ function scanDocument(lines) {
3939
+ const symbols = {
3940
+ imports: [],
3941
+ concepts: [],
3942
+ types: [],
3943
+ policies: [],
3944
+ events: [],
3945
+ commands: [],
3946
+ queries: [],
3947
+ screens: [],
3948
+ triggers: []
3949
+ };
3950
+ lines = eventAnalysisSource(lines);
3951
+ const fences = fenceMap(lines);
3952
+ const eventLines = lines;
3953
+ const eventFences = fences;
3954
+ const eventPropertyLines = lines.map((line) => line.replace(/\s*=(?!=|>).*/, ""));
3955
+ for (let index = 0; index < lines.length; index++) {
3956
+ if (fences[index]) continue;
3957
+ const line = lines[index];
3958
+ const trimmed = line.trim();
3959
+ const indent = indentOf(line);
3960
+ const importMatch = eventLines[index].trim().match(/^import\s+([\w.]+)\s*$/);
3961
+ if (importMatch && indent === 0) {
3962
+ const qualifiedName = importMatch[1];
3963
+ const shortName = qualifiedName.split(".").pop() ?? qualifiedName;
3964
+ symbols.imports.push({ qualifiedName, shortName, line: index });
3965
+ continue;
3966
+ }
3967
+ const conceptMatch = trimmed.match(conceptPattern2);
3968
+ if (conceptMatch) {
3969
+ const body = collectBody(lines, fences, index, indent).map((i) => lines[i].trim());
3970
+ const attributeReasons = {};
3971
+ for (const line2 of body) {
3972
+ const reason = line2.match(attributeReasonPattern2);
3973
+ if (reason && attributeReasons[reason[1]] === void 0) {
3974
+ attributeReasons[reason[1]] = reason[2];
3975
+ }
3976
+ }
3977
+ const enumValues = conceptMatch[2] === "Enum" ? body.filter((line2) => !attributeReasonPattern2.test(line2)) : [];
3978
+ symbols.concepts.push({
3979
+ name: conceptMatch[1],
3980
+ primitive: conceptMatch[2],
3981
+ attributes: conceptMatch[3].trim().split(/\s+/).filter(Boolean),
3982
+ attributeReasons,
3983
+ enumValues,
3984
+ line: index
3985
+ });
3986
+ continue;
3987
+ }
3988
+ const typeMatch = trimmed.match(/^type\s+(\w+)\s*$/);
3989
+ if (typeMatch) {
3990
+ symbols.types.push({
3991
+ name: typeMatch[1],
3992
+ properties: propertiesIn(lines, collectBody(lines, fences, index, indent), clauseKeywords),
3993
+ line: index
3994
+ });
3995
+ continue;
3996
+ }
3997
+ const policyMatch = trimmed.match(/^policy\s+(\w+)\s*$/);
3998
+ if (policyMatch) {
3999
+ const requires = collectBody(lines, fences, index, indent).filter((i) => !fences[i]).map((i) => lines[i].trim());
4000
+ symbols.policies.push({ name: policyMatch[1], requires, line: index });
4001
+ continue;
4002
+ }
4003
+ const eventMatch = eventLines[index].trim().match(/^(?:produces\s+)?event\s+(\w+)(?:\s+generation\s+(\d+))?\s*$/);
4004
+ if (eventMatch) {
4005
+ const inline = trimmed.startsWith("produces ");
4006
+ const body = directBody(eventLines, eventFences, index, indent);
4007
+ const propertyBody = inline ? body : body.filter((line2) => fileReferenceOn(eventLines[line2], line2) === void 0);
4008
+ symbols.events.push({
4009
+ name: eventMatch[1],
4010
+ ...eventMatch[2] ? { generation: Number(eventMatch[2]) } : {},
4011
+ inline,
4012
+ properties: propertiesIn(
4013
+ inline ? eventPropertyLines : eventLines,
4014
+ propertyBody,
4015
+ inline ? inlineEventReserved : eventReserved
4016
+ ),
4017
+ line: index
4018
+ });
4019
+ continue;
4020
+ }
4021
+ const commandMatch = eventLines[index].trim().match(/^command\s+(\w+)\s*$/);
4022
+ if (commandMatch) {
4023
+ const body = directBody(lines, fences, index, indent);
4024
+ const productionHeaders = body.filter((line2) => /^\s*produces\b/.test(lines[line2]));
4025
+ symbols.commands.push({
4026
+ name: commandMatch[1],
4027
+ properties: propertiesIn(lines, body.filter((line2) => lines[line2].trim() !== "validate csharp"), commandReserved),
4028
+ productionHeaders,
4029
+ produces: productionHeaders.flatMap((line2) => {
4030
+ const header10 = eventLines[line2].trim();
4031
+ const inline = /^produces\s+event\b/.test(header10);
4032
+ const conditional2 = /^produces\s+when\b/.test(header10);
4033
+ const eventLine = conditional2 ? directBody(eventLines, eventFences, line2, indentOf(eventLines[line2]))[0] : line2;
4034
+ if (eventLine === void 0) return [];
4035
+ const name = conditional2 ? eventLines[eventLine].trim() : header10.match(inline ? /^produces\s+event\s+([A-Za-z_]\w*)(?:\s+generation\s+\d+)?\s*$/ : /^produces\s+([A-Z]\w*)\s*$/)?.[1];
4036
+ if (name === void 0 || !/^[A-Za-z_]\w*$/.test(name)) return [];
4037
+ const children = directBody(eventLines, eventFences, eventLine, indentOf(eventLines[eventLine]));
4038
+ const targets = children.map((index2) => eventLines[index2].trim().match(/^for(?:\s+(.*))?$/)).filter((match) => match !== null);
4039
+ const target = targets.length === 0 ? void 0 : targets.length === 1 ? targets[0][1] ?? "" : "";
4040
+ const mappings = children.flatMap((index2) => {
4041
+ const match = eventLines[index2].trim().match(inline ? /^(@?[a-z_]\w*)\s+[\w.]+(?:\[\])?(?:\?|\s+optional)?\s*=(?!=|>)\s*(.+)$/ : /^(@?[\w.]+)\s*=(?!=|>)\s*(.+)$/);
4042
+ return match === null ? [] : [{ name: match[1].replace(/^@/, ""), source: match[2], line: index2 }];
4043
+ });
4044
+ return [{ name, inline, conditional: conditional2, line: line2, target, mappings }];
4045
+ }),
4046
+ reads: body.filter((line2) => !fences[line2]).map((line2) => ({ line: line2, match: lines[line2].match(readPattern) })).filter((entry) => entry.match !== null).map(({ line: line2, match }) => ({
4047
+ view: match[1],
4048
+ ...match[2] ? { alias: match[2] } : {},
4049
+ ...match[3] ? { by: match[3] } : {},
4050
+ line: line2
4051
+ })),
4052
+ line: index
4053
+ });
4054
+ continue;
4055
+ }
4056
+ const queryMatch = trimmed.match(/^query\s+(\w+)\s*=>\s*(?:observable\s+)?([\w.]+(?:\[\])?(?:\?|\s+optional)?)\s*$/);
4057
+ if (queryMatch) {
4058
+ const parameters = collectBody(lines, fences, index, indent).map((i) => ({ index: i, match: lines[i].match(queryParameterPattern) })).filter(
4059
+ (entry) => entry.match !== null
4060
+ ).map(({ index: line2, match }) => ({
4061
+ name: match[1],
4062
+ type: match[2],
4063
+ typeReference: typeReferenceSymbol(match[2]),
4064
+ isIdentifier: false,
4065
+ line: line2
4066
+ }));
4067
+ symbols.queries.push({
4068
+ name: queryMatch[1],
4069
+ returnType: queryMatch[2],
4070
+ returnTypeReference: typeReferenceSymbol(queryMatch[2]),
4071
+ parameters,
4072
+ line: index
4073
+ });
4074
+ continue;
4075
+ }
4076
+ const screenMatch = trimmed.match(/^screen\s+(\w+)\s*$/);
4077
+ if (screenMatch) {
4078
+ symbols.screens.push({ name: screenMatch[1], line: index });
4079
+ continue;
4080
+ }
4081
+ const triggerMatch = trimmed.match(/^trigger\s+(\w+)\s*$/);
4082
+ if (triggerMatch && indent === 0) {
4083
+ symbols.triggers.push({ name: triggerMatch[1], line: index });
4131
4084
  }
4132
4085
  }
4133
- visitSpecification(syntax) {
4134
- this.visitNode(syntax);
4135
- if (syntax.givenClock !== null)
4136
- this.visitSpecificationClock(syntax.givenClock);
4137
- syntax.given.forEach((node) => this.visitSpecificationEvent(node));
4138
- syntax.givenReadModels.forEach((node) => this.visitSpecificationReadModel(node));
4139
- if (syntax.when !== null)
4140
- this.visitSpecificationCommand(syntax.when);
4141
- syntax.givenCaptures.forEach((node) => this.visitSpecificationCapture(node));
4142
- if (syntax.whenAppended !== null)
4143
- this.visitSpecificationEvent(syntax.whenAppended);
4144
- if (syntax.whenClock !== null)
4145
- this.visitSpecificationClock(syntax.whenClock);
4146
- if (syntax.whenTrigger !== null)
4147
- this.visitSpecificationTrigger(syntax.whenTrigger);
4148
- if (syntax.whenCapture !== null)
4149
- this.visitSpecificationCapture(syntax.whenCapture);
4150
- if (syntax.whenQuery !== null)
4151
- this.visitSpecificationWhenQuery(syntax.whenQuery);
4152
- syntax.thenEvents.forEach((node) => this.visitSpecificationEvent(node));
4153
- syntax.thenReadModels.forEach((node) => this.visitSpecificationReadModel(node));
4154
- syntax.thenResults.forEach((node) => this.visitSpecificationQueryResult(node));
4155
- if (syntax.thenNoResult !== null)
4156
- this.visitNode(syntax.thenNoResult);
4157
- syntax.thenErrors.forEach((node) => this.visitNode(node));
4158
- }
4159
- visitSpecificationClock(syntax) {
4160
- this.visitNode(syntax);
4161
- }
4162
- visitSpecificationTrigger(syntax) {
4163
- this.visitNode(syntax);
4164
- syntax.values.forEach((node) => this.visitPropertyMapping(node));
4165
- }
4166
- visitSpecificationCapture(syntax) {
4167
- this.visitNode(syntax);
4168
- syntax.record.forEach((node) => this.visitPropertyMapping(node));
4169
- }
4170
- visitSpecificationWhenQuery(syntax) {
4171
- this.visitNode(syntax);
4172
- syntax.arguments.forEach((node) => this.visitPropertyMapping(node));
4173
- }
4174
- visitSpecificationQueryResult(syntax) {
4175
- this.visitNode(syntax);
4176
- syntax.properties.forEach((node) => this.visitPropertyMapping(node));
4177
- }
4178
- visitSpecificationEvent(syntax) {
4179
- this.visitNode(syntax);
4180
- syntax.values.forEach((node) => this.visitPropertyMapping(node));
4181
- if (syntax.for !== null)
4182
- this.visitExpression(syntax.for);
4183
- }
4184
- visitSpecificationCommand(syntax) {
4185
- this.visitNode(syntax);
4186
- syntax.values.forEach((node) => this.visitPropertyMapping(node));
4187
- if (syntax.for !== null)
4188
- this.visitExpression(syntax.for);
4189
- }
4190
- visitSpecificationReadModel(syntax) {
4191
- this.visitNode(syntax);
4192
- syntax.properties.forEach((node) => this.visitPropertyMapping(node));
4193
- }
4194
- visitPropertyMapping(syntax) {
4195
- this.visitNode(syntax);
4196
- this.visitExpression(syntax.source);
4086
+ return symbols;
4087
+ }
4088
+ function mergeSymbols(...documents) {
4089
+ return {
4090
+ imports: documents.flatMap((document) => document.imports),
4091
+ concepts: documents.flatMap((document) => document.concepts),
4092
+ types: documents.flatMap((document) => document.types),
4093
+ policies: documents.flatMap((document) => document.policies),
4094
+ events: documents.flatMap((document) => document.events),
4095
+ commands: documents.flatMap((document) => document.commands),
4096
+ queries: documents.flatMap((document) => document.queries),
4097
+ screens: documents.flatMap((document) => document.screens),
4098
+ triggers: documents.flatMap((document) => document.triggers)
4099
+ };
4100
+ }
4101
+ function knownEventNames(symbols) {
4102
+ return [
4103
+ ...symbols.events.map((event) => event.name),
4104
+ ...symbols.imports.map((imported) => imported.shortName)
4105
+ ];
4106
+ }
4107
+ var builtInTriggerNames = ["Startup", "Shutdown"];
4108
+ function knownTriggerNames(symbols) {
4109
+ return [
4110
+ ...knownEventNames(symbols),
4111
+ ...symbols.triggers.map((trigger) => trigger.name),
4112
+ ...builtInTriggerNames
4113
+ ];
4114
+ }
4115
+ function knownTypeNames(symbols, primitives) {
4116
+ return [
4117
+ ...primitives,
4118
+ ...symbols.concepts.map((concept) => concept.name),
4119
+ ...symbols.types.map((type) => type.name),
4120
+ ...symbols.imports.map((imported) => imported.shortName)
4121
+ ];
4122
+ }
4123
+
4124
+ // event-context-catalog.ts
4125
+ var eventContextRootType = "EventContext";
4126
+ var eventContextTypes = {
4127
+ "EventContext": [
4128
+ { name: "eventType", type: "EventType", kind: "composite", description: "The type of the event - its identifier, generation and whether it is a tombstone." },
4129
+ { name: "eventSourceType", type: "EventSourceType", kind: "value", description: "The type of the event source the event was appended to." },
4130
+ { name: "eventSourceId", type: "EventSourceId", kind: "value", description: "The identifier of the event source the event was appended to - the value $eventSourceId resolves." },
4131
+ { name: "eventStreamType", type: "EventStreamType", kind: "value", description: "The type of the event stream the event belongs to." },
4132
+ { name: "eventStreamId", type: "EventStreamId", kind: "value", description: "The identifier of the event stream the event belongs to." },
4133
+ { name: "sequenceNumber", type: "EventSequenceNumber", kind: "value", description: "The position of the event in its event sequence." },
4134
+ { name: "occurred", type: "DateTimeOffset", kind: "value", description: "When the event occurred - the time it was appended unless one was given." },
4135
+ { name: "eventStore", type: "EventStoreName", kind: "value", description: "The name of the event store the event belongs to." },
4136
+ { name: "namespace", type: "EventStoreNamespaceName", kind: "value", description: "The namespace within the event store the event belongs to." },
4137
+ { name: "correlationId", type: "CorrelationId", kind: "value", description: "The correlation identifier the event was appended with." },
4138
+ { name: "causation", type: "IEnumerable<Causation>", kind: "collection", description: "The chain of causes that led to the event - a collection, not addressable below." },
4139
+ { name: "causedBy", type: "Identity", kind: "composite", description: "The identity that caused the event." },
4140
+ { name: "tags", type: "IEnumerable<Tag>", kind: "collection", description: "The tags the event was appended with - a collection, not addressable below." },
4141
+ { name: "hash", type: "EventHash", kind: "value", description: "The hash of the event content." },
4142
+ { name: "observationState", type: "EventObservationState", kind: "value", description: "Whether the observer sees the event for the first time or again on replay - differs between live processing and replay." },
4143
+ { name: "subject", type: "Subject", kind: "value", description: "The compliance subject the event is about - the event source identifier unless one was given." },
4144
+ { name: "subjectIsEventSourceId", type: "bool", kind: "value", description: "Whether the subject is the event source identifier." }
4145
+ ],
4146
+ "EventType": [
4147
+ { name: "id", type: "EventTypeId", kind: "value", description: "The identifier of the event type." },
4148
+ { name: "generation", type: "EventTypeGeneration", kind: "value", description: "The generation of the event type." },
4149
+ { name: "tombstone", type: "bool", kind: "value", description: "Whether the event is a tombstone event." }
4150
+ ],
4151
+ "EventSourceType": [
4152
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4153
+ ],
4154
+ "EventSourceId": [
4155
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4156
+ ],
4157
+ "EventStreamType": [
4158
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4159
+ ],
4160
+ "EventStreamId": [
4161
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4162
+ ],
4163
+ "EventSequenceNumber": [
4164
+ { name: "value", type: "ulong", kind: "value", description: "The underlying ulong value." }
4165
+ ],
4166
+ "DateTimeOffset": [
4167
+ { name: "Week", type: "int", kind: "function", description: "The ISO 8601 week of the year the value falls in." }
4168
+ ],
4169
+ "EventStoreName": [
4170
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4171
+ ],
4172
+ "EventStoreNamespaceName": [
4173
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4174
+ ],
4175
+ "CorrelationId": [
4176
+ { name: "value", type: "Guid", kind: "value", description: "The underlying Guid value." }
4177
+ ],
4178
+ "Identity": [
4179
+ { name: "subject", type: "string", kind: "value", description: "The subject identifier of the identity." },
4180
+ { name: "name", type: "string", kind: "value", description: "The display name of the identity." },
4181
+ { name: "userName", type: "string", kind: "value", description: "The user name of the identity." },
4182
+ { name: "onBehalfOf", type: "Identity", kind: "composite", description: "The identity this identity acted on behalf of, if any - an identity with the same members." }
4183
+ ],
4184
+ "EventHash": [
4185
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4186
+ ],
4187
+ "Subject": [
4188
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4189
+ ],
4190
+ "EventTypeId": [
4191
+ { name: "value", type: "string", kind: "value", description: "The underlying string value." }
4192
+ ],
4193
+ "EventTypeGeneration": [
4194
+ { name: "value", type: "uint", kind: "value", description: "The underlying uint value." }
4195
+ ]
4196
+ };
4197
+ var eventContextPaths = [
4198
+ { path: "eventType", name: "eventType", type: "EventType", kind: "composite", description: "The type of the event - its identifier, generation and whether it is a tombstone." },
4199
+ { path: "eventType.id", name: "id", type: "EventTypeId", kind: "value", description: "The identifier of the event type." },
4200
+ { path: "eventType.id.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4201
+ { path: "eventType.generation", name: "generation", type: "EventTypeGeneration", kind: "value", description: "The generation of the event type." },
4202
+ { path: "eventType.generation.value", name: "value", type: "uint", kind: "value", description: "The underlying uint value." },
4203
+ { path: "eventType.tombstone", name: "tombstone", type: "bool", kind: "value", description: "Whether the event is a tombstone event." },
4204
+ { path: "eventSourceType", name: "eventSourceType", type: "EventSourceType", kind: "value", description: "The type of the event source the event was appended to." },
4205
+ { path: "eventSourceType.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4206
+ { path: "eventSourceId", name: "eventSourceId", type: "EventSourceId", kind: "value", description: "The identifier of the event source the event was appended to - the value $eventSourceId resolves." },
4207
+ { path: "eventSourceId.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4208
+ { path: "eventStreamType", name: "eventStreamType", type: "EventStreamType", kind: "value", description: "The type of the event stream the event belongs to." },
4209
+ { path: "eventStreamType.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4210
+ { path: "eventStreamId", name: "eventStreamId", type: "EventStreamId", kind: "value", description: "The identifier of the event stream the event belongs to." },
4211
+ { path: "eventStreamId.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4212
+ { path: "sequenceNumber", name: "sequenceNumber", type: "EventSequenceNumber", kind: "value", description: "The position of the event in its event sequence." },
4213
+ { path: "sequenceNumber.value", name: "value", type: "ulong", kind: "value", description: "The underlying ulong value." },
4214
+ { path: "occurred", name: "occurred", type: "DateTimeOffset", kind: "value", description: "When the event occurred - the time it was appended unless one was given." },
4215
+ { path: "occurred.Week", name: "Week", type: "int", kind: "function", description: "The ISO 8601 week of the year the value falls in." },
4216
+ { path: "eventStore", name: "eventStore", type: "EventStoreName", kind: "value", description: "The name of the event store the event belongs to." },
4217
+ { path: "eventStore.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4218
+ { path: "namespace", name: "namespace", type: "EventStoreNamespaceName", kind: "value", description: "The namespace within the event store the event belongs to." },
4219
+ { path: "namespace.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4220
+ { path: "correlationId", name: "correlationId", type: "CorrelationId", kind: "value", description: "The correlation identifier the event was appended with." },
4221
+ { path: "correlationId.value", name: "value", type: "Guid", kind: "value", description: "The underlying Guid value." },
4222
+ { path: "causation", name: "causation", type: "IEnumerable<Causation>", kind: "collection", description: "The chain of causes that led to the event - a collection, not addressable below." },
4223
+ { path: "causedBy", name: "causedBy", type: "Identity", kind: "composite", description: "The identity that caused the event." },
4224
+ { path: "causedBy.subject", name: "subject", type: "string", kind: "value", description: "The subject identifier of the identity." },
4225
+ { path: "causedBy.name", name: "name", type: "string", kind: "value", description: "The display name of the identity." },
4226
+ { path: "causedBy.userName", name: "userName", type: "string", kind: "value", description: "The user name of the identity." },
4227
+ { path: "causedBy.onBehalfOf", name: "onBehalfOf", type: "Identity", kind: "composite", description: "The identity this identity acted on behalf of, if any - an identity with the same members." },
4228
+ { path: "tags", name: "tags", type: "IEnumerable<Tag>", kind: "collection", description: "The tags the event was appended with - a collection, not addressable below." },
4229
+ { path: "hash", name: "hash", type: "EventHash", kind: "value", description: "The hash of the event content." },
4230
+ { path: "hash.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4231
+ { path: "observationState", name: "observationState", type: "EventObservationState", kind: "value", description: "Whether the observer sees the event for the first time or again on replay - differs between live processing and replay." },
4232
+ { path: "subject", name: "subject", type: "Subject", kind: "value", description: "The compliance subject the event is about - the event source identifier unless one was given." },
4233
+ { path: "subject.value", name: "value", type: "string", kind: "value", description: "The underlying string value." },
4234
+ { path: "subjectIsEventSourceId", name: "subjectIsEventSourceId", type: "bool", kind: "value", description: "Whether the subject is the event source identifier." }
4235
+ ];
4236
+
4237
+ // event-context.ts
4238
+ function namesEventContextMember(member, segment) {
4239
+ if (member.kind === "function") {
4240
+ return segment === member.name || segment === `${member.name}()`;
4197
4241
  }
4198
- visitProperty(syntax) {
4199
- this.visitNode(syntax);
4200
- this.visitTypeRef(syntax.type);
4242
+ const declared = member.name[0].toUpperCase() + member.name.slice(1);
4243
+ return segment === declared || segment.length > 0 && segment[0].toUpperCase() + segment.slice(1) === declared;
4244
+ }
4245
+ var eventContextMembers = eventContextTypes[eventContextRootType];
4246
+ function eventContextMembersAfter(segments) {
4247
+ let members = eventContextMembers;
4248
+ for (const segment of segments) {
4249
+ const member = members.find((candidate) => namesEventContextMember(candidate, segment));
4250
+ if (!member || member.kind === "collection" || member.kind === "function") {
4251
+ return void 0;
4252
+ }
4253
+ members = eventContextTypes[member.type] ?? [];
4201
4254
  }
4202
- visitTypeRef(syntax) {
4203
- this.visitNode(syntax);
4255
+ return members;
4256
+ }
4257
+ function eventContextMemberAt(segments) {
4258
+ if (segments.length === 0) {
4259
+ return void 0;
4204
4260
  }
4205
- visitExpression(syntax) {
4206
- this.visitNode(syntax);
4207
- if (syntax.kind === "ListExpressionSyntax") {
4208
- syntax.items.forEach((item) => this.visitExpression(item));
4209
- } else if (syntax.kind === "ObjectExpressionSyntax") {
4210
- syntax.members.forEach((member) => this.visitObjectMember(member));
4261
+ const members = eventContextMembersAfter(segments.slice(0, -1));
4262
+ return members?.find((member) => namesEventContextMember(member, segments[segments.length - 1]));
4263
+ }
4264
+ function resolveEventContextPath(path) {
4265
+ let current;
4266
+ let expected = eventContextMembers;
4267
+ for (const segment of path.split(".")) {
4268
+ if (segment.length === 0) {
4269
+ return { status: "missing", member: current, expected };
4270
+ }
4271
+ if (current?.kind === "collection") {
4272
+ return { status: "belowCollection", member: current, segment, expected: [] };
4273
+ }
4274
+ const next = expected.find((member) => namesEventContextMember(member, segment));
4275
+ if (!next) {
4276
+ return { status: current ? "unknownSubPath" : "unknownMember", member: current, segment, expected };
4211
4277
  }
4278
+ current = next;
4279
+ expected = next.kind === "function" ? [] : eventContextTypes[next.type] ?? [];
4212
4280
  }
4213
- visitObjectMember(syntax) {
4214
- this.visitNode(syntax);
4215
- this.visitExpression(syntax.value);
4281
+ return { status: "known", member: current, expected: [] };
4282
+ }
4283
+ function describeEventContext() {
4284
+ return [
4285
+ "**$eventContext**",
4286
+ "",
4287
+ "Metadata about the event being projected. Paths are checked against the event-context catalog; `causation` and `tags` are collections and cannot be addressed below.",
4288
+ "",
4289
+ "**Members:**",
4290
+ ...eventContextMembers.map((member) => `- \`${member.name}\` (${member.type}) - ${member.description}`)
4291
+ ].join("\n");
4292
+ }
4293
+ function describeEventContextMember(path, member) {
4294
+ const below = member.kind === "collection" || member.kind === "function" ? [] : eventContextTypes[member.type] ?? [];
4295
+ const lines = [`**$eventContext.${path}**: \`${member.type}\``, "", member.description];
4296
+ if (below.length > 0) {
4297
+ lines.push("", `**Members:** ${below.map((child) => `\`${child.name}\``).join(", ")}`);
4216
4298
  }
4299
+ return lines.join("\n");
4300
+ }
4301
+
4302
+ // production-destinations.ts
4303
+ function productionDestinations(command) {
4304
+ const identifiers = command.properties.filter((property) => property.isIdentifier && !propertyTypeReference(property).isOptional && !propertyTypeReference(property).isCollection);
4305
+ const identifier = identifiers.length === 1 ? identifiers[0].name : void 0;
4306
+ const productions = command.produces ?? [];
4307
+ const mixed = productions.some((production) => production.target !== void 0 && production.target !== identifier) || productions.some((production) => production.inline && production.target === void 0) && productions.some((production) => !production.inline && production.target === void 0);
4308
+ return { identifier, mixed };
4309
+ }
4310
+ function destinationHints(lines) {
4311
+ const source = eventAnalysisSource(lines);
4312
+ return scanDocument(source).commands.flatMap((command) => {
4313
+ const { identifier, mixed } = productionDestinations(command);
4314
+ if (mixed || command.productionHeaders?.length !== command.produces?.length) return [];
4315
+ const hasPromotedDestination = command.produces?.some((sibling) => sibling.target !== void 0 || sibling.inline);
4316
+ return (command.produces ?? []).flatMap((production) => {
4317
+ if (production.target !== void 0 || production.inline && (identifier === void 0 || /\bgeneration\b/.test(source[production.line]))) return [];
4318
+ if (!production.inline && hasPromotedDestination) return [];
4319
+ return [{ line: production.line, column: source[production.line].length + 1, label: production.inline ? `for ${identifier}` : "for <new event source>" }];
4320
+ });
4321
+ });
4322
+ }
4323
+
4324
+ // diagnostic-codes.ts
4325
+ var diagnosticCodes = {
4326
+ eventSourceIdInPayload: "PLAY0469",
4327
+ explicitProducesTargetsRequired: "PLAY0470",
4328
+ redundantEventId: "PLAY0471",
4329
+ invalidEventId: "PLAY0472",
4330
+ inlineEventCollision: "PLAY0473",
4331
+ inlineEventOutsideCommand: "PLAY0474",
4332
+ inlineEventGeneration: "PLAY0475",
4333
+ reservedProductionMetadata: "PLAY0476",
4334
+ invalidEventDocumentation: "PLAY0477",
4335
+ tabIndentation: "PLAY0006",
4336
+ unknownPrimitiveType: "PLAY0008",
4337
+ unknownSliceType: "PLAY0028",
4338
+ duplicateCommandIdentifier: "PLAY0036",
4339
+ unknownContextPath: "PLAY0153",
4340
+ unknownContextCausedByProperty: "PLAY0154",
4341
+ unknownContextIdentityProperty: "PLAY0155",
4342
+ unclosedCodeBlock: "PLAY0164",
4343
+ unknownType: "PLAY0165",
4344
+ unknownEvent: "PLAY0166",
4345
+ unknownPolicy: "PLAY0167",
4346
+ duplicateDeclaration: "PLAY0168",
4347
+ unknownEventContextMember: "PLAY0295",
4348
+ unknownEventContextPath: "PLAY0296",
4349
+ eventContextPathBelowCollection: "PLAY0297",
4350
+ missingEventContextPath: "PLAY0298",
4351
+ unresolvedDynamicKeySource: "PLAY0299",
4352
+ invalidFileImport: "PLAY0454",
4353
+ omittedProductionDestination: "PLAY0478",
4354
+ legacyOptionalSuffix: "PLAY0479",
4355
+ invalidOptionalModifierOrder: "PLAY0480",
4356
+ optionalReadsNotSupported: "PLAY0481"
4217
4357
  };
4218
4358
 
4219
- // ../../Compiler/dist/Authoring/QuickFixes.js
4220
- function isQuickFixDiagnostic(code) {
4221
- return code === DiagnosticCodes.LegacyOptionalSuffix || code === DiagnosticCodes.RedundantEventId;
4359
+ // file-imports.ts
4360
+ var fileImportPattern2 = /^import(\s+)"([^"\\]+)"\s*(?:\/\/.*)?$/;
4361
+ var quotedImportPattern = /^import\s+"/;
4362
+ function isFileImportLine(line) {
4363
+ return quotedImportPattern.test(line.trim());
4222
4364
  }
4223
- function legacyOptionalTypeLength(line, diagnostic) {
4224
- if (diagnostic.code !== DiagnosticCodes.LegacyOptionalSuffix)
4225
- return 0;
4226
- return /^[\p{L}\p{Mn}\p{Nd}\p{Pc}.]+(?:\[\])?\?/u.exec(line.slice(diagnostic.location.column - 1))?.[0].length ?? 0;
4365
+ function fileImportOn(line, lineIndex) {
4366
+ const indent = indentOf(line);
4367
+ const match = line.slice(indent).match(fileImportPattern2);
4368
+ if (!match) return void 0;
4369
+ const startColumn = indent + "import".length + match[1].length + 2;
4370
+ return { pattern: match[2], line: lineIndex, startColumn, endColumn: startColumn + match[2].length };
4227
4371
  }
4228
- function prepareQuickFixes(source, options = {}) {
4229
- const original = parseForAuthoring(source, void 0, options.placement);
4230
- if (!original.success)
4231
- return () => [];
4232
- const lines = splitLines(source);
4233
- const eventsByLine = /* @__PURE__ */ new Map();
4234
- const walker = new class extends ScreenplaySyntaxWalker {
4235
- visitEvent(event2) {
4236
- eventsByLine.set(event2.location.line, event2);
4237
- }
4238
- }();
4239
- walker.visitApplication(original.value);
4240
- const counts = /* @__PURE__ */ new Map();
4241
- const byLine = /* @__PURE__ */ new Map();
4242
- const events = /* @__PURE__ */ new Map();
4243
- let event;
4244
- for (const line of lines) {
4245
- event = eventsByLine.get(line.number) ?? event;
4246
- if (event !== void 0)
4247
- events.set(line.number, event);
4248
- }
4249
- for (const diagnostic of original.diagnostics) {
4250
- counts.set(diagnostic.code, (counts.get(diagnostic.code) ?? 0) + 1);
4251
- const line = lines[diagnostic.location.line - 1];
4252
- const length = legacyOptionalTypeLength(line.raw, diagnostic);
4253
- if (length > 0) {
4254
- byLine.set(line.number, { line: line.number, fix: { diagnosticCode: diagnostic.code, title: "Use 'optional' instead of '?'", scope: "occurrence", edits: [{ start: line.startOffset + diagnostic.location.column + length - 2, length: 1, text: " optional" }] } });
4255
- } else if (diagnostic.code === DiagnosticCodes.RedundantEventId && commentStart(line.raw) < 0) {
4256
- const declaration = events.get(line.number);
4257
- if (declaration?.id !== declaration?.name || declaration === void 0)
4258
- continue;
4259
- byLine.set(line.number, {
4260
- line: line.number,
4261
- fix: { diagnosticCode: diagnostic.code, title: "Remove the redundant event id", scope: "occurrence", edits: [{ start: line.startOffset, length: (lines[line.number]?.startOffset ?? source.length) - line.startOffset, text: "" }] },
4262
- change: { node: declaration, replacement: { ...declaration, id: null } }
4263
- });
4264
- }
4372
+ function fileImports(lines) {
4373
+ const fences = fenceMap(lines);
4374
+ const found = [];
4375
+ for (let index = 0; index < lines.length; index++) {
4376
+ if (fences[index]) continue;
4377
+ const fileImport = fileImportOn(lines[index], index);
4378
+ if (fileImport) found.push(fileImport);
4265
4379
  }
4266
- const optional = [...byLine.values()].filter((candidate) => candidate.fix.diagnosticCode === DiagnosticCodes.LegacyOptionalSuffix);
4267
- const syntax = verificationShape(original);
4268
- const verified = /* @__PURE__ */ new Map();
4269
- let rangeVerdicts;
4270
- let documentChecked = false;
4271
- let documentFix;
4272
- const verify = (fix, change) => {
4273
- const candidate = applyQuickFixEdits(source, fix.edits);
4274
- if (candidate === void 0)
4275
- return void 0;
4276
- const parsed = parseForAuthoring(candidate, void 0, options.placement);
4277
- if (!parsed.success || verificationShape(parsed) !== (change === void 0 ? syntax : verificationShape(original, [change])))
4278
- return void 0;
4279
- return parsed.diagnostics.filter((diagnostic) => diagnostic.code === fix.diagnosticCode).length === (counts.get(fix.diagnosticCode) ?? 0) - fix.edits.length ? fix : void 0;
4280
- };
4281
- return (line, diagnosticCode) => {
4282
- const requests = typeof line === "number" || line === void 0 ? void 0 : line;
4283
- const includeDocument = requests === void 0 ? diagnosticCode === void 0 || diagnosticCode === DiagnosticCodes.LegacyOptionalSuffix : requests.some((request) => request.diagnosticCode === DiagnosticCodes.LegacyOptionalSuffix);
4284
- if (includeDocument && !documentChecked) {
4285
- if (optional.length > 0)
4286
- documentFix = verify({ diagnosticCode: DiagnosticCodes.LegacyOptionalSuffix, title: "Use 'optional' throughout this document", scope: "document", edits: optional.flatMap((candidate) => candidate.fix.edits) });
4287
- documentChecked = true;
4288
- }
4289
- if (requests !== void 0) {
4290
- if (rangeVerdicts === void 0) {
4291
- rangeVerdicts = /* @__PURE__ */ new Map();
4292
- const candidates = lines.flatMap((line2) => byLine.has(line2.number) ? [byLine.get(line2.number)] : []);
4293
- const edits = candidates.flatMap((candidate) => candidate.fix.edits);
4294
- const candidateSource = applyQuickFixEdits(source, edits);
4295
- if (edits.length > 0 && candidateSource !== void 0) {
4296
- const parsed = parseForAuthoring(candidateSource, void 0, options.placement);
4297
- const changes = candidates.flatMap((candidate) => candidate.change === void 0 ? [] : [candidate.change]);
4298
- if (parsed.success && verificationShape(parsed) === verificationShape(original, changes)) {
4299
- const remaining = /* @__PURE__ */ new Map();
4300
- const removed = /* @__PURE__ */ new Map();
4301
- for (const diagnostic of parsed.diagnostics)
4302
- remaining.set(diagnostic.code, (remaining.get(diagnostic.code) ?? 0) + 1);
4303
- for (const candidate of candidates)
4304
- removed.set(candidate.fix.diagnosticCode, (removed.get(candidate.fix.diagnosticCode) ?? 0) + candidate.fix.edits.length);
4305
- if ([...removed].every(([code, count]) => (remaining.get(code) ?? 0) === (counts.get(code) ?? 0) - count)) {
4306
- for (const candidate of candidates)
4307
- rangeVerdicts.set(candidate.line, candidate.fix);
4308
- }
4309
- }
4310
- }
4311
- }
4312
- const selected2 = /* @__PURE__ */ new Map();
4313
- for (const request of requests) {
4314
- const fix = rangeVerdicts.get(request.line);
4315
- if (fix?.diagnosticCode === request.diagnosticCode)
4316
- selected2.set(request.line, fix);
4317
- }
4318
- return [...selected2.values(), ...includeDocument && documentFix !== void 0 ? [documentFix] : []];
4319
- }
4320
- const occurrenceLine = typeof line === "number" ? line : void 0;
4321
- const selected = occurrenceLine === void 0 ? void 0 : byLine.get(occurrenceLine);
4322
- let occurrenceFix;
4323
- if (selected !== void 0 && occurrenceLine !== void 0 && (diagnosticCode === void 0 || selected.fix.diagnosticCode === diagnosticCode)) {
4324
- if (!verified.has(occurrenceLine)) {
4325
- if (verified.size === 32)
4326
- verified.delete(verified.keys().next().value);
4327
- verified.set(occurrenceLine, verify(selected.fix, selected.change));
4328
- }
4329
- occurrenceFix = verified.get(occurrenceLine);
4330
- }
4331
- return [occurrenceFix, includeDocument ? documentFix : void 0].filter((fix) => fix !== void 0);
4332
- };
4380
+ return found;
4333
4381
  }
4334
- function verificationShape(parsed, changes = []) {
4335
- const replacements = new Map(changes.map((change) => [change.node, change.replacement]));
4336
- return JSON.stringify([parsed.value, parsed.triggerData], (key, value) => key === "location" ? void 0 : replacements.get(value) ?? value);
4382
+ var folderOf = (path) => path.split("/").slice(0, -1);
4383
+ function relativeTo(from, path) {
4384
+ const segments = path.split("/");
4385
+ let common = 0;
4386
+ while (common < from.length && common < segments.length - 1 && from[common] === segments[common]) common++;
4387
+ return [...from.slice(common).map(() => ".."), ...segments.slice(common)].join("/");
4337
4388
  }
4338
- function applyQuickFixEdits(source, edits) {
4339
- const parts = [];
4340
- let end = 0;
4341
- for (const edit of edits) {
4342
- if (edit.start < end || edit.start < 0 || edit.length < 0 || edit.start + edit.length > source.length)
4343
- return void 0;
4344
- parts.push(source.slice(end, edit.start), edit.text);
4345
- end = edit.start + edit.length;
4389
+ function importablePaths(documentPath, files) {
4390
+ const from = folderOf(documentPath);
4391
+ const paths = /* @__PURE__ */ new Set();
4392
+ for (const file of files.filter((candidate) => candidate !== documentPath && candidate.toLowerCase().endsWith(".play"))) {
4393
+ const relative = relativeTo(from, file);
4394
+ const folders = folderOf(relative);
4395
+ paths.add(relative);
4396
+ paths.add([...folders, "*.play"].join("/"));
4397
+ for (let depth = 0; depth <= folders.length; depth++) {
4398
+ paths.add([...folders.slice(0, depth), "**", "*.play"].join("/"));
4399
+ }
4346
4400
  }
4347
- parts.push(source.slice(end));
4348
- return parts.join("");
4401
+ return [...paths].sort();
4349
4402
  }
4350
4403
 
4351
4404
  // inline-event-validation.ts
@@ -4799,12 +4852,19 @@ export {
4799
4852
  languageConfiguration,
4800
4853
  typeReferenceSymbol,
4801
4854
  typeReferenceText,
4855
+ DiagnosticCodes,
4856
+ isQuickFixDiagnostic,
4857
+ prepareQuickFixes,
4802
4858
  indentOf,
4803
4859
  firstWord,
4804
4860
  fenceMap,
4805
4861
  enclosingChain,
4806
4862
  nearestEnclosingLine,
4807
4863
  eventAnalysisSource,
4864
+ fileReferenceKeyword,
4865
+ isAbsoluteFileReferencePath,
4866
+ fileReferenceOn,
4867
+ fileReferences,
4808
4868
  propertyTypeReference,
4809
4869
  directBody,
4810
4870
  scanDocument,
@@ -4822,9 +4882,6 @@ export {
4822
4882
  describeEventContextMember,
4823
4883
  productionDestinations,
4824
4884
  destinationHints,
4825
- DiagnosticCodes,
4826
- isQuickFixDiagnostic,
4827
- prepareQuickFixes,
4828
4885
  diagnosticCodes,
4829
4886
  isFileImportLine,
4830
4887
  fileImportOn,
@@ -4833,4 +4890,4 @@ export {
4833
4890
  validateLines,
4834
4891
  validateEventContextPaths
4835
4892
  };
4836
- //# sourceMappingURL=chunk-GJX4NJYC.js.map
4893
+ //# sourceMappingURL=chunk-LXM5L4YK.js.map