Skip to content

Commit

Permalink
feat: Add BaseConfigBuilder class for building configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
7Sageer committed Aug 4, 2024
1 parent f2b31bc commit 4d88419
Show file tree
Hide file tree
Showing 5 changed files with 376 additions and 354 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"wrangler": "^3.60.3"
},
"dependencies": {
"js-yaml": "^4.1.0"
"js-yaml": "^4.1.0",
"sublink-plus": "file:"
}
}
52 changes: 52 additions & 0 deletions src/BaseConfigBuilder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ProxyParser } from './ProxyParsers.js';
import { DeepCopy } from './utils.js';

export class BaseConfigBuilder {
constructor(inputString, baseConfig) {
this.inputString = inputString;
this.config = DeepCopy(baseConfig);
}

async build() {
const customItems = await this.parseCustomItems();
this.addCustomItems(customItems);
this.addSelectors();
return this.formatConfig();
}

async parseCustomItems() {
const urls = this.inputString.split('\n').filter(url => url.trim() !== '');
const parsedItems = [];

for (const url of urls) {
const result = await ProxyParser.parse(url);
if (Array.isArray(result)) {
for (const subUrl of result) {
const subResult = await ProxyParser.parse(subUrl);
if (subResult) {
parsedItems.push(subResult);
}
}
} else if (result) {
parsedItems.push(result);
}
}

return parsedItems;
}

addCustomItems(customItems) {
// This method should be implemented in child classes
throw new Error('addCustomItems must be implemented in child class');
}

addSelectors() {
// This method should be implemented in child classes
throw new Error('addSelectors must be implemented in child class');
}

formatConfig() {
// This method should be implemented in child classes
throw new Error('formatConfig must be implemented in child class');
}
}
69 changes: 23 additions & 46 deletions src/ClashConfigBuilder.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,23 @@
import yaml from 'js-yaml';
import { ProxyParser } from './ProxyParsers.js';
import { CLASH_CONFIG, SELECTORS_LIST } from './config.js';
import { BaseConfigBuilder } from './BaseConfigBuilder.js';
import { DeepCopy } from './utils.js';

export class ClashConfigBuilder {
export class ClashConfigBuilder extends BaseConfigBuilder {
constructor(inputString) {
this.inputString = inputString;
this.config = DeepCopy(CLASH_CONFIG);
super(inputString, CLASH_CONFIG);
}

async build() {
const customProxies = await this.parseCustomProxies();
this.addCustomProxies(customProxies);
return yaml.dump(this.config);
}

async parseCustomProxies() {
const urls = this.inputString.split('\n').filter(url => url.trim() !== '');
const parsedProxies = [];

for (const url of urls) {
const result = await ProxyParser.parse(url);
if (Array.isArray(result)) {
// If the result is an array, it's from an HTTP(S) source
for (const subUrl of result) {
const subResult = await ProxyParser.parse(subUrl);
if (subResult) {
parsedProxies.push(subResult);
}
}
} else if (result) {
parsedProxies.push(result);
addCustomItems(customItems) {
customItems.forEach(item => {
if (item?.tag && !this.config.proxies.some(p => p.name === item.tag)) {
this.config.proxies.push(this.convertToClashProxy(item));
}
}

return parsedProxies;
});
}

addCustomProxies(customProxies) {
customProxies.forEach(proxy => {
if (proxy?.tag && !this.config.proxies.some(p => p.name === proxy.tag)) {
this.config.proxies.push(this.convertToClashProxy(proxy));
}
});
const proxyList = customProxies.filter(proxy => proxy?.tag !== undefined).map(proxy => proxy?.tag);
addSelectors() {
const proxyList = this.config.proxies.map(proxy => proxy.name);
this.config['proxy-groups'].push({
name: '⚡ 自动选择',
type: 'url-test',
Expand All @@ -53,17 +27,20 @@ export class ClashConfigBuilder {
lazy: false
});
proxyList.unshift('DIRECT', 'REJECT', '⚡ 自动选择');
SELECTORS_LIST.forEach(selector => {
if (!this.config['proxy-groups'].some(g => g.name === selector)) {
this.config['proxy-groups'].push({
type: "select",
name: selector,
proxies: selector !== '🚀 节点选择' ? ['🚀 节点选择', ...proxyList] : proxyList
});
}
});
}
SELECTORS_LIST.forEach(selector => {
if (!this.config['proxy-groups'].some(g => g.name === selector)) {
this.config['proxy-groups'].push({
type: "select",
name: selector,
proxies: selector !== '🚀 节点选择' ? ['🚀 节点选择', ...proxyList] : proxyList
});
}
});
}

formatConfig() {
return yaml.dump(this.config);
}
convertToClashProxy(proxy) {
switch(proxy.type) {
case 'shadowsocks':
Expand Down
67 changes: 20 additions & 47 deletions src/SingboxConfigBuilder.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,35 @@
import { SING_BOX_CONFIG, SELECTORS_LIST } from './config.js';
import { ProxyParser } from './ProxyParsers.js';
import { BaseConfigBuilder } from './BaseConfigBuilder.js';
import { DeepCopy } from './utils.js';

export class ConfigBuilder {
export class ConfigBuilder extends BaseConfigBuilder {
constructor(inputString) {
this.inputString = inputString;
this.config = DeepCopy(SING_BOX_CONFIG);
super(inputString, SING_BOX_CONFIG);
}

async build() {
const customOutbounds = await this.parseCustomOutbounds();
this.addCustomOutbounds(customOutbounds);
this.addSelectors();
return this.config;
}

async parseCustomOutbounds() {
const urls = this.inputString.split('\n').filter(url => url.trim() !== '');
const parsedOutbounds = [];

for (const url of urls) {
const result = await ProxyParser.parse(url);
if (Array.isArray(result)) {
// If the result is an array, it's from an HTTP(S) source
for (const subUrl of result) {
const subResult = await ProxyParser.parse(subUrl);
if (subResult) {
parsedOutbounds.push(subResult);
}
}
} else if (result) {
parsedOutbounds.push(result);
}
}

return parsedOutbounds;
}

addCustomOutbounds(customOutbounds) {
// Filter out null values before adding to config.outbounds
const validOutbounds = customOutbounds.filter(outbound => outbound != null);
this.config.outbounds.push(...validOutbounds);
addCustomItems(customItems) {
const validItems = customItems.filter(item => item != null);
this.config.outbounds.push(...validItems);
}

addSelectors() {
const tagList = this.config.outbounds.filter(outbound => outbound?.server != undefined).map(outbound => outbound.tag);
addSelectors() {
const tagList = this.config.outbounds.filter(outbound => outbound?.server != undefined).map(outbound => outbound.tag);
this.config.outbounds.push({
type: "urltest",
tag: "⚡ 自动选择",
outbounds: DeepCopy(tagList),
});
tagList.unshift('DIRECT', 'REJECT', '⚡ 自动选择');
SELECTORS_LIST.forEach(selector => {
this.config.outbounds.push({
type: "selector",
tag: selector,
outbounds: selector !== '🚀 节点选择' ? ['🚀 节点选择', ...tagList] : tagList
});
});
}
SELECTORS_LIST.forEach(selector => {
this.config.outbounds.push({
type: "selector",
tag: selector,
outbounds: selector !== '🚀 节点选择' ? ['🚀 节点选择', ...tagList] : tagList
});
});
}

formatConfig() {
return this.config;
}
}
Loading

0 comments on commit 4d88419

Please sign in to comment.