@oj-module/cli 0.1.15 → 0.1.17
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/devkit/SKILL.md +3 -0
- package/devkit/framework-dev.md +2 -2
- package/devkit/manual.md +60 -5
- package/package.json +3 -2
- package/shell-dist/assets/runtime.js +34 -3
- package/shell-dist/assets/vditor-index-css.js +7 -0
- package/shell-dist/assets/vditor.js +15223 -0
- package/shell-dist/index.html +4 -2
- package/shell-dist/versions.json +7 -5
- package/src/contract/check.ts +254 -73
- package/src/contract/emit-stub.ts +1 -1
- package/src/index.ts +7 -0
- package/src/shared-deps.ts +18 -0
- package/src/usage.ts +2 -0
- package/src/versions.ts +10 -0
- package/templates/api/src/notification/contract.ts +51 -5
- package/templates/web/src/notification/client/api.schemas.ts +30 -2
- package/templates/web/src/notification/client/api.ts +52 -1
- package/templates/web/src/notification/entry.ts +13 -4
- package/vendor/host-versions.json +7 -5
|
@@ -4,19 +4,47 @@
|
|
|
4
4
|
import { z } from "@oj-module/runtime";
|
|
5
5
|
|
|
6
6
|
export const schemas = {
|
|
7
|
+
del: {
|
|
8
|
+
body: z.object({
|
|
9
|
+
id: z.string(),
|
|
10
|
+
userId: z.union([z.string(), z.number()]).optional(),
|
|
11
|
+
}),
|
|
12
|
+
},
|
|
7
13
|
fetchNotifications: {
|
|
8
14
|
data: z.array(z.object({
|
|
9
|
-
id: z.
|
|
15
|
+
id: z.string(),
|
|
16
|
+
scope: z.enum(["user","broadcast"]),
|
|
10
17
|
avatar: z.string(),
|
|
11
18
|
date: z.string(),
|
|
12
19
|
isRead: z.boolean().optional(),
|
|
13
20
|
message: z.string(),
|
|
14
21
|
title: z.string(),
|
|
22
|
+
link: z.string().nullable().optional(),
|
|
23
|
+
category: z.enum(["notice","pm","mention"]).optional(),
|
|
15
24
|
})),
|
|
16
25
|
},
|
|
17
26
|
markRead: {
|
|
18
27
|
body: z.object({
|
|
19
|
-
id: z.
|
|
28
|
+
id: z.string(),
|
|
29
|
+
}),
|
|
30
|
+
},
|
|
31
|
+
push: {
|
|
32
|
+
body: z.object({
|
|
33
|
+
userId: z.union([z.string(), z.number()]).optional(),
|
|
34
|
+
title: z.string(),
|
|
35
|
+
message: z.string(),
|
|
36
|
+
link: z.string().optional(),
|
|
37
|
+
avatar: z.string().optional(),
|
|
38
|
+
category: z.enum(["notice","pm","mention"]).optional(),
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
pushBroadcast: {
|
|
42
|
+
body: z.object({
|
|
43
|
+
title: z.string(),
|
|
44
|
+
message: z.string(),
|
|
45
|
+
link: z.string().optional(),
|
|
46
|
+
avatar: z.string().optional(),
|
|
47
|
+
category: z.enum(["notice","pm","mention"]).optional(),
|
|
20
48
|
}),
|
|
21
49
|
},
|
|
22
50
|
};
|
|
@@ -33,7 +33,7 @@ export function createNotificationClient(ctx: ModuleContext) {
|
|
|
33
33
|
}
|
|
34
34
|
ctx.register.apiPrefix(API_PREFIX);
|
|
35
35
|
bindRequest(ctx.utils.request);
|
|
36
|
-
return { clearAll, fetchNotifications, markAllRead, markRead };
|
|
36
|
+
return { clearAll, del, fetchNotifications, markAllRead, markRead, push, pushBroadcast };
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
@@ -79,6 +79,23 @@ export async function clearAll(): Promise<unknown> {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
export type DelBody = z.input<(typeof schemas)["del"]["body"]>;
|
|
83
|
+
|
|
84
|
+
export async function del(body: DelBody): Promise<unknown> {
|
|
85
|
+
const client = ensureReq();
|
|
86
|
+
try {
|
|
87
|
+
const env = await client.post(`notification/del`, { json: body }).json<OjEnvelope<unknown>>();
|
|
88
|
+
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
89
|
+
if (typeof env.code === "number" && env.code !== 0)
|
|
90
|
+
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
91
|
+
const data = env.data as unknown;
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
throw await toApiError(e);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
82
99
|
export type FetchNotificationsData = z.infer<(typeof schemas)["fetchNotifications"]["data"]>;
|
|
83
100
|
|
|
84
101
|
export async function fetchNotifications(): Promise<FetchNotificationsData> {
|
|
@@ -133,3 +150,37 @@ export async function markRead(body: MarkReadBody): Promise<unknown> {
|
|
|
133
150
|
throw await toApiError(e);
|
|
134
151
|
}
|
|
135
152
|
}
|
|
153
|
+
|
|
154
|
+
export type PushBody = z.input<(typeof schemas)["push"]["body"]>;
|
|
155
|
+
|
|
156
|
+
export async function push(body: PushBody): Promise<unknown> {
|
|
157
|
+
const client = ensureReq();
|
|
158
|
+
try {
|
|
159
|
+
const env = await client.post(`notification/push`, { json: body }).json<OjEnvelope<unknown>>();
|
|
160
|
+
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
161
|
+
if (typeof env.code === "number" && env.code !== 0)
|
|
162
|
+
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
163
|
+
const data = env.data as unknown;
|
|
164
|
+
return data;
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
throw await toApiError(e);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export type PushBroadcastBody = z.input<(typeof schemas)["pushBroadcast"]["body"]>;
|
|
172
|
+
|
|
173
|
+
export async function pushBroadcast(body: PushBroadcastBody): Promise<unknown> {
|
|
174
|
+
const client = ensureReq();
|
|
175
|
+
try {
|
|
176
|
+
const env = await client.post(`notification/push-broadcast`, { json: body }).json<OjEnvelope<unknown>>();
|
|
177
|
+
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
178
|
+
if (typeof env.code === "number" && env.code !== 0)
|
|
179
|
+
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
180
|
+
const data = env.data as unknown;
|
|
181
|
+
return data;
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
throw await toApiError(e);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -7,9 +7,10 @@ import { createNotificationClient } from "./client/api";
|
|
|
7
7
|
/**
|
|
8
8
|
* notification 模块(G5 模板形态,对齐 apps/playground-oj/web/src/notification)。
|
|
9
9
|
*
|
|
10
|
-
* 无页面路由;仅通过 onInit 全量接管通知 API(D9 + G4
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* 无页面路由;仅通过 onInit 全量接管通知 API(D9 + G4):把内置 root 级通知读/写
|
|
11
|
+
* 收敛到本模块 `/notification` 前缀下的 oj 后端,通知铃的互动(单条已读/全部已读/
|
|
12
|
+
* 清空)由此生效;发射端三方法(push/pushBroadcast/del)使本模块同时作为跨模块
|
|
13
|
+
* 通知原语的接收端(前端 facade 委托至此)。
|
|
13
14
|
*/
|
|
14
15
|
export default defineModule({
|
|
15
16
|
name: "notification",
|
|
@@ -26,9 +27,17 @@ export default defineModule({
|
|
|
26
27
|
const notificationClient = createNotificationClient(ctx);
|
|
27
28
|
const provider: NotificationsApiProvider = {
|
|
28
29
|
fetchNotifications: () => notificationClient.fetchNotifications(),
|
|
29
|
-
|
|
30
|
+
// id 为命名空间串("u:<id>" / "b:<id>"),原样透传
|
|
31
|
+
markRead: id => notificationClient.markRead({ id: String(id) }).then(() => {}),
|
|
30
32
|
markAllRead: () => notificationClient.markAllRead().then(() => {}),
|
|
31
33
|
clearAll: () => notificationClient.clearAll().then(() => {}),
|
|
34
|
+
push: input => notificationClient
|
|
35
|
+
.push({ userId: input.userId, title: input.title, message: input.message, link: input.link, avatar: input.avatar, category: input.category })
|
|
36
|
+
.then(r => String((r as { id: string }).id)),
|
|
37
|
+
pushBroadcast: input => notificationClient
|
|
38
|
+
.pushBroadcast({ title: input.title, message: input.message, link: input.link, avatar: input.avatar, category: input.category })
|
|
39
|
+
.then(r => String((r as { id: string }).id)),
|
|
40
|
+
del: (id, userId) => notificationClient.del({ id: String(id), userId }).then(() => {}),
|
|
32
41
|
};
|
|
33
42
|
ctx.register.notificationsApi(provider);
|
|
34
43
|
},
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
"react-router": "7.18.2",
|
|
9
9
|
"react-router/dom": "7.18.2",
|
|
10
10
|
"@tanstack/react-query": "5.102.8",
|
|
11
|
-
"@oj-module/runtime": "0.1.
|
|
12
|
-
"@oj-module/runtime/contract": "0.1.
|
|
13
|
-
"@oj-module/runtime/contract/errors": "0.1.
|
|
14
|
-
"@plane/kit": "0.1.
|
|
15
|
-
"@plane/editor": "0.1.
|
|
11
|
+
"@oj-module/runtime": "0.1.17",
|
|
12
|
+
"@oj-module/runtime/contract": "0.1.17",
|
|
13
|
+
"@oj-module/runtime/contract/errors": "0.1.17",
|
|
14
|
+
"@plane/kit": "0.1.17",
|
|
15
|
+
"@plane/editor": "0.1.17",
|
|
16
16
|
"antd": "6.6.1",
|
|
17
17
|
"antd/locale/en_US": "6.6.1",
|
|
18
18
|
"antd/locale/zh_CN": "6.6.1",
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
"simplebar-react": "3.3.2",
|
|
65
65
|
"spin-delay": "2.0.1",
|
|
66
66
|
"tailwind-merge": "3.6.0",
|
|
67
|
+
"vditor": "4.0.0",
|
|
68
|
+
"vditor/dist/index.css": "4.0.0",
|
|
67
69
|
"typescript": "6.0.3",
|
|
68
70
|
"@types/react": "19.2.18"
|
|
69
71
|
}
|