Repository: benyap/resolve-tspaths (ts)

Issue:
Paths with special characters are not properly handled
Hi there! Thank you for maintaining this library. My colleagues and I recently stumbled onto a bug that left us scratching our heads for a while, until we figured out the specific reason our build process was failing for only one person on the team.

We concluded that `resolve-tspaths` just doesn't handle  paths with special characters well.

To reproduce this, have a path such as:
```
/home/user/Projects/MyProject (MP)/tsconfig.json`
```
Then running `resolve-tspaths --verbose` in that directory. This will result in `resolve-tspaths` detecting no files to process, even though there are such files. We saw that `filesToProcess` from the `--verbose` output was just empty in this case. The fix for us was simply changing the path to something like:
 ```
/home/user/Projects/MyProject/tsconfig.json`
```
Which works perfectly fine! Spaces didn't seem to be an issue in my tests.

Thanks again, and don't hesitate to reach out if you need further reproduction steps.

Pull request:
fix: escape glob path correctly
Closes #347

Patch:
diff --git a/src/steps/getFilesToProcess.ts b/src/steps/getFilesToProcess.ts
index 14260b1..a2feb6f 100644
--- a/src/steps/getFilesToProcess.ts
+++ b/src/steps/getFilesToProcess.ts
@@ -1,5 +1,5 @@
 import { resolve } from "path";
-import { sync } from "fast-glob";
+import { convertPathToPattern, sync } from "fast-glob";
 
 import { normalizePath } from "~/utils/path";
 
@@ -10,7 +10,7 @@ import { normalizePath } from "~/utils/path";
  * @param extensions A list of extensions to match.
  */
 export function getFilesToProcess(outPath: string, extensions: string[]) {
-  const normalizedOutPath = normalizePath(outPath);
+  const normalizedOutPath = convertPathToPattern(normalizePath(outPath));
 
   let glob = "*";
   if (extensions.length === 1) glob = `*.${extensions[0]}`;
diff --git "a/test/fixtures/(special files*)/file \\slash.js" "b/test/fixtures/(special files*)/file \\slash.js"
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ "b/test/fixtures/(special files*)/file \\slash.js"
@@ -0,0 +1,1 @@
+export {};


Test patch:
diff --git a/test/fixtures/(special files*)/file with (parentheses).js b/test/fixtures/(special files*)/file with (parentheses).js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/test/fixtures/(special files*)/file with (parentheses).js
@@ -0,0 +1,1 @@
+export {};
diff --git a/test/fixtures/(special files*)/file with space.js b/test/fixtures/(special files*)/file with space.js
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/test/fixtures/(special files*)/file with space.js
@@ -0,0 +1,1 @@
+export {};
diff --git a/test/steps/getFilesToProcess.test.ts b/test/steps/getFilesToProcess.test.ts
index 18fa006..102eb09 100644
--- a/test/steps/getFilesToProcess.test.ts
+++ b/test/steps/getFilesToProcess.test.ts
@@ -9,20 +9,47 @@ describe("steps/getFilesToProcess", () => {
     const cwd = process.cwd();
     const testDirectory = join(cwd, "test/fixtures/files");
     const files = getFilesToProcess(testDirectory, ["js"]);
-    expect(files).toHaveLength(1);
+    expect(files.map((path) => path.replace(cwd, ""))).toMatchInlineSnapshot(`
+      [
+        "/test/fixtures/files/file.js",
+      ]
+    `);
   });
 
   it("gets files with multiple extensions correctly", () => {
     const cwd = process.cwd();
     const testDirectory = join(cwd, "test/fixtures/files");
     const files = getFilesToProcess(testDirectory, ["js", "ts"]);
-    expect(files).toHaveLength(2);
+    expect(files.map((path) => path.replace(cwd, ""))).toMatchInlineSnapshot(`
+      [
+        "/test/fixtures/files/file.js",
+        "/test/fixtures/files/file.ts",
+      ]
+    `);
+  });
+
+  it("gets files with paths that have special characters correctly", () => {
+    const cwd = process.cwd();
+    const testDirectory = join(cwd, "test/fixtures/(special files*)");
+    const files = getFilesToProcess(testDirectory, ["js", "ts"]);
+    expect(files.map((path) => path.replace(cwd, ""))).toMatchInlineSnapshot(`
+      [
+        "/test/fixtures/(special files*)/file \\slash.js",
+        "/test/fixtures/(special files*)/file with (parentheses).js",
+        "/test/fixtures/(special files*)/file with space.js",
+      ]
+    `);
   });
 
   it("gets nested files correctly", () => {
     const cwd = process.cwd();
     const testDirectory = join(cwd, "test/fixtures/files");
     const files = getFilesToProcess(testDirectory, ["tsx"]);
-    expect(files).toHaveLength(2);
+    expect(files.map((path) => path.replace(cwd, ""))).toMatchInlineSnapshot(`
+      [
+        "/test/fixtures/files/file.tsx",
+        "/test/fixtures/files/nested/file.tsx",
+      ]
+    `);
   });
 });