@diagrammo/dgmo 0.14.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -194,6 +194,24 @@ export function parseInfra(content: string): ParsedInfra {
194
194
  if (!m) return { label: trimmed };
195
195
  return { label: m[1].trim(), alias: m[2] };
196
196
  }
197
+
198
+ // Infra nodes have no "is a <type>" declaration — capability comes from
199
+ // properties (cache-hit, buffer, drain-rate, …). Strip the suffix if a
200
+ // user wrote it (likely copying from sequence/c4 syntax) and warn.
201
+ const IS_A_SUFFIX = /^(.*?)\s+is\s+an?\s+[A-Za-z][\w-]*\s*$/i;
202
+ function peelInfraDecorations(
203
+ rawName: string,
204
+ lineNumber: number
205
+ ): { label: string; alias?: string } {
206
+ const peeled = peelAlias(rawName);
207
+ const m = peeled.label.match(IS_A_SUFFIX);
208
+ if (!m) return peeled;
209
+ warn(
210
+ lineNumber,
211
+ `Infra nodes don't use 'is a <type>' — types are inferred from properties (cache-hit, buffer, drain-rate, …). Drop the 'is a' suffix.`
212
+ );
213
+ return { label: m[1].trim(), alias: peeled.alias };
214
+ }
197
215
  /**
198
216
  * Resolve a connection-target token. If the token exactly matches a
199
217
  * declared alias, return the bound canonical id. Otherwise fall
@@ -399,7 +417,7 @@ export function parseInfra(content: string): ParsedInfra {
399
417
  finishCurrentTagGroup();
400
418
 
401
419
  const rawName = (compMatch[1] ?? compMatch[2] ?? '').trim();
402
- const peeled = peelAlias(rawName);
420
+ const peeled = peelInfraDecorations(rawName, lineNumber);
403
421
  const name = peeled.label;
404
422
  const rest = compMatch[3] || '';
405
423
  const { tags } = extractPipeMetadata(rest);
@@ -482,7 +500,7 @@ export function parseInfra(content: string): ParsedInfra {
482
500
  if (compMatch) {
483
501
  finishCurrentTagGroup();
484
502
  const rawName = (compMatch[1] ?? compMatch[2] ?? '').trim();
485
- const peeled = peelAlias(rawName);
503
+ const peeled = peelInfraDecorations(rawName, lineNumber);
486
504
  const name = peeled.label;
487
505
  const rest = compMatch[3] || '';
488
506
  const { tags: nodeTags } = extractPipeMetadata(rest);
@@ -764,7 +782,7 @@ export function parseInfra(content: string): ParsedInfra {
764
782
  const compMatch = trimmed.match(COMPONENT_RE);
765
783
  if (compMatch) {
766
784
  const rawName = (compMatch[1] ?? compMatch[2] ?? '').trim();
767
- const peeled = peelAlias(rawName);
785
+ const peeled = peelInfraDecorations(rawName, lineNumber);
768
786
  const name = peeled.label;
769
787
  const rest = compMatch[3] || '';
770
788
  const { tags: nodeTags } = extractPipeMetadata(rest);
@@ -796,10 +814,13 @@ export function parseInfra(content: string): ParsedInfra {
796
814
  finishCurrentTagGroup();
797
815
  currentGroup = null;
798
816
 
799
- const name = (compMatch[1] ?? compMatch[2] ?? '').trim();
817
+ const rawName = (compMatch[1] ?? compMatch[2] ?? '').trim();
818
+ const peeled = peelInfraDecorations(rawName, lineNumber);
819
+ const name = peeled.label;
800
820
  const rest = compMatch[3] || '';
801
821
  const { tags } = extractPipeMetadata(rest);
802
822
  const id = nodeId(name);
823
+ if (peeled.alias) nameAliasMap.set(peeled.alias, id);
803
824
 
804
825
  currentNode = {
805
826
  id,
@@ -877,6 +898,17 @@ import type { DiagramSymbols } from '../completion';
877
898
  * Extract component names (entities) from infra document text.
878
899
  * Used by the dgmo completion API for ghost hints and popup completions.
879
900
  */
901
+ /** Strip ` as <alias>` and ` is a/an <type>` decorations from a node name
902
+ * so completion suggests the bare identifier the user will reference. */
903
+ function stripNodeDecorations(name: string): string {
904
+ let s = name.trim();
905
+ const aliasMatch = s.match(/^(.*?)\s+as\s+[A-Za-z][A-Za-z0-9_]{0,11}\s*$/);
906
+ if (aliasMatch) s = aliasMatch[1].trim();
907
+ const isAMatch = s.match(/^(.*?)\s+is\s+an?\s+[A-Za-z][\w-]*\s*$/i);
908
+ if (isAMatch) s = isAMatch[1].trim();
909
+ return s;
910
+ }
911
+
880
912
  export function extractSymbols(docText: string): DiagramSymbols {
881
913
  const entities: string[] = [];
882
914
  let inMetadata = true;
@@ -916,7 +948,7 @@ export function extractSymbols(docText: string): DiagramSymbols {
916
948
  if (/^\[/.test(line)) continue; // [Group] header
917
949
  const m = COMPONENT_RE.exec(line);
918
950
  if (m) {
919
- const name = (m[1] ?? m[2] ?? '').trim();
951
+ const name = stripNodeDecorations((m[1] ?? m[2] ?? '').trim());
920
952
  if (name && !entities.includes(name)) entities.push(name);
921
953
  }
922
954
  } else {
@@ -940,7 +972,7 @@ export function extractSymbols(docText: string): DiagramSymbols {
940
972
  continue;
941
973
  const m = COMPONENT_RE.exec(line);
942
974
  if (m) {
943
- const name = (m[1] ?? m[2] ?? '').trim();
975
+ const name = stripNodeDecorations((m[1] ?? m[2] ?? '').trim());
944
976
  if (name && !entities.includes(name)) entities.push(name);
945
977
  }
946
978
  }