Repository: benyap/resolve-tspaths (ts)

Issue:
The "extends" field in Tsconfig is not supported
Hello,

I'm trying to use resolve-tspaths in a mono-repo but it seems that the extends in tsconfig is not supported.
Here is an example repo where you can see the problem: [example project](https://github.com/Nooka10/resolve-tspaths-test)

The backend's tsconfig extends `tsconfig/server.json`, which extends `packages/tsconfig/server.json` which extends `packages/tsconfig/base.json`.

The `base.json` config contains the paths but when you run the `build` command, you get an error saying that `compilerOptions.paths is not set in tsconfig`...

<img width="666" alt="Capture d’écran 2023-10-12 à 09 55 05" src="https://github.com/benyap/resolve-tspaths/assets/11243999/f2e1c5a1-110e-4db1-9185-044e4965e2ff">

If you copy the content of the `base.json` file in `backend/tsconfig.json`, then the build works perfectly...

Thanks for the help!

Pull request description:
fix: `extends` field in tsconfig not resolved correctly
Closes #312 

Patch:
diff --git a/src/steps/loadTSConfig.ts b/src/steps/loadTSConfig.ts
index 716cbb2..f02570b 100644
--- a/src/steps/loadTSConfig.ts
+++ b/src/steps/loadTSConfig.ts
@@ -1,3 +1,4 @@
+import { dirname } from "path";
 import {
   findConfigFile,
   parseJsonConfigFileContent,
@@ -17,6 +18,7 @@ export function loadTSConfig(path: string): TSConfig {
   const configFileName = findConfigFile(process.cwd(), sys.fileExists, path);
   if (!configFileName) throw new FileNotFoundError(loadTSConfig.name, path);
   const configFile = readConfigFile(configFileName, sys.readFile);
-  const options = parseJsonConfigFileContent(configFile.config, sys, ".");
+  const directory = dirname(configFileName);
+  const options = parseJsonConfigFileContent(configFile.config, sys, directory);
   return options;
 }


Test patch:
diff --git a/test/fixtures/module/tsconfig.test.json b/test/fixtures/module/tsconfig.test.json
index f07e91b..1de1bbe 100644
--- a/test/fixtures/module/tsconfig.test.json
+++ b/test/fixtures/module/tsconfig.test.json
@@ -1,6 +1,6 @@
 {
   "compilerOptions": {
-    "outDir": "./test/fixtures/module/dist",
+    "outDir": "./dist",
     "baseUrl": ".",
     "paths": {
       "~/*": ["./src/*"]
diff --git a/test/fixtures/tsconfig/tsconfig.extends.jsonc b/test/fixtures/tsconfig/tsconfig.extends.jsonc
index 30dfcce..e3624a8 100644
--- a/test/fixtures/tsconfig/tsconfig.extends.jsonc
+++ b/test/fixtures/tsconfig/tsconfig.extends.jsonc
@@ -1,5 +1,5 @@
 {
-  "extends": "./test/fixtures/tsconfig/nested/tsconfig.parent.jsonc",
+  "extends": "./nested/tsconfig.parent.jsonc",
   /**
    * This is a multiline comment
    */
diff --git a/test/fixtures/tsconfig/tsconfig.extends.no-base-url.jsonc b/test/fixtures/tsconfig/tsconfig.extends.no-base-url.jsonc
index e2ee421..b8a9ed6 100644
--- a/test/fixtures/tsconfig/tsconfig.extends.no-base-url.jsonc
+++ b/test/fixtures/tsconfig/tsconfig.extends.no-base-url.jsonc
@@ -1,5 +1,5 @@
 {
-  "extends": "./test/fixtures/tsconfig/nested/tsconfig.parent.no-base-url.jsonc",
+  "extends": "./nested/tsconfig.parent.no-base-url.jsonc",
   /**
    * This is a multiline comment
    */
diff --git a/test/module/resolveTsPaths.test.ts b/test/module/resolveTsPaths.test.ts
index df84ca0..1fa9815 100644
--- a/test/module/resolveTsPaths.test.ts
+++ b/test/module/resolveTsPaths.test.ts
@@ -19,8 +19,8 @@ describe(resolveTsPaths.name, () => {
     files.forEach((path) =>
       copyFileSync(
         `test/fixtures/module/src/${path}`,
-        `test/fixtures/module/dist/${path}`
-      )
+        `test/fixtures/module/dist/${path}`,
+      ),
     );
   });
 
@@ -31,8 +31,8 @@ describe(resolveTsPaths.name, () => {
     });
     files.forEach((file) =>
       expect(
-        readFileSync(`test/fixtures/module/dist/${file}`).toString()
-      ).toMatchSnapshot()
+        readFileSync(`test/fixtures/module/dist/${file}`).toString(),
+      ).toMatchSnapshot(),
     );
   });
 });
diff --git a/test/steps/loadTSConfig.test.ts b/test/steps/loadTSConfig.test.ts
index da51955..55a678f 100644
--- a/test/steps/loadTSConfig.test.ts
+++ b/test/steps/loadTSConfig.test.ts
@@ -1,10 +1,21 @@
 import { describe, expect, it } from "vitest";
+import { resolve } from "path";
 
 import { loadTSConfig } from "~/steps/loadTSConfig";
 
+/**
+ * HACK: transforms any aboslute paths to relative paths to make testing portable
+ */
+function toRelativePath<T>(path: T): T {
+  if (typeof path === "string")
+    return path.replace(resolve("."), "(relative)") as T;
+  return path;
+}
+
 describe("steps/loadTSConfig", () => {
   it("loads tsconfig (json) correctly", () => {
     const config = loadTSConfig("test/fixtures/tsconfig/tsconfig.test.json");
+    config.options.pathsBasePath = toRelativePath(config.options.pathsBasePath);
     expect(config.options).toMatchInlineSnapshot(`
       {
         "configFilePath": undefined,
@@ -29,8 +40,11 @@ describe("steps/loadTSConfig", () => {
 
   it("loads tsconfig (jsonc) with extends correctly", () => {
     const config = loadTSConfig(
-      "test/fixtures/tsconfig/tsconfig.extends.jsonc"
+      "test/fixtures/tsconfig/tsconfig.extends.jsonc",
     );
+    config.options.baseUrl = toRelativePath(config.options.baseUrl);
+    config.options.outDir = toRelativePath(config.options.outDir);
+    config.options.pathsBasePath = toRelativePath(config.options.pathsBasePath);
     expect(config.options).toMatchInlineSnapshot(`
       {
         "baseUrl": "test/fixtures/tsconfig/nested",
@@ -57,8 +71,10 @@ describe("steps/loadTSConfig", () => {
 
   it("loads tsconfig (jsonc) with extends correctly (no baseUrl)", () => {
     const config = loadTSConfig(
-      "test/fixtures/tsconfig/tsconfig.extends.no-base-url.jsonc"
+      "test/fixtures/tsconfig/tsconfig.extends.no-base-url.jsonc",
     );
+    config.options.outDir = toRelativePath(config.options.outDir);
+    config.options.pathsBasePath = toRelativePath(config.options.pathsBasePath);
     expect(config.options).toMatchInlineSnapshot(`
       {
         "configFilePath": undefined,
@@ -86,8 +102,9 @@ describe("steps/loadTSConfig", () => {
   // Turns out the Typescript config loader does some crazy stuff to recover from syntax errors!
   it("loads tsconfig with syntax errors (crazy stuff!)", () => {
     const config = loadTSConfig(
-      "test/fixtures/tsconfig/tsconfig.syntax-error.json"
+      "test/fixtures/tsconfig/tsconfig.syntax-error.json",
     );
+    config.options.pathsBasePath = toRelativePath(config.options.pathsBasePath);
     expect(config.options).toMatchInlineSnapshot(`
       {
         "configFilePath": undefined,