workers2.js
@@ -0,0 +1,117 @@
+import { parse as parseYAML, stringify as serializeYAML } from 'yaml';
+
+addEventListener('fetch', event => {
+ const { request } = event;
+
+ // 检查 User-Agent 是否为空
+ const userAgent = request.headers.get('User-Agent');
+ if (!userAgent) {
+ event.respondWith(
+ new Response('User-Agent is required', { status: 400 })
+ );
+ return;
+ }
+
+ event.respondWith(handleRequest(request));
+});
+
+async function handleRequest(request) {
+ // 获取原始 YAML 和修改器 YAML 的 URL
+ const url = new URL(request.url);
+ const originalYamlUrl = url.searchParams.get('originalYaml');
+ const modifierYamlUrl = url.searchParams.get('modifierYaml');
+
+ // 获取原始 YAML 和修改器 YAML 的文本
+ const [originalYamlText, modifierYamlText] = await Promise.all([
+ fetch(originalYamlUrl).then(res => res.text()),
+ fetch(modifierYamlUrl).then(res => res.text())
+ ]);
+
+ // 解析 YAML
+ const originalYaml = parseYAML(originalYamlText);
+ const modifierYaml = parseYAML(modifierYamlText);
+
+ // 应用修改
+ applyModifications(originalYaml, modifierYaml);
+
+ // 序列化修改后的 YAML
+ const modifiedYamlText = serializeYAML(originalYaml);
+
+ // 返回修改后的 YAML
+ return new Response(modifiedYamlText, {
+ headers: { 'Content-Type': 'text/plain' }
+ });
+}
+
+function applyModifications(originalYaml, modifierYaml) {
+ const keys = [
+ "append-rules",
+ "prepend-rules",
+ "append-proxies",
+ "prepend-proxies",
+ "append-proxy-groups",
+ "prepend-proxy-groups",
+ "mix-proxy-providers",
+ "mix-rule-providers",
+ "mix-object",
+ "commands",
+ ];
+
+ keys.forEach((key) => {
+ if (modifierYaml.hasOwnProperty(key)) {
+ switch (key) {
+ case "append-rules":
+ case "append-proxies":
+ case "append-proxy-groups":
+ originalYaml[key.replace("append-", "")].push(...modifierYaml[key]);
+ break;
+ case "prepend-rules":
+ case "prepend-proxies":
+ case "prepend-proxy-groups":
+ originalYaml[key.replace("prepend-", "")].unshift(...modifierYaml[key]);
+ break;
+ case "mix-proxy-providers":
+ case "mix-rule-providers":
+ case "mix-object":
+ Object.assign(originalYaml[key.replace("mix-", "")], modifierYaml[key]);
+ break;
+ case "commands":
+ applyCommands(originalYaml, modifierYaml[key]);
+ break;
+ }
+ }
+ });
+}
+
+function applyCommands(originalYaml, commands) {
+ for (let i = 0; i < commands.length; i++) {
+ const parts = commands[i].split('.')
+ let target = originalYaml
+
+ for (let j = 0; j < parts.length - 1; j++) {
+ const part = parts[j]
+ if (part.match(/^\d+$/)) {
+ target = target[parseInt(part)]
+ } else {
+ target = target[part]
+ }
+ }
+
+ const lastPart = parts[parts.length - 1]
+ const cmdParts = lastPart.split(/([=+-])/)
+ const cmd = cmdParts[1]
+ const value = cmdParts[2]
+
+ switch (cmd) {
+ case '=':
+ target[cmdParts[0]] = parseValue(value)
+ break
+ case '+':
+ target[cmdParts[0]].push(parseValue(value))
+ break
+ case '-':
+ target.splice(cmdParts[0], 1)
+ break
+ }
+ }
+}
\ No newline at end of file
workers.js
@@ -0,0 +1,202 @@
+addEventListener('fetch', event => {
+ let curObj = undefined // 初始化为 undefined
+
+ const request = event.request
+ const headersArray = Array.from(request.headers) // 获得 [name, value] 数组
+ const mutableHeaders = new Headers(headersArray) // 构造 Headers 对象
+ mutableHeaders.set('User-Agent', 'My User Agent String') // 设置 User-Agent
+
+ const newRequest = new Request(request, {headers: mutableHeaders}) // 构造新请求
+
+
+ event.respondWith(
+ fetch(newRequest)
+ .then(response => {
+ if (response.status === 200) return response
+ return undefined
+ })
+ .catch(() => Response.ok())
+ )
+
+ function checkResponse(response) {
+ if (response.status != 200) {
+ return undefined
+ }
+ return response
+ .catch(() => Response.ok())
+ }
+})
+
+async function handleRequest(request) {
+ const url = new URL(request.url)
+ const originalYamlUrl = url.searchParams.get('originalYaml')
+ const modifierYamlUrl = url.searchParams.get('modifierYaml')
+
+ let origYamlResponse
+ const originalYamlResponse = await fetch(originalYamlUrl)
+ .catch(() => {
+ origYamlResponse = undefined
+ })
+ console.log(originalYamlResponse) // 打印 originalYamlResponse
+
+ let modYamlResponse
+ const modifierYamlResponse = await fetch(modifierYamlUrl)
+ .catch(() => {
+ modYamlResponse = undefined
+ })
+ console.log(modifierYamlResponse) // 打印 modifierYamlResponse
+
+ const [originalYamlText, modifierYamlText] = await Promise.all([
+ originalYamlResponse.text(),
+ modifierYamlResponse.text()
+ ])
+
+ const originalYaml = parseYAML(originalYamlText)
+ const modifierYaml = parseYAML(modifierYamlText)
+
+ applyModifications(originalYaml, modifierYaml)
+
+ const modifiedYamlText = serializeYAML(originalYaml)
+
+ return new Response(modifiedYamlText, {headers: {'Content-Type': 'text/plain'}})
+}
+
+function parseYAML(yaml) {
+ // 简单的 YAML 解析器
+ let obj
+ let curObj = obj
+ let arrObj
+ let indent = 0
+
+ yaml.split('\n').forEach(line => {
+ if (line.match(/^\s*- /)) { // 数组项
+ if (indent > 0) arrObj.push(curObj)
+ curObj = {}
+ indent++
+ } else if (line.match(/^\s*[a-z0-9_]+:/)) { // 对象属性
+ const parts = line.split(': ')
+ curObj[parts[0]] = parseValue(parts[1])
+ } else if (line.match(/^\s*-$/)) { // 数组结束
+ curObj = arrObj
+ indent--
+ arrObj = null
+ } else if (line.match(/^\s+$/)) { // 空行,忽略
+ } else if (line.match(/^\s+[^-]/)) { // 属于上一层,返回上一层
+ curObj = curObj.parent
+ indent--
+ } else {
+ throw new Error('Unsupported YAML line: ' + line)
+ }
+ })
+
+ return obj
+}
+
+function serializeYAML(obj) {
+ // YAML 序列化器
+ let yaml = ''
+
+ const serializeObj = (obj) => {
+ Object.keys(obj).forEach(key => {
+ yaml += `${key}:`
+ const value = obj[key]
+ if (Array.isArray(value)) {
+ yaml += '\n'
+ value.forEach(v => serializeObj(v))
+ yaml += '- '
+ } else if (typeof value === 'object') {
+ yaml += '\n'
+ serializeObj(value)
+ } else {
+ yaml += ` ${value}\n`
+ }
+ })
+ }
+
+ serializeObj(obj)
+ return yaml
+}
+
+function applyModifications(originalYaml, modifierYaml) {
+ const keys = [
+ "append-rules",
+ "prepend-rules",
+ "append-proxies",
+ "prepend-proxies",
+ "append-proxy-groups",
+ "prepend-proxy-groups",
+ "mix-proxy-providers",
+ "mix-rule-providers",
+ "mix-object",
+ "commands",
+ ];
+
+ keys.forEach((key) => {
+ if (modifierYaml.hasOwnProperty(key)) {
+ switch (key) {
+ case "append-rules":
+ case "append-proxies":
+ case "append-proxy-groups":
+ originalYaml[key.replace("append-", "")].push(...modifierYaml[key]);
+ break;
+ case "prepend-rules":
+ case "prepend-proxies":
+ case "prepend-proxy-groups":
+ originalYaml[key.replace("prepend-", "")].unshift(...modifierYaml[key]);
+ break;
+ case "mix-proxy-providers":
+ case "mix-rule-providers":
+ case "mix-object":
+ Object.assign(originalYaml[key.replace("mix-", "")], modifierYaml[key]);
+ break;
+ case "commands":
+ applyCommands(originalYaml, modifierYaml[key]);
+ break;
+ }
+ }
+ });
+}
+
+function applyCommands(originalYaml, commands) {
+ for (let i = 0; i < commands.length; i++) {
+ const parts = commands[i].split('.')
+ let target = originalYaml
+
+ for (let j = 0; j < parts.length - 1; j++) {
+ const part = parts[j]
+ if (part.match(/^\d+$/)) {
+ target = target[parseInt(part)]
+ } else {
+ target = target[part]
+ }
+ }
+
+ const lastPart = parts[parts.length - 1]
+ const cmdParts = lastPart.split(/([=+-])/)
+ const cmd = cmdParts[1]
+ const value = cmdParts[2]
+
+ switch (cmd) {
+ case '=':
+ target[cmdParts[0]] = parseValue(value)
+ break
+ case '+':
+ target[cmdParts[0]].push(parseValue(value))
+ break
+ case '-':
+ target.splice(cmdParts[0], 1)
+ break
+ }
+ }
+}
+
+function parseValue(value) {
+ if (value === 'true') return true
+ if (value === 'false') return false
+ if (!isNaN(value)) return parseInt(value)
+ try {
+ return JSON.parse(value)
+ } catch (err) {
+ return value
+ }
+}
\ No newline at end of file