<commit_before>/**
 * @func !settings
 *
 * Configure server-specific settings
 */

/* eslint-disable no-restricted-globals */
/* */
const beautify = require('json-beautify');
const settings = require('../../settings.json');
const { getGuildCommandPrefix, update: updateGuildConfig } = require('../../handlers/GuildSettings');

const commandName = 'settings';

/**
 * Available `types`:
 * - string
 * - number
 * - integer
 * - range
 * - boolean
 */
const configOptions = {
  bot: {
    prefix: {
      type: 'string',
      default: settings.prefix,
      description: 'The prefix for executing commands.',
    },
  },
  lfg: {
    createTempChannel: {
      type: 'boolean',
      default: true,
      description: 'Whether to make a temporary party channel for LFG',
    },
  },
  ...(process.env.NODE_ENV === 'test' ? {
    test: {
      'range 0-12': {
        type: 'range',
        min: 0,
        max: 12,
        default: 0,
        description: 'Range',
      },
      number: {
        type: 'number',
      },
      integer: {
        type: 'integer',
      },
      boolean: {
        type: 'boolean',
      },
      string: {
        type: 'string',
      },
    },
  } : {}
  ),
};

/**
 * Returns an array with whether the input is valid for the given expectedType,
 * and the casted type output to transform the input into.
 * (this is because we want to convert the input, which is always `string` into
 * something suitable for the given expectedType)
 *
 * @param {string} input String input for the value attempting to be set
 * @param {string} expectedType Type the input is expected to be
 * @param {Object} settingConfig Config object for the setting
 * @returns {Array<Boolean, any>}
 */
const validateType = (input, expectedType, settingConfig) => {
  // Input MUST be `string`, if not then something went haywire; time to abort
  if (typeof input !== 'string') return [false, null];

  if (input === 'true' || input === 'false') {
    return [expectedType === 'boolean', Boolean(input === 'true')];
  }

  // Don't accept "Infinity" or - somehow? - an empty string
  if (!isNaN(input) && input !== '' && input !== 'Infinity') {
    switch (expectedType) {
      // input = any number (float, int, etc.)
      case 'number':
        return [true, Number(input)];

      // input = integer
      case 'integer':
        return [Number.isInteger(input), Number(input)];

      // input = a number in given range
      case 'range': {
        if (!settingConfig || !settingConfig.min || !settingConfig.max) return [false, null];
        const num = parseFloat(input);

        return [num >= settingConfig.min && num <= settingConfig.max, Number(input)];
      }

      // fail otherwise -> Input is a number, but wasn't one of the number types
      default:
        return [false, null];
    }
  }

  // String type setting can accept anything that came in via "args"
  // (since they *should* be strings to begin with)
  return [expectedType === 'string', input];
};

const getTypeDesc = (setting) => {
  const { type } = setting;
  switch (type) {
    case 'string':
    case 'boolean':
    case 'number':<commit_msg>[Docs] Comments & updated descriptions<commit_after>/**
 * @func !settings
 *
 * Configure server-specific settings
 */

/* eslint-disable no-restricted-globals */
const beautify = require('json-beautify');
const settings = require('../../settings.json');
const { getGuildCommandPrefix, update: updateGuildConfig } = require('../../handlers/GuildSettings');

const commandName = 'settings';

/**
 * Available types:
 * - @type string
 * - @type number
 * - @type integer
 * - @type range
 * - @type boolean
 */
const configOptions = {
  bot: {
    prefix: {
      type: 'string',
      default: settings.prefix,
      description: 'The prefix for executing commands.',
    },
  },

  // =================== Example: ===================
  // lfg: {
  //   create_temp_channel: {
  //     type: 'boolean',
  //     default: settings.lfg.create_temp_channel,
  //     description: 'Whether to make a temporary text channel for an LFG party',
  //   },
  // },
  // =================================================

  // For testing purposes only:
  ...(process.env.NODE_ENV === 'test' ? {
    test: {
      'range 0-10': {
        type: 'range',
        min: 0,
        max: 10,
        default: 0,
        description: 'Some number within this range',
      },
      number: {
        type: 'number',
      },
      integer: {
        type: 'integer',
      },
      boolean: {
        type: 'boolean',
      },
      string: {
        type: 'string',
      },
    },
  } : {}
  ),
};

/**
 * Returns an array with whether the input is valid for the given expectedType,
 * and the casted type output to transform the input into.
 * (this is because we want to convert the input, which is always `string` into
 * something suitable for the given expectedType)
 *
 * @param {string} input String input for the value attempting to be set
 * @param {string} expectedType Type the input is expected to be
 * @param {Object} settingConfig Config object for the setting
 * @returns {Array<Boolean, any>}
 */
const validateType = (input, expectedType, settingConfig) => {
  // Input MUST be `string`, if not then something went haywire; time to abort
  if (typeof input !== 'string') return [false, null];

  if (input === 'true' || input === 'false') {
    return [expectedType === 'boolean', Boolean(input === 'true')];
  }

  // Don't accept "Infinity" or - somehow? - an empty string
  if (!isNaN(input) && input !== '' && input !== 'Infinity') {
    switch (expectedType) {
      // input is any number (float, int, etc.)
      case 'number':
        return [true, Number(input)];

      // input is integer
      case 'integer':
        return [Number.isInteger(input), Number(input)];

      // input is a number in given range
      case 'range': {
        if (!settingConfig || !settingConfig.min || !settingConfig.max) return [false, null];
        const num = parseFloat(input);

        return [num >= settingConfig.min && num <= settingConfig.max, Number(input)];
      }

      // fail otherwise: input is a number, but was supposed to be something else
      default:
        return [false, null];
    }
  }

  // String type setting can accept anything that came in via "args"
  // (since they *should* be strings to begin with)
  return [expectedType === 'string', input];
};

const getTypeDesc = (setting) => {
  const { type } = setting;
  switch (type) {
    case 'string':
    case 'boolean':
    case 'number':
{'fraction_non_alphanumeric': 0.15527477546049628, 'fraction_numerical': 0.0021312224082813214, 'mean_word_length': 2.601973684210526, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2104350', 'n_tokens_mistral': 1908, 'n_tokens_neox': 1853, 'n_words': 637}