Skip to content

Commit da061f7

Browse files
committed
apidiff v3
1 parent 3274218 commit da061f7

4 files changed

Lines changed: 165 additions & 168 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ setup::
2020
go install -v github.com/sqlc-dev/sqlc/cmd/sqlc@latest
2121

2222
apidiff::
23-
npx deno run -A --watch apidiff.ts
23+
open http://localhost:1323/apidiff.html

api/server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ func NewApiServer(config Config) *ApiServer {
159159
g.Get("/developer_apps/:address", app.v1DeveloperApps)
160160
}
161161

162+
app.Static("/", "./static")
163+
162164
// proxy unhandled requests thru to existing discovery API
163165
{
164166
upstreams := []string{

apidiff.ts

Lines changed: 0 additions & 167 deletions
This file was deleted.

static/apidiff.html

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>APIDIFF</title>
7+
<link
8+
rel="stylesheet"
9+
href="https://esm.sh/jsondiffpatch@0.6.0/lib/formatters/styles/html.css"
10+
type="text/css"
11+
/>
12+
<style>
13+
del {
14+
background: #ffbbbb;
15+
text-decoration: none;
16+
}
17+
ins {
18+
background: #bbffbb;
19+
}
20+
</style>
21+
</head>
22+
<body>
23+
<div id="controls"></div>
24+
<div id="output"></div>
25+
</body>
26+
</html>
27+
28+
<script type="module">
29+
const testPaths = [
30+
"/v1/full/playlists?id=K99x4MB&id=Akkz9wv&id=kKdggMN&id=k2J9Na3&id=NVr4gVN&id=1E87V7Q&user_id=aNzoj",
31+
"/v1/full/playlists/P5abMZp/favorites?limit=15&offset=0&user_id=aNzoj",
32+
"/v1/full/playlists/P5abMZp/reposts?limit=15&offset=0&user_id=aNzoj",
33+
"/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",
34+
"/v1/full/tracks?id=ZaXp01y&user_id=7eP5n",
35+
"/v1/full/tracks?id=ZaXp01y&user_id=aNzoj",
36+
"/v1/full/tracks/0dgQM/favorites?limit=15&offset=0&user_id=aNzoj",
37+
"/v1/full/tracks/OvyMAV1/reposts?limit=15&offset=0&user_id=aNzoj",
38+
"/v1/full/tracks/ZaXp01y",
39+
"/v1/full/users?id=0EoAm&id=7eP5n&id=aWvp71&id=Wem1e&user_id=aNzoj",
40+
"/v1/full/users?id=0EoAm&user_id=aNzoj",
41+
"/v1/full/users?id=invalid_id1&id=aNzoj",
42+
"/v1/full/users/7eP5n/reposts?limit=10&offset=0&user_id=aNzoj",
43+
"/v1/full/users/7KVbP/supporters?limit=100&offset=0&user_id=aNzoj",
44+
"/v1/full/users/7KVbP/supporting?limit=100&offset=0&user_id=aNzoj",
45+
"/v1/full/users/aNzoj/reposts?limit=10&offset=0&user_id=aNzoj",
46+
"/v1/full/users/handle/froootmusic/reposts?limit=10&offset=0&user_id=aNzoj",
47+
"/v1/full/users/handle/sammiezonana/tracks?filter_tracks=all&limit=10&offset=0&sort=date&user_id=aNzoj",
48+
"/v1/full/users/handle/stereosteve",
49+
"/v1/full/users/handle/stereosteve/tracks?filter_tracks=all&limit=10&offset=0&sort=date&user_id=7eP5n",
50+
"/v1/full/users/PWgX8NR/followers?limit=15&offset=0&user_id=aNzoj",
51+
"/v1/full/users/PWgX8NR/following?limit=15&offset=0&user_id=aNzoj",
52+
"/v1/full/users/PWgX8NR/mutuals?limit=5&offset=0&user_id=aNzoj",
53+
"/v1/playlists?id=K99x4MB&id=Akkz9wv&id=kKdggMN&id=k2J9Na3&id=NVr4gVN&id=1E87V7Q&user_id=aNzoj",
54+
"/v1/playlists/P5abMZp/favorites?limit=15&offset=0&user_id=aNzoj",
55+
"/v1/playlists/P5abMZp/reposts?limit=15&offset=0&user_id=aNzoj",
56+
"/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",
57+
"/v1/tracks?id=ZaXp01y&user_id=aNzoj",
58+
"/v1/tracks/0dgQM/favorites?limit=15&offset=0&user_id=aNzoj",
59+
"/v1/tracks/OvyMAV1/reposts?limit=15&offset=0&user_id=aNzoj",
60+
"/v1/users?id=0EoAm&id=7eP5n&id=aWvp71&id=Wem1e&user_id=aNzoj",
61+
"/v1/users?id=0EoAm&user_id=aNzoj",
62+
"/v1/users/0EoAm",
63+
"/v1/users/7KVbP/supporters?limit=100&offset=0&user_id=aNzoj",
64+
"/v1/users/7KVbP/supporting?limit=100&offset=0&user_id=aNzoj",
65+
"/v1/users/PWgX8NR/followers?limit=15&offset=0&user_id=aNzoj",
66+
"/v1/users/PWgX8NR/following?limit=15&offset=0&user_id=aNzoj",
67+
"/v1/users/PWgX8NR/mutuals?limit=5&offset=0&user_id=aNzoj",
68+
69+
"/v1/developer_apps/7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6",
70+
];
71+
72+
const html = (strings, ...values) => String.raw({ raw: strings }, ...values);
73+
import * as jsondiffpatch from "https://esm.sh/jsondiffpatch@0.6.0";
74+
import * as htmlFormatter from "https://esm.sh/jsondiffpatch@0.6.0/formatters/html";
75+
76+
const searchParams = new URLSearchParams(window.location.search);
77+
78+
let path =
79+
searchParams.get("example") || searchParams.get("path") || testPaths[0];
80+
if (path.startsWith("http://") || path.startsWith("https://")) {
81+
const url = new URL(path);
82+
path = url.pathname + url.search;
83+
window.location.search = `?path=${encodeURIComponent(path)}`;
84+
}
85+
86+
const oldHost = "https://discoveryprovider.audius.co";
87+
const newHost = "http://localhost:1323";
88+
89+
// for
90+
91+
// for toggle full button
92+
const isFull = path.includes("/full/");
93+
window.toggleFull = function () {
94+
const toggleFullPath = isFull
95+
? path.replace("/v1/full/", "/v1/")
96+
: path.replace("/v1/", "/v1/full/");
97+
window.location.search = `?path=${encodeURIComponent(toggleFullPath)}`;
98+
};
99+
100+
document.querySelector("#controls").innerHTML = html`
101+
<form style="display: flex; gap: 10px;">
102+
<input type="text" name="path" value="${path}" style="flex-grow: 1" />
103+
<select name="example" onchange="this.form.submit()" style="width: 100px">
104+
<option value="" disabled selected>Examples</option>
105+
${testPaths.map((p, i) => html`<option value="${p}">${p}</option>`)}
106+
</select>
107+
<label>
108+
<input
109+
type="checkbox"
110+
${isFull ? "checked" : ""}
111+
onChange="toggleFull()"
112+
/>
113+
Full
114+
</label>
115+
</form>
116+
`;
117+
118+
// fetch...
119+
const outputDiv = document.querySelector("#output");
120+
try {
121+
const [r1, r2] = await Promise.all([
122+
fetchJson(oldHost + path),
123+
fetchJson(newHost + path),
124+
]);
125+
const json1 = r1.data;
126+
const json2 = r2.data;
127+
const delta = jsondiffpatch.diff(json1, json2);
128+
129+
outputDiv.innerHTML = html`
130+
<div>
131+
<a href="${oldHost + path}" target="_blank">
132+
<del>${r1.took}ms</del>
133+
</a>
134+
<a href="${newHost + path}" target="_blank">
135+
<ins>${r2.took}ms</ins>
136+
</a>
137+
</div>
138+
<div>${htmlFormatter.format(delta, json1)}</div>
139+
`;
140+
} catch (e) {
141+
outputDiv.innerHTML = html`
142+
<h1>Bad News</h1>
143+
<pre>${e}</pre>
144+
`;
145+
throw e;
146+
}
147+
148+
async function fetchJson(url) {
149+
const start = performance.now();
150+
const response = await fetch(url);
151+
const took = (performance.now() - start).toFixed(0);
152+
if (!response.ok) {
153+
// throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
154+
console.log(response.status, url);
155+
}
156+
const resp = await response.json();
157+
return {
158+
data: resp.data,
159+
took,
160+
};
161+
}
162+
</script>

0 commit comments

Comments
 (0)