// ==UserScript== // @name 墨水屏Rlog按time重排 // @namespace aizigao // @version 1.0 // @description Modify specific fetch responses on a given page. // @author aizigao // @match https://log-search-docker.zuoyebang.cc/explore // @grant none // @license MIT // @downloadURL none // ==/UserScript== (function () { 'use strict'; const originalFetch = window.fetch; const log = (...args) => console.log('😜', ...args); function get(obj, path, defaultValue = undefined) { const keys = Array.isArray(path) ? path : path.split('.'); let result = obj; for (const key of keys) { result = result ? result[key] : undefined; if (result === undefined) { return defaultValue; } } return result; } function set(obj, path, value) { const keys = Array.isArray(path) ? path : path.split('.'); let current = obj; keys.forEach((key, index) => { if (index === keys.length - 1) { current[key] = value; } else { current[key] = current[key] || {}; current = current[key]; } }); return obj; } const TARGET_APP_AUTH = ['zphybrid-log-debug', 'zphybrid-log'] const authKey = (() => { // const search = window.location.search; const deCodeQuery = decodeURIComponent(window.location.search) // // 获取特定参数 // const left = urlParams.get('left'); // 'John' // log(left) // if (!left) { // return '' // } // const qsObjRList = JSON.parse(left) // // log(qsObjR) // const target = qsObjRList.find(i => i.queryText) // if (!target) { // return '' // } // log('target.queryText', target.queryText) const m = deCodeQuery.match(/app=\\"(.*?)\\"/) return m ? m[1] : '' })(); log('authKey', authKey) if (TARGET_APP_AUTH.includes(authKey)) { window.fetch = async function (resource, init) { // Check if the request URL matches the target API endpoint if (typeof resource === 'string' && resource.includes('/loki/api/v1/query_range')) { log('Intercepted fetch request:', resource); // Call the original fetch const response = await originalFetch(resource, init); // Clone the response so we can modify it const clonedResponse = response.clone(); const data = await clonedResponse.json(); // Modify the response data log('Original response data:', data); const originList = get(data, ['data', 'result', 0, 'values'], []); const rstList = originList .map(([_oldTs, objStr]) => { const obj = JSON.parse(objStr); const time = obj.time; const content = JSON.parse(obj.content); delete obj.content; return [ String(time * 1e6), JSON.stringify({ ...content, ...obj, }), ]; }) .sort((a, b) => a[0] > b[0]); // Example modification: add a custom field to the response data.customField = 'Modified content'; if (originList.length) { set(data, ['data', 'result', 0, 'values'], rstList); } // Create a new response with the modified data const modifiedResponse = new Response(JSON.stringify(data), { status: response.status, statusText: response.statusText, headers: response.headers, }); log('Modified response data:', data); return modifiedResponse; } // If not our target URL, just proceed with the normal fetch return originalFetch(resource, init); }; } })();