pstream is dead; long live pstream
taciturnaxolotl.github.io/pstream-ng/
1import { conf } from "@/setup/config";
2import { useAuthStore } from "@/stores/auth";
3
4const originalUrls = conf().PROXY_URLS;
5const types = ["proxy"] as const;
6
7type ParsedUrlType = (typeof types)[number];
8
9export interface ParsedUrl {
10 url: string;
11 type: ParsedUrlType;
12}
13
14function canParseUrl(url: string): boolean {
15 try {
16 return !!new URL(url);
17 } catch {
18 return false;
19 }
20}
21
22function isParsedUrlType(type: string): type is ParsedUrlType {
23 return types.includes(type as any);
24}
25
26/**
27 * Turn a string like "a=b;c=d;d=e" into a dictionary object
28 */
29function parseParams(input: string): Record<string, string> {
30 const entriesParams = input
31 .split(";")
32 .map((param) => param.split("=", 2).filter((part) => part.length !== 0))
33 .filter((v) => v.length === 2);
34 return Object.fromEntries(entriesParams);
35}
36
37export function getParsedUrls() {
38 const urls = useAuthStore.getState().proxySet ?? originalUrls;
39 const output: ParsedUrl[] = [];
40 urls.forEach((url) => {
41 if (!url.startsWith("|")) {
42 if (canParseUrl(url)) {
43 output.push({
44 url,
45 type: "proxy",
46 });
47 return;
48 }
49 }
50
51 const match = /^\|([^|]+)\|(.*)$/g.exec(url);
52 if (!match || !match[2]) return;
53 if (!canParseUrl(match[2])) return;
54 const params = parseParams(match[1]);
55 const type = params.type ?? "proxy";
56
57 if (!isParsedUrlType(type)) return;
58 output.push({
59 url: match[2],
60 type,
61 });
62 });
63
64 return output;
65}
66
67export function getProxyUrls() {
68 return getParsedUrls()
69 .filter((v) => v.type === "proxy")
70 .map((v) => v.url);
71}
72
73export function getM3U8ProxyUrls(): string[] {
74 return conf().M3U8_PROXY_URLS;
75}