/
QueryResolver.ts
89 lines (79 loc) 路 3.83 KB
/
QueryResolver.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { YouTube } from 'youtube-sr';
import { QueryType } from '../types/types';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import * as soundcloud from 'soundcloud-scraper';
// #region scary things below *sigh*
const spotifySongRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})(\?si=.+)?$/;
const spotifyPlaylistRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})(\?si=.+)?$/;
const spotifyAlbumRegex = /^https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})(\?si=.+)?$/;
const vimeoRegex = /^(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)$/;
const reverbnationRegex = /^https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)$/;
const attachmentRegex = /^https?:\/\/.+$/;
const appleMusicSongRegex = /^https?:\/\/music\.apple\.com\/.+?\/(song|album)\/.+?(\/.+?\?i=|\/)([0-9]+)$/;
const appleMusicPlaylistRegex = /^https?:\/\/music\.apple\.com\/.+?\/playlist\/.+\/pl\.(u-)?[a-zA-Z0-9]+$/;
const appleMusicAlbumRegex = /^https?:\/\/music\.apple\.com\/.+?\/album\/.+\/([0-9]+)$/;
// #endregion scary things above *sigh*
class QueryResolver {
/**
* Query resolver
*/
private constructor() {} // eslint-disable-line @typescript-eslint/no-empty-function
static get regex() {
return {
spotifyAlbumRegex,
spotifyPlaylistRegex,
spotifySongRegex,
vimeoRegex,
reverbnationRegex,
attachmentRegex,
appleMusicAlbumRegex,
appleMusicPlaylistRegex,
appleMusicSongRegex
};
}
/**
* Resolves the given search query
* @param {string} query The query
* @returns {QueryType}
*/
static resolve(query: string): (typeof QueryType)[keyof typeof QueryType] {
query = !query.includes('youtube.com') ? query.trim() : query.replace(/(m(usic)?|gaming)\./, '').trim();
// @ts-expect-error
if ((soundcloud.validateURL || soundcloud.default.validateURL)(query, 'track')) return QueryType.SOUNDCLOUD_TRACK;
// @ts-expect-error
if ((soundcloud.validateURL || soundcloud.default.validateURL)(query, 'playlist') || query.includes('/sets/')) return QueryType.SOUNDCLOUD_PLAYLIST;
if (YouTube.isPlaylist(query)) return QueryType.YOUTUBE_PLAYLIST;
if (QueryResolver.validateId(query) || QueryResolver.validateURL(query)) return QueryType.YOUTUBE_VIDEO;
if (spotifySongRegex.test(query)) return QueryType.SPOTIFY_SONG;
if (spotifyPlaylistRegex.test(query)) return QueryType.SPOTIFY_PLAYLIST;
if (spotifyAlbumRegex.test(query)) return QueryType.SPOTIFY_ALBUM;
if (vimeoRegex.test(query)) return QueryType.VIMEO;
if (reverbnationRegex.test(query)) return QueryType.REVERBNATION;
if (appleMusicAlbumRegex.test(query)) return QueryType.APPLE_MUSIC_ALBUM;
if (appleMusicPlaylistRegex.test(query)) return QueryType.APPLE_MUSIC_PLAYLIST;
if (appleMusicSongRegex.test(query)) return QueryType.APPLE_MUSIC_SONG;
if (attachmentRegex.test(query)) return QueryType.ARBITRARY;
return QueryType.YOUTUBE_SEARCH;
}
/**
* Parses vimeo id from url
* @param {string} query The query
* @returns {string}
*/
static getVimeoID(query: string): string | null | undefined {
return QueryResolver.resolve(query) === QueryType.VIMEO
? query
.split('/')
.filter((x) => !!x)
.pop()
: null;
}
static validateId(q: string) {
return YouTube.Regex.VIDEO_ID.test(q);
}
static validateURL(q: string) {
return YouTube.Regex.VIDEO_URL.test(q);
}
}
export { QueryResolver };