93 lines
2.7 KiB
JavaScript
93 lines
2.7 KiB
JavaScript
const fs = require("node:fs/promises");
|
|
const path = require("node:path");
|
|
const { collectFilesByExtensions } = require("./content");
|
|
|
|
const DEFAULT_URL_TEXT_EXTENSIONS = Object.freeze([
|
|
".json",
|
|
".markdown",
|
|
".md",
|
|
".yaml",
|
|
".yml",
|
|
]);
|
|
|
|
/**
|
|
* Compte les occurrences exactes d'une chaine dans un texte.
|
|
* @param {string} text Texte a analyser.
|
|
* @param {string} needle Chaine recherchee.
|
|
* @returns {number} Nombre d'occurrences trouvees.
|
|
*/
|
|
function countOccurrences(text, needle) {
|
|
if (typeof text !== "string") {
|
|
return 0;
|
|
}
|
|
if (typeof needle !== "string" || !needle) {
|
|
return 0;
|
|
}
|
|
return text.split(needle).length - 1;
|
|
}
|
|
|
|
/**
|
|
* Retourne la liste des fichiers textuels contenant une URL donnee.
|
|
* @param {string} rootDir Racine a parcourir.
|
|
* @param {string} targetUrl URL a rechercher.
|
|
* @param {{ extensions?: string[] }} options Options de recherche.
|
|
* @returns {Promise<Array<{ filePath: string, occurrences: number }>>}
|
|
*/
|
|
async function findUrlOccurrences(rootDir, targetUrl, options = {}) {
|
|
let extensions = DEFAULT_URL_TEXT_EXTENSIONS;
|
|
if (Array.isArray(options.extensions)) {
|
|
extensions = options.extensions;
|
|
}
|
|
const files = await collectFilesByExtensions(rootDir, extensions);
|
|
const matches = [];
|
|
|
|
for (const filePath of files) {
|
|
const content = await fs.readFile(filePath, "utf8");
|
|
const occurrences = countOccurrences(content, targetUrl);
|
|
if (occurrences <= 0) {
|
|
continue;
|
|
}
|
|
matches.push({ filePath, occurrences });
|
|
}
|
|
|
|
return matches;
|
|
}
|
|
|
|
/**
|
|
* Remplace toutes les occurrences exactes d'une URL dans une liste de fichiers.
|
|
* @param {string} rootDir Racine de recherche.
|
|
* @param {string} targetUrl URL a remplacer.
|
|
* @param {string} replacementUrl URL de remplacement.
|
|
* @param {{ extensions?: string[], matches?: Array<{ filePath: string, occurrences: number }> }} options Options d'ecriture.
|
|
* @returns {Promise<{ changedFiles: string[], totalOccurrences: number }>}
|
|
*/
|
|
async function replaceUrlInFiles(rootDir, targetUrl, replacementUrl, options = {}) {
|
|
let matches = [];
|
|
if (Array.isArray(options.matches)) {
|
|
matches = options.matches;
|
|
} else {
|
|
matches = await findUrlOccurrences(rootDir, targetUrl, options);
|
|
}
|
|
|
|
const changedFiles = [];
|
|
let totalOccurrences = 0;
|
|
|
|
for (const match of matches) {
|
|
const filePath = path.resolve(match.filePath);
|
|
const content = await fs.readFile(filePath, "utf8");
|
|
const updatedContent = content.split(targetUrl).join(replacementUrl);
|
|
await fs.writeFile(filePath, updatedContent, "utf8");
|
|
changedFiles.push(filePath);
|
|
totalOccurrences += match.occurrences;
|
|
}
|
|
|
|
return { changedFiles, totalOccurrences };
|
|
}
|
|
|
|
module.exports = {
|
|
DEFAULT_URL_TEXT_EXTENSIONS,
|
|
countOccurrences,
|
|
findUrlOccurrences,
|
|
replaceUrlInFiles,
|
|
};
|