@bbki.ng/backend 0.3.19 → 0.3.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # backend
2
2
 
3
+ ## 0.3.21
4
+
5
+ ### Patch Changes
6
+
7
+ - 8d26c74: update version color
8
+
9
+ ## 0.3.20
10
+
11
+ ### Patch Changes
12
+
13
+ - d1b95ed: add api to fetch manifest
14
+
3
15
  ## 0.3.19
4
16
 
5
17
  ### Patch Changes
@@ -0,0 +1,17 @@
1
+ CREATE TABLE IF NOT EXISTS plugins (
2
+ id TEXT PRIMARY KEY,
3
+ name TEXT NOT NULL,
4
+ version TEXT NOT NULL,
5
+ description TEXT,
6
+ perm TEXT DEFAULT 'guest',
7
+ icon TEXT,
8
+ dependencies TEXT
9
+ );
10
+
11
+ INSERT INTO plugins (id, name, version, description, perm, dependencies) VALUES
12
+ ('sticker', '贴纸', '0.1.0', '在页面一些地方显示奇怪的贴纸', 'guest', '[]'),
13
+ ('store', '插件商店', '0.1.0', '一个管理 bbki.ng 插件的商店', 'admin', '[]'),
14
+ ('now', '最近', '1.0.0', '显示网站最近更新的版本,以及一些文字动态', 'guest', '[]'),
15
+ ('extra-cd', '捷径', '0.1.0', '提供额外的页面跳转链接。例如在标题列表末尾添加一个 "cd ~" 的选项,点击后跳转到主页', 'guest', '[]'),
16
+ ('fx', '特效', '0.1.0', '提供一些额外的视觉效果。例如版本、设备信息水印,加载状态螺旋线、背景纹理等', 'guest', '[]'),
17
+ ('xwy', '小乌鸦', '0.1.0', '为小乌鸦合集实现定制功能或者样式的插件', 'guest', '[]');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbki.ng/backend",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "@simplewebauthn/server": "13.2.2",
@@ -22,7 +22,7 @@
22
22
  "prettier": "^3.2.0",
23
23
  "typescript": "^5.3.0",
24
24
  "wrangler": "^4.58.0",
25
- "@bbki.ng/config": "1.0.6"
25
+ "@bbki.ng/config": "2.0.1"
26
26
  },
27
27
  "prettier": "@bbki.ng/config/prettier",
28
28
  "scripts": {
@@ -0,0 +1,31 @@
1
+ import { Context } from 'hono';
2
+
3
+ import { safeParseJSON } from '../../utils';
4
+
5
+ export const listPlugins = async (c: Context) => {
6
+ try {
7
+ const { results } = await c.env.DB.prepare(
8
+ `SELECT id, name, version, description, perm, icon, dependencies
9
+ FROM plugins`
10
+ ).all();
11
+
12
+ return c.json({
13
+ status: 'success',
14
+ data: results.map((p: { dependencies: string }) => ({
15
+ ...p,
16
+ dependencies:
17
+ safeParseJSON<{ dependencies: string[] }>(p.dependencies, { dependencies: [] })
18
+ ?.dependencies || [],
19
+ })),
20
+ });
21
+ } catch (error: Error | unknown) {
22
+ return c.json(
23
+ {
24
+ status: 'error',
25
+ message: 'Failed to fetch plugins',
26
+ error: error instanceof Error ? error.message : String(error),
27
+ },
28
+ 500
29
+ );
30
+ }
31
+ };
@@ -6,9 +6,11 @@ export const listStreaming = async (c: Context) => {
6
6
  // 'before' - fetch records older than this ID (for pagination / next page)
7
7
  // 'after' - fetch records newer than this ID (for polling / new messages)
8
8
  // 'offset' - number of records to fetch (default: 8, max: 100)
9
+ // 'type' - optional filter by type (note, article, link, image, ci)
9
10
  const before = c.req.query('before');
10
11
  const after = c.req.query('after');
11
12
  const offset = Math.min(parseInt(c.req.query('offset') || '8', 10), 100);
13
+ const type = c.req.query('type');
12
14
 
13
15
  let results;
14
16
 
@@ -18,6 +20,7 @@ export const listStreaming = async (c: Context) => {
18
20
  `SELECT id, author, content, type, created_at as createdAt
19
21
  FROM streaming
20
22
  WHERE created_at < (SELECT created_at FROM streaming WHERE id = ?)
23
+ ${type ? 'AND type = ?' : ''}
21
24
  ORDER BY created_at DESC
22
25
  LIMIT ?`
23
26
  )
@@ -31,6 +34,7 @@ export const listStreaming = async (c: Context) => {
31
34
  `SELECT id, author, content, type, created_at as createdAt
32
35
  FROM streaming
33
36
  WHERE created_at > (SELECT created_at FROM streaming WHERE id = ?)
37
+ ${type ? 'AND type = ?' : ''}
34
38
  ORDER BY created_at ASC
35
39
  LIMIT ?`
36
40
  )
@@ -42,6 +46,7 @@ export const listStreaming = async (c: Context) => {
42
46
  const { results: recentResults } = await c.env.DB.prepare(
43
47
  `SELECT id, author, content, type, created_at as createdAt
44
48
  FROM streaming
49
+ ${type ? 'WHERE type = ?' : ''}
45
50
  ORDER BY created_at DESC
46
51
  LIMIT ?`
47
52
  )
package/src/index.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  import app from './config/app.config';
2
-
3
2
  import { commentRouter } from './routes/comment.routes';
4
3
  import { streamingRouter } from './routes/streaming.routes';
5
4
  import { postsRouter } from './routes/posts.routes';
5
+ import { pluginsRouter } from './routes/plugins.routes';
6
6
 
7
7
  app.route('comment', commentRouter);
8
8
  app.route('streaming', streamingRouter);
9
9
  app.route('posts', postsRouter);
10
+ app.route('plugins', pluginsRouter);
10
11
 
11
12
  app.get('/', c => {
12
13
  return c.text('Hello Hono!');
@@ -0,0 +1,9 @@
1
+ import { Hono } from 'hono';
2
+
3
+ import { listPlugins } from '../controllers/plugins/list.controller';
4
+
5
+ const pluginsRouter = new Hono();
6
+
7
+ pluginsRouter.get('/', listPlugins);
8
+
9
+ export { pluginsRouter };
@@ -0,0 +1,8 @@
1
+ export const safeParseJSON = <T>(str: string, defaultValue: T): T => {
2
+ try {
3
+ return JSON.parse(str) as T;
4
+ } catch (error) {
5
+ console.error('Failed to parse JSON:', error);
6
+ return defaultValue;
7
+ }
8
+ };