codtracker-js/node_modules/eslint/lib/languages/js/validate-language-options.js
2025-04-19 23:12:19 -04:00

195 lines
4.7 KiB
JavaScript

/**
* @fileoverview The schema to validate language options
* @author Nicholas C. Zakas
*/
'use strict';
//-----------------------------------------------------------------------------
// Data
//-----------------------------------------------------------------------------
const globalVariablesValues = new Set([
true,
'true',
'writable',
'writeable',
false,
'false',
'readonly',
'readable',
null,
'off',
]);
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Check if a value is a non-null object.
* @param {any} value The value to check.
* @returns {boolean} `true` if the value is a non-null object.
*/
function isNonNullObject(value) {
return typeof value === 'object' && value !== null;
}
/**
* Check if a value is a non-null non-array object.
* @param {any} value The value to check.
* @returns {boolean} `true` if the value is a non-null non-array object.
*/
function isNonArrayObject(value) {
return isNonNullObject(value) && !Array.isArray(value);
}
/**
* Check if a value is undefined.
* @param {any} value The value to check.
* @returns {boolean} `true` if the value is undefined.
*/
function isUndefined(value) {
return typeof value === 'undefined';
}
//-----------------------------------------------------------------------------
// Schemas
//-----------------------------------------------------------------------------
/**
* Validates the ecmaVersion property.
* @param {string|number} ecmaVersion The value to check.
* @returns {void}
* @throws {TypeError} If the value is invalid.
*/
function validateEcmaVersion(ecmaVersion) {
if (isUndefined(ecmaVersion)) {
throw new TypeError(
'Key "ecmaVersion": Expected an "ecmaVersion" property.'
);
}
if (typeof ecmaVersion !== 'number' && ecmaVersion !== 'latest') {
throw new TypeError('Key "ecmaVersion": Expected a number or "latest".');
}
}
/**
* Validates the sourceType property.
* @param {string} sourceType The value to check.
* @returns {void}
* @throws {TypeError} If the value is invalid.
*/
function validateSourceType(sourceType) {
if (
typeof sourceType !== 'string' ||
!/^(?:script|module|commonjs)$/u.test(sourceType)
) {
throw new TypeError(
'Key "sourceType": Expected "script", "module", or "commonjs".'
);
}
}
/**
* Validates the globals property.
* @param {Object} globals The value to check.
* @returns {void}
* @throws {TypeError} If the value is invalid.
*/
function validateGlobals(globals) {
if (!isNonArrayObject(globals)) {
throw new TypeError('Key "globals": Expected an object.');
}
for (const key of Object.keys(globals)) {
// avoid hairy edge case
if (key === '__proto__') {
continue;
}
if (key !== key.trim()) {
throw new TypeError(
`Key "globals": Global "${key}" has leading or trailing whitespace.`
);
}
if (!globalVariablesValues.has(globals[key])) {
throw new TypeError(
`Key "globals": Key "${key}": Expected "readonly", "writable", or "off".`
);
}
}
}
/**
* Validates the parser property.
* @param {Object} parser The value to check.
* @returns {void}
* @throws {TypeError} If the value is invalid.
*/
function validateParser(parser) {
if (
!parser ||
typeof parser !== 'object' ||
(typeof parser.parse !== 'function' &&
typeof parser.parseForESLint !== 'function')
) {
throw new TypeError(
'Key "parser": Expected object with parse() or parseForESLint() method.'
);
}
}
/**
* Validates the language options.
* @param {Object} languageOptions The language options to validate.
* @returns {void}
* @throws {TypeError} If the language options are invalid.
*/
function validateLanguageOptions(languageOptions) {
if (!isNonArrayObject(languageOptions)) {
throw new TypeError('Expected an object.');
}
const {
ecmaVersion,
sourceType,
globals,
parser,
parserOptions,
...otherOptions
} = languageOptions;
if ('ecmaVersion' in languageOptions) {
validateEcmaVersion(ecmaVersion);
}
if ('sourceType' in languageOptions) {
validateSourceType(sourceType);
}
if ('globals' in languageOptions) {
validateGlobals(globals);
}
if ('parser' in languageOptions) {
validateParser(parser);
}
if ('parserOptions' in languageOptions) {
if (!isNonArrayObject(parserOptions)) {
throw new TypeError('Key "parserOptions": Expected an object.');
}
}
const otherOptionKeys = Object.keys(otherOptions);
if (otherOptionKeys.length > 0) {
throw new TypeError(`Unexpected key "${otherOptionKeys[0]}" found.`);
}
}
module.exports = { validateLanguageOptions };