tsconfig-loader.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. "use strict";
  2. var __assign = (this && this.__assign) || function () {
  3. __assign = Object.assign || function(t) {
  4. for (var s, i = 1, n = arguments.length; i < n; i++) {
  5. s = arguments[i];
  6. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
  7. t[p] = s[p];
  8. }
  9. return t;
  10. };
  11. return __assign.apply(this, arguments);
  12. };
  13. Object.defineProperty(exports, "__esModule", { value: true });
  14. exports.loadTsconfig = exports.walkForTsConfig = exports.tsConfigLoader = void 0;
  15. var path = require("path");
  16. var fs = require("fs");
  17. // eslint-disable-next-line @typescript-eslint/no-require-imports
  18. var JSON5 = require("json5");
  19. // eslint-disable-next-line @typescript-eslint/no-require-imports
  20. var StripBom = require("strip-bom");
  21. function tsConfigLoader(_a) {
  22. var getEnv = _a.getEnv, cwd = _a.cwd, _b = _a.loadSync, loadSync = _b === void 0 ? loadSyncDefault : _b;
  23. var TS_NODE_PROJECT = getEnv("TS_NODE_PROJECT");
  24. var TS_NODE_BASEURL = getEnv("TS_NODE_BASEURL");
  25. // tsconfig.loadSync handles if TS_NODE_PROJECT is a file or directory
  26. // and also overrides baseURL if TS_NODE_BASEURL is available.
  27. var loadResult = loadSync(cwd, TS_NODE_PROJECT, TS_NODE_BASEURL);
  28. return loadResult;
  29. }
  30. exports.tsConfigLoader = tsConfigLoader;
  31. function loadSyncDefault(cwd, filename, baseUrl) {
  32. // Tsconfig.loadSync uses path.resolve. This is why we can use an absolute path as filename
  33. var configPath = resolveConfigPath(cwd, filename);
  34. if (!configPath) {
  35. return {
  36. tsConfigPath: undefined,
  37. baseUrl: undefined,
  38. paths: undefined,
  39. };
  40. }
  41. var config = loadTsconfig(configPath);
  42. return {
  43. tsConfigPath: configPath,
  44. baseUrl: baseUrl ||
  45. (config && config.compilerOptions && config.compilerOptions.baseUrl),
  46. paths: config && config.compilerOptions && config.compilerOptions.paths,
  47. };
  48. }
  49. function resolveConfigPath(cwd, filename) {
  50. if (filename) {
  51. var absolutePath = fs.lstatSync(filename).isDirectory()
  52. ? path.resolve(filename, "./tsconfig.json")
  53. : path.resolve(cwd, filename);
  54. return absolutePath;
  55. }
  56. if (fs.statSync(cwd).isFile()) {
  57. return path.resolve(cwd);
  58. }
  59. var configAbsolutePath = walkForTsConfig(cwd);
  60. return configAbsolutePath ? path.resolve(configAbsolutePath) : undefined;
  61. }
  62. function walkForTsConfig(directory, readdirSync) {
  63. if (readdirSync === void 0) { readdirSync = fs.readdirSync; }
  64. var files = readdirSync(directory);
  65. var filesToCheck = ["tsconfig.json", "jsconfig.json"];
  66. for (var _i = 0, filesToCheck_1 = filesToCheck; _i < filesToCheck_1.length; _i++) {
  67. var fileToCheck = filesToCheck_1[_i];
  68. if (files.indexOf(fileToCheck) !== -1) {
  69. return path.join(directory, fileToCheck);
  70. }
  71. }
  72. var parentDirectory = path.dirname(directory);
  73. // If we reached the top
  74. if (directory === parentDirectory) {
  75. return undefined;
  76. }
  77. return walkForTsConfig(parentDirectory, readdirSync);
  78. }
  79. exports.walkForTsConfig = walkForTsConfig;
  80. function loadTsconfig(configFilePath,
  81. // eslint-disable-next-line no-shadow
  82. existsSync, readFileSync) {
  83. if (existsSync === void 0) { existsSync = fs.existsSync; }
  84. if (readFileSync === void 0) { readFileSync = function (filename) {
  85. return fs.readFileSync(filename, "utf8");
  86. }; }
  87. if (!existsSync(configFilePath)) {
  88. return undefined;
  89. }
  90. var configString = readFileSync(configFilePath);
  91. var cleanedJson = StripBom(configString);
  92. var config;
  93. try {
  94. config = JSON5.parse(cleanedJson);
  95. }
  96. catch (e) {
  97. throw new Error("".concat(configFilePath, " is malformed ").concat(e.message));
  98. }
  99. var extendedConfig = config.extends;
  100. if (extendedConfig) {
  101. var base = void 0;
  102. if (Array.isArray(extendedConfig)) {
  103. base = extendedConfig.reduce(function (currBase, extendedConfigElement) {
  104. return mergeTsconfigs(currBase, loadTsconfigFromExtends(configFilePath, extendedConfigElement, existsSync, readFileSync));
  105. }, {});
  106. }
  107. else {
  108. base = loadTsconfigFromExtends(configFilePath, extendedConfig, existsSync, readFileSync);
  109. }
  110. return mergeTsconfigs(base, config);
  111. }
  112. return config;
  113. }
  114. exports.loadTsconfig = loadTsconfig;
  115. /**
  116. * Intended to be called only from loadTsconfig.
  117. * Parameters don't have defaults because they should use the same as loadTsconfig.
  118. */
  119. function loadTsconfigFromExtends(configFilePath, extendedConfigValue,
  120. // eslint-disable-next-line no-shadow
  121. existsSync, readFileSync) {
  122. var _a;
  123. if (typeof extendedConfigValue === "string" &&
  124. extendedConfigValue.indexOf(".json") === -1) {
  125. extendedConfigValue += ".json";
  126. }
  127. var currentDir = path.dirname(configFilePath);
  128. var extendedConfigPath = path.join(currentDir, extendedConfigValue);
  129. if (extendedConfigValue.indexOf("/") !== -1 &&
  130. extendedConfigValue.indexOf(".") !== -1 &&
  131. !existsSync(extendedConfigPath)) {
  132. extendedConfigPath = path.join(currentDir, "node_modules", extendedConfigValue);
  133. }
  134. var config = loadTsconfig(extendedConfigPath, existsSync, readFileSync) || {};
  135. // baseUrl should be interpreted as relative to extendedConfigPath,
  136. // but we need to update it so it is relative to the original tsconfig being loaded
  137. if ((_a = config.compilerOptions) === null || _a === void 0 ? void 0 : _a.baseUrl) {
  138. var extendsDir = path.dirname(extendedConfigValue);
  139. config.compilerOptions.baseUrl = path.join(extendsDir, config.compilerOptions.baseUrl);
  140. }
  141. return config;
  142. }
  143. function mergeTsconfigs(base, config) {
  144. base = base || {};
  145. config = config || {};
  146. return __assign(__assign(__assign({}, base), config), { compilerOptions: __assign(__assign({}, base.compilerOptions), config.compilerOptions) });
  147. }
  148. //# sourceMappingURL=tsconfig-loader.js.map