feat: migrate to _ locales handler

This commit is contained in:
divocat
2025-10-07 16:55:50 +03:00
parent e0874c3775
commit 9a72785fa7
25 changed files with 213 additions and 212 deletions

View File

@@ -4,20 +4,21 @@ import { ValidationResult } from './types';
export function validateDNS(value: string): ValidationResult {
if (!value) {
return { valid: false, message: 'DNS server address cannot be empty' };
return { valid: false, message: _('DNS server address cannot be empty') };
}
if (validateIPV4(value).valid) {
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
}
if (validateDomain(value).valid) {
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
}
return {
valid: false,
message:
message: _(
'Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com or dns.example.com/nicedns for DoH',
),
};
}

View File

@@ -5,7 +5,7 @@ export function validateDomain(domain: string): ValidationResult {
/^(?=.{1,253}(?:\/|$))(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)\.)+(?:[a-zA-Z]{2,}|xn--[a-zA-Z0-9-]{1,59}[a-zA-Z0-9])(?:\/[^\s]*)?$/;
if (!domainRegex.test(domain)) {
return { valid: false, message: 'Invalid domain address' };
return { valid: false, message: _('Invalid domain address') };
}
const hostname = domain.split('/')[0];
@@ -14,8 +14,8 @@ export function validateDomain(domain: string): ValidationResult {
const atLeastOneInvalidPart = parts.some((part) => part.length > 63);
if (atLeastOneInvalidPart) {
return { valid: false, message: 'Invalid domain address' };
return { valid: false, message: _('Invalid domain address') };
}
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
}

View File

@@ -5,8 +5,8 @@ export function validateIPV4(ip: string): ValidationResult {
/^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/;
if (ipRegex.test(ip)) {
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
}
return { valid: false, message: 'Invalid IP address' };
return { valid: false, message: _('Invalid IP address') };
}

View File

@@ -8,13 +8,14 @@ export function validateOutboundJson(value: string): ValidationResult {
if (!parsed.type || !parsed.server || !parsed.server_port) {
return {
valid: false,
message:
message: _(
'Outbound JSON must contain at least "type", "server" and "server_port" fields',
),
};
}
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
} catch {
return { valid: false, message: 'Invalid JSON format' };
return { valid: false, message: _('Invalid JSON format') };
}
}

View File

@@ -4,7 +4,7 @@ export function validatePath(value: string): ValidationResult {
if (!value) {
return {
valid: false,
message: 'Path cannot be empty',
message: _('Path cannot be empty'),
};
}
@@ -19,7 +19,8 @@ export function validatePath(value: string): ValidationResult {
return {
valid: false,
message:
message: _(
'Invalid path format. Path must start with "/" and contain valid characters',
),
};
}

View File

@@ -19,6 +19,6 @@ export function validateProxyUrl(url: string): ValidationResult {
return {
valid: false,
message: 'URL must start with vless:// or ss:// or trojan://',
message: _('URL must start with vless:// or ss:// or trojan://'),
};
}

View File

@@ -5,7 +5,7 @@ export function validateShadowsocksUrl(url: string): ValidationResult {
if (!url.startsWith('ss://')) {
return {
valid: false,
message: 'Invalid Shadowsocks URL: must start with ss://',
message: _('Invalid Shadowsocks URL: must start with ss://'),
};
}
@@ -13,7 +13,7 @@ export function validateShadowsocksUrl(url: string): ValidationResult {
if (!url || /\s/.test(url)) {
return {
valid: false,
message: 'Invalid Shadowsocks URL: must not contain spaces',
message: _('Invalid Shadowsocks URL: must not contain spaces'),
};
}
@@ -24,7 +24,7 @@ export function validateShadowsocksUrl(url: string): ValidationResult {
if (!encryptedPart) {
return {
valid: false,
message: 'Invalid Shadowsocks URL: missing credentials',
message: _('Invalid Shadowsocks URL: missing credentials'),
};
}
@@ -34,16 +34,18 @@ export function validateShadowsocksUrl(url: string): ValidationResult {
if (!decoded.includes(':')) {
return {
valid: false,
message:
message: _(
'Invalid Shadowsocks URL: decoded credentials must contain method:password',
),
};
}
} catch (_e) {
if (!encryptedPart.includes(':') && !encryptedPart.includes('-')) {
return {
valid: false,
message:
message: _(
'Invalid Shadowsocks URL: missing method and password separator ":"',
),
};
}
}
@@ -53,7 +55,7 @@ export function validateShadowsocksUrl(url: string): ValidationResult {
if (!serverPart) {
return {
valid: false,
message: 'Invalid Shadowsocks URL: missing server address',
message: _('Invalid Shadowsocks URL: missing server address'),
};
}
@@ -62,14 +64,17 @@ export function validateShadowsocksUrl(url: string): ValidationResult {
if (!server) {
return {
valid: false,
message: 'Invalid Shadowsocks URL: missing server',
message: _('Invalid Shadowsocks URL: missing server'),
};
}
const port = portAndRest ? portAndRest.split(/[?#]/)[0] : null;
if (!port) {
return { valid: false, message: 'Invalid Shadowsocks URL: missing port' };
return {
valid: false,
message: _('Invalid Shadowsocks URL: missing port'),
};
}
const portNum = parseInt(port, 10);
@@ -77,12 +82,15 @@ export function validateShadowsocksUrl(url: string): ValidationResult {
if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
return {
valid: false,
message: 'Invalid port number. Must be between 1 and 65535',
message: _('Invalid port number. Must be between 1 and 65535'),
};
}
} catch (_e) {
return { valid: false, message: 'Invalid Shadowsocks URL: parsing failed' };
return {
valid: false,
message: _('Invalid Shadowsocks URL: parsing failed'),
};
}
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
}

View File

@@ -8,14 +8,14 @@ export function validateSubnet(value: string): ValidationResult {
if (!subnetRegex.test(value)) {
return {
valid: false,
message: 'Invalid format. Use X.X.X.X or X.X.X.X/Y',
message: _('Invalid format. Use X.X.X.X or X.X.X.X/Y'),
};
}
const [ip, cidr] = value.split('/');
if (ip === '0.0.0.0') {
return { valid: false, message: 'IP address 0.0.0.0 is not allowed' };
return { valid: false, message: _('IP address 0.0.0.0 is not allowed') };
}
const ipCheck = validateIPV4(ip);
@@ -30,10 +30,10 @@ export function validateSubnet(value: string): ValidationResult {
if (cidrNum < 0 || cidrNum > 32) {
return {
valid: false,
message: 'CIDR must be between 0 and 32',
message: _('CIDR must be between 0 and 32'),
};
}
}
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
}

View File

@@ -5,14 +5,14 @@ export function validateTrojanUrl(url: string): ValidationResult {
if (!url.startsWith('trojan://')) {
return {
valid: false,
message: 'Invalid Trojan URL: must start with trojan://',
message: _('Invalid Trojan URL: must start with trojan://'),
};
}
if (!url || /\s/.test(url)) {
return {
valid: false,
message: 'Invalid Trojan URL: must not contain spaces',
message: _('Invalid Trojan URL: must not contain spaces'),
};
}
@@ -22,12 +22,14 @@ export function validateTrojanUrl(url: string): ValidationResult {
if (!parsedUrl.username || !parsedUrl.hostname || !parsedUrl.port) {
return {
valid: false,
message: 'Invalid Trojan URL: must contain username, hostname and port',
message: _(
'Invalid Trojan URL: must contain username, hostname and port',
),
};
}
} catch (_e) {
return { valid: false, message: 'Invalid Trojan URL: parsing failed' };
return { valid: false, message: _('Invalid Trojan URL: parsing failed') };
}
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
}

View File

@@ -10,11 +10,11 @@ export function validateUrl(
if (!protocols.includes(parsedUrl.protocol)) {
return {
valid: false,
message: `URL must use one of the following protocols: ${protocols.join(', ')}`,
message: `${_('URL must use one of the following protocols:')} ${protocols.join(', ')}`,
};
}
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
} catch (_e) {
return { valid: false, message: 'Invalid URL format' };
return { valid: false, message: _('Invalid URL format') };
}
}

View File

@@ -7,27 +7,27 @@ export function validateVlessUrl(url: string): ValidationResult {
if (!url || /\s/.test(url)) {
return {
valid: false,
message: 'Invalid VLESS URL: must not contain spaces',
message: _('Invalid VLESS URL: must not contain spaces'),
};
}
if (parsedUrl.protocol !== 'vless:') {
return {
valid: false,
message: 'Invalid VLESS URL: must start with vless://',
message: _('Invalid VLESS URL: must start with vless://'),
};
}
if (!parsedUrl.username) {
return { valid: false, message: 'Invalid VLESS URL: missing UUID' };
return { valid: false, message: _('Invalid VLESS URL: missing UUID') };
}
if (!parsedUrl.hostname) {
return { valid: false, message: 'Invalid VLESS URL: missing server' };
return { valid: false, message: _('Invalid VLESS URL: missing server') };
}
if (!parsedUrl.port) {
return { valid: false, message: 'Invalid VLESS URL: missing port' };
return { valid: false, message: _('Invalid VLESS URL: missing port') };
}
if (
@@ -37,15 +37,16 @@ export function validateVlessUrl(url: string): ValidationResult {
) {
return {
valid: false,
message:
message: _(
'Invalid VLESS URL: invalid port number. Must be between 1 and 65535',
),
};
}
if (!parsedUrl.search) {
return {
valid: false,
message: 'Invalid VLESS URL: missing query parameters',
message: _('Invalid VLESS URL: missing query parameters'),
};
}
@@ -67,8 +68,9 @@ export function validateVlessUrl(url: string): ValidationResult {
if (!type || !validTypes.includes(type)) {
return {
valid: false,
message:
message: _(
'Invalid VLESS URL: type must be one of tcp, raw, udp, grpc, http, ws',
),
};
}
@@ -78,8 +80,9 @@ export function validateVlessUrl(url: string): ValidationResult {
if (!security || !validSecurities.includes(security)) {
return {
valid: false,
message:
message: _(
'Invalid VLESS URL: security must be one of tls, reality, none',
),
};
}
@@ -87,21 +90,23 @@ export function validateVlessUrl(url: string): ValidationResult {
if (!params.get('pbk')) {
return {
valid: false,
message:
message: _(
'Invalid VLESS URL: missing pbk parameter for reality security',
),
};
}
if (!params.get('fp')) {
return {
valid: false,
message:
message: _(
'Invalid VLESS URL: missing fp parameter for reality security',
),
};
}
}
return { valid: true, message: 'Valid' };
return { valid: true, message: _('Valid') };
} catch (_e) {
return { valid: false, message: 'Invalid VLESS URL: parsing failed' };
return { valid: false, message: _('Invalid VLESS URL: parsing failed') };
}
}