@oj-module/cli 0.2.6 → 0.2.14
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/README.md +1 -1
- package/devkit/README.md +70 -24
- package/devkit/framework-dev.md +14 -5
- package/devkit/manual.md +28 -23
- package/devkit/module-dev-and-cdn-playground.md +197 -0
- package/devkit/sql-builder-missing-capabilities-pr.md +268 -0
- package/package.json +2 -2
- package/shell-dist/assets/runtime.js +130 -45
- package/shell-dist/index.html +2 -2
- package/shell-dist/versions.json +3 -3
- package/src/__tests__/build-backend.test.ts +64 -0
- package/src/__tests__/versions.test.ts +26 -0
- package/src/build.ts +9 -0
- package/src/bundle.ts +8 -5
- package/src/contract/__tests__/handler-scan.test.ts +29 -0
- package/src/contract/__tests__/market-client.integration.test.ts +170 -0
- package/src/contract/handler-scan.ts +35 -4
- package/src/dev.ts +10 -2
- package/src/index.ts +9 -3
- package/src/init.ts +24 -0
- package/src/lifecycle/__tests__/bundle.test.ts +3 -3
- package/src/market/__tests__/bootstrap.test.ts +204 -0
- package/src/market/__tests__/build-index.test.ts +154 -0
- package/src/market/__tests__/cdn-layout.test.ts +96 -0
- package/src/market/__tests__/failure-playbook.test.ts +33 -0
- package/src/market/__tests__/fixture.test.ts +48 -0
- package/src/market/__tests__/publish.test.ts +109 -0
- package/src/market/__tests__/report.test.ts +51 -0
- package/src/market/__tests__/setup.test.ts +114 -0
- package/src/market/__tests__/verify.test.ts +111 -0
- package/src/market/bootstrap.ts +255 -0
- package/src/market/build-index.ts +159 -0
- package/src/market/cdn-layout.ts +122 -0
- package/src/market/command.ts +139 -0
- package/src/market/failure-playbook.ts +57 -0
- package/src/market/fixture.ts +138 -0
- package/src/market/index-builder.ts +76 -0
- package/src/market/publish.ts +156 -0
- package/src/market/report.ts +67 -0
- package/src/market/scan.ts +99 -0
- package/src/market/setup.ts +144 -0
- package/src/market/trial.ts +121 -0
- package/src/market/verify.ts +298 -0
- package/src/market/walkthrough.ts +506 -0
- package/src/oj.ts +3 -1
- package/src/preview-config.ts +177 -0
- package/src/preview.ts +106 -56
- package/src/sign.ts +21 -6
- package/src/usage.ts +22 -2
- package/src/vendor.ts +4 -2
- package/src/versions.ts +28 -0
- package/templates/api/.ojm-api-exempt.json +6 -2
- package/templates/api/config.yaml +24 -2
- package/templates/api/src/_platform/README.md +31 -0
- package/templates/api/src/_platform/_lifecycle/atomic.ts +1 -1
- package/templates/api/src/_platform/_lifecycle/history.ts +10 -5
- package/templates/api/src/_platform/_lifecycle/installer.ts +4 -4
- package/templates/api/src/_platform/_lifecycle/sha384.ts +1 -1
- package/templates/api/src/_platform/_lifecycle/steps/download.ts +1 -1
- package/templates/api/src/_platform/_lifecycle/steps/extract.ts +8 -8
- package/templates/api/src/_platform/_lifecycle/steps/register.ts +57 -29
- package/templates/api/src/_platform/_lifecycle/trust.ts +1 -1
- package/templates/api/src/_platform/_lifecycle/uninstall.ts +29 -56
- package/templates/api/src/_platform/_lifecycle/verify-checks.ts +2 -2
- package/templates/api/src/_platform/_shared/service/{contacts.ts → domain/contacts.ts} +20 -13
- package/templates/api/src/_platform/_shared/service/{roles.ts → domain/roles.ts} +18 -19
- package/templates/api/src/_platform/_shared/service/{settings.ts → domain/settings.ts} +6 -6
- package/templates/api/src/_platform/_shared/service/{solution-perms.ts → domain/solution-perms.ts} +25 -22
- package/templates/api/src/_platform/_shared/service/{users.ts → domain/users.ts} +20 -26
- package/templates/api/src/_platform/_shared/service/{access.ts → infra/access.ts} +5 -8
- package/templates/api/src/_platform/_shared/service/{audit.ts → infra/audit.ts} +26 -26
- package/templates/api/src/_platform/_shared/service/infra/oplog.ts +40 -0
- package/templates/api/src/_platform/_shared/service/{query.ts → infra/query.ts} +18 -0
- package/templates/api/src/_platform/_shared/service/{rate.ts → infra/rate.ts} +16 -13
- package/templates/api/src/_platform/_shared/site-facade.ts +1 -1
- package/templates/api/src/_platform/contacts/api.ts +2 -2
- package/templates/api/src/_platform/contacts/detail/api.ts +2 -2
- package/templates/api/src/_platform/fixtures/l1-test-user.sql +13 -0
- package/templates/api/src/_platform/manifest.yaml +4 -1
- package/templates/api/src/_platform/market/api.ts +54 -16
- package/templates/api/src/_platform/migrations/0013__users_profile.sql +4 -0
- package/templates/api/src/_platform/schema.yaml +26 -0
- package/templates/api/src/_platform/solutions/api.ts +13 -12
- package/templates/api/src/auth/_shared/ldap-login.ts +11 -7
- package/templates/api/src/auth/_shared/login-throttle.ts +2 -2
- package/templates/api/src/auth/_shared/session.ts +26 -22
- package/templates/api/src/auth/api.ts +1 -1
- package/templates/api/src/demo/todos/api.ts +8 -8
- package/templates/api/src/home/line/api.ts +4 -4
- package/templates/api/src/home/pie/api.ts +4 -4
- package/templates/api/src/notification/_shared/notify.ts +97 -57
- package/templates/api/src/notification/api.ts +1 -1
- package/templates/api/src/notification/manifest.yaml +1 -0
- package/templates/api/src/notification/migrations/0004__notifications_broadcast_hidden.sql +12 -0
- package/templates/api/src/notification/schema.yaml +7 -0
- package/templates/api/src/notification/seed.sql +5 -4
- package/templates/api/src/personal-center/profile/api.ts +63 -0
- package/templates/api/src/personal-center/upload/api.ts +1 -1
- package/templates/api/src/system/login-methods/api.ts +1 -1
- package/templates/api/src/system/oplog/api.ts +3 -3
- package/templates/api/src/system/permissions/api.ts +2 -2
- package/templates/api/src/system/roles/api.ts +2 -2
- package/templates/api/src/system/roles/bindings/api.ts +2 -2
- package/templates/api/src/system/settings/api.ts +2 -2
- package/templates/api/src/system/users/api.ts +2 -2
- package/templates/api/src/system/users/forbidden/api.ts +2 -2
- package/templates/api/src/system/users/password/api.ts +2 -2
- package/templates/api/src/system/users/roles/api.ts +2 -2
- package/templates/api/src/web/user-info/api.ts +4 -5
- package/templates/api/tests/auth-session.spec.ts +1 -1
- package/templates/api/tests/auth-throttle.spec.ts +1 -1
- package/templates/api/tests/fixture.ts +8 -16
- package/templates/api/tests/guard.spec.ts +1 -1
- package/templates/api/tests/l1-builder.test.ts +91 -0
- package/templates/api/tests/lifecycle/installer.spec.ts +1 -4
- package/templates/api/tests/lifecycle/market-api.spec.ts +2 -4
- package/templates/api/tests/lifecycle/steps-fs.spec.ts +5 -8
- package/templates/api/tests/lifecycle/trust.spec.ts +1 -1
- package/templates/api/tests/lifecycle/uninstall.spec.ts +29 -89
- package/templates/api/tests/query-utils.spec.ts +85 -1
- package/templates/api/tests/rbac-audit.spec.ts +1 -1
- package/templates/api/tests/rbac-contacts.spec.ts +2 -2
- package/templates/api/tests/rbac-guard.spec.ts +1 -1
- package/templates/api/tests/rbac-roles.spec.ts +2 -2
- package/templates/api/tests/rbac-settings.spec.ts +66 -21
- package/templates/api/tests/rbac-solution-perms.spec.ts +1 -1
- package/templates/api/tests/rbac-users.spec.ts +1 -1
- package/templates/api/tsconfig.json +8 -0
- package/templates/cdn/README.md +48 -0
- package/templates/env.d.ts +2 -0
- package/templates/global.d.ts +850 -0
- package/templates/init.include.yaml +14 -2
- package/templates/logs/task-events.jsonl +0 -0
- package/templates/openapi.json +580 -23
- package/templates/package.json +2 -1
- package/templates/web/src/_platform/__client/api.schemas.ts +97 -0
- package/templates/web/src/_platform/__client/api.ts +152 -39
- package/templates/web/src/notification/entry.ts +46 -9
- package/templates/web/src/notification/locales/en-US.json +19 -0
- package/templates/web/src/notification/locales/zh-CN.json +19 -0
- package/templates/web/src/notification/pages/center/index.tsx +131 -0
- package/templates/web/src/oj-market/__tests__/CardGrid.test.tsx +19 -0
- package/templates/web/src/oj-market/__tests__/InstallDialog.test.tsx +3 -0
- package/templates/web/src/oj-market/__tests__/RollbackDialog.test.tsx +1 -0
- package/templates/web/src/oj-market/__tests__/marketClient.fake.ts +1 -0
- package/templates/web/src/oj-market/api/client.ts +5 -105
- package/templates/web/src/oj-market/api/defaultClient.ts +111 -5
- package/templates/web/src/oj-market/components/CardGrid.tsx +4 -1
- package/templates/web/src/oj-market/components/CardItem.tsx +9 -5
- package/templates/web/src/oj-market/components/DetailDrawer.tsx +7 -3
- package/templates/web/src/oj-market/components/InstallDialog.tsx +1 -1
- package/templates/web/src/oj-market/entry.ts +8 -2
- package/templates/web/src/oj-market/hooks/useMarket.ts +4 -1
- package/templates/web/src/oj-market/locales/en-US.json +2 -1
- package/templates/web/src/oj-market/locales/zh-CN.json +2 -1
- package/templates/web/src/oj-market/pages/MarketApp.tsx +16 -1
- package/templates/web/src/personal-center/__client/api.schemas.ts +9 -0
- package/templates/web/src/personal-center/__client/api.ts +25 -1
- package/templates/web/src/personal-center/entry.ts +5 -0
- package/templates/web/src/personal-center/pages/my-profile/index.tsx +25 -3
- package/templates/web/src/system/entry.ts +2 -1
- package/templates/web.config.ts +13 -10
- package/vendor/host-versions.json +3 -3
- package/templates/api/src/_platform/_shared/service/oplog.ts +0 -47
- package/templates/api/src/notifications/api.ts +0 -32
- package/templates/api/src/notifications/manifest.yaml +0 -5
- package/templates/web/src/notifications/__client/api.schemas.ts +0 -8
- package/templates/web/src/notifications/__client/api.ts +0 -80
- /package/templates/api/src/_platform/_shared/service/{guard.ts → infra/guard.ts} +0 -0
package/templates/package.json
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"build": "ojm build",
|
|
9
9
|
"preview": "ojm preview",
|
|
10
10
|
"info": "ojm info",
|
|
11
|
-
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
11
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
12
|
+
"typecheck:api": "tsc --noEmit -p api/tsconfig.json"
|
|
12
13
|
},
|
|
13
14
|
"devDependencies": {
|
|
14
15
|
"@ant-design/cssinjs": "catalog:",
|
|
@@ -4,5 +4,102 @@
|
|
|
4
4
|
import { z } from "@oj-module/runtime";
|
|
5
5
|
|
|
6
6
|
export const schemas = {
|
|
7
|
+
"platformMarketInstallPost": {
|
|
8
|
+
body: z.object({
|
|
9
|
+
"source": z.enum(["cdn", "file"]),
|
|
10
|
+
"name": z.string(),
|
|
11
|
+
"version": z.string().nullable().optional()
|
|
12
|
+
}),
|
|
13
|
+
data: z.object({
|
|
14
|
+
"task_id": z.string().optional()
|
|
15
|
+
}).catchall(z.unknown()),
|
|
16
|
+
},
|
|
17
|
+
"platformMarketInstallCancelPost": {
|
|
18
|
+
body: z.object({
|
|
19
|
+
"name": z.string()
|
|
20
|
+
}),
|
|
21
|
+
data: z.object({
|
|
22
|
+
"ok": z.boolean().optional(),
|
|
23
|
+
"name": z.string().optional(),
|
|
24
|
+
"requested": z.boolean().optional()
|
|
25
|
+
}).catchall(z.unknown()),
|
|
26
|
+
},
|
|
27
|
+
"platformMarketTaskGet": {
|
|
28
|
+
query: z.object({
|
|
29
|
+
"id": z.string()
|
|
30
|
+
}),
|
|
31
|
+
data: z.object({
|
|
7
32
|
|
|
33
|
+
}).catchall(z.unknown()),
|
|
34
|
+
},
|
|
35
|
+
"platformMarketEnablePost": {
|
|
36
|
+
body: z.object({
|
|
37
|
+
"name": z.string(),
|
|
38
|
+
"enabled": z.boolean()
|
|
39
|
+
}),
|
|
40
|
+
data: z.object({
|
|
41
|
+
|
|
42
|
+
}).catchall(z.unknown()),
|
|
43
|
+
},
|
|
44
|
+
"platformMarketMetaGet": {
|
|
45
|
+
data: z.object({
|
|
46
|
+
"apiVersion": z.string().optional()
|
|
47
|
+
}).catchall(z.unknown()),
|
|
48
|
+
},
|
|
49
|
+
"platformMarketTrustGet": {
|
|
50
|
+
data: z.object({
|
|
51
|
+
|
|
52
|
+
}).catchall(z.unknown()),
|
|
53
|
+
},
|
|
54
|
+
"platformMarketTrustPost": {
|
|
55
|
+
body: z.object({
|
|
56
|
+
"task_id": z.string()
|
|
57
|
+
}),
|
|
58
|
+
data: z.object({
|
|
59
|
+
|
|
60
|
+
}).catchall(z.unknown()),
|
|
61
|
+
},
|
|
62
|
+
"platformMarketTrustKeyPost": {
|
|
63
|
+
body: z.object({
|
|
64
|
+
"key_id": z.string(),
|
|
65
|
+
"public_key": z.string()
|
|
66
|
+
}),
|
|
67
|
+
data: z.object({
|
|
68
|
+
|
|
69
|
+
}).catchall(z.unknown()),
|
|
70
|
+
},
|
|
71
|
+
"platformMarketTrustKeyDelete": {
|
|
72
|
+
query: z.object({
|
|
73
|
+
"key_id": z.string()
|
|
74
|
+
}),
|
|
75
|
+
data: z.object({
|
|
76
|
+
|
|
77
|
+
}).catchall(z.unknown()),
|
|
78
|
+
},
|
|
79
|
+
"platformMarketIndexGet": {
|
|
80
|
+
data: z.array(z.object({
|
|
81
|
+
|
|
82
|
+
}).catchall(z.unknown())),
|
|
83
|
+
},
|
|
84
|
+
"platformMarketUninstallImpactGet": {
|
|
85
|
+
query: z.object({
|
|
86
|
+
"name": z.string()
|
|
87
|
+
}),
|
|
88
|
+
data: z.object({
|
|
89
|
+
|
|
90
|
+
}).catchall(z.unknown()),
|
|
91
|
+
},
|
|
92
|
+
"platformMarketUninstallPost": {
|
|
93
|
+
body: z.object({
|
|
94
|
+
"name": z.string()
|
|
95
|
+
}),
|
|
96
|
+
data: z.object({
|
|
97
|
+
|
|
98
|
+
}).catchall(z.unknown()),
|
|
99
|
+
},
|
|
100
|
+
"platformMarketHistoryGet": {
|
|
101
|
+
data: z.array(z.object({
|
|
102
|
+
|
|
103
|
+
}).catchall(z.unknown())),
|
|
104
|
+
},
|
|
8
105
|
};
|
|
@@ -94,14 +94,23 @@ export async function platformContactsDetailGet(): Promise<unknown> {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export
|
|
97
|
+
export type PlatformMarketInstallPostBody = z.input<(typeof schemas)["platformMarketInstallPost"]["body"]>;
|
|
98
|
+
export type PlatformMarketInstallPostData = z.infer<(typeof schemas)["platformMarketInstallPost"]["data"]>;
|
|
99
|
+
|
|
100
|
+
export async function platformMarketInstallPost(body: PlatformMarketInstallPostBody): Promise<PlatformMarketInstallPostData> {
|
|
98
101
|
const client = ensureReq();
|
|
99
102
|
try {
|
|
100
|
-
const env = await client.post(`_platform/market/install
|
|
103
|
+
const env = await client.post(`_platform/market/install`, { json: body }).json<OjEnvelope<PlatformMarketInstallPostData>>();
|
|
101
104
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
102
105
|
if (typeof env.code === "number" && env.code !== 0)
|
|
103
106
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
104
|
-
const data = env.data as
|
|
107
|
+
const data = env.data as PlatformMarketInstallPostData;
|
|
108
|
+
if (import.meta.env.DEV) {
|
|
109
|
+
const { schemas } = await import("./api.schemas");
|
|
110
|
+
const r = schemas["platformMarketInstallPost"].data.safeParse(data);
|
|
111
|
+
if (!r.success)
|
|
112
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketInstallPost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
113
|
+
}
|
|
105
114
|
return data;
|
|
106
115
|
}
|
|
107
116
|
catch (e) {
|
|
@@ -109,14 +118,23 @@ export async function platformMarketInstallPost(): Promise<unknown> {
|
|
|
109
118
|
}
|
|
110
119
|
}
|
|
111
120
|
|
|
112
|
-
export
|
|
121
|
+
export type PlatformMarketInstallCancelPostBody = z.input<(typeof schemas)["platformMarketInstallCancelPost"]["body"]>;
|
|
122
|
+
export type PlatformMarketInstallCancelPostData = z.infer<(typeof schemas)["platformMarketInstallCancelPost"]["data"]>;
|
|
123
|
+
|
|
124
|
+
export async function platformMarketInstallCancelPost(body: PlatformMarketInstallCancelPostBody): Promise<PlatformMarketInstallCancelPostData> {
|
|
113
125
|
const client = ensureReq();
|
|
114
126
|
try {
|
|
115
|
-
const env = await client.post(`_platform/market/install/cancel
|
|
127
|
+
const env = await client.post(`_platform/market/install/cancel`, { json: body }).json<OjEnvelope<PlatformMarketInstallCancelPostData>>();
|
|
116
128
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
117
129
|
if (typeof env.code === "number" && env.code !== 0)
|
|
118
130
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
119
|
-
const data = env.data as
|
|
131
|
+
const data = env.data as PlatformMarketInstallCancelPostData;
|
|
132
|
+
if (import.meta.env.DEV) {
|
|
133
|
+
const { schemas } = await import("./api.schemas");
|
|
134
|
+
const r = schemas["platformMarketInstallCancelPost"].data.safeParse(data);
|
|
135
|
+
if (!r.success)
|
|
136
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketInstallCancelPost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
137
|
+
}
|
|
120
138
|
return data;
|
|
121
139
|
}
|
|
122
140
|
catch (e) {
|
|
@@ -124,14 +142,23 @@ export async function platformMarketInstallCancelPost(): Promise<unknown> {
|
|
|
124
142
|
}
|
|
125
143
|
}
|
|
126
144
|
|
|
127
|
-
export
|
|
145
|
+
export type PlatformMarketTaskGetQuery = z.input<(typeof schemas)["platformMarketTaskGet"]["query"]>;
|
|
146
|
+
export type PlatformMarketTaskGetData = z.infer<(typeof schemas)["platformMarketTaskGet"]["data"]>;
|
|
147
|
+
|
|
148
|
+
export async function platformMarketTaskGet(query: PlatformMarketTaskGetQuery): Promise<PlatformMarketTaskGetData> {
|
|
128
149
|
const client = ensureReq();
|
|
129
150
|
try {
|
|
130
|
-
const env = await client.get(`_platform/market/task
|
|
151
|
+
const env = await client.get(`_platform/market/task`, { searchParams: query as Record<string, string | number | boolean> }).json<OjEnvelope<PlatformMarketTaskGetData>>();
|
|
131
152
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
132
153
|
if (typeof env.code === "number" && env.code !== 0)
|
|
133
154
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
134
|
-
const data = env.data as
|
|
155
|
+
const data = env.data as PlatformMarketTaskGetData;
|
|
156
|
+
if (import.meta.env.DEV) {
|
|
157
|
+
const { schemas } = await import("./api.schemas");
|
|
158
|
+
const r = schemas["platformMarketTaskGet"].data.safeParse(data);
|
|
159
|
+
if (!r.success)
|
|
160
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketTaskGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
161
|
+
}
|
|
135
162
|
return data;
|
|
136
163
|
}
|
|
137
164
|
catch (e) {
|
|
@@ -139,14 +166,23 @@ export async function platformMarketTaskGet(): Promise<unknown> {
|
|
|
139
166
|
}
|
|
140
167
|
}
|
|
141
168
|
|
|
142
|
-
export
|
|
169
|
+
export type PlatformMarketEnablePostBody = z.input<(typeof schemas)["platformMarketEnablePost"]["body"]>;
|
|
170
|
+
export type PlatformMarketEnablePostData = z.infer<(typeof schemas)["platformMarketEnablePost"]["data"]>;
|
|
171
|
+
|
|
172
|
+
export async function platformMarketEnablePost(body: PlatformMarketEnablePostBody): Promise<PlatformMarketEnablePostData> {
|
|
143
173
|
const client = ensureReq();
|
|
144
174
|
try {
|
|
145
|
-
const env = await client.post(`_platform/market/enable
|
|
175
|
+
const env = await client.post(`_platform/market/enable`, { json: body }).json<OjEnvelope<PlatformMarketEnablePostData>>();
|
|
146
176
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
147
177
|
if (typeof env.code === "number" && env.code !== 0)
|
|
148
178
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
149
|
-
const data = env.data as
|
|
179
|
+
const data = env.data as PlatformMarketEnablePostData;
|
|
180
|
+
if (import.meta.env.DEV) {
|
|
181
|
+
const { schemas } = await import("./api.schemas");
|
|
182
|
+
const r = schemas["platformMarketEnablePost"].data.safeParse(data);
|
|
183
|
+
if (!r.success)
|
|
184
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketEnablePost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
185
|
+
}
|
|
150
186
|
return data;
|
|
151
187
|
}
|
|
152
188
|
catch (e) {
|
|
@@ -154,14 +190,22 @@ export async function platformMarketEnablePost(): Promise<unknown> {
|
|
|
154
190
|
}
|
|
155
191
|
}
|
|
156
192
|
|
|
157
|
-
export
|
|
193
|
+
export type PlatformMarketMetaGetData = z.infer<(typeof schemas)["platformMarketMetaGet"]["data"]>;
|
|
194
|
+
|
|
195
|
+
export async function platformMarketMetaGet(): Promise<PlatformMarketMetaGetData> {
|
|
158
196
|
const client = ensureReq();
|
|
159
197
|
try {
|
|
160
|
-
const env = await client.get(`_platform/market/meta`).json<OjEnvelope<
|
|
198
|
+
const env = await client.get(`_platform/market/meta`).json<OjEnvelope<PlatformMarketMetaGetData>>();
|
|
161
199
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
162
200
|
if (typeof env.code === "number" && env.code !== 0)
|
|
163
201
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
164
|
-
const data = env.data as
|
|
202
|
+
const data = env.data as PlatformMarketMetaGetData;
|
|
203
|
+
if (import.meta.env.DEV) {
|
|
204
|
+
const { schemas } = await import("./api.schemas");
|
|
205
|
+
const r = schemas["platformMarketMetaGet"].data.safeParse(data);
|
|
206
|
+
if (!r.success)
|
|
207
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketMetaGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
208
|
+
}
|
|
165
209
|
return data;
|
|
166
210
|
}
|
|
167
211
|
catch (e) {
|
|
@@ -169,14 +213,22 @@ export async function platformMarketMetaGet(): Promise<unknown> {
|
|
|
169
213
|
}
|
|
170
214
|
}
|
|
171
215
|
|
|
172
|
-
export
|
|
216
|
+
export type PlatformMarketTrustGetData = z.infer<(typeof schemas)["platformMarketTrustGet"]["data"]>;
|
|
217
|
+
|
|
218
|
+
export async function platformMarketTrustGet(): Promise<PlatformMarketTrustGetData> {
|
|
173
219
|
const client = ensureReq();
|
|
174
220
|
try {
|
|
175
|
-
const env = await client.get(`_platform/market/trust`).json<OjEnvelope<
|
|
221
|
+
const env = await client.get(`_platform/market/trust`).json<OjEnvelope<PlatformMarketTrustGetData>>();
|
|
176
222
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
177
223
|
if (typeof env.code === "number" && env.code !== 0)
|
|
178
224
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
179
|
-
const data = env.data as
|
|
225
|
+
const data = env.data as PlatformMarketTrustGetData;
|
|
226
|
+
if (import.meta.env.DEV) {
|
|
227
|
+
const { schemas } = await import("./api.schemas");
|
|
228
|
+
const r = schemas["platformMarketTrustGet"].data.safeParse(data);
|
|
229
|
+
if (!r.success)
|
|
230
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketTrustGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
231
|
+
}
|
|
180
232
|
return data;
|
|
181
233
|
}
|
|
182
234
|
catch (e) {
|
|
@@ -184,14 +236,23 @@ export async function platformMarketTrustGet(): Promise<unknown> {
|
|
|
184
236
|
}
|
|
185
237
|
}
|
|
186
238
|
|
|
187
|
-
export
|
|
239
|
+
export type PlatformMarketTrustPostBody = z.input<(typeof schemas)["platformMarketTrustPost"]["body"]>;
|
|
240
|
+
export type PlatformMarketTrustPostData = z.infer<(typeof schemas)["platformMarketTrustPost"]["data"]>;
|
|
241
|
+
|
|
242
|
+
export async function platformMarketTrustPost(body: PlatformMarketTrustPostBody): Promise<PlatformMarketTrustPostData> {
|
|
188
243
|
const client = ensureReq();
|
|
189
244
|
try {
|
|
190
|
-
const env = await client.post(`_platform/market/trust
|
|
245
|
+
const env = await client.post(`_platform/market/trust`, { json: body }).json<OjEnvelope<PlatformMarketTrustPostData>>();
|
|
191
246
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
192
247
|
if (typeof env.code === "number" && env.code !== 0)
|
|
193
248
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
194
|
-
const data = env.data as
|
|
249
|
+
const data = env.data as PlatformMarketTrustPostData;
|
|
250
|
+
if (import.meta.env.DEV) {
|
|
251
|
+
const { schemas } = await import("./api.schemas");
|
|
252
|
+
const r = schemas["platformMarketTrustPost"].data.safeParse(data);
|
|
253
|
+
if (!r.success)
|
|
254
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketTrustPost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
255
|
+
}
|
|
195
256
|
return data;
|
|
196
257
|
}
|
|
197
258
|
catch (e) {
|
|
@@ -199,14 +260,23 @@ export async function platformMarketTrustPost(): Promise<unknown> {
|
|
|
199
260
|
}
|
|
200
261
|
}
|
|
201
262
|
|
|
202
|
-
export
|
|
263
|
+
export type PlatformMarketTrustKeyPostBody = z.input<(typeof schemas)["platformMarketTrustKeyPost"]["body"]>;
|
|
264
|
+
export type PlatformMarketTrustKeyPostData = z.infer<(typeof schemas)["platformMarketTrustKeyPost"]["data"]>;
|
|
265
|
+
|
|
266
|
+
export async function platformMarketTrustKeyPost(body: PlatformMarketTrustKeyPostBody): Promise<PlatformMarketTrustKeyPostData> {
|
|
203
267
|
const client = ensureReq();
|
|
204
268
|
try {
|
|
205
|
-
const env = await client.post(`_platform/market/trust/key
|
|
269
|
+
const env = await client.post(`_platform/market/trust/key`, { json: body }).json<OjEnvelope<PlatformMarketTrustKeyPostData>>();
|
|
206
270
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
207
271
|
if (typeof env.code === "number" && env.code !== 0)
|
|
208
272
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
209
|
-
const data = env.data as
|
|
273
|
+
const data = env.data as PlatformMarketTrustKeyPostData;
|
|
274
|
+
if (import.meta.env.DEV) {
|
|
275
|
+
const { schemas } = await import("./api.schemas");
|
|
276
|
+
const r = schemas["platformMarketTrustKeyPost"].data.safeParse(data);
|
|
277
|
+
if (!r.success)
|
|
278
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketTrustKeyPost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
279
|
+
}
|
|
210
280
|
return data;
|
|
211
281
|
}
|
|
212
282
|
catch (e) {
|
|
@@ -214,14 +284,23 @@ export async function platformMarketTrustKeyPost(): Promise<unknown> {
|
|
|
214
284
|
}
|
|
215
285
|
}
|
|
216
286
|
|
|
217
|
-
export
|
|
287
|
+
export type PlatformMarketTrustKeyDeleteQuery = z.input<(typeof schemas)["platformMarketTrustKeyDelete"]["query"]>;
|
|
288
|
+
export type PlatformMarketTrustKeyDeleteData = z.infer<(typeof schemas)["platformMarketTrustKeyDelete"]["data"]>;
|
|
289
|
+
|
|
290
|
+
export async function platformMarketTrustKeyDelete(query: PlatformMarketTrustKeyDeleteQuery): Promise<PlatformMarketTrustKeyDeleteData> {
|
|
218
291
|
const client = ensureReq();
|
|
219
292
|
try {
|
|
220
|
-
const env = await client.delete(`_platform/market/trust/key
|
|
293
|
+
const env = await client.delete(`_platform/market/trust/key`, { searchParams: query as Record<string, string | number | boolean> }).json<OjEnvelope<PlatformMarketTrustKeyDeleteData>>();
|
|
221
294
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
222
295
|
if (typeof env.code === "number" && env.code !== 0)
|
|
223
296
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
224
|
-
const data = env.data as
|
|
297
|
+
const data = env.data as PlatformMarketTrustKeyDeleteData;
|
|
298
|
+
if (import.meta.env.DEV) {
|
|
299
|
+
const { schemas } = await import("./api.schemas");
|
|
300
|
+
const r = schemas["platformMarketTrustKeyDelete"].data.safeParse(data);
|
|
301
|
+
if (!r.success)
|
|
302
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketTrustKeyDelete 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
303
|
+
}
|
|
225
304
|
return data;
|
|
226
305
|
}
|
|
227
306
|
catch (e) {
|
|
@@ -229,14 +308,22 @@ export async function platformMarketTrustKeyDelete(): Promise<unknown> {
|
|
|
229
308
|
}
|
|
230
309
|
}
|
|
231
310
|
|
|
232
|
-
export
|
|
311
|
+
export type PlatformMarketIndexGetData = z.infer<(typeof schemas)["platformMarketIndexGet"]["data"]>;
|
|
312
|
+
|
|
313
|
+
export async function platformMarketIndexGet(): Promise<PlatformMarketIndexGetData> {
|
|
233
314
|
const client = ensureReq();
|
|
234
315
|
try {
|
|
235
|
-
const env = await client.get(`_platform/market/index`).json<OjEnvelope<
|
|
316
|
+
const env = await client.get(`_platform/market/index`).json<OjEnvelope<PlatformMarketIndexGetData>>();
|
|
236
317
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
237
318
|
if (typeof env.code === "number" && env.code !== 0)
|
|
238
319
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
239
|
-
const data = env.data as
|
|
320
|
+
const data = env.data as PlatformMarketIndexGetData;
|
|
321
|
+
if (import.meta.env.DEV) {
|
|
322
|
+
const { schemas } = await import("./api.schemas");
|
|
323
|
+
const r = schemas["platformMarketIndexGet"].data.safeParse(data);
|
|
324
|
+
if (!r.success)
|
|
325
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketIndexGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
326
|
+
}
|
|
240
327
|
return data;
|
|
241
328
|
}
|
|
242
329
|
catch (e) {
|
|
@@ -244,14 +331,23 @@ export async function platformMarketIndexGet(): Promise<unknown> {
|
|
|
244
331
|
}
|
|
245
332
|
}
|
|
246
333
|
|
|
247
|
-
export
|
|
334
|
+
export type PlatformMarketUninstallImpactGetQuery = z.input<(typeof schemas)["platformMarketUninstallImpactGet"]["query"]>;
|
|
335
|
+
export type PlatformMarketUninstallImpactGetData = z.infer<(typeof schemas)["platformMarketUninstallImpactGet"]["data"]>;
|
|
336
|
+
|
|
337
|
+
export async function platformMarketUninstallImpactGet(query: PlatformMarketUninstallImpactGetQuery): Promise<PlatformMarketUninstallImpactGetData> {
|
|
248
338
|
const client = ensureReq();
|
|
249
339
|
try {
|
|
250
|
-
const env = await client.get(`_platform/market/uninstall-impact
|
|
340
|
+
const env = await client.get(`_platform/market/uninstall-impact`, { searchParams: query as Record<string, string | number | boolean> }).json<OjEnvelope<PlatformMarketUninstallImpactGetData>>();
|
|
251
341
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
252
342
|
if (typeof env.code === "number" && env.code !== 0)
|
|
253
343
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
254
|
-
const data = env.data as
|
|
344
|
+
const data = env.data as PlatformMarketUninstallImpactGetData;
|
|
345
|
+
if (import.meta.env.DEV) {
|
|
346
|
+
const { schemas } = await import("./api.schemas");
|
|
347
|
+
const r = schemas["platformMarketUninstallImpactGet"].data.safeParse(data);
|
|
348
|
+
if (!r.success)
|
|
349
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketUninstallImpactGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
350
|
+
}
|
|
255
351
|
return data;
|
|
256
352
|
}
|
|
257
353
|
catch (e) {
|
|
@@ -259,14 +355,23 @@ export async function platformMarketUninstallImpactGet(): Promise<unknown> {
|
|
|
259
355
|
}
|
|
260
356
|
}
|
|
261
357
|
|
|
262
|
-
export
|
|
358
|
+
export type PlatformMarketUninstallPostBody = z.input<(typeof schemas)["platformMarketUninstallPost"]["body"]>;
|
|
359
|
+
export type PlatformMarketUninstallPostData = z.infer<(typeof schemas)["platformMarketUninstallPost"]["data"]>;
|
|
360
|
+
|
|
361
|
+
export async function platformMarketUninstallPost(body: PlatformMarketUninstallPostBody): Promise<PlatformMarketUninstallPostData> {
|
|
263
362
|
const client = ensureReq();
|
|
264
363
|
try {
|
|
265
|
-
const env = await client.post(`_platform/market/uninstall
|
|
364
|
+
const env = await client.post(`_platform/market/uninstall`, { json: body }).json<OjEnvelope<PlatformMarketUninstallPostData>>();
|
|
266
365
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
267
366
|
if (typeof env.code === "number" && env.code !== 0)
|
|
268
367
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
269
|
-
const data = env.data as
|
|
368
|
+
const data = env.data as PlatformMarketUninstallPostData;
|
|
369
|
+
if (import.meta.env.DEV) {
|
|
370
|
+
const { schemas } = await import("./api.schemas");
|
|
371
|
+
const r = schemas["platformMarketUninstallPost"].data.safeParse(data);
|
|
372
|
+
if (!r.success)
|
|
373
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketUninstallPost 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
374
|
+
}
|
|
270
375
|
return data;
|
|
271
376
|
}
|
|
272
377
|
catch (e) {
|
|
@@ -274,14 +379,22 @@ export async function platformMarketUninstallPost(): Promise<unknown> {
|
|
|
274
379
|
}
|
|
275
380
|
}
|
|
276
381
|
|
|
277
|
-
export
|
|
382
|
+
export type PlatformMarketHistoryGetData = z.infer<(typeof schemas)["platformMarketHistoryGet"]["data"]>;
|
|
383
|
+
|
|
384
|
+
export async function platformMarketHistoryGet(): Promise<PlatformMarketHistoryGetData> {
|
|
278
385
|
const client = ensureReq();
|
|
279
386
|
try {
|
|
280
|
-
const env = await client.get(`_platform/market/history`).json<OjEnvelope<
|
|
387
|
+
const env = await client.get(`_platform/market/history`).json<OjEnvelope<PlatformMarketHistoryGetData>>();
|
|
281
388
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
282
389
|
if (typeof env.code === "number" && env.code !== 0)
|
|
283
390
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
284
|
-
const data = env.data as
|
|
391
|
+
const data = env.data as PlatformMarketHistoryGetData;
|
|
392
|
+
if (import.meta.env.DEV) {
|
|
393
|
+
const { schemas } = await import("./api.schemas");
|
|
394
|
+
const r = schemas["platformMarketHistoryGet"].data.safeParse(data);
|
|
395
|
+
if (!r.success)
|
|
396
|
+
throw new ContractApiError(-1, `[契约违例] platformMarketHistoryGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
397
|
+
}
|
|
285
398
|
return data;
|
|
286
399
|
}
|
|
287
400
|
catch (e) {
|
|
@@ -1,23 +1,60 @@
|
|
|
1
|
-
import type { NotificationsApiProvider } from "@oj-module/runtime";
|
|
1
|
+
import type { AppRouteRecordRaw, NotificationsApiProvider } from "@oj-module/runtime";
|
|
2
2
|
|
|
3
|
+
import { BellOutlined } from "@ant-design/icons";
|
|
3
4
|
import { defineModule } from "@oj-module/runtime";
|
|
4
5
|
|
|
6
|
+
import { createElement, lazy } from "react";
|
|
7
|
+
|
|
5
8
|
import { createNotificationClient } from "./__client/api";
|
|
6
9
|
|
|
10
|
+
const NotificationCenter = lazy(() => import("./pages/center"));
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 通知中心页(N3):全量消息 + 类型 Tab,铃铛弹层「查看全部」跳转至此。
|
|
14
|
+
* hideInMenu——入口在铃铛,不占侧边导航。
|
|
15
|
+
* 布局挂父路由 handle(resolveRouteLayouts 只给「无 Component 有 children」的
|
|
16
|
+
* 父路由注入 layout,页面组件写父级上布局会被忽略、裸渲染无 chrome)。
|
|
17
|
+
*/
|
|
18
|
+
const routes: AppRouteRecordRaw[] = [
|
|
19
|
+
{
|
|
20
|
+
path: "/notification-center",
|
|
21
|
+
handle: {
|
|
22
|
+
layout: "container",
|
|
23
|
+
title: "notification:menu.notificationCenter",
|
|
24
|
+
icon: createElement(BellOutlined),
|
|
25
|
+
hideInMenu: true,
|
|
26
|
+
},
|
|
27
|
+
children: [
|
|
28
|
+
{
|
|
29
|
+
index: true,
|
|
30
|
+
Component: NotificationCenter,
|
|
31
|
+
handle: {
|
|
32
|
+
title: "notification:menu.notificationCenter",
|
|
33
|
+
icon: createElement(BellOutlined),
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
7
40
|
/**
|
|
8
|
-
* notification 模块(G5
|
|
41
|
+
* notification 模块(G5 模板形态):通知聚合的唯一前端消费面。
|
|
9
42
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
43
|
+
* onInit 全量接管通知 API(D9 + G4):把通知读/写收敛到本模块 `/notification`
|
|
44
|
+
* 前缀下的 oj 后端,通知铃的互动(单条已读/全部已读/清空)由此生效;发射端
|
|
45
|
+
* 三方法(push/pushBroadcast/del)使本模块同时作为跨模块通知原语的接收端
|
|
46
|
+
* (前端 facade 委托至此)。
|
|
14
47
|
*/
|
|
15
48
|
export default defineModule({
|
|
16
49
|
name: "notification",
|
|
17
|
-
description: "通知模块(D9/G4
|
|
18
|
-
version: "0.0
|
|
50
|
+
description: "通知模块(D9/G4 注入通知读写 + 通知中心页)",
|
|
51
|
+
version: "0.1.0",
|
|
19
52
|
peerRuntime: ">=0.0.0",
|
|
20
|
-
routes
|
|
53
|
+
routes,
|
|
54
|
+
i18n: {
|
|
55
|
+
"zh-CN": () => import("./locales/zh-CN.json"),
|
|
56
|
+
"en-US": () => import("./locales/en-US.json"),
|
|
57
|
+
},
|
|
21
58
|
lifecycle: {
|
|
22
59
|
async onInit(ctx) {
|
|
23
60
|
// 构造即接线:createNotificationClient 登记契约前缀 /notification
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"menu": {
|
|
3
|
+
"notificationCenter": "Notifications"
|
|
4
|
+
},
|
|
5
|
+
"center": {
|
|
6
|
+
"tabAll": "All",
|
|
7
|
+
"category": {
|
|
8
|
+
"notice": "Notice",
|
|
9
|
+
"pm": "Direct",
|
|
10
|
+
"mention": "Mentions"
|
|
11
|
+
},
|
|
12
|
+
"markAllRead": "Mark all as read",
|
|
13
|
+
"clear": "Clear",
|
|
14
|
+
"clearConfirm": "Clear all notifications? (Broadcasts are hidden for you only)",
|
|
15
|
+
"empty": "No notifications",
|
|
16
|
+
"scopeBroadcast": "Broadcast",
|
|
17
|
+
"scopeUser": "Personal"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"menu": {
|
|
3
|
+
"notificationCenter": "通知中心"
|
|
4
|
+
},
|
|
5
|
+
"center": {
|
|
6
|
+
"tabAll": "全部",
|
|
7
|
+
"category": {
|
|
8
|
+
"notice": "通知",
|
|
9
|
+
"pm": "私信",
|
|
10
|
+
"mention": "@我"
|
|
11
|
+
},
|
|
12
|
+
"markAllRead": "全部已读",
|
|
13
|
+
"clear": "清空",
|
|
14
|
+
"clearConfirm": "确定清空所有通知吗?(广播仅对您隐藏,不影响他人)",
|
|
15
|
+
"empty": "暂无通知",
|
|
16
|
+
"scopeBroadcast": "广播",
|
|
17
|
+
"scopeUser": "个人"
|
|
18
|
+
}
|
|
19
|
+
}
|