UNPKG

@augment-vir/common

Version:

A collection of augments, helpers types, functions, and classes for any JavaScript environment.

112 lines (111 loc) 3.71 kB
import { isRuntimeEnv, RuntimeEnv } from '@augment-vir/core'; import { wrapInTry } from '../function/wrap-in-try.js'; import { addPrefix } from '../string/prefix.js'; /** * Replaces a path's extension with a new one. If the original path has no extension, `newExtension` * will be appended. * * @category Path : Common * @category Package : @augment-vir/common * @example * * ```ts * import {replaceExtension} from '@augment-vir/common'; * * replaceExtension({path: '/users/stuff/file.ts?tail', newExtension: '.js'}); * // '/users/stuff/file.js?tail' * ``` * * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common) */ export function replaceExtension({ newExtension, path, }) { const { basename, dirname, tail } = extractExtension(path); return [ dirname, basename, addPrefix({ value: newExtension, prefix: '.' }), tail, ].join(''); } /** * Checks if the given path contains an extension. * * @category Path : Common * @category Package : @augment-vir/common * @example * * ```ts * import {hasExtension} from '@augment-vir/common'; * * hasExtension('/users/stuff/file.ts?tail'); // true * hasExtension('/users/stuff/file?tail'); // false * ``` * * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common) */ export function hasExtension(path) { return !!extractExtension(path).extension; } /** * The default `sep` or path separator for use with universal (Node.js and browser supported) path * operations. In the browser, this uses `'/'`. In Node.js, `node:path.sep` is used. * * @category Path : Common * @category Package : @augment-vir/common * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common) */ /* node:coverage ignore next 3: cannot test both on a single system. */ export const defaultSep = isRuntimeEnv(RuntimeEnv.Web) ? '/' : await wrapInTry(async () => (await import('node:path')).sep, { fallbackValue: '/' }); /** * Extracts a path's extension, amongst other things, from the given path, without relying on * Node.js built-in packages (this works in a browser). * * @category Path : Common * @category Package : @augment-vir/common * @example * * ```ts * import {extractExtension} from '@augment-vir/common'; * * const results = extractExtension('/users/stuff/file.ts?tail'); * * // results = { * // basename: 'file', * // dirname: '/users/stuff/', * // extension: '.ts', * // tail: '?tail', * // } * ``` * * @package [`@augment-vir/common`](https://www.npmjs.com/package/@augment-vir/common) */ export function extractExtension(path, /** * By default, the path separator is determined by {@link defaultSep}. With this input you can * override the path separator in use. */ sepOverride) { const sep = sepOverride || defaultSep; const queryIndex = path.indexOf('?'); const hashIndex = path.indexOf('#'); const headTailSplitIndex = hashIndex === -1 ? queryIndex : queryIndex === -1 ? hashIndex : Math.min(hashIndex, queryIndex); const head = headTailSplitIndex === -1 ? path : path.slice(0, headTailSplitIndex); const tail = headTailSplitIndex === -1 ? '' : path.slice(headTailSplitIndex); const lastSep = head.lastIndexOf(sep); /** Includes last slash (if present). */ const dirname = head.slice(0, lastSep + 1); const basename = head.slice(lastSep + 1); const dotIndex = basename.lastIndexOf('.'); return { dirname, basename: dotIndex > 0 ? basename.slice(0, dotIndex) : basename, extension: dotIndex > 0 ? basename.slice(dotIndex) : '', tail, }; }