<commit_before>// @remove-file-on-eject
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

'use strict';

const chalk = require('chalk');
const fs = require('fs');
const resolve = require('resolve');
const path = require('path');
const paths = require('../../config/paths');
const os = require('os');

function writeJson(fileName, object) {
  fs.writeFileSync(fileName, JSON.stringify(object, null, 2) + os.EOL);
}

const compilerOptions = {
  // These are suggested values and will be set when not present in the
  // tsconfig.json
  target: { suggested: 'es5' },
  allowJs: { suggested: true },
  skipLibCheck: { suggested: true },
  esModuleInterop: { suggested: true },
  allowSyntheticDefaultImports: { suggested: true },
  strict: { suggested: true },

  // This values are required and cannot be changed by the user
  module: { value: 'esnext', reason: 'for import() and import/export' },
  moduleResolution: { value: 'node', reason: 'to match webpack resolution' },
  isolatedModules: { value: true, reason: 'implementation limitation' },
  noEmit: { value: true },
  jsx: { value: 'preserve', reason: 'JSX is compiled by Babel' },
};

function verifyTypeScriptSetup() {
  if (!fs.existsSync(paths.appTsConfig)) {
    if (!paths.appIndexJs.match(/\.ts?$/)) {
      return;
    }
    writeJson(paths.appTsConfig, {});
  }

  const isYarn = fs.existsSync(paths.yarnLockFile);

  // Ensure typescript is installed
  try {
    resolve.sync('typescript', {
      basedir: paths.appNodeModules,
    });
  } catch (_) {
    console.error(
      chalk.red(
        'We detected a',
        chalk.bold('tsconfig.json'),
        "in your package root but couldn't find an installation of",
        chalk.bold('typescript') + '.'
      )
    );
    console.error();
    console.error(
      chalk.bold(
        'Please install',
        chalk.cyan.bold('typescript'),
        'by running',
        chalk.cyan.bold(
          isYarn ? 'yarn add typescript' : 'npm install typescript'
        ) + '.'
      )
    );
    console.error(
      'If you are not trying to use TypeScript, please remove the ' +
        chalk.cyan('tsconfig.json') +
        ' file from your package root.'
    );
    console.error();
    process.exit(1);
  }

  const messages = [];
  let tsconfig;
  try {
    tsconfig = require(paths.appTsConfig);
  } catch (_) {
    console.error(
      chalk.red.bold(
        'Could not parse',
        chalk.cyan('tsconfig.json') + '.',
        'Please make sure it contains syntactically correct JSON.'
      )
    );
    process.exit(1);
  }

  if (tsconfig.compilerOptions == null) {
    tsconfig.compilerOptions = {};
  }

  for (const option of Object.keys(compilerOptions)) {
    const { value, suggested, reason } = compilerOptions[option];
    if (suggested != null) {
      if (tsconfig.compilerOptions[option] === undefined) {
        tsconfig.compilerOptions[option] = suggested;
        messages.push(
          `${chalk.cyan('compilerOptions.' + option)} to be ${chalk.bold(
            'suggested'
          )} value: ${chalk.cyan.bold(suggested)} (this can be changed)`
        );
      }
    } else if (tsconfig.compilerOptions[option] !== value) {
      tsconfig.compilerOptions[option] = value;
      messages.push(
        `${chalk.cyan('compilerOptions.' + option)} ${chalk.bold(
          'must'
        )} be ${chalk.cyan.bold(value)}` +
          (reason != null ? ` (${reason})` : '')
      );
    }
  }

  if (tsconfig.include == null) {
    tsconfig.include = ['src'];
    messages.push(
      `${chalk.cyan('include')} should be ${chalk.cyan.bold('src')}`
    );
  }
  if (tsconfig.exclude == null) {
    tsconfig.exclude = ['**/__tests__/**', '**/?*(spec|test).*'];
    messages.push(`${chalk.cyan('exclude')} should exclude test files`);
  }

  if (messages.length > 0) {
    console.warn(
      chalk.bold(
        'The following changes are being made to your',
        chalk.cyan('tsconfig.json'),
        'file:'
      )
    );
    messages.forEach(message => {
      console.warn('  - ' + message);
    });
    console.warn();
    writeJson(paths.appTsConfig, tsconfig);
  }

  // Copy type declarations associated with this version of `react-scripts`
  const declaredTypes = path.resolve(
    __dirname,
    '..',
    '..',
    'config',
    'react-app.d.ts'
  );
  const declaredTypesContent = fs
    .readFileSync(declaredTypes, 'utf8')
    .replace(/\/\/ @remove-file-on-eject\r?\n/, '');
  fs.writeFileSync(
    path.resolve(paths.appSrc, 'react-app.d.ts'),
    declaredTypesContent
  );
}

module.exports = verifyTypeScriptSetup;
<commit_msg>Print friendly message on first time use<commit_after>// @remove-file-on-eject
/**
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

'use strict';

const chalk = require('chalk');
const fs = require('fs');
const resolve = require('resolve');
const path = require('path');
const paths = require('../../config/paths');
const os = require('os');

function writeJson(fileName, object) {
  fs.writeFileSync(fileName, JSON.stringify(object, null, 2) + os.EOL);
}

const compilerOptions = {
  // These are suggested values and will be set when not present in the
  // tsconfig.json
  target: { suggested: 'es5' },
  allowJs: { suggested: true },
  skipLibCheck: { suggested: true },
  esModuleInterop: { suggested: true },
  allowSyntheticDefaultImports: { suggested: true },
  strict: { suggested: true },

  // This values are required and cannot be changed by the user
  module: { value: 'esnext', reason: 'for import() and import/export' },
  moduleResolution: { value: 'node', reason: 'to match webpack resolution' },
  isolatedModules: { value: true, reason: 'implementation limitation' },
  noEmit: { value: true },
  jsx: { value: 'preserve', reason: 'JSX is compiled by Babel' },
};

function verifyTypeScriptSetup() {
  let firstTimeSetup = false;

  if (!fs.existsSync(paths.appTsConfig)) {
    if (!paths.appIndexJs.match(/\.ts?$/)) {
      return;
    }
    writeJson(paths.appTsConfig, {});
    firstTimeSetup = true;
  }

  const isYarn = fs.existsSync(paths.yarnLockFile);

  // Ensure typescript is installed
  try {
    resolve.sync('typescript', {
      basedir: paths.appNodeModules,
    });
  } catch (_) {
    console.error(
      chalk.red(
        'We detected a',
        chalk.bold('tsconfig.json'),
        "in your package root but couldn't find an installation of",
        chalk.bold('typescript') + '.'
      )
    );
    console.error();
    console.error(
      chalk.bold(
        'Please install',
        chalk.cyan.bold('typescript'),
        'by running',
        chalk.cyan.bold(
          isYarn ? 'yarn add typescript' : 'npm install typescript'
        ) + '.'
      )
    );
    console.error(
      'If you are not trying to use TypeScript, please remove the ' +
        chalk.cyan('tsconfig.json') +
        ' file from your package root.'
    );
    console.error();
    process.exit(1);
  }

  const messages = [];
  let tsconfig;
  try {
    tsconfig = require(paths.appTsConfig);
  } catch (_) {
    console.error(
      chalk.red.bold(
        'Could not parse',
        chalk.cyan('tsconfig.json') + '.',
        'Please make sure it contains syntactically correct JSON.'
      )
    );
    process.exit(1);
  }

  if (tsconfig.compilerOptions == null) {
    tsconfig.compilerOptions = {};
    firstTimeSetup = true;
  }

  for (const option of Object.keys(compilerOptions)) {
    const { value, suggested, reason } = compilerOptions[option];
    if (suggested != null) {
      if (tsconfig.compilerOptions[option] === undefined) {
        tsconfig.compilerOptions[option] = suggested;
        messages.push(
          `${chalk.cyan('compilerOptions.' + option)} to be ${chalk.bold(
            'suggested'
          )} value: ${chalk.cyan.bold(suggested)} (this can be changed)`
        );
      }
    } else if (tsconfig.compilerOptions[option] !== value) {
      tsconfig.compilerOptions[option] = value;
      messages.push(
        `${chalk.cyan('compilerOptions.' + option)} ${chalk.bold(
          'must'
        )} be ${chalk.cyan.bold(value)}` +
          (reason != null ? ` (${reason})` : '')
      );
    }
  }

  if (tsconfig.include == null) {
    tsconfig.include = ['src'];
    messages.push(
      `${chalk.cyan('include')} should be ${chalk.cyan.bold('src')}`
    );
  }
  if (tsconfig.exclude == null) {
    tsconfig.exclude = ['**/__tests__/**', '**/?*(spec|test).*'];
    messages.push(`${chalk.cyan('exclude')} should exclude test files`);
  }

  if (messages.length > 0) {
    if (firstTimeSetup) {
      console.log(
        chalk.bold(
          'Your',
          chalk.cyan('tsconfig.json'),
          'has been populated with default values.'
        )
      );
      console.log();
    } else {
      console.warn(
        chalk.bold(
          'The following changes are being made to your',
          chalk.cyan('tsconfig.json'),
          'file:'
        )
      );
      messages.forEach(message => {
        console.warn('  - ' + message);
      });
      console.warn();
    }
    writeJson(paths.appTsConfig, tsconfig);
  }

  // Copy type declarations associated with this version of `react-scripts`
  const declaredTypes = path.resolve(
    __dirname,
    '..',
    '..',
    'config',
    'react-app.d.ts'
  );
  const declaredTypesContent = fs
    .readFileSync(declaredTypes, 'utf8')
    .replace(/\/\/ @remove-file-on-eject\r?\n/, '');
  fs.writeFileSync(
    path.resolve(paths.appSrc, 'react-app.d.ts'),
    declaredTypesContent
  );
}

module.exports = verifyTypeScriptSetup;

{'fraction_non_alphanumeric': 0.1533448732308319, 'fraction_numerical': 0.0020364524997454436, 'mean_word_length': 2.6404744255003707, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5904724', 'n_tokens_mistral': 3122, 'n_tokens_neox': 3077, 'n_words': 735}