diff --git a/filenamify.d.ts b/filenamify.d.ts index be19a5f..6297d66 100644 --- a/filenamify.d.ts +++ b/filenamify.d.ts @@ -11,6 +11,8 @@ export interface Options { /** Truncate the filename to the given length. + Only the base of the filename is truncated, preserving the extension. If the extension itself is longer than `maxLength`, you will get a string that is longer than `maxLength`, so you need to check for that if you allow arbitrary extensions. + Systems generally allow up to 255 characters, but we default to 100 for usability reasons. @default 100 diff --git a/filenamify.js b/filenamify.js index 662ae32..6d810b4 100644 --- a/filenamify.js +++ b/filenamify.js @@ -35,9 +35,13 @@ export default function filenamify(string, options = {}) { const allowedLength = typeof options.maxLength === 'number' ? options.maxLength : MAX_FILENAME_LENGTH; if (string.length > allowedLength) { const extensionIndex = string.lastIndexOf('.'); - const filename = extensionIndex === -1 ? string : string.slice(0, extensionIndex); - const extension = extensionIndex === -1 ? '' : string.slice(extensionIndex); - string = filename.slice(0, Math.min(allowedLength, filename.length)) + extension; + 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; + } } return string; diff --git a/readme.md b/readme.md index 0120d63..391c53d 100644 --- a/readme.md +++ b/readme.md @@ -59,6 +59,8 @@ Default: `100` Truncate the filename to the given length. +Only the base of the filename is truncated, preserving the extension. If the extension itself is longer than `maxLength`, you will get a string that is longer than `maxLength`, so you need to check for that if you allow arbitrary extensions. + Systems generally allow up to 255 characters, but we default to 100 for usability reasons. ## Browser-only import diff --git a/test.js b/test.js index d23b036..0072651 100644 --- a/test.js +++ b/test.js @@ -30,15 +30,18 @@ test('filnamify()', t => { test('filenamifyPath()', t => { t.is(path.basename(filenamifyPath(path.join(directoryName, 'foo:bar'))), 'foo!bar'); t.is(path.basename(filenamifyPath(path.join(directoryName, 'This? This is very long filename that will lose its extension when passed into filenamify, which could cause issues.csv'))), - 'This! This is very long filename that will lose its extension when passed into filenamify, which cou.csv'); + 'This! This is very long filename that will lose its extension when passed into filenamify, which.csv'); }); test('filenamify length', t => { // Basename length: 152 const filename = 'this/is/a/very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_filename.txt'; - t.is(filenamify(path.basename(filename)), 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_.txt'); + t.is(filenamify(path.basename(filename)), 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_v.txt'); t.is(filenamify(path.basename(filename), {maxLength: 180}), 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_filename.txt'); + // File extension longer than `maxLength` + t.is(filenamify('foo.asdfghjkl', {maxLength: 5}), 'f.asdfghjkl'); + // Basename length: 148 const filenameNoExt = 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_filename'; t.is(filenamify(filenameNoExt), 'very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_');