directus

Форк
0
87 строк · 2.6 Кб
1
import { URL } from 'url';
2

3
export class Url {
4
	protocol: string | null;
5
	host: string | null;
6
	port: string | null;
7
	path: string[];
8
	query: Record<string, string>;
9
	hash: string | null;
10
	hasTrailingSlash: boolean;
11

12
	constructor(url: string) {
13
		const parsedUrl = new URL(url, 'http://localhost');
14

15
		const isProtocolRelative = /^\/\//.test(url);
16
		const isRootRelative = /^\/$|^\/[^/]/.test(url);
17
		const isPathRelative = /^\./.test(url);
18

19
		this.protocol =
20
			!isProtocolRelative && !isRootRelative && !isPathRelative
21
				? parsedUrl.protocol.substring(0, parsedUrl.protocol.length - 1)
22
				: null;
23

24
		this.host = !isRootRelative && !isPathRelative ? parsedUrl.hostname : null;
25
		this.port = parsedUrl.port !== '' ? parsedUrl.port : null;
26
		this.path = parsedUrl.pathname.split('/').filter((p) => p !== '');
27
		this.query = Object.fromEntries(parsedUrl.searchParams.entries());
28
		this.hash = parsedUrl.hash !== '' ? parsedUrl.hash.substring(1) : null;
29

30
		this.hasTrailingSlash = parsedUrl.pathname.length > 1 ? parsedUrl.pathname.endsWith('/') : url.endsWith('/');
31
	}
32

33
	public isAbsolute(): boolean {
34
		return this.protocol !== null && this.host !== null;
35
	}
36

37
	public isProtocolRelative(): boolean {
38
		return this.protocol === null && this.host !== null;
39
	}
40

41
	public isRootRelative(): boolean {
42
		return this.protocol === null && this.host === null;
43
	}
44

45
	public addPath(...paths: (string | number)[]): Url {
46
		const pathToAdd = paths.flatMap((p) => String(p).split('/')).filter((p) => p !== '');
47

48
		for (const pathSegment of pathToAdd) {
49
			if (pathSegment === '..') {
50
				this.path.pop();
51
			} else if (pathSegment !== '.') {
52
				this.path.push(pathSegment);
53
			}
54
		}
55

56
		const lastPath = paths.at(-1);
57

58
		if (pathToAdd.length > 0 && lastPath !== '.' && lastPath !== '..') {
59
			this.hasTrailingSlash = typeof lastPath === 'string' && lastPath.endsWith('/');
60
		}
61

62
		return this;
63
	}
64

65
	public setQuery(key: string, value: string): Url {
66
		this.query[key] = value;
67

68
		return this;
69
	}
70

71
	public toString({ rootRelative } = { rootRelative: false }): string {
72
		const protocol = this.protocol !== null ? `${this.protocol}:` : '';
73
		const host = this.host ?? '';
74
		const port = this.port !== null ? `:${this.port}` : '';
75
		const origin = `${this.host !== null ? `${protocol}//` : ''}${host}${port}`;
76

77
		const path = this.path.length ? `/${this.path.join('/')}` : '';
78

79
		const trailingSlash = this.hasTrailingSlash ? '/' : '';
80

81
		const query = Object.keys(this.query).length !== 0 ? `?${new URLSearchParams(this.query).toString()}` : '';
82

83
		const hash = this.hash !== null ? `#${this.hash}` : '';
84

85
		return `${!rootRelative ? origin : ''}${path}${trailingSlash}${query}${hash}`;
86
	}
87
}
88

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.