From 35cc47c21a9e30a54d6fab542db0663681627974 Mon Sep 17 00:00:00 2001 From: DrJume Date: Thu, 2 Jun 2022 19:56:48 +0200 Subject: [PATCH] feat: add 'collapseSamePrefixes' option to prevent duplication inside namespaced component name --- .../CollapseFolderAndComponentPrefixes.vue | 9 +++ src/core/utils.ts | 27 ++++++++- src/types.ts | 12 +++- test/__snapshots__/search.test.ts.snap | 57 +++++++++++++++++++ test/search.test.ts | 12 ++++ 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 examples/vite-vue3/src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue diff --git a/examples/vite-vue3/src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue b/examples/vite-vue3/src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue new file mode 100644 index 00000000..ba1ae0c8 --- /dev/null +++ b/examples/vite-vue3/src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue @@ -0,0 +1,9 @@ + + + diff --git a/src/core/utils.ts b/src/core/utils.ts index efd326a8..03bb947d 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -111,7 +111,7 @@ export function stringifyComponentImport({ as: name, from: path, name: importNam } export function getNameFromFilePath(filePath: string, options: ResolvedOptions): string { - const { resolvedDirs, directoryAsNamespace, globalNamespaces } = options + const { resolvedDirs, directoryAsNamespace, globalNamespaces, collapseSamePrefixes } = options const parsedFilePath = parse(slash(filePath)) @@ -144,7 +144,30 @@ export function getNameFromFilePath(filePath: string, options: ResolvedOptions): if (!isEmpty(folders)) { // add folders to filename - filename = [...folders, filename].filter(Boolean).join('-') + let namespaced = [...folders, filename] + + if (collapseSamePrefixes) { + const collapsed: string[] = [] + + for (const fileOrFolderName of namespaced) { + const collapsedFilename = collapsed.join('') + if ( + collapsedFilename + && fileOrFolderName.toLowerCase().startsWith(collapsedFilename.toLowerCase()) + ) { + const collapseSamePrefix = fileOrFolderName.slice(collapsedFilename.length) + + collapsed.push(collapseSamePrefix) + continue + } + + collapsed.push(fileOrFolderName) + } + + namespaced = collapsed + } + + filename = namespaced.filter(Boolean).join('-') } return filename diff --git a/src/types.ts b/src/types.ts index 0a79ded1..6cd6eea9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -102,9 +102,19 @@ export interface Options { */ directoryAsNamespace?: boolean + /** + * Collapse same prefixes (case-insensitive) of folders and components + * to prevent duplication inside namespaced component name + * + * Works when `directoryAsNamespace: true` + * @default false + */ + collapseSamePrefixes?: boolean + /** * Subdirectory paths for ignoring namespace prefixes - * works when `directoryAsNamespace: true` + * + * Works when `directoryAsNamespace: true` * @default "[]" */ globalNamespaces?: string[] diff --git a/test/__snapshots__/search.test.ts.snap b/test/__snapshots__/search.test.ts.snap index cd1b6630..ed67ec9e 100644 --- a/test/__snapshots__/search.test.ts.snap +++ b/test/__snapshots__/search.test.ts.snap @@ -1,5 +1,54 @@ // Vitest Snapshot v1 +exports[`search > should with namespace & collapse 1`] = ` +[ + { + "as": "Avatar", + "from": "src/components/global/avatar.vue", + }, + { + "as": "Book", + "from": "src/components/book/index.vue", + }, + { + "as": "CollapseFolderAndComponentPrefixes", + "from": "src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue", + }, + { + "as": "ComponentA", + "from": "src/components/ComponentA.vue", + }, + { + "as": "ComponentAsync", + "from": "src/components/ComponentAsync.vue", + }, + { + "as": "ComponentB", + "from": "src/components/ComponentB.vue", + }, + { + "as": "ComponentC", + "from": "src/components/component-c.vue", + }, + { + "as": "ComponentD", + "from": "src/components/ComponentD.vue", + }, + { + "as": "Recursive", + "from": "src/components/Recursive.vue", + }, + { + "as": "UiButton", + "from": "src/components/ui/button.vue", + }, + { + "as": "UiNestedCheckbox", + "from": "src/components/ui/nested/checkbox.vue", + }, +] +`; + exports[`search > should with namespace 1`] = ` [ { @@ -10,6 +59,10 @@ exports[`search > should with namespace 1`] = ` "as": "Book", "from": "src/components/book/index.vue", }, + { + "as": "CollapseCollapseFolderAndCollapseFolderAndComponentPrefixes", + "from": "src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue", + }, { "as": "ComponentA", "from": "src/components/ComponentA.vue", @@ -63,6 +116,10 @@ exports[`search > should work 1`] = ` "as": "Checkbox", "from": "src/components/ui/nested/checkbox.vue", }, + { + "as": "CollapseFolderAndComponentPrefixes", + "from": "src/components/collapse/collapseFolderAnd/CollapseFolderAndComponentPrefixes.vue", + }, { "as": "ComponentA", "from": "src/components/ComponentA.vue", diff --git a/test/search.test.ts b/test/search.test.ts index baa77f03..d0e78933 100644 --- a/test/search.test.ts +++ b/test/search.test.ts @@ -31,4 +31,16 @@ describe('search', () => { expect(cleanup(ctx.componentNameMap)).toMatchSnapshot() }) + + it('should with namespace & collapse', async () => { + const ctx = new Context({ + directoryAsNamespace: true, + collapseSamePrefixes: true, + globalNamespaces: ['global'], + }) + ctx.setRoot(root) + ctx.searchGlob() + + expect(cleanup(ctx.componentNameMap)).toMatchSnapshot() + }) })