Skip to content

Commit

Permalink
Merge pull request #4331 from Shopify/fix-4320
Browse files Browse the repository at this point in the history
Update the theme selector to no longer match partial theme names
  • Loading branch information
karreiro authored Aug 20, 2024
2 parents ae4aac5 + e3483a1 commit 6c4ac20
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-carpets-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/theme': patch
---

Update the theme selector to no longer match partial theme names by default; use the '*' character to enable partial matching
2 changes: 1 addition & 1 deletion packages/theme/src/cli/services/list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe('list', () => {
{id: 5, name: 'Theme 5', role: 'development'},
] as Theme[])

await list(session, {role: 'live', name: 'eMe 3', json: false})
await list(session, {role: 'live', name: '*eMe 3*', json: false})

expect(renderTable).toBeCalledWith({
rows: [{id: '#3', name: 'Theme 3', role: '[live]'}],
Expand Down
32 changes: 30 additions & 2 deletions packages/theme/src/cli/utilities/theme-selector/filter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,38 @@ describe('filterThemes', () => {
expect(filtered[0]!.name).toBe('theme (7)')
})

test('filters by theme (partial name with different case)', async () => {
test('filters by theme (partial name matching the middle of the name)', async () => {
// Given
const filter = new Filter({
theme: 'eMe (7',
theme: '*eMe (7*',
})

// When
const filtered = filterThemes(store, themes, filter)

// Then
expect(filtered).toHaveLength(1)
expect(filtered[0]!.name).toBe('theme (7)')
})

test('filters by theme (partial name matching the beginning of the name)', async () => {
// Given
const filter = new Filter({
theme: 'theme (7*',
})

// When
const filtered = filterThemes(store, themes, filter)

// Then
expect(filtered).toHaveLength(1)
expect(filtered[0]!.name).toBe('theme (7)')
})

test('filters by theme (partial name matching the end of the name)', async () => {
// Given
const filter = new Filter({
theme: '*me (7)',
})

// When
Expand Down
32 changes: 29 additions & 3 deletions packages/theme/src/cli/utilities/theme-selector/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function filterByRole(store: string, themes: Theme[], filter: Filter) {
return
}

const error = `The ${store} store doesn't have a theme with the "${role}" role`
const error = `No themes on the store ${store} match the role "${role}"`

return filterArray(themes, (theme) => {
return theme.role === role
Expand All @@ -24,10 +24,18 @@ function filterByTheme(store: string, themes: Theme[], filter: Filter) {
const identifiers = filter.themeIdentifiers

return identifiers.flatMap((identifier) => {
const error = `The ${store} store doesn't have a theme with the "${identifier}" ID or name`
const error = `No themes on the store ${store} match the ID or name "${identifier}"`

return filterArray(themes, (theme) => {
return `${theme.id}` === identifier || theme.name.toLowerCase().includes(identifier.toLowerCase())
if (`${theme.id}` === identifier) {
return true
}

if (theme.name.toLowerCase() === identifier.toLowerCase()) {
return true
}

return isPartialMatch(theme.name.toLowerCase(), identifier.toLowerCase())
}).orThrow(error)
})
}
Expand Down Expand Up @@ -89,3 +97,21 @@ export class Filter {
})
}
}

function isPartialMatch(themeName: string, identifier: string): boolean {
const trimmedIdentifier = identifier.replace(/(^\*)|(\*$)/g, '')

if (identifier.startsWith('*') && identifier.endsWith('*')) {
return themeName.includes(trimmedIdentifier)
}

if (identifier.startsWith('*')) {
return themeName.endsWith(trimmedIdentifier)
}

if (identifier.endsWith('*')) {
return themeName.startsWith(trimmedIdentifier)
}

return false
}

0 comments on commit 6c4ac20

Please sign in to comment.