diff --git a/src/index.js b/src/index.js index 564f012..4906a73 100644 --- a/src/index.js +++ b/src/index.js @@ -43,15 +43,22 @@ const sourceMatches = (source, requestPath, allowSegments) => { let results = null; if (allowSegments) { - const normalized = slashed.replace('*', '(.*)'); - const expression = pathToRegExp(normalized, keys); + try { + const normalized = slashed.replace('*', '(.*)'); + const expression = pathToRegExp(normalized, keys); - results = expression.exec(resolvedPath); + results = expression.exec(resolvedPath); - if (!results) { - // clear keys so that they are not used - // later with empty results. this may - // happen if minimatch returns true + if (!results) { + // clear keys so that they are not used + // later with empty results. this may + // happen if minimatch returns true + keys.length = 0; + } + } catch (_) { + // If path-to-regexp cannot parse the source pattern (e.g. + // extglob negation like `!(*.css|*.js)`), fall through to + // the minimatch check below. keys.length = 0; } } diff --git a/test/integration.test.js b/test/integration.test.js index cebc479..cc12a8d 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -362,6 +362,25 @@ test('set `rewrites` config property to path segment', async () => { expect(json).toEqual(content); }); +test('set `rewrites` config property with extglob negation pattern', async () => { + const destination = '.dotfile'; + const related = path.join(fixturesFull, destination); + const content = await fs.readFile(related, 'utf8'); + + const url = await getUrl({ + rewrites: [{ + source: '**/!(*.js|*.css)', + destination + }] + }); + + const response = await fetch(`${url}/face/delete`); + const text = await response.text(); + + expect(response.status).toBe(200); + expect(text).toBe(content); +}); + test('set `redirects` config property to wildcard path', async () => { const destination = 'testing';