blob: 708ea89ea03ef761262a9e9c7e94a61f3ea6454d [file] [log] [blame] [edit]
/* This file is a part of @mdn/browser-compat-data
* See LICENSE file for more information. */
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import fs from 'node:fs';
import chalk from 'chalk-template';
import { fdir } from 'fdir';
import dataFolders from '../../scripts/lib/data-folders.js';
import walk from '../../utils/walk.js';
import stringifyAndOrderProperties from '../lib/stringify-and-order-properties.js';
const dirname = fileURLToPath(new URL('.', import.meta.url));
/**
* Updates the specified key in the given JSON object using the provided updater function.
* @param key The key to update in dot notation (e.g., 'api.foobar').
* @param json The JSON object to update.
* @param updater The function to apply to the '__compat' property of the value corresponding to the key.
* @returns The updated JSON object.
*/
const performUpdate = (key: string, json: any, updater: (any) => any): any => {
const parts = key.split('.');
if (!(parts[0] in json)) {
console.warn('Key not found in file!');
return json;
}
if (parts.length === 1) {
json[parts[0]]['__compat'] = updater(json[parts[0]]['__compat']);
} else {
json[parts[0]] = performUpdate(
parts.slice(1).join('.'),
json[parts[0]],
updater,
);
}
return json;
};
/**
* Updates features in multiple JSON files based on the provided feature IDs and updater function.
* @param featureIDs An array of feature IDs to update.
* @param updater The updater function to apply to each matching feature.
*/
export const updateFeatures = (featureIDs: string[], updater: (any) => any) => {
for (const dir of dataFolders) {
const paths = new fdir()
.withBasePath()
.filter((fp) => fp.endsWith('.json'))
.crawl(path.join(dirname, '..', '..', dir))
.sync() as string[];
for (const fp of paths) {
const rawcontents = fs.readFileSync(fp);
const contents = JSON.parse(rawcontents.toString('utf8'));
let changed = false;
const applyToAnyFeatureID = !featureIDs || featureIDs.length === 0;
const walker = walk(undefined, contents);
for (const { path: featureID } of walker) {
if (
applyToAnyFeatureID ||
featureIDs.some(
(fid) =>
fid === featureID ||
(fid.endsWith('*') && featureID.startsWith(fid.slice(0, -1))),
)
) {
const before = JSON.stringify(contents, undefined, 2);
const after = JSON.stringify(
performUpdate(featureID, contents, updater),
undefined,
2,
);
if (before != after) {
console.log(chalk`{yellow Updated ${featureID}}`);
changed = true;
}
}
}
if (changed) {
fs.writeFileSync(
fp,
stringifyAndOrderProperties(contents) + '\n',
'utf-8',
);
}
}
}
};