-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.ts
136 lines (123 loc) · 3.68 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/// <reference types="@cloudflare/workers-types" />
export interface Env {
DB: D1Database;
}
interface HistoryItem {
url: string;
visitedAt: number;
nextVisitedAt: number | null;
title: string;
datetime: string;
duration: number | null;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
// Handle GET /
if (request.method === "GET" && url.pathname === "/") {
if (!request.url?.startsWith("http://localhost:")) {
return new Response("The GET endpoint only works locally", {
status: 401,
});
}
return handleGetAll(env.DB);
}
// Handle POST /insert
if (request.method === "POST" && url.pathname === "/insert") {
console.log("entered /insert");
return handleInsert(request, env.DB);
}
// Return 404 for other routes
return new Response("Not Found", { status: 404 });
},
};
async function handleGetAll(db: D1Database): Promise<Response> {
try {
// Query all items from the database
const { results } = await db
.prepare("SELECT * FROM history")
.all<HistoryItem>();
// Return the items as a JSON response
return new Response(JSON.stringify(results, undefined, 2), {
headers: { "Content-Type": "application/json" },
});
} catch (error) {
console.error("Error in /:", error);
return new Response(
JSON.stringify({ success: false, error: error.message }),
{ status: 500, headers: { "Content-Type": "application/json" } },
);
}
}
async function handleInsert(
request: Request,
db: D1Database,
): Promise<Response> {
try {
// Parse the request body as an array of HistoryItem
const items: HistoryItem[] = await request.json();
// Ensure the table exists
const res = await db
.prepare(
`
CREATE TABLE IF NOT EXISTS history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL,
visitedAt INTEGER NOT NULL,
nextVisitedAt INTEGER,
title TEXT NOT NULL,
datetime TEXT NOT NULL,
duration INTEGER
)
`,
)
.bind()
.run();
console.log({ res });
// Query the latest item in the database
const latestItem = await db
.prepare("SELECT * FROM history ORDER BY visitedAt DESC LIMIT 1")
.first<HistoryItem>();
// Filter items to insert only those after the latest item
const itemsToInsert = latestItem
? items.filter((item) => item.visitedAt > latestItem.visitedAt)
: items;
console.log({ latestItem, itemsToInsert: itemsToInsert.length });
// Insert new items into the database
if (itemsToInsert.length > 0) {
const stmt = db.prepare(`
INSERT INTO history (url, visitedAt, nextVisitedAt, title, datetime, duration)
VALUES (?, ?, ?, ?, ?, ?);
`);
// Batch insert all items
const results = await db.batch(
itemsToInsert.map((item) =>
stmt.bind(
item.url,
item.visitedAt,
item.nextVisitedAt,
item.title,
item.datetime,
item.duration,
),
),
);
console.log({ results });
}
// Return success response
return new Response(
JSON.stringify({
success: true,
inserted: itemsToInsert.length,
latestItem: latestItem || null,
}),
{ headers: { "Content-Type": "application/json" } },
);
} catch (error) {
console.error("Error in /insert:", error);
return new Response(
JSON.stringify({ success: false, error: error.message }),
{ status: 500, headers: { "Content-Type": "application/json" } },
);
}
}