1import type { ServerProviderSkill } from "@t3tools/contracts";
2
3export type InlineSkill = Pick<ServerProviderSkill, "name" | "displayName">;
4
5export function formatProviderSkillDisplayName(
6 skill: Pick<ServerProviderSkill, "name"> & { readonly displayName?: string | null | undefined },
7): string {
8 return skill.displayName?.trim() || skill.name;
9}
10
11const SKILL_TOKEN_REGEX =
12 /(^|\s)\p{Sc}(?![0-9][0-9_]*(?:[kKmMbBtT]|[eE][0-9]+)?(?:\s|$))(?=[a-zA-Z0-9:_-]*[a-zA-Z])([a-zA-Z0-9][a-zA-Z0-9:_-]*)(?=\s|$)/gu;
13
14export function* matchInlineSkills<Skill extends InlineSkill>(
15 text: string,
16 skills: readonly Skill[],
17) {
18 const byName = new Map<string, Skill | undefined>();
19 for (const match of text.matchAll(SKILL_TOKEN_REGEX)) {
20 const name = match[2] ?? "";
21 if (!byName.has(name)) {
22 byName.set(
23 name,
24 skills.find((candidate) => candidate.name === name),
25 );
26 }
27 const skill = byName.get(name);
28 if (!skill) continue;
29 const start = match.index + (match[1]?.length ?? 0);
30 yield { start, end: match.index + match[0].length, skill, rawText: `$${name}` };
31 }
32}