constructor(config) {
		const { plugins, language, languageOptions, processor, ...otherKeys } =
			config;

		// Validate config object
		const schema = new ObjectSchema(flatConfigSchema);

		schema.validate(config);

		// first, copy all the other keys over
		Object.assign(this, otherKeys);

		// ensure that a language is specified
		if (!language) {
			throw new TypeError("Key 'language' is required.");
		}

		// copy the rest over
		this.plugins = plugins;
		this.language = language;

		// Check language value
		const {
			pluginName: languagePluginName,
			objectName: localLanguageName,
		} = splitPluginIdentifier(language);

		this.#languageName = language;

		if (
			!plugins ||
			!plugins[languagePluginName] ||
			!plugins[languagePluginName].languages ||
			!plugins[languagePluginName].languages[localLanguageName]
		) {
			throw new TypeError(
				`Key "language": Could not find "${localLanguageName}" in plugin "${languagePluginName}".`,
			);
		}

		this.language =
			plugins[languagePluginName].languages[localLanguageName];

		if (this.language.defaultLanguageOptions ?? languageOptions) {
			this.languageOptions = flatConfigSchema.languageOptions.merge(
				this.language.defaultLanguageOptions,
				languageOptions,
			);
		} else {
			this.languageOptions = {};
		}

		// Validate language options
		try {
			this.language.validateLanguageOptions(this.languageOptions);
		} catch (error) {
			throw new TypeError(`Key "languageOptions": ${error.message}`, {
				cause: error,
			});
		}

		// Normalize language options if necessary
		if (this.language.normalizeLanguageOptions) {
			this.languageOptions = this.language.normalizeLanguageOptions(
				this.languageOptions,
			);
		}

		// Check processor value
		if (processor) {
			this.processor = processor;

			if (typeof processor === "string") {
				const { pluginName, objectName: localProcessorName } =
					splitPluginIdentifier(processor);

				this.#processorName = processor;

				if (
					!plugins ||
					!plugins[pluginName] ||
					!plugins[pluginName].processors ||
					!plugins[pluginName].processors[localProcessorName]
				) {
					throw new TypeError(
						`Key "processor": Could not find "${localProcessorName}" in plugin "${pluginName}".`,
					);
				}

				this.processor =
					plugins[pluginName].processors[localProcessorName];
			} else if (typeof processor === "object") {
				this.#processorName = getObjectId(processor);
				this.processor = processor;
			} else {
				throw new TypeError(
					"Key 'processor' must be a string or an object.",
				);
			}
		}

		// Process the rules
		if (this.rules) {
			this.#normalizeRulesConfig();
			this.validateRulesConfig(this.rules);
		}
	}
Creates a new instance.
@param {Object} config The configuration object.