📄 config-validator¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 7 |
| 📦 Imports | 13 |
| 📊 Variables & Constants | 3 |
| 📑 Type Aliases | 1 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/rule-tester/src/utils/config-validator.ts
📦 Imports¶
| Name | Source |
|---|---|
AnyRuleModule |
@typescript-eslint/utils/ts-eslint |
Linter |
@typescript-eslint/utils/ts-eslint |
AdditionalPropertiesParams |
ajv |
AjvErrorObject |
ajv |
ValidateFunction |
ajv |
builtinRules |
eslint/use-at-your-own-risk |
util |
node:util |
TesterConfigWithDefaults |
../types |
ajvBuilder |
./ajv |
emitDeprecationWarning |
./deprecation-warnings |
flatConfigSchema |
./flat-config-schema |
getRuleOptionsSchema |
./getRuleOptionsSchema |
hasOwnProperty |
./hasOwnProperty |
Variables & Constants¶
| Name | Type | Kind | Value | Exported |
|---|---|---|---|---|
ruleValidators |
WeakMap<AnyRuleModule, ValidateFunction> |
const | new WeakMap<AnyRuleModule, ValidateFunction>() |
✗ |
validateSchema |
ValidateFunction \| undefined |
let/var | *not shown* |
✗ |
severityMap |
{ readonly error: 2; readonly off: 0;... |
const | { error: 2, off: 0, warn: 1, } as const |
✗ |
Functions¶
validate(config: TesterConfigWithDefaults, source: string, getAdditionalRule: GetAdditionalRule): void¶
Validates an entire config object.
Parameters:
configany: The config object to validate.sourceany: The name of the configuration source to report in any errors.getAdditionalRuleany: A map from strings to loaded rules.
Raw JSDoc
Calls:
validateConfigSchemavalidateRules
Code
validateRuleSeverity(options: Linter.RuleEntry): number | string¶
Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid.
Parameters:
optionsany: The given options for the rule.
Throws:
Error: Wrong severity value.
Raw JSDoc
Calls:
Array.isArrayseverity.toLowerCaseutil .inspect(severity) .replaceAll("'", '"') .replaceAll
Code
function validateRuleSeverity(options: Linter.RuleEntry): number | string {
const severity = Array.isArray(options) ? options[0] : options;
const normSeverity =
typeof severity === 'string'
? (severityMap[severity.toLowerCase() as Linter.SeverityString] as
number | undefined)
: (severity as number);
if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) {
return normSeverity;
}
throw new Error(
`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util
.inspect(severity)
.replaceAll("'", '"')
.replaceAll('\n', '')}').\n`,
);
}
validateRuleSchema(rule: AnyRuleModule, localOptions: unknown[]): void¶
Validates the non-severity options passed to a rule, based on its schema.
Parameters:
ruleany: The rule to validatelocalOptionsany: The options for the rule, excluding severity
Throws:
Error: Any rule validation errors.
Raw JSDoc
Calls:
ruleValidators.hasgetRuleOptionsSchema (from ./getRuleOptionsSchema)ruleValidators.setajv.compileruleValidators.getvalidateRulevalidateRule.errors .map( error =>\tValue ${JSON.stringify(error.data)} ${error.message}.\n, ) .join
Code
function validateRuleSchema(
rule: AnyRuleModule,
localOptions: unknown[],
): void {
if (!ruleValidators.has(rule)) {
const schema = getRuleOptionsSchema(rule);
if (schema) {
ruleValidators.set(rule, ajv.compile(schema));
}
}
const validateRule = ruleValidators.get(rule);
if (validateRule) {
void validateRule(localOptions);
if (validateRule.errors) {
throw new Error(
validateRule.errors
.map(
error =>
`\tValue ${JSON.stringify(error.data)} ${error.message}.\n`,
)
.join(''),
);
}
}
}
validateRuleOptions(rule: AnyRuleModule, ruleId: string, options: Linter.RuleEntry, source: string | null): void¶
Validates a rule's options against its schema.
Parameters:
ruleany: The rule that the config is being validated forruleIdany: The rule's unique name.optionsany: The given options for the rule.sourceany: The name of the configuration source to report in any errors. If null or undefined, no source is prepended to the message.
Throws:
Error: Upon any bad rule configuration.
Raw JSDoc
/**
* Validates a rule's options against its schema.
* @param rule The rule that the config is being validated for
* @param ruleId The rule's unique name.
* @param options The given options for the rule.
* @param source The name of the configuration source to report in any errors. If null or undefined,
* no source is prepended to the message.
* @throws {Error} Upon any bad rule configuration.
*/
Calls:
validateRuleSeverityvalidateRuleSchemaArray.isArrayoptions.slice
Code
function validateRuleOptions(
rule: AnyRuleModule,
ruleId: string,
options: Linter.RuleEntry,
source: string | null = null,
): void {
try {
const severity = validateRuleSeverity(options);
if (severity !== 0) {
validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []);
}
} catch (err) {
const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${
(err as Error).message
}`;
if (typeof source === 'string') {
throw new Error(`${source}:\n\t${enhancedMessage}`, { cause: err });
} else {
throw new Error(enhancedMessage, { cause: err });
}
}
}
validateRules(rulesConfig: Linter.RulesRecord | undefined, source: string, getAdditionalRule: GetAdditionalRule): void¶
Validates a rules config object
Parameters:
rulesConfigany: The rules config object to validate.sourceany: The name of the configuration source to report in any errors.getAdditionalRuleany: A map from strings to loaded rules
Raw JSDoc
Calls:
Object.keys(rulesConfig).forEachgetAdditionalRulebuiltinRules.getvalidateRuleOptions
Internal Comments:
Code
function validateRules(
rulesConfig: Linter.RulesRecord | undefined,
source: string,
getAdditionalRule: GetAdditionalRule,
): void {
if (!rulesConfig) {
return;
}
Object.keys(rulesConfig).forEach(id => {
const rule = getAdditionalRule(id) ?? builtinRules.get(id) ?? null;
if (rule == null) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
validateRuleOptions(rule, id, rulesConfig[id]!, source);
});
}
formatErrors(errors: AjvErrorObject[]): string¶
Formats an array of schema validation errors.
Calls:
-
errors .map(error => { if (error.keyword === 'additionalProperties') { const params = error.params as AdditionalPropertiesParams; const formattedPropertyPath = error.dataPath.length ?${error.dataPath.slice(1)}.${params.additionalProperty}` : params.additionalProperty;return `Unexpected top-level property "${formattedPropertyPath}"`;} if (error.keyword === 'type') { const formattedField = error.dataPath.slice(1); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join('/') : error.schema; const formattedValue = JSON.stringify(error.data);
return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`;}
const field = error.dataPath[0] === '.' ? error.dataPath.slice(1) : error.dataPath;
return
"${field}" ${error.message}. Value: ${JSON.stringify( error.data, )}; }) .map(message =>\t- ${message}.\n) .join`
Internal Comments:
Code
function formatErrors(errors: AjvErrorObject[]): string {
return errors
.map(error => {
if (error.keyword === 'additionalProperties') {
const params = error.params as AdditionalPropertiesParams;
const formattedPropertyPath = error.dataPath.length
? `${error.dataPath.slice(1)}.${params.additionalProperty}`
: params.additionalProperty;
return `Unexpected top-level property "${formattedPropertyPath}"`;
}
if (error.keyword === 'type') {
const formattedField = error.dataPath.slice(1);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const formattedExpectedType = Array.isArray(error.schema)
? error.schema.join('/')
: error.schema;
const formattedValue = JSON.stringify(error.data);
return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`;
}
const field =
error.dataPath[0] === '.' ? error.dataPath.slice(1) : error.dataPath;
return `"${field}" ${error.message}. Value: ${JSON.stringify(
error.data,
)}`;
})
.map(message => `\t- ${message}.\n`)
.join('');
}
validateConfigSchema(config: TesterConfigWithDefaults, source: string): void¶
Validates the top level properties of the config object.
Parameters:
configany: The config object to validate.sourceany: The name of the configuration source to report in any errors.
Throws:
Error: For any config invalid per the schema.
Raw JSDoc
Calls:
ajv.compilevalidateSchemaformatErrorshasOwnProperty (from ./hasOwnProperty)emitDeprecationWarning (from ./deprecation-warnings)
Internal Comments:
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion (x3)
// @ts-expect-error -- intentional deprecated check
Code
function validateConfigSchema(
config: TesterConfigWithDefaults,
source: string,
): void {
validateSchema ??= ajv.compile(flatConfigSchema);
if (!validateSchema(config)) {
throw new Error(
`ESLint configuration in ${source} is invalid:\n${formatErrors(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
validateSchema.errors!,
)}`,
);
}
// @ts-expect-error -- intentional deprecated check
if (hasOwnProperty(config, 'ecmaFeatures')) {
emitDeprecationWarning(source, 'ESLINT_LEGACY_ECMAFEATURES');
}
}
Type Aliases¶
GetAdditionalRule¶
Generated by Syntax Scribe