Revisions for untitled paste

View the changes made to this paste.

unlisted ⁨2⁩ ⁨files⁩ 2023-05-24 08:59:42 UTC

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