Repository: facebook/jest
File: packages/jest-config/src/readConfigFileAndSetRootDir.ts (TypeScript)

Code before:
 * LICENSE file in the root directory of this source tree.
 */

import * as path from 'path';
import * as fs from 'graceful-fs';
import parseJson = require('parse-json');
import stripJsonComments = require('strip-json-comments');
import type {Service} from 'ts-node';
import type {Config} from '@jest/types';
import {interopRequireDefault, requireOrImportModule} from 'jest-util';
import {
  JEST_CONFIG_EXT_CTS,
  JEST_CONFIG_EXT_JSON,
  JEST_CONFIG_EXT_TS,
  PACKAGE_JSON,
} from './constants';

// Read the configuration and set its `rootDir`
// 1. If it's a `package.json` file, we look into its "jest" property
// 2. If it's a `jest.config.ts` file, we use `ts-node` to transpile & require it
// 3. For any other file, we just require it. If we receive an 'ERR_REQUIRE_ESM'
//    from node, perform a dynamic import instead.
export default async function readConfigFileAndSetRootDir(
  configPath: string,
): Promise<Config.InitialOptions> {
  const isTS = configPath.endsWith(JEST_CONFIG_EXT_TS || JEST_CONFIG_EXT_CTS);
  const isJSON = configPath.endsWith(JEST_CONFIG_EXT_JSON);
  let configObject;

  try {
    if (isTS) {
      configObject = await loadTSConfigFile(configPath);
    } else if (isJSON) {
      const fileContent = fs.readFileSync(configPath, 'utf8');
      configObject = parseJson(stripJsonComments(fileContent), configPath);
    } else {
      configObject = await requireOrImportModule<any>(configPath);
    }
  } catch (error) {
    if (isTS) {
      throw new Error(
        `Jest: Failed to parse the TypeScript config file ${configPath}\n` +
          `  ${error}`,
      );
    }

    throw error;
  }

  if (configPath.endsWith(PACKAGE_JSON)) {
    // Event if there's no "jest" property in package.json we will still use

Review comment (suggestion):
```suggestion
  const isTS =
    configPath.endsWith(JEST_CONFIG_EXT_TS) ||
    configPath.endsWith(JEST_CONFIG_EXT_CTS);
```

@DerTimonius I think this is your issue - `cts` was never considered

Code after:
 * LICENSE file in the root directory of this source tree.
 */

import * as path from 'path';
import * as fs from 'graceful-fs';
import parseJson = require('parse-json');
import stripJsonComments = require('strip-json-comments');
import type {Service} from 'ts-node';
import type {Config} from '@jest/types';
import {interopRequireDefault, requireOrImportModule} from 'jest-util';
import {
  JEST_CONFIG_EXT_CTS,
  JEST_CONFIG_EXT_JSON,
  JEST_CONFIG_EXT_TS,
  PACKAGE_JSON,
} from './constants';

// Read the configuration and set its `rootDir`
// 1. If it's a `package.json` file, we look into its "jest" property
// 2. If it's a `jest.config.ts` file, we use `ts-node` to transpile & require it
// 3. For any other file, we just require it. If we receive an 'ERR_REQUIRE_ESM'
//    from node, perform a dynamic import instead.
export default async function readConfigFileAndSetRootDir(
  configPath: string,
): Promise<Config.InitialOptions> {
  const isTS =
    configPath.endsWith(JEST_CONFIG_EXT_TS) ||
    configPath.endsWith(JEST_CONFIG_EXT_CTS);
  const isJSON = configPath.endsWith(JEST_CONFIG_EXT_JSON);
  let configObject;

  try {
    if (isTS) {
      configObject = await loadTSConfigFile(configPath);
    } else if (isJSON) {
      const fileContent = fs.readFileSync(configPath, 'utf8');
      configObject = parseJson(stripJsonComments(fileContent), configPath);
    } else {
      configObject = await requireOrImportModule<any>(configPath);
    }
  } catch (error) {
    if (isTS) {
      throw new Error(
        `Jest: Failed to parse the TypeScript config file ${configPath}\n` +
          `  ${error}`,
      );
    }

    throw error;
  }