mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 01:20:24 +03:00
Ensure generating server IDs work even if server URLs are invalid
This commit is contained in:
parent
645abea72a
commit
b31949b468
3 changed files with 64 additions and 3 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org).
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
* [#1360](https://github.com/shlinkio/shlink-web-client/issues/1360) Added ability for server IDs to be generated based on the server name and URL, instead of generating a random UUID.
|
||||
|
||||
This can improve sharing a predefined set of servers cia servers.json, env vars, or simply export and import your servers in some other device, and then be able to share server URLs which continue working.
|
||||
|
||||
All existing servers will keep their generated IDs in existing devices for backwards compatibility, but newly created servers will use the new approach.
|
||||
|
||||
### Changed
|
||||
* *Nothing*
|
||||
|
||||
### Deprecated
|
||||
* *Nothing*
|
||||
|
||||
### Removed
|
||||
* *Nothing*
|
||||
|
||||
### Fixed
|
||||
* *Nothing*
|
||||
|
||||
|
||||
## [4.2.2] - 2024-10-19
|
||||
### Added
|
||||
* *Nothing*
|
||||
|
|
|
@ -6,9 +6,23 @@ import type { ServerData, ServersMap, ServerWithId } from '../data';
|
|||
* in lowercase and replacing invalid URL characters with hyphens.
|
||||
*/
|
||||
function idForServer(server: ServerData): string {
|
||||
// TODO Handle invalid URLs. If not valid url, use the value as is
|
||||
const url = new URL(server.url);
|
||||
return `${server.name} ${url.host}`.toLowerCase().replace(/[^a-zA-Z0-9-_.~]/g, '-');
|
||||
let urlSegment = server.url;
|
||||
try {
|
||||
const { host, pathname } = new URL(urlSegment);
|
||||
urlSegment = host;
|
||||
|
||||
// Remove leading slash from pathname
|
||||
const normalizedPathname = pathname.substring(1);
|
||||
|
||||
// Include pathname in the ID, if not empty
|
||||
if (normalizedPathname.length > 0) {
|
||||
urlSegment = `${urlSegment} ${normalizedPathname}`;
|
||||
}
|
||||
} catch {
|
||||
// If the server URL is not valid, use the value as is
|
||||
}
|
||||
|
||||
return `${server.name} ${urlSegment}`.toLowerCase().replace(/[^a-zA-Z0-9-_.~]/g, '-');
|
||||
}
|
||||
|
||||
export function serversListToMap(servers: ServerWithId[]): ServersMap {
|
||||
|
|
|
@ -39,5 +39,31 @@ describe('index', () => {
|
|||
expect.objectContaining({ id: 'baz-s.test' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('includes server paths when not empty', () => {
|
||||
const result = ensureUniqueIds({}, [
|
||||
fromPartial({ name: 'Foo', url: 'https://example.com' }),
|
||||
fromPartial({ name: 'Bar', url: 'https://s.test/some/path' }),
|
||||
fromPartial({ name: 'Baz', url: 'https://s.test/some/other-path-here/123' }),
|
||||
]);
|
||||
|
||||
expect(result).toEqual([
|
||||
expect.objectContaining({ id: 'foo-example.com' }),
|
||||
expect.objectContaining({ id: 'bar-s.test-some-path' }),
|
||||
expect.objectContaining({ id: 'baz-s.test-some-other-path-here-123' }),
|
||||
]);
|
||||
});
|
||||
|
||||
it('uses server URL verbatim when it is not a valid URL', () => {
|
||||
const result = ensureUniqueIds({}, [
|
||||
fromPartial({ name: 'Foo', url: 'invalid' }),
|
||||
fromPartial({ name: 'Bar', url: 'this is not a URL' }),
|
||||
]);
|
||||
|
||||
expect(result).toEqual([
|
||||
expect.objectContaining({ id: 'foo-invalid' }),
|
||||
expect.objectContaining({ id: 'bar-this-is-not-a-url' }),
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue