|
| 1 | +/* |
| 2 | +deno run -A --watch apidiff2.ts |
| 3 | +http://localhost:62185/ |
| 4 | +*/ |
| 5 | + |
| 6 | +const testPaths = [ |
| 7 | + "/v1/full/users?id=0EoAm&user_id=aNzoj", |
| 8 | + "/v1/full/users?id=0EoAm&id=7eP5n&id=aWvp71&id=Wem1e&user_id=aNzoj", |
| 9 | + |
| 10 | + "/v1/full/tracks?id=ZaXp01y&user_id=aNzoj", |
| 11 | + "/v1/full/tracks?id=ZaXp01y&id=5zdbywJ&id=Pb4MbAX&id=YVog04p&id=7Mv7ZMP&id=g5yzMy2&id=P7dlqNR&id=RR7krAG&id=O7OdxYV&id=72oXyvr&id=jYWyGG0&id=W6KOm8k&id=Xj554dq&id=gbOmq7k&id=G0z4Ap7&id=Yo0XYMm&id=80jlRwP&id=X63z9Wq&id=lZYWRKb&id=JEz6V0o&id=JZq6550&id=b9rbNdM&id=yy71xr7&id=JGNob5Z&id=VpxQ2Aa&id=qGbEZdz&id=B94qO0j&id=oRGgBka&id=jzwlVj0&id=Y5PNmOr&id=5zRm7dx&id=r3KjOg&id=WVP8qav&id=Nvayj1Y&id=V6GZJ3b&id=YoWO0MJ&id=JboVK8Y&id=9bbRG02&id=QRgjAJR&id=gWaBbkW&id=79q1xY7&id=51o1r9J&id=AMJ7d3k&id=O6ZKK0V&id=RpVzBx1&id=VPdaGdQ&id=lv7Obol&id=GQpBNxw&id=83xb96v&id=BJoM2Qx&id=bQoMKlK&id=8E1QjMW&id=O5OVlK4&id=63Gz0yQ&user_id=aNzoj", |
| 12 | + |
| 13 | + "/v1/full/playlists?id=K99x4MB&id=Akkz9wv&id=kKdggMN&id=k2J9Na3&id=NVr4gVN&id=1E87V7Q&user_id=aNzoj", |
| 14 | + |
| 15 | + "/v1/full/tracks/OvyMAV1/reposts?limit=15&offset=0&user_id=aNzoj", |
| 16 | + "/v1/full/tracks/0dgQM/favorites?limit=15&offset=0&user_id=aNzoj", |
| 17 | + |
| 18 | + "/v1/full/users/PWgX8NR/followers?limit=15&offset=0&user_id=aNzoj", |
| 19 | + "/v1/full/users/PWgX8NR/following?limit=15&offset=0&user_id=aNzoj", |
| 20 | + "/v1/full/users/PWgX8NR/mutuals?limit=5&offset=0&user_id=aNzoj", |
| 21 | + |
| 22 | + "/v1/full/users/7KVbP/supporting?limit=100&offset=0&user_id=aNzoj", |
| 23 | + "/v1/full/users/7KVbP/supporters?limit=100&offset=0&user_id=aNzoj", |
| 24 | + |
| 25 | + "/v1/full/playlists/P5abMZp/reposts?limit=15&offset=0&user_id=aNzoj", |
| 26 | + "/v1/full/playlists/P5abMZp/favorites?limit=15&offset=0&user_id=aNzoj", |
| 27 | + |
| 28 | + "/v1/users?id=0EoAm&user_id=aNzoj", |
| 29 | + "/v1/users?id=0EoAm&id=7eP5n&id=aWvp71&id=Wem1e&user_id=aNzoj", |
| 30 | + |
| 31 | + "/v1/tracks?id=ZaXp01y&user_id=aNzoj", |
| 32 | + "/v1/tracks?id=ZaXp01y&id=5zdbywJ&id=Pb4MbAX&id=YVog04p&id=7Mv7ZMP&id=g5yzMy2&id=P7dlqNR&id=RR7krAG&id=O7OdxYV&id=72oXyvr&id=jYWyGG0&id=W6KOm8k&id=Xj554dq&id=gbOmq7k&id=G0z4Ap7&id=Yo0XYMm&id=80jlRwP&id=X63z9Wq&id=lZYWRKb&id=JEz6V0o&id=JZq6550&id=b9rbNdM&id=yy71xr7&id=JGNob5Z&id=VpxQ2Aa&id=qGbEZdz&id=B94qO0j&id=oRGgBka&id=jzwlVj0&id=Y5PNmOr&id=5zRm7dx&id=r3KjOg&id=WVP8qav&id=Nvayj1Y&id=V6GZJ3b&id=YoWO0MJ&id=JboVK8Y&id=9bbRG02&id=QRgjAJR&id=gWaBbkW&id=79q1xY7&id=51o1r9J&id=AMJ7d3k&id=O6ZKK0V&id=RpVzBx1&id=VPdaGdQ&id=lv7Obol&id=GQpBNxw&id=83xb96v&id=BJoM2Qx&id=bQoMKlK&id=8E1QjMW&id=O5OVlK4&id=63Gz0yQ&user_id=aNzoj", |
| 33 | + |
| 34 | + "/v1/playlists?id=K99x4MB&id=Akkz9wv&id=kKdggMN&id=k2J9Na3&id=NVr4gVN&id=1E87V7Q&user_id=aNzoj", |
| 35 | + |
| 36 | + "/v1/tracks/OvyMAV1/reposts?limit=15&offset=0&user_id=aNzoj", |
| 37 | + "/v1/tracks/0dgQM/favorites?limit=15&offset=0&user_id=aNzoj", |
| 38 | + |
| 39 | + "/v1/users/PWgX8NR/followers?limit=15&offset=0&user_id=aNzoj", |
| 40 | + "/v1/users/PWgX8NR/following?limit=15&offset=0&user_id=aNzoj", |
| 41 | + "/v1/users/PWgX8NR/mutuals?limit=5&offset=0&user_id=aNzoj", |
| 42 | + |
| 43 | + "/v1/users/7KVbP/supporting?limit=100&offset=0&user_id=aNzoj", |
| 44 | + "/v1/users/7KVbP/supporters?limit=100&offset=0&user_id=aNzoj", |
| 45 | + |
| 46 | + "/v1/playlists/P5abMZp/reposts?limit=15&offset=0&user_id=aNzoj", |
| 47 | + "/v1/playlists/P5abMZp/favorites?limit=15&offset=0&user_id=aNzoj", |
| 48 | + |
| 49 | + "/v1/developer_apps/7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6", |
| 50 | +]; |
| 51 | + |
| 52 | +import { html } from "https://deno.land/x/html/mod.ts"; |
| 53 | +import * as jsondiffpatch from "https://esm.sh/jsondiffpatch@0.6.0"; |
| 54 | +import * as htmlFormatter from "https://esm.sh/jsondiffpatch@0.6.0/formatters/html"; |
| 55 | + |
| 56 | +Deno.serve({ port: 62185 }, async (req) => { |
| 57 | + const reqUrl = new URL(req.url); |
| 58 | + const idx = parseInt(reqUrl.searchParams.get("idx") || "0"); |
| 59 | + const path = testPaths[idx]; |
| 60 | + if (!path || path == "/favicon.ico") return new Response("not found"); |
| 61 | + |
| 62 | + const [r1, r2] = await Promise.all([ |
| 63 | + fetchJson("https://discoveryprovider.audius.co" + path), |
| 64 | + fetchJson("http://localhost:1323" + path), |
| 65 | + ]); |
| 66 | + |
| 67 | + const json1 = r1.data; |
| 68 | + const json2 = r2.data; |
| 69 | + |
| 70 | + const delta = jsondiffpatch.diff(json1, json2); |
| 71 | + |
| 72 | + return new Response( |
| 73 | + html` |
| 74 | + <!DOCTYPE html> |
| 75 | + <html lang="en"> |
| 76 | + <head> |
| 77 | + <meta charset="UTF-8" /> |
| 78 | + <meta |
| 79 | + name="viewport" |
| 80 | + content="width=device-width, initial-scale=1.0" |
| 81 | + /> |
| 82 | + <title>APIDIFF</title> |
| 83 | + <link |
| 84 | + rel="stylesheet" |
| 85 | + href="https://esm.sh/jsondiffpatch@0.6.0/lib/formatters/styles/html.css" |
| 86 | + type="text/css" |
| 87 | + /> |
| 88 | + <style> |
| 89 | + del { |
| 90 | + background: #ffbbbb; |
| 91 | + text-decoration: line-through; |
| 92 | + } |
| 93 | + ins { |
| 94 | + background: #bbffbb; |
| 95 | + } |
| 96 | + </style> |
| 97 | + </head> |
| 98 | + <body> |
| 99 | + <div style="display: flex; gap: 10px;"> |
| 100 | + <select |
| 101 | + onchange="location.href='?idx=' + this.value" |
| 102 | + style="width: 500px" |
| 103 | + > |
| 104 | + ${testPaths.map( |
| 105 | + (path, i) => |
| 106 | + html`<option value="${i}" ${i === idx ? "selected" : ""}> |
| 107 | + ${path} |
| 108 | + </option>` |
| 109 | + )} |
| 110 | + </select> |
| 111 | + <a href="?idx=${idx - 1}">prev</a> |
| 112 | + <a href="?idx=${idx + 1}">next</a> |
| 113 | + </div> |
| 114 | +
|
| 115 | + <pre>${path}</pre> |
| 116 | + <div> |
| 117 | + <del>${r1.took}ms</del> |
| 118 | + <ins>${r2.took}ms</ins> |
| 119 | + </div> |
| 120 | + <div>${htmlFormatter.format(delta, json1)}</div> |
| 121 | + </body> |
| 122 | + </html> |
| 123 | + `, |
| 124 | + { |
| 125 | + status: 200, |
| 126 | + headers: { |
| 127 | + "content-type": "text/html", |
| 128 | + }, |
| 129 | + } |
| 130 | + ); |
| 131 | +}); |
| 132 | + |
| 133 | +async function fetchJson(url: string): Promise<any> { |
| 134 | + const start = performance.now(); |
| 135 | + const response = await fetch(url); |
| 136 | + const took = (performance.now() - start).toFixed(0); |
| 137 | + if (!response.ok) { |
| 138 | + throw new Error(`Failed to fetch ${url}: ${response.statusText}`); |
| 139 | + } |
| 140 | + const resp = await response.json(); |
| 141 | + return { |
| 142 | + data: resp.data, |
| 143 | + took, |
| 144 | + }; |
| 145 | +} |
0 commit comments