Skip to content

Commit e48c705

Browse files
committed
Add basic /domains API
1 parent a762968 commit e48c705

File tree

3 files changed

+61
-28
lines changed

3 files changed

+61
-28
lines changed

app/api/domains/route.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import fetchDomainsByTechnology from "@/lib/db/domains-by-technology";
2+
import { NextRequest } from "next/server";
3+
4+
export async function GET(
5+
request: NextRequest,
6+
context: {
7+
},
8+
) {
9+
const technology = request.nextUrl.searchParams.get("technology");
10+
if (!technology) {
11+
return Response.json({
12+
error: "Missing required parameter: technology",
13+
}, {
14+
status: 400,
15+
});
16+
}
17+
18+
const data = await fetchDomainsByTechnology(technology, 100);
19+
return Response.json({
20+
// We really need to decide on some sort of way to enforce a contract here.
21+
// Maybe zod-openapi?
22+
data: data.data.map((item) => {
23+
return {
24+
domain: item.domain,
25+
creation_date: item.creation_date,
26+
}
27+
}).sort((a, b) => b.creation_date.getTime() - a.creation_date.getTime()),
28+
count: data.count,
29+
});
30+
}

app/technology/[identifier]/page.tsx

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import Grid from "@/components/Grid";
22
import Header from "@/components/Header";
33
import { db } from "@/lib/db/connection";
4+
import fetchDomainsByTechnology from "@/lib/db/domains-by-technology";
45
import { GENRE_REGISTRY, REGISTRY } from "@/lib/services";
56
import * as Dialog from "@radix-ui/react-dialog";
67

7-
const PAGE_SIZE = 101;
8-
98
const SHOVEL_PRO_URL = process.env.SHOVEL_PRO_URL;
109

10+
const PAGE_SIZE = 100;
11+
1112
import { Metadata, ResolvingMetadata } from "next";
1213

1314
type Props = {
@@ -35,27 +36,7 @@ export default async function TechnologyPage({
3536
params: { identifier: string };
3637
}) {
3738
const service = REGISTRY[params.identifier];
38-
const data = process.env.DISABLE_DATABASE
39-
? { data: [], moreCount: 0 }
40-
: await db
41-
.selectFrom("detected_technologies")
42-
.where("technology", "=", params.identifier)
43-
.selectAll()
44-
.distinctOn("domain")
45-
.execute()
46-
.then((results) => {
47-
if (results.length > PAGE_SIZE) {
48-
const moreCount = results.length - PAGE_SIZE;
49-
return {
50-
data: results.slice(0, PAGE_SIZE),
51-
moreCount,
52-
};
53-
}
54-
return {
55-
data: results,
56-
moreCount: 0,
57-
};
58-
});
39+
const data = await fetchDomainsByTechnology(params.identifier, PAGE_SIZE);
5940

6041
const technologyCounts = process.env.DISABLE_DATABASE
6142
? []
@@ -118,10 +99,10 @@ export default async function TechnologyPage({
11899
{trancoCount > 0
119100
? (
120101
(trancoCount * 100) /
121-
(data.data.length + data.moreCount)
102+
(data.count)
122103
).toFixed(2)
123104
: "0.00"}
124-
%) / {data.data.length + data.moreCount} total domains
105+
%) / {data.count} total domains
125106
</div>
126107
</div>
127108
</>
@@ -139,14 +120,14 @@ export default async function TechnologyPage({
139120
<div className="text-xs">{item.domain}</div>
140121
</Grid.Item>
141122
))}
142-
{data.moreCount > 0 && (
123+
{data.count > PAGE_SIZE && (
143124
<Grid.Item>
144125
<div className="text-xs opacity-50">
145126
{/* Note: This component should be moved to a client-side component */}
146127
<Dialog.Root>
147128
<Dialog.Trigger asChild>
148129
<button className="hover:underline focus:outline-none">
149-
+ {data.moreCount} more
130+
+ {data.count - PAGE_SIZE} more
150131
</button>
151132
</Dialog.Trigger>
152133
<Dialog.Portal>
@@ -191,7 +172,7 @@ export default async function TechnologyPage({
191172
{item.count} (
192173
{(
193174
(Number(item.count) * 100) /
194-
(data.data.length + data.moreCount)
175+
(data.count)
195176
).toFixed(2)}
196177
%)
197178
</div>

lib/db/domains-by-technology.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { db } from "@/lib/db/connection";
2+
3+
const fetchDomainsByTechnology = async (technology: string, limit: number) => {
4+
const data = process.env.DISABLE_DATABASE
5+
? { data: [], count: 0 }
6+
: await db
7+
.selectFrom("detected_technologies")
8+
.where("technology", "=", technology)
9+
.selectAll()
10+
.distinctOn("domain")
11+
.execute()
12+
.then((results) => {
13+
return {
14+
data: results.slice(0, limit),
15+
count: results.length,
16+
};
17+
});
18+
19+
return data;
20+
};
21+
22+
export default fetchDomainsByTechnology;

0 commit comments

Comments
 (0)