feat(path/unstable): support URL in extname() (#5818)

* feat(path/unstable): support URL in `extname()`

* update

* fix

* fixes

* use fromFileUrl in window implementation

---------

Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
This commit is contained in:
Asher Gomez 2024-08-26 17:33:53 +10:00 committed by GitHub
parent 3cf1e611a6
commit 3666d84513
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 88 additions and 12 deletions

View File

@ -22,6 +22,29 @@ import { extname as windowsExtname } from "./windows/extname.ts";
* @param path Path with extension.
* @returns The file extension. E.g. returns `.ts` for `file.ts`.
*/
export function extname(path: string): string {
return isWindows ? windowsExtname(path) : posixExtname(path);
export function extname(path: string): string;
/**
* Return the extension of the path with leading period (".").
*
* @experimental **UNSTABLE**: New API, yet to be vetted.
*
* @example Usage
* ```ts
* import { extname } from "@std/path/extname";
* import { assertEquals } from "@std/assert";
*
* if (Deno.build.os === "windows") {
* assertEquals(extname(new URL("file:///C:/home/user/Documents/image.png")), ".png");
* } else {
* assertEquals(extname(new URL("file:///home/user/Documents/image.png")), ".png");
* }
* ```
*
* @param path Path with extension.
* @returns The file extension. E.g. returns `.ts` for `file.ts`.
*/
export function extname(path: URL): string;
export function extname(path: string | URL): string {
// deno-lint-ignore no-explicit-any
return isWindows ? windowsExtname(path as any) : posixExtname(path as any);
}

View File

@ -68,6 +68,15 @@ Deno.test("posix.extname()", function () {
assertEquals(posix.extname("file\\\\"), "");
assertEquals(posix.extname("file.\\"), ".\\");
assertEquals(posix.extname("file.\\\\"), ".\\\\");
assertEquals(
posix.extname(new URL("file:///home/user/Documents/image.png")),
".png",
);
assertEquals(
posix.extname(new URL("file:///home/user/Documents")),
"",
);
});
Deno.test("windows.extname()", function () {
@ -87,4 +96,13 @@ Deno.test("windows.extname()", function () {
assertEquals(windows.extname("file\\\\"), "");
assertEquals(windows.extname("file.\\"), ".");
assertEquals(windows.extname("file.\\\\"), ".");
assertEquals(
windows.extname(new URL("file:///C:/home/user/Documents/image.png")),
".png",
);
assertEquals(
windows.extname(new URL("file:///C:/home/user/Documents")),
"",
);
});

View File

@ -4,6 +4,7 @@
import { CHAR_DOT } from "../_common/constants.ts";
import { assertPath } from "../_common/assert_path.ts";
import { isPosixPathSeparator } from "./_util.ts";
import { fromFileUrl } from "./from_file_url.ts";
/**
* Return the extension of the `path` with leading period.
@ -18,26 +19,37 @@ import { isPosixPathSeparator } from "./_util.ts";
* assertEquals(extname("/home/user/Documents/image.png"), ".png");
* ```
*
* @example Working with URLs
* @param path The path to get the extension from.
* @returns The extension (ex. for `file.ts` returns `.ts`).
*/
export function extname(path: string): string;
/**
* Return the extension of the `path` with leading period.
*
* Note: This function doesn't automatically strip hash and query parts from
* URLs. If your URL contains a hash or query, remove them before passing the
* URL to the function. This can be done by passing the URL to `new URL(url)`,
* and setting the `hash` and `search` properties to empty strings.
* Note: Hashes and query parameters are ignore when constructing a URL.
*
* @experimental **UNSTABLE**: New API, yet to be vetted.
*
* @example Usage
*
* ```ts
* import { extname } from "@std/path/posix/extname";
* import { assertEquals } from "@std/assert";
*
* assertEquals(extname("https://deno.land/std/path/mod.ts"), ".ts");
* assertEquals(extname("https://deno.land/std/path/mod.ts?a=b"), ".ts?a=b");
* assertEquals(extname("https://deno.land/std/path/mod.ts#header"), ".ts#header");
* assertEquals(extname(new URL("file:///home/user/Documents/file.ts")), ".ts");
* assertEquals(extname(new URL("file:///home/user/Documents/file.ts?a=b")), ".ts");
* assertEquals(extname(new URL("file:///home/user/Documents/file.ts#header")), ".ts");
* ```
*
* @param path The path to get the extension from.
* @returns The extension (ex. for `file.ts` returns `.ts`).
*/
export function extname(path: string): string {
export function extname(path: URL): string;
export function extname(path: string | URL): string {
if (path instanceof URL) {
path = fromFileUrl(path);
}
assertPath(path);
let startDot = -1;

View File

@ -4,6 +4,7 @@
import { CHAR_COLON, CHAR_DOT } from "../_common/constants.ts";
import { assertPath } from "../_common/assert_path.ts";
import { isPathSeparator, isWindowsDeviceRoot } from "./_util.ts";
import { fromFileUrl } from "./from_file_url.ts";
/**
* Return the extension of the `path` with leading period.
@ -20,7 +21,29 @@ import { isPathSeparator, isWindowsDeviceRoot } from "./_util.ts";
* @param path The path to get the extension from.
* @returns The extension of the `path`.
*/
export function extname(path: string): string {
export function extname(path: string): string;
/**
* Return the extension of the `path` with leading period.
*
* @experimental **UNSTABLE**: New API, yet to be vetted.
*
* @example Usage
* ```ts
* import { extname } from "@std/path/windows/extname";
* import { assertEquals } from "@std/assert";
*
* const ext = extname(new URL("file:///C:/foo/bar/baz.ext"));
* assertEquals(ext, ".ext");
* ```
*
* @param path The path to get the extension from.
* @returns The extension of the `path`.
*/
export function extname(path: URL): string;
export function extname(path: string | URL): string {
if (path instanceof URL) {
path = fromFileUrl(path);
}
assertPath(path);
let start = 0;