Socket
Socket
Sign inDemoInstall

tsconfig-paths

Package Overview
Dependencies
3
Maintainers
14
Versions
50
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.1.2 to 4.2.0

12

CHANGELOG.md

@@ -10,2 +10,14 @@ # Change Log

## [4.2.0] - 2023-03-29
### Added
- Add support for tsconfig extends as array of strings. #. See PR [#245](https://github.com/dividab/tsconfig-paths/pull/245). Thanks to [@DanielSidhion](https://github.com/DanielSidhion) for this PR!
## [3.14.2] - 2023-02-25
### Fixed
- bump JSON5 from v1.0.1 to v1.0.2 in tsconfig-paths v3.14.1 to fix CVE-2022-46175 #234. See PR [#234](https://github.com/dividab/tsconfig-paths/pull/234). Thanks to [@mihaiplesa](https://github.com/mihaiplesa) for this PR!
## [4.1.2] - 2023-01-02

@@ -12,0 +24,0 @@

91

lib/__tests__/tsconfig-loader.test.js

@@ -138,3 +138,3 @@ "use strict";

describe("loadConfig", function () {
it("It should load a config", function () {
it("should load a config", function () {
var config = { compilerOptions: { baseUrl: "hej" } };

@@ -144,3 +144,3 @@ var res = (0, tsconfig_loader_1.loadTsconfig)("/root/dir1/tsconfig.json", function (path) { return path === "/root/dir1/tsconfig.json"; }, function (_) { return JSON.stringify(config); });

});
it("It should load a config with comments", function () {
it("should load a config with comments", function () {
var config = { compilerOptions: { baseUrl: "hej" } };

@@ -150,3 +150,3 @@ var res = (0, tsconfig_loader_1.loadTsconfig)("/root/dir1/tsconfig.json", function (path) { return path === "/root/dir1/tsconfig.json"; }, function (_) { return "{\n // my comment\n \"compilerOptions\": { \n \"baseUrl\": \"hej\"\n }\n }"; });

});
it("It should load a config with trailing commas", function () {
it("should load a config with trailing commas", function () {
var config = { compilerOptions: { baseUrl: "hej" } };

@@ -156,3 +156,3 @@ var res = (0, tsconfig_loader_1.loadTsconfig)("/root/dir1/tsconfig.json", function (path) { return path === "/root/dir1/tsconfig.json"; }, function (_) { return "{\n \"compilerOptions\": { \n \"baseUrl\": \"hej\",\n },\n }"; });

});
it("It should throw an error including the file path when encountering invalid JSON5", function () {
it("should throw an error including the file path when encountering invalid JSON5", function () {
expect(function () {

@@ -162,3 +162,3 @@ return (0, tsconfig_loader_1.loadTsconfig)("/root/dir1/tsconfig.json", function (path) { return path === "/root/dir1/tsconfig.json"; }, function (_) { return "{\n \"compilerOptions\": {\n }"; });

});
it("It should load a config with extends and overwrite all options", function () {
it("should load a config with string extends and overwrite all options", function () {
var firstConfig = {

@@ -195,3 +195,3 @@ extends: "../base-config.json",

});
it("It should load a config with extends from node_modules and overwrite all options", function () {
it("should load a config with string extends from node_modules and overwrite all options", function () {
var firstConfig = {

@@ -228,3 +228,3 @@ extends: "my-package/base-config.json",

});
it("Should use baseUrl relative to location of extended tsconfig", function () {
it("should use baseUrl relative to location of extended tsconfig", function () {
var firstConfig = { compilerOptions: { baseUrl: "." } };

@@ -257,3 +257,80 @@ var firstConfigPath = (0, path_1.join)("/root", "first-config.json");

});
it("should load a config with array extends and overwrite all options", function () {
var baseConfig1 = {
compilerOptions: { baseUrl: ".", paths: { foo: ["bar"] } },
};
var baseConfig1Path = (0, path_1.join)("/root", "base-config-1.json");
var baseConfig2 = { compilerOptions: { baseUrl: "." } };
var baseConfig2Path = (0, path_1.join)("/root", "dir1", "base-config-2.json");
var baseConfig3 = {
compilerOptions: { baseUrl: ".", paths: { foo: ["bar2"] } },
};
var baseConfig3Path = (0, path_1.join)("/root", "dir1", "dir2", "base-config-3.json");
var actualConfig = {
extends: [
"./base-config-1.json",
"./dir1/base-config-2.json",
"./dir1/dir2/base-config-3.json",
],
};
var actualConfigPath = (0, path_1.join)("/root", "tsconfig.json");
var res = (0, tsconfig_loader_1.loadTsconfig)((0, path_1.join)("/root", "tsconfig.json"), function (path) {
return [
baseConfig1Path,
baseConfig2Path,
baseConfig3Path,
actualConfigPath,
].indexOf(path) >= 0;
}, function (path) {
if (path === baseConfig1Path) {
return JSON.stringify(baseConfig1);
}
if (path === baseConfig2Path) {
return JSON.stringify(baseConfig2);
}
if (path === baseConfig3Path) {
return JSON.stringify(baseConfig3);
}
if (path === actualConfigPath) {
return JSON.stringify(actualConfig);
}
return "";
});
expect(res).toEqual({
extends: [
"./base-config-1.json",
"./dir1/base-config-2.json",
"./dir1/dir2/base-config-3.json",
],
compilerOptions: {
baseUrl: (0, path_1.join)("dir1", "dir2"),
paths: { foo: ["bar2"] },
},
});
});
it("should load a config with array extends without .json extension", function () {
var baseConfig = {
compilerOptions: { baseUrl: ".", paths: { foo: ["bar"] } },
};
var baseConfigPath = (0, path_1.join)("/root", "base-config-1.json");
var actualConfig = { extends: ["./base-config-1"] };
var actualConfigPath = (0, path_1.join)("/root", "tsconfig.json");
var res = (0, tsconfig_loader_1.loadTsconfig)((0, path_1.join)("/root", "tsconfig.json"), function (path) { return [baseConfigPath, actualConfigPath].indexOf(path) >= 0; }, function (path) {
if (path === baseConfigPath) {
return JSON.stringify(baseConfig);
}
if (path === actualConfigPath) {
return JSON.stringify(actualConfig);
}
return "";
});
expect(res).toEqual({
extends: ["./base-config-1"],
compilerOptions: {
baseUrl: ".",
paths: { foo: ["bar"] },
},
});
});
});
//# sourceMappingURL=tsconfig-loader.test.js.map

2

lib/tsconfig-loader.d.ts

@@ -5,3 +5,3 @@ /**

export interface Tsconfig {
extends?: string;
extends?: string | string[];
compilerOptions?: {

@@ -8,0 +8,0 @@ baseUrl?: string;

@@ -101,21 +101,12 @@ "use strict";

if (extendedConfig) {
if (typeof extendedConfig === "string" &&
extendedConfig.indexOf(".json") === -1) {
extendedConfig += ".json";
var base = void 0;
if (Array.isArray(extendedConfig)) {
base = extendedConfig.reduce(function (currBase, extendedConfigElement) {
return mergeTsconfigs(currBase, loadTsconfigFromExtends(configFilePath, extendedConfigElement, existsSync, readFileSync));
}, {});
}
var currentDir = path.dirname(configFilePath);
var extendedConfigPath = path.join(currentDir, extendedConfig);
if (extendedConfig.indexOf("/") !== -1 &&
extendedConfig.indexOf(".") !== -1 &&
!existsSync(extendedConfigPath)) {
extendedConfigPath = path.join(currentDir, "node_modules", extendedConfig);
else {
base = loadTsconfigFromExtends(configFilePath, extendedConfig, existsSync, readFileSync);
}
var base = loadTsconfig(extendedConfigPath, existsSync, readFileSync) || {};
// baseUrl should be interpreted as relative to the base tsconfig,
// but we need to update it so it is relative to the original tsconfig being loaded
if (base.compilerOptions && base.compilerOptions.baseUrl) {
var extendsDir = path.dirname(extendedConfig);
base.compilerOptions.baseUrl = path.join(extendsDir, base.compilerOptions.baseUrl);
}
return __assign(__assign(__assign({}, base), config), { compilerOptions: __assign(__assign({}, base.compilerOptions), config.compilerOptions) });
return mergeTsconfigs(base, config);
}

@@ -125,2 +116,35 @@ return config;

exports.loadTsconfig = loadTsconfig;
/**
* Intended to be called only from loadTsconfig.
* Parameters don't have defaults because they should use the same as loadTsconfig.
*/
function loadTsconfigFromExtends(configFilePath, extendedConfigValue,
// eslint-disable-next-line no-shadow
existsSync, readFileSync) {
var _a;
if (typeof extendedConfigValue === "string" &&
extendedConfigValue.indexOf(".json") === -1) {
extendedConfigValue += ".json";
}
var currentDir = path.dirname(configFilePath);
var extendedConfigPath = path.join(currentDir, extendedConfigValue);
if (extendedConfigValue.indexOf("/") !== -1 &&
extendedConfigValue.indexOf(".") !== -1 &&
!existsSync(extendedConfigPath)) {
extendedConfigPath = path.join(currentDir, "node_modules", extendedConfigValue);
}
var config = loadTsconfig(extendedConfigPath, existsSync, readFileSync) || {};
// baseUrl should be interpreted as relative to extendedConfigPath,
// but we need to update it so it is relative to the original tsconfig being loaded
if ((_a = config.compilerOptions) === null || _a === void 0 ? void 0 : _a.baseUrl) {
var extendsDir = path.dirname(extendedConfigValue);
config.compilerOptions.baseUrl = path.join(extendsDir, config.compilerOptions.baseUrl);
}
return config;
}
function mergeTsconfigs(base, config) {
base = base || {};
config = config || {};
return __assign(__assign(__assign({}, base), config), { compilerOptions: __assign(__assign({}, base.compilerOptions), config.compilerOptions) });
}
//# sourceMappingURL=tsconfig-loader.js.map
{
"name": "tsconfig-paths",
"version": "4.1.2",
"version": "4.2.0",
"description": "Load node modules according to tsconfig paths, in run-time or via API.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -171,3 +171,3 @@ import {

describe("loadConfig", () => {
it("It should load a config", () => {
it("should load a config", () => {
const config = { compilerOptions: { baseUrl: "hej" } };

@@ -182,3 +182,3 @@ const res = loadTsconfig(

it("It should load a config with comments", () => {
it("should load a config with comments", () => {
const config = { compilerOptions: { baseUrl: "hej" } };

@@ -198,3 +198,3 @@ const res = loadTsconfig(

it("It should load a config with trailing commas", () => {
it("should load a config with trailing commas", () => {
const config = { compilerOptions: { baseUrl: "hej" } };

@@ -213,3 +213,3 @@ const res = loadTsconfig(

it("It should throw an error including the file path when encountering invalid JSON5", () => {
it("should throw an error including the file path when encountering invalid JSON5", () => {
expect(() =>

@@ -228,3 +228,3 @@ loadTsconfig(

it("It should load a config with extends and overwrite all options", () => {
it("should load a config with string extends and overwrite all options", () => {
const firstConfig = {

@@ -267,3 +267,3 @@ extends: "../base-config.json",

it("It should load a config with extends from node_modules and overwrite all options", () => {
it("should load a config with string extends from node_modules and overwrite all options", () => {
const firstConfig = {

@@ -312,3 +312,3 @@ extends: "my-package/base-config.json",

it("Should use baseUrl relative to location of extended tsconfig", () => {
it("should use baseUrl relative to location of extended tsconfig", () => {
const firstConfig = { compilerOptions: { baseUrl: "." } };

@@ -345,2 +345,92 @@ const firstConfigPath = join("/root", "first-config.json");

});
it("should load a config with array extends and overwrite all options", () => {
const baseConfig1 = {
compilerOptions: { baseUrl: ".", paths: { foo: ["bar"] } },
};
const baseConfig1Path = join("/root", "base-config-1.json");
const baseConfig2 = { compilerOptions: { baseUrl: "." } };
const baseConfig2Path = join("/root", "dir1", "base-config-2.json");
const baseConfig3 = {
compilerOptions: { baseUrl: ".", paths: { foo: ["bar2"] } },
};
const baseConfig3Path = join("/root", "dir1", "dir2", "base-config-3.json");
const actualConfig = {
extends: [
"./base-config-1.json",
"./dir1/base-config-2.json",
"./dir1/dir2/base-config-3.json",
],
};
const actualConfigPath = join("/root", "tsconfig.json");
const res = loadTsconfig(
join("/root", "tsconfig.json"),
(path) =>
[
baseConfig1Path,
baseConfig2Path,
baseConfig3Path,
actualConfigPath,
].indexOf(path) >= 0,
(path) => {
if (path === baseConfig1Path) {
return JSON.stringify(baseConfig1);
}
if (path === baseConfig2Path) {
return JSON.stringify(baseConfig2);
}
if (path === baseConfig3Path) {
return JSON.stringify(baseConfig3);
}
if (path === actualConfigPath) {
return JSON.stringify(actualConfig);
}
return "";
}
);
expect(res).toEqual({
extends: [
"./base-config-1.json",
"./dir1/base-config-2.json",
"./dir1/dir2/base-config-3.json",
],
compilerOptions: {
baseUrl: join("dir1", "dir2"),
paths: { foo: ["bar2"] },
},
});
});
it("should load a config with array extends without .json extension", () => {
const baseConfig = {
compilerOptions: { baseUrl: ".", paths: { foo: ["bar"] } },
};
const baseConfigPath = join("/root", "base-config-1.json");
const actualConfig = { extends: ["./base-config-1"] };
const actualConfigPath = join("/root", "tsconfig.json");
const res = loadTsconfig(
join("/root", "tsconfig.json"),
(path) => [baseConfigPath, actualConfigPath].indexOf(path) >= 0,
(path) => {
if (path === baseConfigPath) {
return JSON.stringify(baseConfig);
}
if (path === actualConfigPath) {
return JSON.stringify(actualConfig);
}
return "";
}
);
expect(res).toEqual({
extends: ["./base-config-1"],
compilerOptions: {
baseUrl: ".",
paths: { foo: ["bar"] },
},
});
});
});

@@ -12,3 +12,3 @@ import * as path from "path";

export interface Tsconfig {
extends?: string;
extends?: string | string[];
compilerOptions?: {

@@ -135,48 +135,97 @@ baseUrl?: string;

}
let extendedConfig = config.extends;
if (extendedConfig) {
let base: Tsconfig;
if (extendedConfig) {
if (
typeof extendedConfig === "string" &&
extendedConfig.indexOf(".json") === -1
) {
extendedConfig += ".json";
}
const currentDir = path.dirname(configFilePath);
let extendedConfigPath = path.join(currentDir, extendedConfig);
if (
extendedConfig.indexOf("/") !== -1 &&
extendedConfig.indexOf(".") !== -1 &&
!existsSync(extendedConfigPath)
) {
extendedConfigPath = path.join(
currentDir,
"node_modules",
extendedConfig
if (Array.isArray(extendedConfig)) {
base = extendedConfig.reduce(
(currBase, extendedConfigElement) =>
mergeTsconfigs(
currBase,
loadTsconfigFromExtends(
configFilePath,
extendedConfigElement,
existsSync,
readFileSync
)
),
{}
);
} else {
base = loadTsconfigFromExtends(
configFilePath,
extendedConfig,
existsSync,
readFileSync
);
}
const base =
loadTsconfig(extendedConfigPath, existsSync, readFileSync) || {};
return mergeTsconfigs(base, config);
}
return config;
}
// baseUrl should be interpreted as relative to the base tsconfig,
// but we need to update it so it is relative to the original tsconfig being loaded
if (base.compilerOptions && base.compilerOptions.baseUrl) {
const extendsDir = path.dirname(extendedConfig);
base.compilerOptions.baseUrl = path.join(
extendsDir,
base.compilerOptions.baseUrl
);
}
/**
* Intended to be called only from loadTsconfig.
* Parameters don't have defaults because they should use the same as loadTsconfig.
*/
function loadTsconfigFromExtends(
configFilePath: string,
extendedConfigValue: string,
// eslint-disable-next-line no-shadow
existsSync: (path: string) => boolean,
readFileSync: (filename: string) => string
): Tsconfig {
if (
typeof extendedConfigValue === "string" &&
extendedConfigValue.indexOf(".json") === -1
) {
extendedConfigValue += ".json";
}
const currentDir = path.dirname(configFilePath);
let extendedConfigPath = path.join(currentDir, extendedConfigValue);
if (
extendedConfigValue.indexOf("/") !== -1 &&
extendedConfigValue.indexOf(".") !== -1 &&
!existsSync(extendedConfigPath)
) {
extendedConfigPath = path.join(
currentDir,
"node_modules",
extendedConfigValue
);
}
return {
...base,
...config,
compilerOptions: {
...base.compilerOptions,
...config.compilerOptions,
},
};
const config =
loadTsconfig(extendedConfigPath, existsSync, readFileSync) || {};
// baseUrl should be interpreted as relative to extendedConfigPath,
// but we need to update it so it is relative to the original tsconfig being loaded
if (config.compilerOptions?.baseUrl) {
const extendsDir = path.dirname(extendedConfigValue);
config.compilerOptions.baseUrl = path.join(
extendsDir,
config.compilerOptions.baseUrl
);
}
return config;
}
function mergeTsconfigs(
base: Tsconfig | undefined,
config: Tsconfig | undefined
): Tsconfig {
base = base || {};
config = config || {};
return {
...base,
...config,
compilerOptions: {
...base.compilerOptions,
...config.compilerOptions,
},
};
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc