Skip to content

Commit

Permalink
feat(utils): add reverseResolveAlias util (#173)
Browse files Browse the repository at this point in the history
Co-authored-by: Pooya Parsa <[email protected]>
  • Loading branch information
Jesse1989pp and pi0 authored Jan 3, 2025
1 parent b91e344 commit 9158288
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Pathe exports some extra utilities that do not exist in standard Node.js [path m
In order to use them, you can import from `pathe/utils` subpath:

```js
import { filename, normalizeAliases, resolveAlias } from 'pathe/utils'
import { filename, normalizeAliases, resolveAlias, reverseResolveAlias } from 'pathe/utils'
```

## License
Expand Down
31 changes: 31 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,37 @@ export function resolveAlias(path: string, aliases: Record<string, string>) {
return _path;
}

/**
* Resolves a path string to its possible alias.
*
* Returns an array of possible alias resolutions (could be empty), sorted by specificity (longest first).
*/
export function reverseResolveAlias(
path: string,
aliases: Record<string, string>,
): string[] {
const _path = normalizeWindowsPath(path);
aliases = normalizeAliases(aliases);

const matches: string[] = [];

for (const [to, alias] of Object.entries(aliases)) {
if (!_path.startsWith(alias)) {
continue;
}

// Strip trailing slash from alias for check
const _alias = hasTrailingSlash(alias) ? alias.slice(0, -1) : alias;

if (hasTrailingSlash(_path[_alias.length])) {
matches.push(join(to, _path.slice(alias.length)));
}
}

// Sort by length, longest (more specific) first
return matches.sort((a, b) => b.length - a.length);
}

/**
* Extracts the filename from a given path, excluding any directory paths and the file extension.
*
Expand Down
44 changes: 43 additions & 1 deletion test/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { describe, expect, it } from "vitest";

import { normalizeAliases, filename, resolveAlias } from "../src/utils";
import {
normalizeAliases,
filename,
resolveAlias,
reverseResolveAlias,
} from "../src/utils";

describe("alias", () => {
const _aliases = {
Expand Down Expand Up @@ -56,6 +61,43 @@ describe("alias", () => {
expect(resolveAlias("~win/foo/bar", aliases)).toBe("C:/src/foo/bar");
});
});

describe("reverseResolveAlias", () => {
const overrides = {
"/root/bingpot/index.ts": ["@/bingpot/index.ts", "bingpot"],
"/root/index.js": ["@/index.js", "~"],
};
for (const [to, from] of Object.entries(aliases)) {
const expected = overrides[from] || [to];
it(`reverseResolveAlias("${from}")`, () => {
expect(reverseResolveAlias(from, aliases)).toMatchObject(expected);
});
}

it("respects path separators", () => {
const aliases = {
"~": "/root",
"~assets": "/root/some/assets",
};
expect(
reverseResolveAlias("/root/some/assets/smth.jpg", aliases),
).toMatchObject(["~/some/assets/smth.jpg", "~assets/smth.jpg"]);
});

it("no match", () => {
expect(reverseResolveAlias("foo/bar.js", aliases)).toMatchObject([]);
expect(reverseResolveAlias("./bar.js", aliases)).toMatchObject([]);
});

it("respect ending with /", () => {
expect(reverseResolveAlias("/src/foo/bar", aliases)).toMatchObject([
"~/foo/bar",
]);
expect(reverseResolveAlias("C:/src/foo/bar", aliases)).toMatchObject([
"~win/foo/bar",
]);
});
});
});

describe("filename", () => {
Expand Down

0 comments on commit 9158288

Please sign in to comment.