MCPcopy Create free account
hub / github.com/bytebase/dbhub / SafeURL

Class SafeURL

src/utils/safe-url.ts:29–148  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

27 * with special characters that might break the standard URL constructor
28 */
29export class SafeURL implements ISafeURL {
30 protocol: string;
31 hostname: string;
32 port: string;
33 pathname: string;
34 username: string;
35 password: string;
36 searchParams: Map<string, string>;
37
38 /**
39 * Parse a URL and handle special characters in passwords
40 * This is a safe alternative to the URL constructor
41 *
42 * @param urlString - The DSN string to parse
43 */
44 constructor(urlString: string) {
45 // Initialize with defaults
46 this.protocol = '';
47 this.hostname = '';
48 this.port = '';
49 this.pathname = '';
50 this.username = '';
51 this.password = '';
52 this.searchParams = new Map<string, string>();
53
54 // Validate URL string
55 if (!urlString || urlString.trim() === '') {
56 throw new Error('URL string cannot be empty');
57 }
58
59 try {
60 // Extract protocol
61 const protocolSeparator: number = urlString.indexOf('://');
62 if (protocolSeparator !== -1) {
63 this.protocol = urlString.substring(0, protocolSeparator + 1); // includes the colon
64 urlString = urlString.substring(protocolSeparator + 3); // rest after ://
65 } else {
66 throw new Error('Invalid URL format: missing protocol (e.g., "mysql://")');
67 }
68
69 // Extract query params if any
70 const questionMarkIndex: number = urlString.indexOf('?');
71 let queryParams: string = '';
72 if (questionMarkIndex !== -1) {
73 queryParams = urlString.substring(questionMarkIndex + 1);
74 urlString = urlString.substring(0, questionMarkIndex);
75
76 // Parse query parameters
77 queryParams.split('&').forEach(pair => {
78 const parts: string[] = pair.split('=');
79 if (parts.length === 2 && parts[0] && parts[1]) {
80 this.searchParams.set(parts[0], decodeURIComponent(parts[1]));
81 }
82 });
83 }
84
85 // Extract authentication
86 const atIndex: number = urlString.indexOf('@');

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected