Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a browser-only export #17

Merged
merged 6 commits into from Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions filenamify-path.d.ts
@@ -0,0 +1,8 @@
import filenamify = require('./filenamify');

/**
Convert the filename in a path a valid filename and return the augmented path.
*/
declare const filenamifyPath: (path: string, options?: filenamify.Options) => string;

export = filenamifyPath;
10 changes: 10 additions & 0 deletions filenamify-path.js
@@ -0,0 +1,10 @@
'use strict';
const path = require('path');
const filenamify = require('./filenamify');

const filenamifyPath = (filePath, options) => {
filePath = path.resolve(filePath);
return path.join(path.dirname(filePath), filenamify(path.basename(filePath), options));
};

module.exports = filenamifyPath;
39 changes: 39 additions & 0 deletions filenamify.d.ts
@@ -0,0 +1,39 @@
declare namespace filenamify {
interface Options {
/**
String to use as replacement for reserved filename characters.

Cannot contain: `<` `>` `:` `"` `/` `\` `|` `?` `*`

@default '!'
*/
readonly replacement?: string;

/**
Truncate the filename to the given length.

Systems generally allow up to 255 characters, but we default to 100 for usability reasons.

@default 100
*/
readonly maxLength?: number;
}
}

/**
Convert a string to a valid filename.

@example
```
import filenamify = require('filenamify');

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

filenamify('foo:"bar"', {replacement: '🐴'});
//=> 'foo🐴bar'
```
*/
declare const filenamify: (string: string, options?: filenamify.Options) => string;

export = filenamify;
38 changes: 38 additions & 0 deletions filenamify.js
@@ -0,0 +1,38 @@
'use strict';
const trimRepeated = require('trim-repeated');
const filenameReservedRegex = require('filename-reserved-regex');
const stripOuter = require('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 filenamify = (string, options = {}) => {
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');
}

string = string.replace(filenameReservedRegex(), replacement);
string = string.replace(reControlChars, replacement);
string = string.replace(reRelativePath, replacement);

if (replacement.length > 0) {
string = trimRepeated(string, replacement);
string = string.length > 1 ? stripOuter(string, replacement) : string;
}

string = filenameReservedRegex.windowsNames().test(string) ? string + replacement : string;
string = string.slice(0, typeof options.maxLength === 'number' ? options.maxLength : MAX_FILENAME_LENGTH);

return string;
};

module.exports = filenamify;
32 changes: 5 additions & 27 deletions index.d.ts
@@ -1,26 +1,7 @@
declare namespace filenamify {
interface Options {
/**
String to use as replacement for reserved filename characters.
import filenamify = require('./filenamify');
import filenamifyPath = require('./filenamify-path');

Cannot contain: `<` `>` `:` `"` `/` `\` `|` `?` `*`

@default '!'
*/
readonly replacement?: string;

/**
Truncate the filename to the given length.

Systems generally allow up to 255 characters, but we default to 100 for usability reasons.

@default 100
*/
readonly maxLength?: number;
}
}

declare const filenamify: {
declare const filenamifyCombined: {
/**
Convert a string to a valid filename.

Expand All @@ -37,10 +18,7 @@ declare const filenamify: {
*/
(string: string, options?: filenamify.Options): string;

/**
Convert the filename in a path a valid filename and return the augmented path.
*/
path(path: string, options?: filenamify.Options): string;
path: typeof filenamifyPath;
};

export = filenamify;
export = filenamifyCombined;
44 changes: 4 additions & 40 deletions index.js
@@ -1,44 +1,8 @@
'use strict';
const path = require('path');
const trimRepeated = require('trim-repeated');
const filenameReservedRegex = require('filename-reserved-regex');
const stripOuter = require('strip-outer');
const filenamify = require('./filenamify');
const filenamifyPath = require('./filenamify-path');

// 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 filenamify = (string, options = {}) => {
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');
}

string = string.replace(filenameReservedRegex(), replacement);
string = string.replace(reControlChars, replacement);
string = string.replace(reRelativePath, replacement);

if (replacement.length > 0) {
string = trimRepeated(string, replacement);
string = string.length > 1 ? stripOuter(string, replacement) : string;
}

string = filenameReservedRegex.windowsNames().test(string) ? string + replacement : string;
string = string.slice(0, typeof options.maxLength === 'number' ? options.maxLength : MAX_FILENAME_LENGTH);

return string;
};

filenamify.path = (filePath, options) => {
filePath = path.resolve(filePath);
return path.join(path.dirname(filePath), filenamify(path.basename(filePath), options));
};
const filenamifyCombined = filenamify;
filenamifyCombined.path = filenamifyPath;

module.exports = filenamify;
4 changes: 4 additions & 0 deletions package.json
Expand Up @@ -19,6 +19,10 @@
"index.js",
"index.d.ts"
],
"exports": {
".": "./index.js",
"./browser": "./filenamify.js"
},
"keywords": [
"filename",
"safe",
Expand Down