From 25c150136dc6e589b1fdf0c90c8d37010c3409a0 Mon Sep 17 00:00:00 2001
From: Daniel Roe <daniel@roe.dev>
Date: Fri, 19 May 2023 08:11:46 +0100
Subject: [PATCH] fix(nuxt): don't match partial component names with prefix
 (#20939)

---
 packages/nuxt/src/components/scan.ts       | 9 +++++----
 packages/nuxt/test/scan-components.test.ts | 5 ++++-
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/packages/nuxt/src/components/scan.ts b/packages/nuxt/src/components/scan.ts
index 4c755eec9..ede5f4795 100644
--- a/packages/nuxt/src/components/scan.ts
+++ b/packages/nuxt/src/components/scan.ts
@@ -130,13 +130,14 @@ export function resolveComponentName (fileName: string, prefixParts: string[]) {
    * @example AwesomeComponent -> ['Awesome', 'Component']
    */
   const fileNameParts = splitByCase(fileName)
-  const fileNamePartsContent = fileNameParts.join('').toLowerCase()
+  const fileNamePartsContent = fileNameParts.join('/').toLowerCase()
   const componentNameParts: string[] = [...prefixParts]
   let index = prefixParts.length - 1
-  const matchedSuffix:string[] = []
+  const matchedSuffix: string[] = []
   while (index >= 0) {
-    matchedSuffix.unshift((prefixParts[index] || '').toLowerCase())
-    if (fileNamePartsContent.startsWith(matchedSuffix.join('')) ||
+    matchedSuffix.unshift(...splitByCase(prefixParts[index] || '').map(p => p.toLowerCase()))
+    const matchedSuffixContent = matchedSuffix.join('/')
+    if ((fileNamePartsContent === matchedSuffixContent || fileNamePartsContent.startsWith(matchedSuffixContent + '/')) ||
       // e.g Item/Item/Item.vue -> Item
       (prefixParts[index].toLowerCase() === fileNamePartsContent &&
         prefixParts[index + 1] &&
diff --git a/packages/nuxt/test/scan-components.test.ts b/packages/nuxt/test/scan-components.test.ts
index 0c4025f2a..52cd8bb14 100644
--- a/packages/nuxt/test/scan-components.test.ts
+++ b/packages/nuxt/test/scan-components.test.ts
@@ -257,7 +257,10 @@ const tests: Array<[string, string[], string]> = [
   ['ThingItemTest', ['Item', 'Thing', 'Foo'], 'ItemThingFooThingItemTest'],
   ['ItemIn', ['Item', 'Holder', 'Item', 'In'], 'ItemHolderItemIn'],
   ['Item', ['Item', 'Holder', 'Test'], 'ItemHolderTestItem'],
-  ['ItemHolderItem', ['Item', 'Holder', 'Item', 'Holder'], 'ItemHolderItemHolderItem']
+  ['ItemHolderItem', ['Item', 'Holder', 'Item', 'Holder'], 'ItemHolderItemHolderItem'],
+  ['Icones', ['Icon'], 'IconIcones'],
+  ['Icon', ['Icones'], 'IconesIcon'],
+  ['IconHolder', ['IconHolder'], 'IconHolder']
 ]
 
 describe('components:resolveComponentName', () => {