-
-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: normalize prefix when parsing. fixes #9081
- Loading branch information
Showing
3 changed files
with
352 additions
and
24 deletions.
There are no files selected for viewing
318 changes: 318 additions & 0 deletions
318
packages/native/src/__tests__/extractPathFromURL.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,318 @@ | ||
import extractPathFromURL from '../extractPathFromURL'; | ||
|
||
it('extracts path from URL with protocol', () => { | ||
expect(extractPathFromURL(['scheme://'], 'scheme://some/path')).toBe( | ||
'some/path' | ||
); | ||
|
||
expect(extractPathFromURL(['scheme://'], 'scheme:some/path')).toBe( | ||
'some/path' | ||
); | ||
|
||
expect(extractPathFromURL(['scheme://'], 'scheme:///some/path')).toBe( | ||
'some/path' | ||
); | ||
|
||
expect(extractPathFromURL(['scheme:///'], 'scheme:some/path')).toBe( | ||
'some/path' | ||
); | ||
|
||
expect(extractPathFromURL(['scheme:'], 'scheme:some/path')).toBe('some/path'); | ||
|
||
expect(extractPathFromURL(['scheme:'], 'scheme://some/path')).toBe( | ||
'some/path' | ||
); | ||
|
||
expect(extractPathFromURL(['scheme:'], 'scheme:///some/path')).toBe( | ||
'some/path' | ||
); | ||
}); | ||
|
||
it('extracts path from URL with protocol and host', () => { | ||
expect( | ||
extractPathFromURL( | ||
['scheme://example.com'], | ||
'scheme://example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL(['scheme://example.com'], 'scheme:example.com/some/path') | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme://example.com'], | ||
'scheme:///example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:///example.com'], | ||
'scheme:example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL(['scheme:example.com'], 'scheme:example.com/some/path') | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL(['scheme:example.com'], 'scheme://example.com/some/path') | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:example.com'], | ||
'scheme:///example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
}); | ||
|
||
it('extracts path from URL with protocol and host with wildcard', () => { | ||
expect( | ||
extractPathFromURL( | ||
['scheme://*.example.com'], | ||
'scheme://test.example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme://*.example.com'], | ||
'scheme:test.example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme://*.example.com'], | ||
'scheme:///test.example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:///*.example.com'], | ||
'scheme:test.example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:*.example.com'], | ||
'scheme:test.example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:*.example.com'], | ||
'scheme://test.example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:*.example.com'], | ||
'scheme:///test.example.com/some/path' | ||
) | ||
).toBe('/some/path'); | ||
}); | ||
|
||
it('extracts path from URL with protocol, host and path', () => { | ||
expect( | ||
extractPathFromURL( | ||
['scheme://example.com/test'], | ||
'scheme://example.com/test/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL(['scheme://example.com'], 'scheme:example.com/some/path') | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme://example.com/test'], | ||
'scheme:///example.com/test/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:///example.com/test'], | ||
'scheme:example.com/test/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:example.com/test'], | ||
'scheme:example.com/test/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:example.com/test'], | ||
'scheme://example.com/test/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:example.com/test'], | ||
'scheme:///example.com/test/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:example.com/test'], | ||
'scheme:///example.com//test/some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:example.com/test'], | ||
'scheme:///example.com/test//some/path' | ||
) | ||
).toBe('/some/path'); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:example.com/test'], | ||
'scheme:///example.com/test/some//path' | ||
) | ||
).toBe('/some/path'); | ||
}); | ||
|
||
it('returns undefined for non-matching protocol', () => { | ||
expect(extractPathFromURL(['scheme://'], 'foo://some/path')).toBe(undefined); | ||
|
||
expect(extractPathFromURL(['scheme://'], 'foo:some/path')).toBe(undefined); | ||
|
||
expect(extractPathFromURL(['scheme://'], 'foo:///some/path')).toBe(undefined); | ||
|
||
expect(extractPathFromURL(['scheme:///'], 'foo:some/path')).toBe(undefined); | ||
|
||
expect(extractPathFromURL(['scheme:'], 'foo:some/path')).toBe(undefined); | ||
|
||
expect(extractPathFromURL(['scheme:'], 'foo://some/path')).toBe(undefined); | ||
|
||
expect(extractPathFromURL(['scheme:'], 'foo:///some/path')).toBe(undefined); | ||
}); | ||
|
||
it('returns undefined for non-matching path', () => { | ||
expect(extractPathFromURL(['scheme://foo'], 'scheme://some/path')).toBe( | ||
undefined | ||
); | ||
|
||
expect(extractPathFromURL(['scheme://foo'], 'scheme:some/path')).toBe( | ||
undefined | ||
); | ||
|
||
expect(extractPathFromURL(['scheme://foo'], 'scheme:///some/path')).toBe( | ||
undefined | ||
); | ||
|
||
expect(extractPathFromURL(['scheme:///foo'], 'scheme:some/path')).toBe( | ||
undefined | ||
); | ||
|
||
expect(extractPathFromURL(['scheme:foo'], 'scheme:some/path')).toBe( | ||
undefined | ||
); | ||
|
||
expect(extractPathFromURL(['scheme:foo'], 'scheme://some/path')).toBe( | ||
undefined | ||
); | ||
|
||
expect(extractPathFromURL(['scheme:foo'], 'scheme:///some/path')).toBe( | ||
undefined | ||
); | ||
}); | ||
|
||
it('returns undefined for non-matching host', () => { | ||
expect( | ||
extractPathFromURL(['scheme://example.com'], 'scheme://foo.com/some/path') | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL(['scheme://example.com'], 'scheme:foo.com/some/path') | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL(['scheme://example.com'], 'scheme:///foo.com/some/path') | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL(['scheme:///example.com'], 'scheme:foo.com/some/path') | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL(['scheme:example.com'], 'scheme:foo.com/some/path') | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL(['scheme:example.com'], 'scheme://foo.com/some/path') | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL(['scheme:example.com'], 'scheme:///foo.com/some/path') | ||
).toBe(undefined); | ||
}); | ||
|
||
it('returns undefined for non-matching host with wildcard', () => { | ||
expect( | ||
extractPathFromURL( | ||
['scheme://*.example.com'], | ||
'scheme://test.foo.com/some/path' | ||
) | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme://*.example.com'], | ||
'scheme:test.foo.com/some/path' | ||
) | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme://*.example.com'], | ||
'scheme:///test.foo.com/some/path' | ||
) | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:///*.example.com'], | ||
'scheme:test.foo.com/some/path' | ||
) | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:*.example.com'], | ||
'scheme:test.foo.com/some/path' | ||
) | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:*.example.com'], | ||
'scheme://test.foo.com/some/path' | ||
) | ||
).toBe(undefined); | ||
|
||
expect( | ||
extractPathFromURL( | ||
['scheme:*.example.com'], | ||
'scheme:///test.foo.com/some/path' | ||
) | ||
).toBe(undefined); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import escapeStringRegexp from 'escape-string-regexp'; | ||
|
||
export default function extractPathFromURL(prefixes: string[], url: string) { | ||
for (const prefix of prefixes) { | ||
const protocol = prefix.match(/^[^:]+:/)?.[0] ?? ''; | ||
const host = prefix | ||
.replace(new RegExp(`^${escapeStringRegexp(protocol)}`), '') | ||
.replace(/\/+/g, '/') // Replace multiple slash (//) with single ones | ||
.replace(/^\//, ''); // Remove extra leading slash | ||
|
||
const prefixRegex = new RegExp( | ||
`^${escapeStringRegexp(protocol)}(/)*${host | ||
.split('.') | ||
.map((it) => (it === '*' ? '[^/]+' : escapeStringRegexp(it))) | ||
.join('\\.')}` | ||
); | ||
|
||
const normalizedURL = url.replace(/\/+/g, '/'); | ||
|
||
if (prefixRegex.test(normalizedURL)) { | ||
return normalizedURL.replace(prefixRegex, ''); | ||
} | ||
} | ||
|
||
return undefined; | ||
} |
Oops, something went wrong.