Skip to content

Commit

Permalink
refactor(utils): [changeExt] allow file extension removal
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <unicornware@flexdevelopment.llc>
  • Loading branch information
unicornware committed Dec 16, 2022
1 parent 5f0de54 commit 3d069cb
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 14 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,14 @@ console.debug(addExt('file.d.mts', '.mts')) // 'file.d.mts'

Changes the file extension of the given `path`.

Does nothing if a file extension is not provided.
Does nothing if a file extension isn't provided. If the file extension is an empty string, however, the path's file
extension will be removed.

```typescript
import { changeExt } from '@flex-development/pathe'

console.debug(changeExt('file')) // 'file'
console.debug(changeExt('file.mjs', '')) // 'file'
console.debug(changeExt('file', 'mjs')) // 'file.mjs'
console.debug(changeExt('file', '.mjs')) // 'file.mjs'
console.debug(changeExt('file.mts', '.d.mts')) // 'file.d.mts'
Expand Down
7 changes: 4 additions & 3 deletions src/interfaces/pathe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ interface Pathe extends PlatformPath {
/**
* Changes the file extension of the given `path`.
*
* Does nothing if a file extension isn't provided.
* Does nothing if a file extension isn't provided. If the file extension is
* an empty string, however, `path`'s file extension will be removed.
*
* @param {string} path - Path to evaluate
* @param {Nullable<string>} [ext] - File extension to add
* @return {string} `path` unmodified or with new file extension
* @param {Nullable<string>} [ext] - New file extension
* @return {string} `path` unmodified or with changed file extension
* @throws {TypeError} If `path` is not a string or `ext` is not a string
*/
changeExt(path: string, ext?: Nullable<string>): string
Expand Down
7 changes: 3 additions & 4 deletions src/utils/__tests__/change-ext.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import testSubject from '../change-ext'

describe('unit:utils/changeExt', () => {
it('should return path with new file extension', () => {
it('should return path with changed file extension', () => {
// Arrange
const cases: [...Parameters<typeof testSubject>, string][] = [
['file.mjs', '', 'file'],
['file', 'mjs', 'file.mjs'],
['file', 'mts', 'file.mts'],
['file.', '.mjs', 'file.mjs'],
Expand All @@ -23,11 +24,9 @@ describe('unit:utils/changeExt', () => {
})
})

it('should return path without modications if ext is empty', () => {
it('should return path without modications if ext is nil', () => {
// Arrange
const cases: [...Parameters<typeof testSubject>, string][] = [
['file.cjs', '', 'file.cjs'],
['file.cts', ' ', 'file.cts'],
['file.mjs', null, 'file.mjs'],
['file.mts', undefined, 'file.mts']
]
Expand Down
16 changes: 10 additions & 6 deletions src/utils/change-ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,28 @@ import type { Ext } from '#src/types'
import type { EmptyString, Nullable } from '@flex-development/tutils'
import addExt from './add-ext'
import formatExt from './format-ext'
import removeExt from './remove-ext'

/**
* Changes the file extension of the given `path`.
*
* Does nothing if a file extension isn't provided.
* Does nothing if a file extension isn't provided. If the file extension is an
* empty string, however, `path`'s file extension will be removed.
*
* @example
* changeExt('file') // 'file'
* @example
* changeExt('file.mjs', '') // 'file'
* @example
* changeExt('file', 'mjs') // 'file.mjs'
* @example
* changeExt('file', '.mjs') // 'file.mjs'
* @example
* changeExt('file.mts', '.d.mts') // 'file.d.mts'
*
* @param {string} path - Path to evaluate
* @param {Nullable<string>} [ext] - File extension to add
* @return {string} `path` unmodified or with new file extension
* @param {Nullable<string>} [ext] - New file extension
* @return {string} `path` unmodified or with changed file extension
* @throws {TypeError} If `path` is not a string or `ext` is not a string
*/
const changeExt = (path: string, ext?: Nullable<string>): string => {
Expand All @@ -37,9 +41,6 @@ const changeExt = (path: string, ext?: Nullable<string>): string => {
// validate file extension
else validateString(ext, 'ext')

// exit early if extension is empty string
if (!ext.trim()) return path

// ensure path does not end with dot character
path = path.replace(/\.$/, '')

Expand All @@ -50,6 +51,9 @@ const changeExt = (path: string, ext?: Nullable<string>): string => {
*/
const extension: EmptyString | Ext = extname(path)

// remove file extension if new extension is empty string
if (!ext.trim()) return removeExt(path, extension)

return extension
? path.replace(new RegExp(`\\${extension}$`), formatExt(ext))
: addExt(path, ext)
Expand Down

0 comments on commit 3d069cb

Please sign in to comment.