diff --git a/src/filesystem.ts b/src/filesystem.ts index cf889fd..8af0f32 100644 --- a/src/filesystem.ts +++ b/src/filesystem.ts @@ -60,3 +60,7 @@ export function fileExistsAsync( callback2(undefined, stats ? stats.isFile() : false); }); } + +export function removeExtension(path: string): string { + return path.substring(0, path.lastIndexOf(".")) || path; +} diff --git a/src/match-path-async.ts b/src/match-path-async.ts index 9bb51e6..cbb5e9b 100644 --- a/src/match-path-async.ts +++ b/src/match-path-async.ts @@ -1,6 +1,7 @@ import * as TryPath from "./try-path"; import * as MappingEntry from "./mapping-entry"; import * as Filesystem from "./filesystem"; +import { dirname } from "path"; /** * Function that can match a path async @@ -86,7 +87,7 @@ export function matchFromAbsolutePathsAsync( return afterFilesChecked(new Error("pathsToTry cannot be undefined.")); } const toTry = pathsToTry[index]; - if (toTry.type === "file") { + if (toTry.type === "file" || toTry.type === "index") { fileExists(toTry.path, (err: Error, exists: boolean) => { if (err) { return afterFilesChecked(err); @@ -116,7 +117,14 @@ export function matchFromAbsolutePathsAsync( } for (let i = 0; i < fileExistsResults.length; i++) { if (fileExistsResults[i]) { - return callback(undefined, pathsToTry[i].path); + const tryPath = pathsToTry[i]; + const result = + tryPath.type === "index" + ? dirname(tryPath.path) + : tryPath.type === "file" + ? Filesystem.removeExtension(tryPath.path) + : tryPath.path; + return callback(undefined, result); } } return callback(); diff --git a/src/try-path.ts b/src/try-path.ts index 0f60266..4144e6a 100644 --- a/src/try-path.ts +++ b/src/try-path.ts @@ -3,7 +3,7 @@ import { matchStar } from "./match-star"; import { MappingEntry } from "./mapping-entry"; export interface TryPath { - readonly type: "file" | "package"; + readonly type: "file" | "index" | "package"; readonly path: string; } @@ -49,7 +49,7 @@ export function getPathsToTry( const indexPath = path.join(physicalPath, "/index"); pathsToTry.push( ...extensions.map( - e => ({ type: "file", path: indexPath + e } as TryPath) + e => ({ type: "index", path: indexPath + e } as TryPath) ) ); } diff --git a/test/match-path-async-tests.ts b/test/match-path-async-tests.ts index ba58ee6..cbb968c 100644 --- a/test/match-path-async-tests.ts +++ b/test/match-path-async-tests.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { createMatchPathAsync } from "../src/match-path-async"; -import { join } from "path"; +import { join, dirname } from "path"; describe("match-path-async", () => { it("should locate path that matches with star and exists", done => { @@ -14,25 +14,24 @@ describe("match-path-async", () => { (path, callback) => callback(undefined, path === existingPath), undefined, (_err, result) => { - assert.equal(result, existingPath); + assert.equal(result, dirname(existingPath)); done(); } ); }); - /* it("should resolve to correct path when many are specified", () => { const matchPath = createMatchPath("/root/", { "lib/*": ["foo1/*", "foo2/*", "location/*", "foo3/*"] }); + const existingPath = join("/root", "location", "mylib", "index.ts"); const result = matchPath( - "/root/test.ts", "lib/mylib", (_: string) => undefined, - (name: string) => name === join("/root", "location", "mylib", "index.ts"), + (name: string) => name === existingPath, [".ts"] ); - assert.equal(result, join("/root", "location", "mylib")); + assert.equal(result, dirname(existingPath)); }); it("should locate path that matches with star and prioritize pattern with longest prefix", () => { @@ -40,80 +39,78 @@ describe("match-path-async", () => { "*": ["location/*"], "lib/*": ["location/*"] }); + const existingPath1 = join("/root", "location", "lib", "mylib", "index.ts"); + const existingPath2 = join("/root", "location", "mylib", "index.ts"); const result = matchPath( - "/root/test.ts", "lib/mylib", undefined, - (name: string) => - name === join("/root", "location", "lib", "mylib", "index.ts") || - name === join("/root", "location", "mylib", "index.ts") + (name: string) => name === existingPath1 || name === existingPath2 ); - assert.equal(result, join("/root", "location", "mylib")); + assert.equal(result, dirname(existingPath2)); }); it("should locate path that matches with star and exists with extension", () => { const matchPath = createMatchPath("/root/", { "lib/*": ["location/*"] }); + const existingPath = join("/root", "location", "mylib.myext"); const result = matchPath( - "/root/test.ts", "lib/mylib", (_: string) => undefined, - (name: string) => name === join("/root", "location", "mylib.myext"), + (name: string) => name === existingPath, [".js", ".myext"] ); - assert.equal(result, join("/root", "location", "mylib")); + assert.equal(result, removeExtension(existingPath)); }); it("should resolve request with extension specified", () => { const matchPath = createMatchPath("/root/", { "lib/*": ["location/*"] }); + const existingPath = join("/root", "location", "test.jpg"); const result = matchPath( - "/root/test.ts", "lib/test.jpg", (_: string) => undefined, - (name: string) => name === join("/root", "location", "test.jpg"), + (name: string) => name === existingPath, [".js", ".myext"] ); - assert.equal(result, join("/root", "location", "test.jpg")); + assert.equal(result, existingPath); }); it("should locate path that matches without star and exists", () => { const matchPath = createMatchPath("/root/", { "lib/foo": ["location/foo"] }); + const existingPath = join("/root", "location", "foo.ts"); const result = matchPath( - "/root/test.ts", "lib/foo", (_: string) => undefined, - (name: string) => name === join("/root", "location", "foo.ts") + (name: string) => name === existingPath ); - assert.equal(result, join("/root", "location", "foo")); + assert.equal(result, removeExtension(existingPath)); }); it("should resolve to parent folder when filename is in subfolder", () => { const matchPath = createMatchPath("/root/", { "lib/*": ["location/*"] }); + const existingPath = join("/root", "location", "mylib", "index.ts"); const result = matchPath( - "/root/subfolder/file.ts", "lib/mylib", (_: string) => undefined, - (name: string) => name === join("/root", "location", "mylib", "index.ts") + (name: string) => name === existingPath ); - assert.equal(result, join("/root", "location", "mylib")); + assert.equal(result, dirname(existingPath)); }); it("should resolve from main field in package.json", () => { const matchPath = createMatchPath("/root/", { "lib/*": ["location/*"] }); + const existingPath = join("/root", "location", "mylib", "kalle.ts"); const result = matchPath( - "/root/subfolder/file.ts", "lib/mylib", (_: string) => ({ main: "./kalle.ts" }), - (name: string) => name === join("/root", "location", "mylib", "kalle.ts") + (name: string) => name === existingPath ); - assert.equal(result, join("/root", "location", "mylib", "kalle")); + assert.equal(result, removeExtension(existingPath)); }); it("should resolve from main field in package.json and correctly remove file extension", () => { const matchPath = createMatchPath("/root/", { "lib/*": ["location/*"] }); const result = matchPath( - "/root/subfolder/file.js", "lib/mylib.js", (_: string) => ({ main: "./kalle.js" }), (name: string) => @@ -123,7 +120,6 @@ describe("match-path-async", () => { // Make sure we escape the "." const result2 = matchPath( - "/root/subfolder/file.js", "lib/mylibjs", (_: string) => ({ main: "./kallejs" }), (name: string) => @@ -137,25 +133,24 @@ describe("match-path-async", () => { it("should resolve to with the help of baseUrl when not explicitly set", () => { const matchPath = createMatchPath("/root/", {}); + const existingPath = join("/root", "mylib", "index.ts"); const result = matchPath( - "/root/test.ts", "mylib", (_: string) => undefined, - (name: string) => name === join("/root", "mylib", "index.ts") + (name: string) => name === existingPath ); - assert.equal(result, "/root/mylib"); + assert.equal(result, dirname(existingPath)); }); it("should not locate path that does not match", () => { const matchPath = createMatchPath("/root/", { "lib/*": ["location/*"] }); + const existingPath = join("root", "location", "mylib"); const result = matchPath( - "/root/asd.ts", "mylib", (_: string) => undefined, - (name: string) => name === join("root", "location", "mylib") + (name: string) => name === existingPath ); assert.equal(result, undefined); }); - */ }); diff --git a/test/match-path-sync-tests.ts b/test/match-path-sync-tests.ts index 1445af9..850a9fc 100644 --- a/test/match-path-sync-tests.ts +++ b/test/match-path-sync-tests.ts @@ -1,10 +1,7 @@ import { assert } from "chai"; import { createMatchPath } from "../src/match-path-sync"; import { join, dirname } from "path"; - -function removeExtension(path: string): string { - return path.substring(0, path.lastIndexOf(".")) || path; -} +import { removeExtension } from "../src/filesystem"; describe("match-path-sync", () => { it("should locate path that matches with star and exists", () => { diff --git a/test/try-path-tests.ts b/test/try-path-tests.ts index 47e15db..a5e7700 100644 --- a/test/try-path-tests.ts +++ b/test/try-path-tests.ts @@ -46,15 +46,15 @@ describe("mapping-entry", () => { { type: "file", path: "/absolute/base/url/foo2/bar.ts" }, { type: "file", path: "/absolute/base/url/foo2/bar.tsx" }, { type: "package", path: "/absolute/base/url/foo2/bar/package.json" }, - { type: "file", path: "/absolute/base/url/foo2/bar/index.ts" }, - { type: "file", path: "/absolute/base/url/foo2/bar/index.tsx" }, + { type: "index", path: "/absolute/base/url/foo2/bar/index.ts" }, + { type: "index", path: "/absolute/base/url/foo2/bar/index.tsx" }, // "*" { type: "file", path: "/absolute/base/url/foo1" }, { type: "file", path: "/absolute/base/url/foo1.ts" }, { type: "file", path: "/absolute/base/url/foo1.tsx" }, { type: "package", path: "/absolute/base/url/foo1/package.json" }, - { type: "file", path: "/absolute/base/url/foo1/index.ts" }, - { type: "file", path: "/absolute/base/url/foo1/index.tsx" } + { type: "index", path: "/absolute/base/url/foo1/index.ts" }, + { type: "index", path: "/absolute/base/url/foo1/index.tsx" } ]); }); });