Skip to content

Commit

Permalink
add escapePath utility function (#36)
Browse files Browse the repository at this point in the history
Co-authored-by: Ben McCann <[email protected]>

---------

Co-authored-by: Superchupu <[email protected]>
  • Loading branch information
benmccann and SuperchupuDev authored Sep 29, 2024
1 parent 0fcb1b3 commit cace1a1
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,5 @@ export function globSync(patternsOrOptions: string | string[] | GlobOptions, opt

return crawl(opts, cwd, true);
}

export { escapePath } from './utils.ts';
18 changes: 18 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// #region escapePath

/*
Matches the following unescaped symbols:
`(){}[]`, `!+@` before `(`, `!` at the beginning,
plus the following platform-specific symbols:
Posix: `*?|`, `\` before non-special characters.
*/
const POSIX_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}*?|]|^!|[!+@](?=\()|\\(?![()[\]{}!*+?@|]))/g;
const WIN32_UNESCAPED_GLOB_SYMBOLS = /(?<!\\)([()[\]{}]|^!|[!+@](?=\())/g;

export const escapePosixPath = (pattern: string): string => pattern.replace(POSIX_UNESCAPED_GLOB_SYMBOLS, '\\$&');
export const escapeWin32Path = (pattern: string): string => pattern.replace(WIN32_UNESCAPED_GLOB_SYMBOLS, '\\$&');

export const escapePath: (pattern: string) => string = process.platform === 'win32' ? escapeWin32Path : escapePosixPath;

// #endregion
36 changes: 36 additions & 0 deletions test/escapePath.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import assert from 'node:assert/strict';
import { describe, test } from 'node:test';
import { escapePosixPath, escapeWin32Path } from '../src/utils.ts';

for (const platform of ['win32', 'posix']) {
const escapePath = platform === 'posix' ? escapePosixPath : escapeWin32Path;

describe(`escapePath (${platform})`, () => {
test("doesn't add backslashes to already escaped patterns", () => {
assert.strictEqual(escapeWin32Path('\\['), '\\[');

if (platform === 'posix') {
assert.strictEqual(escapePath('\\|'), '\\|');
}
});

test("doesn't add wrong backslashes", () => {
assert.strictEqual(escapePath('hi!@+'), 'hi!@+');
});

test('correctly escapes characters', () => {
assert.strictEqual(escapePath('!nox'), '\\!nox');
assert.strictEqual(escapePath('hi+(@(!())))'), 'hi\\+\\(\\@\\(\\!\\(\\)\\)\\)\\)');

if (platform === 'posix') {
assert.strictEqual(escapePath('\\'), '\\\\');
assert.strictEqual(escapePath('meo*w'), 'meo\\*w');
} else if (platform === 'win32') {
assert.strictEqual(
escapePath('C:\\Users\\meeee\\New Folder (1)\\**'),
'C:\\Users\\meeee\\New Folder \\(1\\)\\**'
);
}
});
});
}
2 changes: 1 addition & 1 deletion test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ test('absolute + empty commonPath', async () => {
});

test('works with non-absolute cwd', async () => {
const files = await glob({ patterns: ['*.test.ts'], cwd: 'test' });
const files = await glob({ patterns: ['index.test.ts'], cwd: 'test' });
assert.deepEqual(files.sort(), ['index.test.ts']);
});

Expand Down

0 comments on commit cace1a1

Please sign in to comment.