UNPKG

surgio

Version:

Generating rules for Surge, Clash, Quantumult like a PRO

234 lines 9.18 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadLocalSnippet = exports.convertNewSurgeScriptRuleToQuantumultXRewriteRule = exports.convertSurgeScriptRuleToQuantumultXRewriteRule = void 0; exports.getEngine = getEngine; const path_1 = __importDefault(require("path")); const fs_extra_1 = __importDefault(require("fs-extra")); const nunjucks_1 = __importDefault(require("nunjucks")); const yaml_1 = __importDefault(require("yaml")); const utils_1 = require("../utils"); const constant_1 = require("../constant"); function getEngine(templateDir, options = {}) { const engine = nunjucks_1.default.configure(templateDir, { autoescape: false, }); const getClashFilter = (clashCore) => { const supportedRule = (() => { switch (clashCore) { case 'stash': return constant_1.STASH_SUPPORTED_RULE; case 'clash.meta': return constant_1.CLASH_META_SUPPORTED_RULE; default: return constant_1.CLASH_SUPPORTED_RULE; } })(); return (str) => { // istanbul ignore next if (!str) { return ''; } const array = str.split('\n'); return array .map((item) => { const testString = !!item && item.trim() !== '' ? item.toUpperCase() : ''; if (testString.startsWith('#') || testString === '') { return item; } const matched = testString.match(/^([\w-]+),/); if (matched && supportedRule.some((s) => matched[1] === s)) { // 过滤出支持的规则类型 return `- ${item}`.replace(/\/\/.*$/, '').trim(); } return null; }) .filter((item) => !!item) .join('\n'); }; }; if (options.clashCore) { engine.addFilter('clash', getClashFilter(options.clashCore)); } else { engine.addFilter('clash', getClashFilter('clash')); } engine.addFilter('clashMeta', getClashFilter('clash.meta')); engine.addFilter('stash', getClashFilter('stash')); engine.addFilter('quantumultx', (str) => { // istanbul ignore next if (!str) { return ''; } const array = str.split('\n'); return array .map((item) => { const testString = !!item && item.trim() !== '' ? item.toUpperCase() : ''; if (testString.startsWith('#') || testString === '') { return item; } // Surge Script 处理 if (testString.startsWith('HTTP-RESPONSE')) { return (0, exports.convertSurgeScriptRuleToQuantumultXRewriteRule)(item); } if (testString.startsWith('HTTP-REQUEST')) { return (0, exports.convertSurgeScriptRuleToQuantumultXRewriteRule)(item); } if (/type\s?=\s?http-response/.test(item)) { return (0, exports.convertNewSurgeScriptRuleToQuantumultXRewriteRule)(item); } if (/type\s?=\s?http-request/.test(item)) { return (0, exports.convertNewSurgeScriptRuleToQuantumultXRewriteRule)(item); } const matched = testString.match(/^([\w-]+),/); if (matched && constant_1.QUANTUMULT_X_SUPPORTED_RULE.some((s) => matched[1] === s)) { if (matched[1] === 'IP-CIDR6') { return item.replace(/IP-CIDR6/i, 'IP6-CIDR'); } // 过滤出支持的规则类型 return item; } return null; }) .filter((item) => !!item) .join('\n'); }); engine.addFilter('loon', (str) => { // istanbul ignore next if (!str) { return ''; } const array = str.split('\n'); return array .map((item) => { const testString = !!item && item.trim() !== '' ? item.toUpperCase() : ''; if (testString.startsWith('#') || testString === '') { return item; } const matched = testString.match(/^([\w-]+),/); if (matched && constant_1.LOON_SUPPORTED_RULE.some((s) => matched[1] === s)) { // 过滤出支持的规则类型 return `${item}`.replace(/\/\/.*$/, '').trim(); } return null; }) .filter((item) => !!item) .join('\n'); }); engine.addFilter('surfboard', (str) => { // istanbul ignore next if (!str) { return ''; } const array = str.split('\n'); return array .map((item) => { const testString = !!item && item.trim() !== '' ? item.toUpperCase() : ''; if (testString.startsWith('#') || testString === '') { return item; } const matched = testString.match(/^([\w-]+),/); if (matched && constant_1.SURFBOARD_SUPPORTED_RULE.some((s) => matched[1] === s)) { // 过滤出支持的规则类型 return item.trim(); } return null; }) .filter((item) => !!item) .join('\n'); }); // yaml engine.addFilter('yaml', (obj) => yaml_1.default.stringify(obj)); // base64 engine.addFilter('base64', (str) => (0, utils_1.toBase64)(str)); // json engine.addFilter('json', (obj) => JSON.stringify(obj)); return engine; } const convertSurgeScriptRuleToQuantumultXRewriteRule = (str) => { const parts = str.split(' '); const result = []; switch (parts[0]) { case 'http-response': { const params = (0, utils_1.decodeStringList)(parts.splice(2).join('').split(',')); const scriptPath = params['script-path']; const isRequireBody = 'requires-body' in params; if (isRequireBody) { // parts[1] => Effective URL Rule result.push(parts[1], 'url', 'script-response-body', scriptPath); } else { result.push(parts[1], 'url', 'script-response-header', scriptPath); } return result.join(' '); } case 'http-request': { const params = (0, utils_1.decodeStringList)(parts.splice(2).join('').split(',')); const scriptPath = params['script-path']; const isRequireBody = 'requires-body' in params; if (isRequireBody) { // parts[1] => Effective URL Rule result.push(parts[1], 'url', 'script-request-body', scriptPath); } else { result.push(parts[1], 'url', 'script-request-header', scriptPath); } return result.join(' '); } default: return ''; } }; exports.convertSurgeScriptRuleToQuantumultXRewriteRule = convertSurgeScriptRuleToQuantumultXRewriteRule; const convertNewSurgeScriptRuleToQuantumultXRewriteRule = (str) => { const matched = str.match(/^(.+?)=(.+?)$/); const result = []; if (!matched) { return ''; } const params = (0, utils_1.decodeStringList)(matched[2].trim().split(',')); switch (params.type) { case 'http-response': { const isRequireBody = 'requires-body' in params; if (isRequireBody) { result.push(params.pattern, 'url', 'script-response-body', params['script-path']); } else { result.push(params.pattern, 'url', 'script-response-header', params['script-path']); } return result.join(' '); } case 'http-request': { const isRequireBody = 'requires-body' in params; if (isRequireBody) { result.push(params.pattern, 'url', 'script-request-body', params['script-path']); } else { result.push(params.pattern, 'url', 'script-request-header', params['script-path']); } return result.join(' '); } default: return ''; } }; exports.convertNewSurgeScriptRuleToQuantumultXRewriteRule = convertNewSurgeScriptRuleToQuantumultXRewriteRule; const loadLocalSnippet = (cwd, relativeFilePath) => { // istanbul ignore next if (!relativeFilePath) { throw new Error('必须指定一个文件'); } const absFilePath = path_1.default.join(cwd, relativeFilePath); const file = fs_extra_1.default.readFileSync(absFilePath, { encoding: 'utf-8' }); return { url: absFilePath, name: '', main: (rule) => (0, utils_1.addProxyToSurgeRuleSet)(file, rule), text: file, }; }; exports.loadLocalSnippet = loadLocalSnippet; //# sourceMappingURL=template.js.map