Skip to content

Commit d56aed9

Browse files
committed
fix types
1 parent 3a84800 commit d56aed9

File tree

8 files changed

+72
-42
lines changed

8 files changed

+72
-42
lines changed

client/src/page/feed.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ type Feed = {
2525
title: string | null;
2626
content: string;
2727
uid: number;
28-
createdAt: Date;
29-
updatedAt: Date;
28+
createdAt: Date | string;
29+
updatedAt: Date | string;
3030
ai_summary: string;
3131
hashtags: {
3232
id: number;
@@ -39,6 +39,7 @@ type Feed = {
3939
};
4040
pv: number;
4141
uv: number;
42+
top: number;
4243
};
4344

4445

@@ -143,11 +144,12 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen
143144
setError(error.value as string);
144145
} else if (data && typeof data !== "string") {
145146
setTimeout(() => {
146-
setFeed(data as any);
147-
setTop((data as any).top);
147+
const feedData = data as unknown as Feed;
148+
setFeed(feedData);
149+
setTop(feedData.top);
148150
// Extract head image
149151
const img_reg = /!\[.*?\]\((.*?)\)/;
150-
const img_match = img_reg.exec((data as any).content);
152+
const img_match = img_reg.exec(feedData.content);
151153
if (img_match) {
152154
setHeadImage(img_match[1]);
153155
}
@@ -585,8 +587,8 @@ function ReplyInput({
585587
type Comment = {
586588
id: number;
587589
content: string;
588-
createdAt: Date;
589-
updatedAt: Date;
590+
createdAt: Date | string;
591+
updatedAt: Date | string;
590592
parentId?: number | null;
591593
replyToUser?: {
592594
id: number;
@@ -618,7 +620,7 @@ function Comments({ id }: { id: string }) {
618620
if (error) {
619621
setError(error.value as string);
620622
} else if (data && Array.isArray(data)) {
621-
setComments(data as any);
623+
setComments(data as unknown as Comment[]);
622624
}
623625
});
624626
}

server/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44
"type": "module",
55
"scripts": {
66
"cf:deploy": "wrangler deploy",
7-
"dev": "bun wrangler dev --port 11498",
7+
"dev": "bun wrangler dev src/_worker.ts --port 11498",
88
"dev:cron": "bun wrangler dev --port 11498 --test-scheduled #see https://developers.cloudflare.com/workers/configuration/cron-triggers/#test-cron-triggers",
99
"cf-typegen": "wrangler types",
1010
"db:gen": "bun drizzle-kit generate",
1111
"preview": "wrangler pages dev dist --compatibility-date=2023-12-20"
1212
},
1313
"devDependencies": {
14-
"@types/bun": "^1.1.2",
15-
"drizzle-kit": "^0.21.2",
16-
"wrangler": "^3.63.1",
1714
"@cloudflare/vitest-pool-workers": "^0.1.0",
1815
"@cloudflare/workers-types": "^4.20240529.0",
16+
"@types/bun": "^1.1.2",
17+
"drizzle-kit": "^0.21.2",
18+
"strip-indent": "^4.0.0",
1919
"typescript": "^5.0.4",
20-
"strip-indent": "^4.0.0"
20+
"wrangler": "^4.60.0"
2121
},
2222
"peerDependencies": {
2323
"typescript": "^5.0.0"

server/src/db/schema.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { relations, sql } from "drizzle-orm";
2-
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
2+
import { foreignKey, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
33

44
const created_at = integer("created_at", { mode: 'timestamp' }).default(sql`(unixepoch())`).notNull();
55
const updated_at = integer("updated_at", { mode: 'timestamp' }).default(sql`(unixepoch())`).notNull();
@@ -68,11 +68,17 @@ export const comments = sqliteTable("comments", {
6868
feedId: integer("feed_id").references(() => feeds.id, { onDelete: 'cascade' }).notNull(),
6969
userId: integer("user_id").references(() => users.id, { onDelete: 'cascade' }).notNull(),
7070
content: text("content").notNull(),
71-
parentId: integer("parent_id").references(() => comments.id, { onDelete: 'cascade' }),
71+
parentId: integer("parent_id"),
7272
replyToUserId: integer("reply_to_user_id").references(() => users.id, { onDelete: 'set null' }),
7373
createdAt: created_at,
7474
updatedAt: updated_at,
75-
}) as any;
75+
}, (table) => ({
76+
parentReference: foreignKey({
77+
columns: [table.parentId],
78+
foreignColumns: [table.id],
79+
name: "comments_parent_id_fk"
80+
}).onDelete("cascade")
81+
}));
7682

7783
export const hashtags = sqliteTable("hashtags", {
7884
id: integer("id").primaryKey(),

server/src/services/comments.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,19 @@ export function CommentService() {
3333
});
3434

3535
// Build nested structure
36-
const rootComments: any[] = [];
37-
const replyMap = new Map();
36+
type CommentItem = typeof allComments[number];
37+
type CommentWithReplies = CommentItem & { replies?: CommentItem[] };
38+
39+
const rootComments: CommentWithReplies[] = [];
40+
const replyMap = new Map<number, CommentItem[]>();
3841

3942
// First, collect all replies by parent ID
4043
for (const comment of allComments) {
4144
if (comment.parentId) {
4245
if (!replyMap.has(comment.parentId)) {
4346
replyMap.set(comment.parentId, []);
4447
}
45-
replyMap.get(comment.parentId).push(comment);
48+
replyMap.get(comment.parentId)!.push(comment);
4649
} else {
4750
rootComments.push(comment);
4851
}
@@ -52,8 +55,8 @@ export function CommentService() {
5255
for (const root of rootComments) {
5356
const replies = replyMap.get(root.id) || [];
5457
// Sort replies by createdAt ascending (older first)
55-
replies.sort((a: any, b: any) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
56-
(root as any).replies = replies;
58+
replies.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
59+
root.replies = replies;
5760
}
5861

5962
return rootComments;
@@ -79,11 +82,12 @@ export function CommentService() {
7982
set.status = 400;
8083
return 'Feed not found';
8184
}
82-
let finalParentId = parentId || null;
83-
let finalReplyToUserId = replyToUserId ? parseInt(replyToUserId as string) : null;
85+
let parsedParentId = parentId ? (typeof parentId === 'string' ? parseInt(parentId) : parentId) : null;
86+
let finalParentId = parsedParentId;
87+
let finalReplyToUserId = replyToUserId ? (typeof replyToUserId === 'string' ? parseInt(replyToUserId) : replyToUserId) : null;
8488

85-
if (parentId) {
86-
const parentComment = await db.query.comments.findFirst({ where: eq(comments.id, parentId) });
89+
if (parsedParentId) {
90+
const parentComment = await db.query.comments.findFirst({ where: eq(comments.id, parsedParentId) });
8791
if (!parentComment || parentComment.feedId !== feedId) {
8892
set.status = 400;
8993
return 'Parent comment not found';

server/src/services/favicon.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { PutObjectCommand } from "@aws-sdk/client-s3";
33
import { getEnv } from "../utils/di";
44
import { setup } from "../setup";
55
import { createS3Client } from "../utils/s3";
6-
import path from "path";
6+
import path from "node:path";
77

88
// @see https://developers.cloudflare.com/images/url-format#supported-formats-and-limitations
99
export const FAVICON_ALLOWED_TYPES: { [key: string]: string } = {

server/src/services/feed.ts

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export function FeedService() {
6565
const avatar = extractImage(content);
6666
return {
6767
summary: summary.length > 0 ? summary : content.length > 100 ? content.slice(0, 100) : content,
68-
hashtags: (hashtags as any).map(({ hashtag }: any) => hashtag),
68+
hashtags: (hashtags as unknown as { hashtag: { id: number; name: string } }[]).map(({ hashtag }) => hashtag),
6969
avatar,
7070
...other
7171
}
@@ -198,7 +198,7 @@ export function FeedService() {
198198
}
199199

200200
const { hashtags, ...other } = feed;
201-
const hashtags_flatten = (hashtags as any).map((f: any) => f.hashtag);
201+
const hashtags_flatten = (hashtags as unknown as { hashtag: { id: number; name: string } }[]).map((f) => f.hashtag);
202202

203203

204204
// update visits
@@ -255,11 +255,19 @@ export function FeedService() {
255255

256256
const cache = PublicCache();
257257
function formatAndCacheData(
258-
feed: any,
258+
feed: {
259+
id: number;
260+
title: string | null;
261+
summary: string;
262+
content: string;
263+
createdAt: Date;
264+
updatedAt: Date;
265+
hashtags: { hashtag: { id: number; name: string } }[];
266+
} | null | undefined,
259267
feedDirection: "previous_feed" | "next_feed",
260268
) {
261269
if (feed) {
262-
const hashtags_flatten = (feed.hashtags as any).map((f: any) => f.hashtag);
270+
const hashtags_flatten = (feed.hashtags as unknown as { hashtag: { id: number; name: string } }[]).map((f) => f.hashtag);
263271
const summary =
264272
feed.summary.length > 0
265273
? feed.summary
@@ -508,7 +516,7 @@ export function FeedService() {
508516
}))).map(({ content, hashtags, summary, ...other }) => {
509517
return {
510518
summary: summary.length > 0 ? summary : content.length > 100 ? content.slice(0, 100) : content,
511-
hashtags: (hashtags as any).map(({ hashtag }: any) => hashtag),
519+
hashtags: (hashtags as unknown as { hashtag: { id: number; name: string } }[]).map(({ hashtag }) => hashtag),
512520
...other
513521
}
514522
});
@@ -554,16 +562,16 @@ export function FeedService() {
554562
set.status = 404;
555563
return 'No items found';
556564
}
557-
const feedItems: FeedItem[] = items?.map((item: any) => {
558-
const createdAt = new Date(item?.['wp:post_date']);
559-
const updatedAt = new Date(item?.['wp:post_modified']);
560-
const draft = item?.['wp:status'] !== 'publish';
561-
const contentHtml = item?.['content:encoded'];
565+
const feedItems: FeedItem[] = items?.map((item: WPItem) => {
566+
const createdAt = new Date(item['wp:post_date']);
567+
const updatedAt = new Date(item['wp:post_modified']);
568+
const draft = item['wp:status'] !== 'publish';
569+
const contentHtml = item['content:encoded'];
562570
const content = html2md(contentHtml);
563571
const summary = content.length > 100 ? content.slice(0, 100) : content;
564-
let tags = item?.['category'];
572+
let tags = item.category;
565573
if (tags && Array.isArray(tags)) {
566-
tags = tags.map((tag: any) => tag + '');
574+
tags = tags.map((tag: string) => tag + '');
567575
} else if (tags && typeof tags === 'string') {
568576
tags = [tags];
569577
}
@@ -623,6 +631,15 @@ export function FeedService() {
623631
}
624632

625633

634+
interface WPItem {
635+
title: string;
636+
'wp:post_date': string;
637+
'wp:post_modified': string;
638+
'wp:status': string;
639+
'content:encoded': string;
640+
category?: string | string[];
641+
}
642+
626643
type FeedItem = {
627644
title: string;
628645
summary: string;

server/src/services/rss.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { drizzle } from "drizzle-orm/d1";
44
import Elysia from "elysia";
55
import { FAVICON_ALLOWED_TYPES, getFaviconKey } from "./favicon";
66
import { Feed } from "feed";
7-
import path from 'path';
7+
import type { FeedOptions } from "feed";
8+
import path from 'node:path';
89
import rehypeStringify from "rehype-stringify";
910
import remarkGfm from "remark-gfm";
1011
import remarkParse from "remark-parse";
@@ -64,7 +65,7 @@ export async function rssCrontab(env: Env) {
6465
const accessHost = env.S3_ACCESS_HOST || env.S3_ENDPOINT;
6566
const faviconKey = getFaviconKey();
6667

67-
let feedConfig: any = {
68+
let feedConfig: FeedOptions = {
6869
title: env.RSS_TITLE,
6970
description: env.RSS_DESCRIPTION || "Feed from Rin",
7071
id: frontendUrl,
@@ -146,7 +147,7 @@ export async function rssCrontab(env: Env) {
146147
? content.slice(0, 100)
147148
: content,
148149
content: contentHtml,
149-
author: [{ name: (user as any).username }],
150+
author: [{ name: user.username }],
150151
image: extractImage(content),
151152
});
152153
}

server/src/utils/cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PutObjectCommand } from "@aws-sdk/client-s3";
2-
import path from "path";
2+
import path from "node:path";
33
import Container, { Service } from "typedi";
44
import type { DB } from "../_worker";
55
import type { Env } from "../db/db";

0 commit comments

Comments
 (0)