diff --git a/src/__tests__/index.test.ts b/src/__tests__/index.test.ts index 9e942eae..045e7df6 100644 --- a/src/__tests__/index.test.ts +++ b/src/__tests__/index.test.ts @@ -59,4 +59,16 @@ describe('rewrite(fs, rewrites)', () => { expect(lfs.readFileSync('/4', 'utf8')).toBe('foo'); }); + + it('handles file rename', () => { + const vol = Volume.fromJSON({ + '/1/2/3/4': 'foo' + }); + + const lfs = link(vol, ['/', '/1/2/3']); + + lfs.renameSync('/4', '/5'); + + expect(lfs.readFileSync('/5', 'utf8')).toBe('foo'); + }) }); diff --git a/src/index.ts b/src/index.ts index f301e8d8..a2653a70 100644 --- a/src/index.ts +++ b/src/index.ts @@ -66,6 +66,11 @@ export const rewritableMethods = [ 'writeFile', ]; +export const multiArgumentMethods = [ + 'renameSync', + 'rename', +] + export const proxyableMethods = [ 'ftruncateSync', 'fchownSync', @@ -115,33 +120,39 @@ export function link(fs, rewrites: string[] | string[][]): any { if(typeof func !== 'function') continue; lfs[method] = (...args) => { - const path = args[0]; - - // If first argument is not a path, just proxy the function. - if((typeof path !== 'string') && !Buffer.isBuffer(path)) { - if(!require('url').URL || !(path instanceof require('url').URL)) - return func.apply(fs, args); - } - - // Rewrite the path argument. - let filename = resolve(String(path)); - for(const [from, to] of rews) { - if(filename.indexOf(from) === 0) { - const rootRegex = /(?:^[a-zA-Z]:\\$)|(?:^\/$)/; // C:\ vs / - const isRoot = from.match(rootRegex); - const baseRegex = '^(' + from.replace(/\\/g, '\\\\') + ')'; - - if(isRoot) { - const regex = new RegExp(baseRegex); - filename = filename.replace(regex, () => to + sep); - } else { - const regex = new RegExp(baseRegex + '(\\\\|\/|$)'); - filename = filename.replace(regex, (match, p1, p2) => to + p2); + const multi = multiArgumentMethods.indexOf(method) !== -1; + const paths = !multi ? [args[0]] : [args[0], args[1]]; + + for(let index = 0; index <= paths.length; index++) { + const path = paths[index]; + + // If first argument is not a path, just proxy the function. + if((typeof path !== 'string') && !Buffer.isBuffer(path)) { + if(!require('url').URL || !(path instanceof require('url').URL)) + return func.apply(fs, args); + } + + // Rewrite the path argument. + let filename = resolve(String(path)); + for(const [from, to] of rews) { + if(filename.indexOf(from) === 0) { + const rootRegex = /(?:^[a-zA-Z]:\\$)|(?:^\/$)/; // C:\ vs / + const isRoot = from.match(rootRegex); + const baseRegex = '^(' + from.replace(/\\/g, '\\\\') + ')'; + + if(isRoot) { + const regex = new RegExp(baseRegex); + filename = filename.replace(regex, () => to + sep); + } else { + const regex = new RegExp(baseRegex + '(\\\\|\/|$)'); + filename = filename.replace(regex, (match, p1, p2) => to + p2); + } } - } + } + + args[index] = filename; } - args[0] = filename; return func.apply(fs, args); }; }