feat: Introduce fe modular build system

This commit is contained in:
divocat
2025-10-02 21:40:16 +03:00
parent 4ef15f7340
commit 294cb21e91
21 changed files with 2294 additions and 17 deletions

View File

@@ -4,19 +4,9 @@
'require ui';
'require network';
'require view.podkop.constants as constants';
'require view.podkop.main as main';
'require tools.widgets as widgets';
function validateUrl(url, protocols = ['http:', 'https:']) {
try {
const parsedUrl = new URL(url);
if (!protocols.includes(parsedUrl.protocol)) {
return _('URL must use one of the following protocols: ') + protocols.join(', ');
}
return true;
} catch (e) {
return _('Invalid URL format');
}
}
function createConfigSection(section, map, network) {
const s = section;
@@ -438,8 +428,18 @@ function createConfigSection(section, map, network) {
o.rmempty = false;
o.ucisection = s.section;
o.validate = function (section_id, value) {
if (!value || value.length === 0) return true;
return validateUrl(value);
// Optional
if (!value || value.length === 0) {
return true
}
const validation = main.validateUrl(url);
if (validation.valid) {
return true;
}
return _(validation.message)
};
o = s.taboption('basic', form.Flag, 'local_subnet_lists_enabled', _('Local Subnet Lists'), _('Use the list from the router filesystem'));
@@ -562,8 +562,18 @@ function createConfigSection(section, map, network) {
o.rmempty = false;
o.ucisection = s.section;
o.validate = function (section_id, value) {
if (!value || value.length === 0) return true;
return validateUrl(value);
// Optional
if (!value || value.length === 0) {
return true
}
const validation = main.validateUrl(url);
if (validation.valid) {
return true;
}
return _(validation.message)
};
o = s.taboption('basic', form.Flag, 'all_traffic_from_ip_enabled', _('IP for full redirection'), _('Specify local IP addresses whose traffic will always use the configured route'));
@@ -591,4 +601,4 @@ function createConfigSection(section, map, network) {
return baseclass.extend({
createConfigSection
});
});

View File

@@ -0,0 +1,66 @@
// This file is autogenerated, please don't change manually
"use strict";
"require baseclass";
// src/validators/validateIp.ts
function validateIPV4(ip) {
const ipRegex = /^(?:(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: false, message: "Invalid IP address" };
}
// src/validators/validateDomain.ts
function validateDomain(domain) {
const domainRegex = /^(?=.{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" };
}
const hostname = domain.split("/")[0];
const parts = hostname.split(".");
const atLeastOneInvalidPart = parts.some((part) => part.length > 63);
if (atLeastOneInvalidPart) {
return { valid: false, message: "Invalid domain address" };
}
return { valid: true, message: "Valid" };
}
// src/validators/validateDns.ts
function validateDNS(value) {
if (!value) {
return { valid: false, message: "DNS server address cannot be empty" };
}
if (validateIPV4(value).valid) {
return { valid: true, message: "Valid" };
}
if (validateDomain(value).valid) {
return { valid: true, message: "Valid" };
}
return {
valid: false,
message: "Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com or dns.example.com/nicedns for DoH"
};
}
// src/validators/validateUrl.ts
function validateUrl(url, protocols = ["http:", "https:"]) {
try {
const parsedUrl = new URL(url);
if (!protocols.includes(parsedUrl.protocol)) {
return {
valid: false,
message: `URL must use one of the following protocols: ${protocols.join(", ")}`
};
}
return { valid: true, message: "Valid" };
} catch (e) {
return { valid: false, message: "Invalid URL format" };
}
}
return baseclass.extend({
validateDNS,
validateDomain,
validateIPV4,
validateUrl
});