Skip to content

Commit

Permalink
Prevent stripping of outer replaced characters (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
orsett0 committed Apr 23, 2023
1 parent 1f09cd4 commit 7d4846f
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 16 deletions.
4 changes: 2 additions & 2 deletions filenamify.d.ts
Expand Up @@ -28,10 +28,10 @@ Convert a string to a valid filename.
import filenamify from 'filenamify';
filenamify('<foo/bar>');
//=> 'foo!bar'
//=> '!foo!bar!'
filenamify('foo:"bar"', {replacement: '🐴'});
//=> 'foo🐴bar'
//=> 'foo🐴bar🐴'
```
*/
export default function filenamify(string: string, options?: Options): string;
13 changes: 7 additions & 6 deletions filenamify.js
@@ -1,15 +1,15 @@
import trimRepeated from 'trim-repeated';
import filenameReservedRegex, {windowsReservedNameRegex} from 'filename-reserved-regex';
import stripOuter from 'strip-outer';

// Doesn't make sense to have longer filenames
const MAX_FILENAME_LENGTH = 100;

const reControlChars = /[\u0000-\u001F\u0080-\u009F]/g; // eslint-disable-line no-control-regex
const reRelativePath = /^\.+(\\|\/)|^\.+$/;
const reTrailingPeriods = /\.+$/;

export default 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');
}
Expand All @@ -20,6 +20,10 @@ export default function filenamify(string, options = {}) {
throw new Error('Replacement string cannot contain reserved filename characters');
}

if (replacement.length > 0) {
string = string.replace(reRepeatedReservedCharacters, '$1');
}

string = string.normalize('NFD');
string = string.replace(reRelativePath, replacement);
string = string.replace(filenameReservedRegex(), replacement);
Expand All @@ -29,9 +33,6 @@ export default function filenamify(string, options = {}) {
if (replacement.length > 0) {
const startedWithDot = string[0] === '.';

string = trimRepeated(string, replacement);
string = string.length > 1 ? stripOuter(string, replacement) : string;

// We removed the whole filename
if (!startedWithDot && string[0] === '.') {
string = replacement + string;
Expand Down
4 changes: 1 addition & 3 deletions package.json
Expand Up @@ -43,9 +43,7 @@
"dirname"
],
"dependencies": {
"filename-reserved-regex": "^3.0.0",
"strip-outer": "^2.0.0",
"trim-repeated": "^2.0.0"
"filename-reserved-regex": "^3.0.0"
},
"devDependencies": {
"ava": "^3.15.0",
Expand Down
6 changes: 3 additions & 3 deletions readme.md
Expand Up @@ -16,10 +16,10 @@ npm install filenamify
import filenamify from 'filenamify';

filenamify('<foo/bar>');
//=> 'foo!bar'
//=> '!foo!bar!'

filenamify('foo:"bar"', {replacement: '🐴'});
//=> 'foo🐴bar'
//=> 'foo🐴bar🐴'
```

## API
Expand Down Expand Up @@ -71,7 +71,7 @@ You can also import `filenamify/browser`, which only imports `filenamify` and no
import filenamify from 'filenamify/browser';

filenamify('<foo/bar>');
//=> 'foo!bar'
//=> '!foo!bar!'
```

## Related
Expand Down
9 changes: 7 additions & 2 deletions test.js
Expand Up @@ -8,10 +8,10 @@ const directoryName = path.dirname(fileURLToPath(import.meta.url));
test('filenamify()', t => {
t.is(filenamify('foo/bar'), 'foo!bar');
t.is(filenamify('foo//bar'), 'foo!bar');
t.is(filenamify('//foo//bar//'), 'foo!bar');
t.is(filenamify('//foo//bar//'), '!foo!bar!');
t.is(filenamify('foo\\\\\\bar'), 'foo!bar');
t.is(filenamify('foo/bar', {replacement: '🐴🐴'}), 'foo🐴🐴bar');
t.is(filenamify('////foo////bar////', {replacement: '(('}), 'foo((bar');
t.is(filenamify('////foo////bar////', {replacement: '(('}), '((foo((bar((');
t.is(filenamify('foo\u0000bar'), 'foo!bar');
t.is(filenamify('.'), '!');
t.is(filenamify('..'), '!');
Expand All @@ -28,6 +28,11 @@ test('filenamify()', t => {
t.is(filenamify('c/n', {replacement: 'o'}), 'cono');
t.is(filenamify('c/n', {replacement: 'con'}), 'cconn');
t.is(filenamify('.dotfile'), '.dotfile');
t.is(filenamify('my <file name-', {replacement: '-'}), 'my -file name-');
t.is(filenamify('--<abc->>>--', {replacement: '-'}), '---abc----');
t.is(filenamify('-<<abc>-', {replacement: '-'}), '--abc--');
t.is(filenamify('my <file name<', {replacement: '-'}), 'my -file name-');
t.is(filenamify('my <file name<'), 'my !file name!');
});

test('filenamifyPath()', t => {
Expand Down

0 comments on commit 7d4846f

Please sign in to comment.