mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-19 09:45:37 -04:00
refactor: reorganize files in commons package
Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
This commit is contained in:
parent
c9b98f6185
commit
4d9792bcb9
23 changed files with 94 additions and 69 deletions
17
commons/src/parse-url/errors.ts
Normal file
17
commons/src/parse-url/errors.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export class MissingTrailingSlashError extends Error {
|
||||
constructor() {
|
||||
super("Path doesn't end with a trailing slash")
|
||||
}
|
||||
}
|
||||
|
||||
export class WrongProtocolError extends Error {
|
||||
constructor() {
|
||||
super('Protocol must be HTTP or HTTPS')
|
||||
}
|
||||
}
|
8
commons/src/parse-url/index.ts
Normal file
8
commons/src/parse-url/index.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
export { parseUrl } from './parse-url.js'
|
||||
export { MissingTrailingSlashError, WrongProtocolError } from './errors.js'
|
58
commons/src/parse-url/parse-url.spec.ts
Normal file
58
commons/src/parse-url/parse-url.spec.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { MissingTrailingSlashError, WrongProtocolError } from './errors.js'
|
||||
import { parseUrl } from './parse-url.js'
|
||||
import { describe, expect, it } from '@jest/globals'
|
||||
|
||||
describe('validate url', () => {
|
||||
it("doesn't accept non-urls", () => {
|
||||
expect(parseUrl('noUrl').isEmpty()).toBeTruthy()
|
||||
})
|
||||
|
||||
describe('protocols', () => {
|
||||
it('works with http', () => {
|
||||
expect(parseUrl('http://example.org').get().toString()).toEqual(
|
||||
'http://example.org/'
|
||||
)
|
||||
})
|
||||
it('works with https', () => {
|
||||
expect(parseUrl('https://example.org').get().toString()).toEqual(
|
||||
'https://example.org/'
|
||||
)
|
||||
})
|
||||
it("doesn't work without protocol", () => {
|
||||
expect(() => parseUrl('example.org').isEmpty()).toBeTruthy()
|
||||
})
|
||||
it("doesn't work any other protocol", () => {
|
||||
expect(() => parseUrl('git://example.org').get()).toThrowError(
|
||||
WrongProtocolError
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('trailing slash', () => {
|
||||
it('accepts urls with just domain with trailing slash', () => {
|
||||
expect(parseUrl('http://example.org/').get().toString()).toEqual(
|
||||
'http://example.org/'
|
||||
)
|
||||
})
|
||||
it('accepts urls with just domain without trailing slash', () => {
|
||||
expect(parseUrl('http://example.org').get().toString()).toEqual(
|
||||
'http://example.org/'
|
||||
)
|
||||
})
|
||||
it('accepts urls with with subpath and trailing slash', () => {
|
||||
expect(parseUrl('http://example.org/asd/').get().toString()).toEqual(
|
||||
'http://example.org/asd/'
|
||||
)
|
||||
})
|
||||
it("doesn't accept urls with with subpath and without trailing slash", () => {
|
||||
expect(() => parseUrl('http://example.org/asd').get().toString()).toThrow(
|
||||
MissingTrailingSlashError
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
35
commons/src/parse-url/parse-url.ts
Normal file
35
commons/src/parse-url/parse-url.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
import { MissingTrailingSlashError, WrongProtocolError } from './errors.js'
|
||||
import { Optional } from '@mrdrogdrog/optional'
|
||||
|
||||
/**
|
||||
* Parses the given string as URL
|
||||
*
|
||||
* @param {String | undefined} url the raw url
|
||||
* @return An {@link Optional} that contains the parsed URL or is empty if the raw value isn't a valid URL
|
||||
* @throws WrongProtocolError if the protocol of the URL isn't either http nor https
|
||||
* @throws MissingTrailingSlashError if the URL has a path that doesn't end with a trailing slash
|
||||
*/
|
||||
export function parseUrl(url: string | undefined): Optional<URL> {
|
||||
return createOptionalUrl(url)
|
||||
.guard(
|
||||
(value) => value.protocol === 'https:' || value.protocol === 'http:',
|
||||
() => new WrongProtocolError()
|
||||
)
|
||||
.guard(
|
||||
(value) => value.pathname.endsWith('/'),
|
||||
() => new MissingTrailingSlashError()
|
||||
)
|
||||
}
|
||||
|
||||
function createOptionalUrl(url: string | undefined): Optional<URL> {
|
||||
try {
|
||||
return Optional.ofNullable(url).map((value) => new URL(value))
|
||||
} catch (error) {
|
||||
return Optional.empty()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue