@likec4/language-server 1.59.0 → 1.59.2

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.
@@ -65,6 +65,7 @@ declare const DeploymentNodeOrElementKind = "DeploymentNodeOrElementKind";
65
65
  type DeploymentViewRule = DeploymentViewRulePredicate | DeploymentViewRuleStyle | ViewRuleAncestors | ViewRuleAutoLayout;
66
66
  declare const DeploymentViewRule = "DeploymentViewRule";
67
67
  type DynamicViewDisplayVariantValue = 'diagram' | 'sequence';
68
+ type DynamicViewFlowKeyword = 'alt' | 'break' | 'catch' | 'else' | 'finally' | 'if' | 'loop' | 'opt' | 'par' | 'parallel' | 'try' | 'when';
68
69
  type DynamicViewProperty = DynamicViewDisplayVariantProperty | ViewProperty;
69
70
  declare const DynamicViewProperty = "DynamicViewProperty";
70
71
  type DynamicViewRule = DynamicViewGlobalPredicateRef | DynamicViewIncludePredicate | ViewRuleAutoLayout | ViewRuleStyleOrGlobalRef;
@@ -90,7 +91,7 @@ type FqnReferenceable = Element | ExtendDeployment | ExtendElement | Referenceab
90
91
  declare const FqnReferenceable = "FqnReferenceable";
91
92
  type IconId = string;
92
93
  type IconPositionValue = 'bottom' | 'left' | 'right' | 'top';
93
- type Id = 'deployment' | 'element' | 'group' | 'instance' | 'model' | 'node' | 'relationship' | ArrowType | DynamicViewDisplayVariantValue | ElementShape | IconPositionValue | LineOptions | Participant | RankValue | SizeValue | ThemeColor | string;
94
+ type Id = 'deployment' | 'element' | 'group' | 'instance' | 'model' | 'node' | 'relationship' | ArrowType | DynamicViewDisplayVariantValue | DynamicViewFlowKeyword | ElementShape | IconPositionValue | LineOptions | Participant | RankValue | SizeValue | ThemeColor | string;
94
95
  type LikeC4View = DeploymentView | DynamicView | ElementView;
95
96
  declare const LikeC4View = "LikeC4View";
96
97
  type LineOptions = 'dashed' | 'dotted' | 'solid';
@@ -128,6 +129,7 @@ type StringProperty = ElementStringProperty | MetadataAttribute | NotationProper
128
129
  declare const StringProperty = "StringProperty";
129
130
  type StyleProperty = BorderProperty | ColorProperty | IconColorProperty | IconPositionProperty | IconProperty | IconSizeProperty | MultipleProperty | OpacityProperty | PaddingSizeProperty | ShapeProperty | ShapeSizeProperty | TextSizeProperty;
130
131
  declare const StyleProperty = "StyleProperty";
132
+ type SubflowKind = 'break' | 'else' | 'if' | 'loop' | 'opt' | 'par' | 'parallel' | 'when';
131
133
  type ThemeColor = 'amber' | 'blue' | 'gray' | 'green' | 'indigo' | 'muted' | 'primary' | 'red' | 'secondary' | 'sky' | 'slate';
132
134
  type TryStep = CatchBlock | FinallyBlock | TryBlock;
133
135
  declare const TryStep = "TryStep";
@@ -1179,7 +1181,7 @@ declare const StepSeries = "StepSeries";
1179
1181
  interface SubflowStep extends StepsBlock {
1180
1182
  readonly $container: AltSteps | DynamicViewBody | StepsBlock;
1181
1183
  readonly $type: 'SubflowStep';
1182
- kind: 'break' | 'else' | 'if' | 'loop' | 'opt' | 'par' | 'parallel' | 'when';
1184
+ kind: SubflowKind;
1183
1185
  title?: string;
1184
1186
  }
1185
1187
  declare const SubflowStep = "SubflowStep";
@@ -2512,6 +2514,7 @@ declare const DocumentParserFromMixins: {
2512
2514
  parseAbstractDynamicStep(astnode: AbstractStep): import("type-fest").Writable<import("type-fest").Except<ProjectId, "source", {
2513
2515
  requireExactProps: true;
2514
2516
  }>>;
2517
+ parseDynamicStepEndpoint(node: ElementRef, endpoint: "source" | "target"): ProjectId;
2515
2518
  parseSubflowStep(node: SubflowStep): ProjectId | ProjectId | ProjectId | ProjectId;
2516
2519
  parseTryStep(node: TryStep): ProjectId;
2517
2520
  parseAltSteps(node: AltSteps): ProjectId;
@@ -2621,6 +2624,7 @@ declare const DocumentParserFromMixins: {
2621
2624
  parseAbstractDynamicStep(astnode: AbstractStep): import("type-fest").Writable<import("type-fest").Except<ProjectId, "source", {
2622
2625
  requireExactProps: true;
2623
2626
  }>>;
2627
+ parseDynamicStepEndpoint(node: ElementRef, endpoint: "source" | "target"): ProjectId;
2624
2628
  parseSubflowStep(node: SubflowStep): ProjectId | ProjectId | ProjectId | ProjectId;
2625
2629
  parseTryStep(node: TryStep): ProjectId;
2626
2630
  parseAltSteps(node: AltSteps): ProjectId;
@@ -6,7 +6,7 @@ import { BuildDocuments, ChangeView, DidChangeModelNotification, DidChangeProjec
6
6
  import { DefaultMap, DefaultWeakMap, MultiMap, ancestorsFqn, compareNatural, compareNaturalHierarchically, ifilter, invariant, isNonEmptyArray, isString, nameFromFqn, nonNullable, nonexhaustive, onNextTick, parentFqn, sortNaturalByFqn, sortParentsFirst, stringHash, toArray } from "@likec4/core/utils";
7
7
  import { loggable, wrapError } from "@likec4/log";
8
8
  import { AstUtils, Cancellation, ContextCache, CstUtils, DefaultDocumentValidator, DefaultIndexManager, DefaultLangiumDocuments, DefaultNameProvider, DefaultScopeComputation, DefaultScopeProvider, DefaultValueConverter, DefaultWorkspaceManager, Disposable, DocumentState, EMPTY_SCOPE, EMPTY_STREAM, GrammarAST, GrammarUtils, JSDocDocumentationProvider, MapScope, MultiMap as MultiMap$1, StreamScope, TextDocument, URI, UriUtils, ValueConverter, WorkspaceCache, inject, interruptAndCheck, isAstNode, isNamed, isOperationCancelled, stream } from "langium";
9
- import { cleanDoubleSlashes, hasLeadingSlash, hasProtocol, isRelative, joinRelativeURL, joinURL, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash } from "ufo";
9
+ import { cleanDoubleSlashes, hasLeadingSlash, hasProtocol, isRelative, joinRelativeURL, joinURL, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutTrailingSlash } from "ufo";
10
10
  import { anyPass, clamp, entries, filter, find, findLast, first, flatMap, forEach, forEachObj, funnel, groupBy, hasAtLeast, identity, indexBy, isArray, isBoolean, isDefined, isEmpty, isEmptyish, isNonNullish, isNot, isNullish, isNumber, isPromise, isString as isString$1, isTruthy, keys, last, map, mapToObj, mapValues, omitBy, once, only, pipe, piped, prop, purry, reduce, sort, unique, uniqueBy, values } from "remeda";
11
11
  import * as c4 from "@likec4/core";
12
12
  import { DefaultMap as DefaultMap$1, Fqn, FqnExpr, FqnRef, GlobalFqn, LinkedList, RelationExpr, _layout, _stage, _type, ancestorsFqn as ancestorsFqn$1, applyCachedLayout, applyManualLayout, calcDriftsFromSnapshot, exact, invariant as invariant$1, isAncestor, isAndOperator, isAnyOf, isDeploymentNode, isElementView, isGlobalFqn, isNonEmptyArray as isNonEmptyArray$1, isOrOperator, isSameHierarchy, nameFromFqn as nameFromFqn$1, nonNullable as nonNullable$1, nonexhaustive as nonexhaustive$1, preferSummary, splitGlobalFqn } from "@likec4/core";
@@ -375,6 +375,14 @@ function normalizeUri(uri) {
375
375
  }
376
376
  return uri.toString();
377
377
  }
378
+ const windowsDrivePath = /^\/?([A-Za-z]):(?=\/|$)/;
379
+ function normalizeWindowsDrivePath(path) {
380
+ return path.replace(windowsDrivePath, (_, drive) => `/${drive.toLowerCase()}:`);
381
+ }
382
+ function uriPathForMatcher(uri) {
383
+ if (URI.isUri(uri)) return normalizeWindowsDrivePath(uri.path);
384
+ return normalizeWindowsDrivePath(URI.parse(uri).path);
385
+ }
378
386
  /**
379
387
  * Compare function to ensure consistent order
380
388
  */
@@ -402,7 +410,7 @@ function _isInScope(project, docUri) {
402
410
  return docUri.startsWith(project.folder) || (project.includePaths?.some(isParentFolderFor(docUri)) ?? false);
403
411
  }
404
412
  function _excludes(project, docUri) {
405
- return project.exclude?.(withoutProtocol(docUri)) ?? false;
413
+ return project.exclude?.(uriPathForMatcher(docUri)) ?? false;
406
414
  }
407
415
  function includes(...args) {
408
416
  return purry(_includes, args);
@@ -439,7 +447,7 @@ const DefaultProject = {
439
447
  }
440
448
  };
441
449
  function isExcludedByDefault(uri) {
442
- return DefaultProject.exclude(withoutProtocol(uri));
450
+ return DefaultProject.exclude(uriPathForMatcher(uri));
443
451
  }
444
452
  /**
445
453
  * Parses the given options and returns an object with the following properties:
@@ -542,7 +550,7 @@ var ProjectsManager = class ProjectsManager extends ADisposable {
542
550
  isExcludedByWorkspace(uri) {
543
551
  if (!this.#workspaceExclude) return false;
544
552
  if (URI.isUri(uri)) uri = normalizeUri(uri);
545
- return this.#workspaceExclude(withoutProtocol(uri));
553
+ return this.#workspaceExclude(uriPathForMatcher(uri));
546
554
  }
547
555
  /**
548
556
  * Updates the workspace-level exclude patterns from VS Code settings.
@@ -555,6 +563,7 @@ var ProjectsManager = class ProjectsManager extends ADisposable {
555
563
  return;
556
564
  }
557
565
  const normalizedPatterns = pipe(patterns, filter(isTruthy), map((p) => {
566
+ p = normalizeWindowsDrivePath(p);
558
567
  if (!isAbsolute(p) && !p.startsWith("**")) p = joinURL("**", p);
559
568
  return p;
560
569
  }));
@@ -925,7 +934,7 @@ var ProjectsManager = class ProjectsManager extends ADisposable {
925
934
  if (isNullish(exclude)) project.exclude = DefaultProject.exclude;
926
935
  else if (hasAtLeast(exclude, 1)) project.exclude = picomatch([project.folderUri, ...map(project.includePaths ?? [], prop("uri"))].flatMap((root) => map(exclude, (p) => {
927
936
  if (!isRelative(p) && !p.startsWith("**")) p = joinURL("**", p);
928
- return cleanDoubleSlashes(joinRelativeURL(root.path, p));
937
+ return cleanDoubleSlashes(joinRelativeURL(uriPathForMatcher(root), p));
929
938
  })), {
930
939
  contains: true,
931
940
  dot: true
@@ -1050,7 +1059,7 @@ var LikeC4WorkspaceManager = class extends DefaultWorkspaceManager {
1050
1059
  */
1051
1060
  async scanProjectIncludePaths() {
1052
1061
  const includePaths = this.services.workspace.ProjectsManager.getAllIncludePaths();
1053
- if (hasAtLeast(includePaths, 1)) return [];
1062
+ if (!hasAtLeast(includePaths, 1)) return [];
1054
1063
  const isNotExcludedByWorkspace = isNot((f) => this.services.workspace.ProjectsManager.isExcludedByWorkspace(f.uri));
1055
1064
  const foundFiles = [];
1056
1065
  for (const { projectId, includePath, includeConfig } of includePaths) try {
@@ -6441,11 +6450,9 @@ function ViewsParser(B) {
6441
6450
  return [...allprevious, thisStep];
6442
6451
  }
6443
6452
  parseStep(node) {
6444
- const sourceEl = elementRef(node.source);
6445
- if (!sourceEl) throw new Error("Invalid reference to source");
6446
6453
  let baseStep = {
6447
6454
  ...this.parseAbstractDynamicStep(node),
6448
- source: this.resolveFqn(sourceEl)
6455
+ source: this.parseDynamicStepEndpoint(node.source, "source")
6449
6456
  };
6450
6457
  if (node.isBackward) baseStep = {
6451
6458
  ...baseStep,
@@ -6456,11 +6463,9 @@ function ViewsParser(B) {
6456
6463
  return baseStep;
6457
6464
  }
6458
6465
  parseAbstractDynamicStep(astnode) {
6459
- const targetEl = elementRef(astnode.target);
6460
- if (!targetEl) throw new Error("Invalid reference to target");
6461
6466
  const astPath = pathInsideDynamicView(astnode);
6462
6467
  const step = {
6463
- target: this.resolveFqn(targetEl),
6468
+ target: this.parseDynamicStepEndpoint(astnode.target, "target"),
6464
6469
  astPath
6465
6470
  };
6466
6471
  const title = removeIndent(astnode.title);
@@ -6503,6 +6508,11 @@ function ViewsParser(B) {
6503
6508
  }
6504
6509
  return step;
6505
6510
  }
6511
+ parseDynamicStepEndpoint(node, endpoint) {
6512
+ const ref = this.parseFqnRef(node.modelElement);
6513
+ if (!c4.FqnRef.isModelRef(ref)) throw new Error(`Invalid reference to ${endpoint}`);
6514
+ return c4.FqnRef.flatten(ref);
6515
+ }
6506
6516
  parseSubflowStep(node) {
6507
6517
  const kind = node.kind === "parallel" ? "par" : node.kind;
6508
6518
  switch (kind) {
@@ -7188,7 +7198,7 @@ var LikeC4ScopeComputation = class extends DefaultScopeComputation {
7188
7198
  if (isTruthy(spec.tag.name)) docExports.push(this.descriptions.createDescription(spec.tag, spec.tag.name, document), this.descriptions.createDescription(spec.tag, "#" + spec.tag.name, document));
7189
7199
  continue;
7190
7200
  case isSpecificationRelationshipKind(spec):
7191
- if (isTruthy(spec.kind.name)) docExports.push(this.descriptions.createDescription(spec.kind, spec.kind.name, document), this.descriptions.createDescription(spec.kind, "." + spec.kind.name, document));
7201
+ if (isTruthy(spec.kind.name)) docExports.push(this.descriptions.createDescription(spec.kind, spec.kind.name, document));
7192
7202
  continue;
7193
7203
  case isSpecificationColor(spec):
7194
7204
  if (isTruthy(spec.name.name)) docExports.push(this.descriptions.createDescription(spec.name, spec.name.name, document));