Skip to content

Commit

Permalink
Resolve extended TypeScript configuration files
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmckeb committed Sep 28, 2021
1 parent dd81424 commit a316041
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 26 deletions.
59 changes: 33 additions & 26 deletions src/ExportMap.js
@@ -1,4 +1,5 @@
import fs from 'fs';
import path from 'path';

import doctrine from 'doctrine';

Expand All @@ -18,7 +19,7 @@ import { tsConfigLoader } from 'tsconfig-paths/lib/tsconfig-loader';

import includes from 'array-includes';

let parseConfigFileTextToJson;
let ts;

const log = debug('eslint-plugin-import:ExportMap');

Expand Down Expand Up @@ -516,40 +517,17 @@ ExportMap.parse = function (path, content, context) {

const source = makeSourceCode(content, ast);

function readTsConfig() {
const tsConfigInfo = tsConfigLoader({
cwd:
(context.parserOptions && context.parserOptions.tsconfigRootDir) ||
process.cwd(),
getEnv: (key) => process.env[key],
});
try {
if (tsConfigInfo.tsConfigPath !== undefined) {
const jsonText = fs.readFileSync(tsConfigInfo.tsConfigPath).toString();
if (!parseConfigFileTextToJson) {
// this is because projects not using TypeScript won't have typescript installed
({ parseConfigFileTextToJson } = require('typescript'));
}
return parseConfigFileTextToJson(tsConfigInfo.tsConfigPath, jsonText).config;
}
} catch (e) {
// Catch any errors
}

return null;
}

function isEsModuleInterop() {
const cacheKey = hashObject({
tsconfigRootDir: context.parserOptions && context.parserOptions.tsconfigRootDir,
}).digest('hex');
let tsConfig = tsConfigCache.get(cacheKey);
if (typeof tsConfig === 'undefined') {
tsConfig = readTsConfig();
tsConfig = readTsConfig(context);
tsConfigCache.set(cacheKey, tsConfig);
}

return tsConfig && tsConfig.compilerOptions ? tsConfig.compilerOptions.esModuleInterop : false;
return tsConfig && tsConfig.options ? tsConfig.options.esModuleInterop : false;
}

ast.body.forEach(function (n) {
Expand Down Expand Up @@ -785,3 +763,32 @@ function makeSourceCode(text, ast) {
return new SourceCode({ text, ast });
}
}

/**
* Returns a project's TypeScript configuration.
*/
export function readTsConfig(context) {
const tsConfigInfo = tsConfigLoader({
cwd:
(context.parserOptions && context.parserOptions.tsconfigRootDir) ||
process.cwd(),
getEnv: (key) => process.env[key],
});
try {
if (tsConfigInfo.tsConfigPath !== undefined) {
// Projects not using TypeScript won't have `typescript` installed.
if (!ts) (ts = require('typescript'));

const configFile = ts.readConfigFile(tsConfigInfo.tsConfigPath, ts.sys.readFile);
return ts.parseJsonConfigFileContent(
configFile.config,
ts.sys,
path.dirname(tsConfigInfo.tsConfigPath),
);
}
} catch (e) {
// Catch any errors
}

return null;
}
8 changes: 8 additions & 0 deletions tests/files/typescript-extended-config/tsconfig.base.json
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"strict": true
}
}
6 changes: 6 additions & 0 deletions tests/files/typescript-extended-config/tsconfig.json
@@ -0,0 +1,6 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"noEmit": true
}
}
21 changes: 21 additions & 0 deletions tests/src/ExportMap.js
@@ -0,0 +1,21 @@
import { expect } from 'chai';
import { readTsConfig } from '../../src/ExportMap';

describe('ExportMap', function () {
describe('readTsConfig', function () {
const config = readTsConfig({
parserOptions: {
tsconfigRootDir: './tests/files/typescript-extended-config',
},
});
expect(config.options).to.contain({
// Rules from primary config.
noEmit: true,
// Rules from extended config.
esModuleInterop: true,
forceConsistentCasingInFileNames: true,
skipLibCheck: true,
strict: true,
});
});
});

0 comments on commit a316041

Please sign in to comment.