function generateRuleIndexPage() {
	const docsSiteOutputFile = path.join(DOCS_DATA_DIR, "rules.json"),
		docsSiteMetaOutputFile = path.join(DOCS_DATA_DIR, "rules_meta.json"),
		ruleTypes = "conf/rule-type-list.json",
		ruleTypesData = JSON.parse(cat(path.resolve(ruleTypes)));

	const meta = {};

	RULE_FILES.map(filename => [filename, path.basename(filename, ".js")])
		.sort((a, b) => a[1].localeCompare(b[1]))
		.forEach(pair => {
			const filename = pair[0];
			const basename = pair[1];
			const rule = require(path.resolve(filename));

			/*
			 * Eleventy interprets the {{ }} in messages as being variables,
			 * which can cause an error if there's syntax it doesn't expect.
			 * Because we don't use this info in the website anyway, it's safer
			 * to just remove it.
			 *
			 * Also removing the schema because we don't need it.
			 */
			meta[basename] = {
				...rule.meta,
				schema: void 0,
				messages: void 0,
			};

			if (rule.meta.deprecated) {
				ruleTypesData.deprecated.push({
					name: basename,
					replacedBy: rule.meta.deprecated.replacedBy ?? [],
					fixable: !!rule.meta.fixable,
					hasSuggestions: !!rule.meta.hasSuggestions,
				});
			} else {
				const output = {
						name: basename,
						description: rule.meta.docs.description,
						recommended: rule.meta.docs.recommended || false,
						fixable: !!rule.meta.fixable,
						frozen: !!rule.meta.docs.frozen,
						hasSuggestions: !!rule.meta.hasSuggestions,
					},
					ruleType = ruleTypesData.types[rule.meta.type];

				ruleType.push(output);
			}
		});

	ruleTypesData.types = Object.fromEntries(
		Object.entries(ruleTypesData.types).filter(
			([, value]) => value && value.length > 0,
		),
	);

	JSON.stringify(ruleTypesData, null, 4).to(docsSiteOutputFile);
	JSON.stringify(meta, null, 4).to(docsSiteMetaOutputFile);
}
Generate a doc page that lists all of the rules and links to them
@returns {void}