diff --git a/package.json b/package.json index 6603c35..9b0b9a4 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "test:types": "tsc --noEmit" }, "devDependencies": { - "@types/node": "^22.10.2", + "@types/node": "^22.10.5", "@vitest/coverage-v8": "^2.1.8", "changelogen": "^0.5.7", "esbuild": "^0.24.2", @@ -59,5 +59,5 @@ "vitest": "^2.1.8", "zeptomatch": "^2.0.0" }, - "packageManager": "pnpm@9.15.2" + "packageManager": "pnpm@9.15.3" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ff77d2..e455741 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,11 +9,11 @@ importers: .: devDependencies: '@types/node': - specifier: ^22.10.2 - version: 22.10.2 + specifier: ^22.10.5 + version: 22.10.5 '@vitest/coverage-v8': specifier: ^2.1.8 - version: 2.1.8(vitest@2.1.8(@types/node@22.10.2)) + version: 2.1.8(vitest@2.1.8(@types/node@22.10.5)) changelogen: specifier: ^0.5.7 version: 0.5.7(magicast@0.3.5) @@ -40,7 +40,7 @@ importers: version: 3.2.0(typescript@5.7.2) vitest: specifier: ^2.1.8 - version: 2.1.8(@types/node@22.10.2) + version: 2.1.8(@types/node@22.10.5) zeptomatch: specifier: ^2.0.0 version: 2.0.0 @@ -667,8 +667,8 @@ packages: '@types/mdast@3.0.15': resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} - '@types/node@22.10.2': - resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} + '@types/node@22.10.5': + resolution: {integrity: sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2752,7 +2752,7 @@ snapshots: dependencies: '@types/unist': 2.0.11 - '@types/node@22.10.2': + '@types/node@22.10.5': dependencies: undici-types: 6.20.0 @@ -2839,7 +2839,7 @@ snapshots: '@typescript-eslint/types': 8.18.2 eslint-visitor-keys: 4.2.0 - '@vitest/coverage-v8@2.1.8(vitest@2.1.8(@types/node@22.10.2))': + '@vitest/coverage-v8@2.1.8(vitest@2.1.8(@types/node@22.10.5))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -2853,7 +2853,7 @@ snapshots: std-env: 3.8.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.8(@types/node@22.10.2) + vitest: 2.1.8(@types/node@22.10.5) transitivePeerDependencies: - supports-color @@ -2864,13 +2864,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.2))': + '@vitest/mocker@2.1.8(vite@5.4.11(@types/node@22.10.5))': dependencies: '@vitest/spy': 2.1.8 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 5.4.11(@types/node@22.10.2) + vite: 5.4.11(@types/node@22.10.5) '@vitest/pretty-format@2.1.8': dependencies: @@ -4408,13 +4408,13 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-node@2.1.8(@types/node@22.10.2): + vite-node@2.1.8(@types/node@22.10.5): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 1.1.2 - vite: 5.4.11(@types/node@22.10.2) + vite: 5.4.11(@types/node@22.10.5) transitivePeerDependencies: - '@types/node' - less @@ -4426,19 +4426,19 @@ snapshots: - supports-color - terser - vite@5.4.11(@types/node@22.10.2): + vite@5.4.11(@types/node@22.10.5): dependencies: esbuild: 0.21.5 postcss: 8.4.49 rollup: 4.29.1 optionalDependencies: - '@types/node': 22.10.2 + '@types/node': 22.10.5 fsevents: 2.3.3 - vitest@2.1.8(@types/node@22.10.2): + vitest@2.1.8(@types/node@22.10.5): dependencies: '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.2)) + '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.5)) '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.8 '@vitest/snapshot': 2.1.8 @@ -4454,11 +4454,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.11(@types/node@22.10.2) - vite-node: 2.1.8(@types/node@22.10.2) + vite: 5.4.11(@types/node@22.10.5) + vite-node: 2.1.8(@types/node@22.10.5) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.10.2 + '@types/node': 22.10.5 transitivePeerDependencies: - less - lightningcss diff --git a/src/path.ts b/src/_path.ts similarity index 97% rename from src/path.ts rename to src/_path.ts index 3de767c..84eb4c9 100644 --- a/src/path.ts +++ b/src/_path.ts @@ -26,13 +26,6 @@ const _PATH_ROOT_RE = /^[/\\]|^[a-zA-Z]:[/\\]/; */ export const sep = "/"; -/** - * The platform-specific file delimiter. - * - * Equals to `";"` in windows and `":"` in all other platforms. - */ -export const delimiter = globalThis.process?.platform === "win32" ? ";" : ":"; - export const normalize: typeof path.normalize = function (path: string) { if (path.length === 0) { return "."; diff --git a/src/index.ts b/src/index.ts index 93f172c..e0c8ada 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,36 @@ -import type NodePath from "node:path"; +import type { posix as Posix, win32 as Win32, PlatformPath } from "node:path"; -import * as path from "./path"; +import * as _path from "./_path"; -export * from "./path"; +export * from "./_path"; -export type Pathe = Omit; +/** + * The platform-specific file delimiter. + * + * Equals to `";"` in windows and `":"` in all other platforms. + */ +export const delimiter: ";" | ":" = /* @__PURE__ */ (() => + globalThis.process?.platform === "win32" ? ";" : ":")(); -export const posix = path satisfies Pathe; +// Mix namespaces without side-effects of object to allow tree-shaking -export const win32 = path satisfies Pathe; +const _platforms = { posix: undefined, win32: undefined } as { + posix: typeof Posix; + win32: typeof Win32; +}; -export default path satisfies Pathe; +const mix = (del: ";" | ":" = delimiter) => { + return new Proxy(_path, { + get(_, prop) { + if (prop === "delimiter") return del; + if (prop === "posix") return posix; + if (prop === "win32") return win32; + return _platforms[prop] || _path[prop]; + }, + }) as unknown as PlatformPath; +}; + +export const posix = /* @__PURE__ */ mix(":") as typeof Posix; +export const win32 = /* @__PURE__ */ mix(";") as typeof Win32; + +export default posix; diff --git a/src/utils.ts b/src/utils.ts index 300df7e..41cafad 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { join } from "./path"; +import { join } from "./_path"; import { normalizeWindowsPath } from "./_internal"; const pathSeparators = new Set(["/", "\\", undefined]); diff --git a/test/index.spec.ts b/test/index.spec.ts index 269c911..4dca383 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -16,6 +16,8 @@ import { toNamespacedPath, normalizeString, matchesGlob, + posix, + win32, } from "../src"; import { normalizeWindowsPath } from "../src/_internal"; @@ -397,6 +399,8 @@ runTest("toNamespacedPath", toNamespacedPath, { describe("constants", () => { it("delimiter", () => { + expect(posix.delimiter).to.equal(":"); + expect(win32.delimiter).to.equal(";"); expect(delimiter).to.equal( globalThis.process?.platform === "win32" ? ";" : ":", ); @@ -407,6 +411,13 @@ describe("constants", () => { }); }); +describe("mixed namespaces", () => { + it("nested namespaces work", () => { + expect(posix.win32.posix.delimiter).to.equal(":"); + expect(win32.posix.win32.delimiter).to.equal(";"); + }); +}); + runTest("matchesGlob", matchesGlob, [ ["/foo/bar", "/foo/**", true], [String.raw`\foo\bar`, "/foo/**", true],