All files / src/shared/lib/helpers resourceLinks.ts

100% Statements 18/18
100% Branches 5/5
100% Functions 2/2
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58                        2x           8x 8x     2x   13x 13x   13x     13x 16x 9x           16x   16x               16x     13x 5x     13x    
type LinkEntityType = "scene" | "actor" | "trigger" | "customEvent" | "sprite";
 
export type ParsedResourceTextSegment =
  | { type: "text"; value: string }
  | {
      type: "link";
      linkText: string;
      entityId: string;
      entityType: LinkEntityType;
      sceneId?: string;
    };
 
export const createLinkToResource = (
  label: string,
  id: string,
  type: LinkEntityType,
  sceneId = "",
): string => {
  const escapedLabel = label.replace(/@/g, "@@@");
  return `|@@|${escapedLabel}|@|${id}|@|${type}|@|${sceneId}|@@|`;
};
 
export const parseLinkedText = (text: string): ParsedResourceTextSegment[] => {
  const regex =
    /\|@@\|(.+?)\|@\|(.+?)\|@\|(scene|actor|trigger|customEvent|sprite)\|@\|(.*?)\|@@\|/g;
  const segments: ParsedResourceTextSegment[] = [];
 
  let lastIndex = 0;
  let match: RegExpExecArray | null;
 
  while ((match = regex.exec(text)) !== null) {
    if (match.index > lastIndex) {
      segments.push({
        type: "text",
        value: text.slice(lastIndex, match.index),
      });
    }
 
    const [, linkText, entityId, entityType, sceneId] = match;
 
    segments.push({
      type: "link",
      linkText: linkText.replace(/@@@/g, "@"),
      entityId,
      entityType: entityType as LinkEntityType,
      ...(sceneId && { sceneId }),
    });
 
    lastIndex = regex.lastIndex;
  }
 
  if (lastIndex < text.length) {
    segments.push({ type: "text", value: text.slice(lastIndex) });
  }
 
  return segments;
};