diff --git a/internal/references/references.go b/internal/references/references.go index 509e918..4caa238 100644 --- a/internal/references/references.go +++ b/internal/references/references.go @@ -54,6 +54,7 @@ var codeExts = map[string]bool{ } var quotedSpecRe = regexp.MustCompile(`(?i)['"\x60]([^'"\x60]*(?:\$\{[^'"\x60]*\}|[*{}])?[^'"\x60]*\.(?:avif|gif|heic|heif|jpe?g|png|svg|webp)(?:\?[^'"\x60]*)?)['"\x60]`) +var templateExprRe = regexp.MustCompile(`\$\{[^}]*\}`) var cssSpecRe = regexp.MustCompile(`(?i)url\(\s*['"]?([^'")\s]+\.(?:avif|gif|heic|heif|jpe?g|png|svg|webp)(?:\?[^'")\s]*)?)['"]?\s*\)`) func BuildMap(ctx context.Context, projects []Project, assets []Asset) (map[string][]Reference, error) { @@ -348,6 +349,7 @@ func resolvePattern(importerRepoPath, specifier string, aliases map[string]strin if spec == "" { return "" } + spec = templateExprRe.ReplaceAllString(spec, "*") if resolved := resolveAlias(spec, aliases); resolved != "" { return resolved } diff --git a/internal/references/references_test.go b/internal/references/references_test.go index 2106392..9c0349a 100644 --- a/internal/references/references_test.go +++ b/internal/references/references_test.go @@ -350,6 +350,33 @@ func TestReferenceHelperFunctions(t *testing.T) { } } +func TestBuildMapResolvesTemplateLiteralPattern(t *testing.T) { + root := t.TempDir() + mustWrite(t, filepath.Join(root, "apps", "myapp", "src", "views", "Dashboard", "icons", "apple.webp"), "image") + mustWrite(t, filepath.Join(root, "apps", "myapp", "src", "views", "Dashboard", "icons", "banana.webp"), "image") + mustWrite(t, filepath.Join(root, "apps", "myapp", "src", "views", "Dashboard", "CategoryIcon.tsx"), + "function getIcon(code: string) {\n return new URL(`./icons/${code}.webp`, import.meta.url).href\n}") + + refs, err := BuildMap(context.Background(), + []Project{{ID: "p", Path: root}}, + []Asset{ + {ProjectID: "p", RepoPath: "apps/myapp/src/views/Dashboard/icons/apple.webp"}, + {ProjectID: "p", RepoPath: "apps/myapp/src/views/Dashboard/icons/banana.webp"}, + }, + ) + if err != nil { + t.Fatal(err) + } + a := refs["p\x00apps/myapp/src/views/Dashboard/icons/apple.webp"] + if len(a) != 1 || a[0].File != "apps/myapp/src/views/Dashboard/CategoryIcon.tsx" { + t.Fatalf("template literal apple refs = %#v, want 1 ref from CategoryIcon.tsx", a) + } + b := refs["p\x00apps/myapp/src/views/Dashboard/icons/banana.webp"] + if len(b) != 1 || b[0].File != "apps/myapp/src/views/Dashboard/CategoryIcon.tsx" { + t.Fatalf("template literal banana refs = %#v, want 1 ref from CategoryIcon.tsx", b) + } +} + func TestBuildMapHonorsContextCancellation(t *testing.T) { root := t.TempDir() mustWrite(t, filepath.Join(root, "src", "App.tsx"), `import logo from "./logo.png"`)