1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-19 13:19:44 +02:00
planka/server/utils/filenamify.js
2024-09-16 00:45:53 +02:00

76 lines
2.4 KiB
JavaScript

/* https://github.com/sindresorhus/filename-reserved-regex */
function filenameReservedRegex() {
return /[<>:"/\\|?*\u0000-\u001F]/g; // eslint-disable-line no-control-regex
}
function windowsReservedNameRegex() {
return /^(con|prn|aux|nul|com\d|lpt\d)$/i;
}
/* https://github.com/sindresorhus/filenamify */
// Doesn't make sense to have longer filenames
const MAX_FILENAME_LENGTH = 100;
const reRelativePath = /^\.+(\\|\/)|^\.+$/;
const reTrailingPeriods = /\.+$/;
function filenamify(string, options = {}) {
const reControlChars = /[\u0000-\u001F\u0080-\u009F]/g; // eslint-disable-line no-control-regex
const reRepeatedReservedCharacters = /([<>:"/\\|?*\u0000-\u001F]){2,}/g; // eslint-disable-line no-control-regex
if (typeof string !== 'string') {
throw new TypeError('Expected a string');
}
const replacement = options.replacement === undefined ? '!' : options.replacement;
if (filenameReservedRegex().test(replacement) && reControlChars.test(replacement)) {
throw new Error('Replacement string cannot contain reserved filename characters');
}
/* eslint-disable no-param-reassign */
if (replacement.length > 0) {
string = string.replace(reRepeatedReservedCharacters, '$1');
}
string = string.normalize('NFD');
string = string.replace(reRelativePath, replacement);
string = string.replace(filenameReservedRegex(), replacement);
string = string.replace(reControlChars, replacement);
string = string.replace(reTrailingPeriods, '');
if (replacement.length > 0) {
const startedWithDot = string[0] === '.';
// We removed the whole filename
if (!startedWithDot && string[0] === '.') {
string = replacement + string;
}
// We removed the whole extension
if (string[string.length - 1] === '.') {
string += replacement;
}
}
string = windowsReservedNameRegex().test(string) ? string + replacement : string;
const allowedLength =
typeof options.maxLength === 'number' ? options.maxLength : MAX_FILENAME_LENGTH;
if (string.length > allowedLength) {
const extensionIndex = string.lastIndexOf('.');
if (extensionIndex === -1) {
string = string.slice(0, allowedLength);
} else {
const filename = string.slice(0, extensionIndex);
const extension = string.slice(extensionIndex);
string = filename.slice(0, Math.max(1, allowedLength - extension.length)) + extension;
}
}
/* eslint-enable no-param-reassign */
return string;
}
module.exports = filenamify;