Skip to content

Commit

Permalink
feat(lib): extnames
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <[email protected]>
  • Loading branch information
unicornware committed Sep 22, 2024
1 parent c08ae10 commit 587e890
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 0 deletions.
1 change: 1 addition & 0 deletions .dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pathe
pkgs
posix
preid
remarkrc
shfmt
tscu
unstub
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ This package exports the following identifiers:
- [`dirname`](./src/lib/dirname.ts)
- [`dot`](./src/lib/dot.ts)
- [`extname`](./src/lib/extname.ts)
- [`extnames`](./src/lib/extnames.ts)
- [`formatExt`](./src/lib/format-ext.ts)
- [`format`](./src/lib/format.ts)
- [`isAbsolute`](./src/lib/is-absolute.ts)
Expand Down
1 change: 1 addition & 0 deletions src/__snapshots__/index.e2e.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ exports[`e2e:pathe > should expose public api 1`] = `
"dirname",
"dot",
"extname",
"extnames",
"format",
"formatExt",
"isAbsolute",
Expand Down
13 changes: 13 additions & 0 deletions src/interfaces/pathe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ interface Pathe extends PosixPlatformPath {
*/
formatExt(this: void, ext: string | null | undefined): EmptyString | Ext

/**
* Get a list of file extensions for `path`.
*
* @see {@linkcode Ext}
* @see {@linkcode extname}
*
* @param {string} path
* Path to handle
* @return {Ext[]}
* List of extensions
*/
extnames(path: string): Ext[]

/**
* Check if `value` is a device root.
*
Expand Down
36 changes: 36 additions & 0 deletions src/lib/__snapshots__/extnames.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`unit:lib/extnames > should return list of extensions ("") 1`] = `[]`;

exports[`unit:lib/extnames > should return list of extensions (".") 1`] = `[]`;

exports[`unit:lib/extnames > should return list of extensions (".remarkignore") 1`] = `[]`;

exports[`unit:lib/extnames > should return list of extensions (".remarkrc.mjs") 1`] = `
[
".mjs",
]
`;

exports[`unit:lib/extnames > should return list of extensions ("/") 1`] = `[]`;

exports[`unit:lib/extnames > should return list of extensions ("eslint.base.config.mjs") 1`] = `
[
".base",
".config",
".mjs",
]
`;

exports[`unit:lib/extnames > should return list of extensions ("grease.config.mjs") 1`] = `
[
".config",
".mjs",
]
`;

exports[`unit:lib/extnames > should return list of extensions ("src/lib/extnames.ts") 1`] = `
[
".ts",
]
`;
21 changes: 21 additions & 0 deletions src/lib/__tests__/extnames.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @file Unit Tests - extnames
* @module pathe/lib/tests/unit/extnames
*/

import testSubject from '../extnames'

describe('unit:lib/extnames', () => {
it.each<Parameters<typeof testSubject>>([
[''],
['.'],
['.remarkignore'],
['.remarkrc.mjs'],
['/'],
['eslint.base.config.mjs'],
['grease.config.mjs'],
['src/lib/extnames.ts']
])('should return list of extensions (%j)', path => {
expect(testSubject(path)).toMatchSnapshot()
})
})
57 changes: 57 additions & 0 deletions src/lib/extnames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @file extnames
* @module pathe/lib/extnames
*/

import validateString from '#internal/validate-string'
import type { EmptyString, Ext } from '@flex-development/pathe'
import dot from './dot'
import extname from './extname'
import toPosix from './to-posix'

/**
* Get a list of file extensions for `path`.
*
* @see {@linkcode Ext}
* @see {@linkcode extname}
*
* @param {string} path
* Path to handle
* @return {Ext[]}
* List of extensions
*/
function extnames(path: string): Ext[] {
validateString(path, 'path')

/**
* List of extensions.
*
* @const {Ext[]} extensions
*/
const extensions: Ext[] = []

/**
* Current path.
*
* @var {string} subpath
*/
let subpath: string = toPosix(path)

while (subpath.includes(dot)) {
/**
* Current extension.
*
* @const {EmptyString | Ext} ext
*/
const ext: EmptyString | Ext = extname(subpath)

if (ext === '') break

extensions.unshift(ext)
subpath = subpath.slice(0, subpath.lastIndexOf(ext))
}

return extensions
}

export default extnames
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export { default as delimiter } from './delimiter'
export { default as dirname } from './dirname'
export { default as dot } from './dot'
export { default as extname } from './extname'
export { default as extnames } from './extnames'
export { default as format } from './format'
export { default as formatExt } from './format-ext'
export { default as isAbsolute } from './is-absolute'
Expand Down
2 changes: 2 additions & 0 deletions src/pathe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
dirname,
dot,
extname,
extnames,
format,
formatExt,
isAbsolute,
Expand Down Expand Up @@ -109,6 +110,7 @@ const pathe: Pathe = {
dirname,
dot,
extname,
extnames,
format,
formatExt,
isAbsolute,
Expand Down

0 comments on commit 587e890

Please sign in to comment.