@oj-module/cli 0.2.50 → 0.2.54
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 +2 -2
- package/devkit/manual.md +32 -25
- package/devkit/wecom-internal-app.md +111 -4
- package/package.json +2 -2
- package/shell-dist/assets/{index-FYt9CjFd.js → index-e_Mp2mb5.js} +5 -1
- package/shell-dist/assets/runtime.js +29 -5
- package/shell-dist/index.html +9 -12
- package/shell-dist/versions.json +3 -3
- package/src/__tests__/templates-tenant-scope.test.ts +3 -2
- package/src/build.ts +19 -2
- package/src/config.ts +9 -0
- package/src/contract/__tests__/client-path.test.ts +30 -0
- package/src/contract/__tests__/emit-client.test.ts +18 -0
- package/src/contract/__tests__/handler-scan.test.ts +23 -0
- package/src/contract/check.ts +5 -5
- package/src/contract/client-path.ts +30 -0
- package/src/contract/emit-client.ts +18 -4
- package/src/contract/handler-scan.ts +40 -3
- package/src/contract/run.ts +5 -3
- package/src/init.ts +19 -1
- package/src/shared-deps.ts +27 -9
- package/src/site-base.ts +1 -1
- package/templates/README.md +40 -44
- package/templates/init.include.yaml +15 -14
- package/templates/openapi.json +3422 -1955
- package/templates/src/_platform/api/_shared/service/domain/users.ts +40 -4
- package/templates/src/_platform/api/contacts/api.ts +29 -1
- package/templates/src/_platform/api/contacts/detail/api.ts +25 -1
- package/templates/src/_platform/api/solutions/api.ts +60 -1
- package/templates/src/_platform/web/__client/api.schemas.ts +99 -35
- package/templates/src/_platform/web/__client/api.ts +103 -59
- package/templates/src/app/web/entry.ts +77 -0
- package/templates/src/{home/web → app/web/home}/__client/api.ts +5 -2
- package/templates/src/app/web/home/routes.ts +41 -0
- package/templates/src/{login/web → app/web/login}/pages/login.tsx +54 -24
- package/templates/src/app/web/login/routes.ts +71 -0
- package/templates/src/{notification/web → app/web/notification}/__client/api.schemas.ts +14 -0
- package/templates/src/{notification/web → app/web/notification}/__client/api.ts +67 -20
- package/templates/src/app/web/notification/routes.ts +70 -0
- package/templates/src/{personal-center/web → app/web/personal-center}/__client/api.ts +5 -2
- package/templates/src/app/web/personal-center/routes.ts +49 -0
- package/templates/src/{system/web → app/web/system}/__client/api.schemas.ts +28 -22
- package/templates/src/{system/web → app/web/system}/__client/api.ts +103 -58
- package/templates/src/{system/web → app/web/system}/locales/en-US.json +14 -0
- package/templates/src/{system/web → app/web/system}/locales/zh-CN.json +14 -0
- package/templates/src/{system/web → app/web/system}/pages/users/index.tsx +5 -2
- package/templates/src/{system/web → app/web/system}/pages/users/roles.tsx +14 -3
- package/templates/src/{system/web → app/web/system}/pages/wecom/index.tsx +139 -1
- package/templates/src/app/web/system/routes.ts +97 -0
- package/templates/src/auth/api/_shared/wecom/admin.ts +4 -0
- package/templates/src/auth/api/_shared/wecom/client.ts +9 -2
- package/templates/src/auth/api/_shared/wecom/events.ts +3 -0
- package/templates/src/auth/api/_shared/wecom/tenant-admin.ts +194 -0
- package/templates/src/auth/api/api.ts +59 -0
- package/templates/src/auth/api/ldap-login/api.ts +37 -1
- package/templates/src/auth/api/wecom/admin/tenant-admin/api.ts +41 -0
- package/templates/src/auth/api/wecom/admin/tenant-admin/password/api.ts +66 -0
- package/templates/src/auth/api/wecom/api.ts +23 -0
- package/templates/src/auth/web/__client/api.schemas.ts +133 -13
- package/templates/src/auth/web/__client/api.ts +129 -31
- package/templates/src/notification/api/api.ts +17 -0
- package/templates/src/notification/api/del/api.ts +2 -0
- package/templates/src/system/api/roles/api.ts +3 -0
- package/templates/src/system/api/roles/bindings/api.ts +3 -0
- package/templates/src/system/api/settings/api.ts +6 -3
- package/templates/src/system/api/users/forbidden/api.ts +3 -0
- package/templates/src/system/api/users/password/api.ts +3 -0
- package/templates/src/system/api/users/roles/api.ts +3 -0
- package/templates/src/web/api/get-async-routes/api.ts +16 -1
- package/templates/src/web/api/hello/api.ts +13 -1
- package/templates/src/web/api/user-info/api.ts +21 -1
- package/templates/src/web/web/__client/api.schemas.ts +28 -0
- package/templates/src/web/web/__client/api.ts +33 -9
- package/templates/tsconfig.paths.json +0 -1
- package/templates/web.config.ts +22 -17
- package/vendor/host-versions.json +3 -3
- package/shell-dist/assets/echarts-charts.js +0 -58571
- package/shell-dist/assets/echarts-features.js +0 -24057
- package/shell-dist/assets/echarts-for-react.js +0 -704
- package/shell-dist/assets/echarts.js +0 -82916
- package/shell-dist/assets/editor.js +0 -161457
- package/shell-dist/assets/vditor-index-css.js +0 -7
- package/shell-dist/assets/vditor.js +0 -15223
- package/templates/src/demo/api/manifest.yaml +0 -5
- package/templates/src/demo/api/migrations/0001__create_todos.sql +0 -9
- package/templates/src/demo/api/migrations/0002__tenant.mysql.sql +0 -2
- package/templates/src/demo/api/migrations/0002__tenant.sql +0 -2
- package/templates/src/demo/api/schema.yaml +0 -12
- package/templates/src/demo/api/seed.sql +0 -5
- package/templates/src/demo/api/todos/api.ts +0 -59
- package/templates/src/demo/web/__client/api.schemas.ts +0 -20
- package/templates/src/demo/web/__client/api.ts +0 -89
- package/templates/src/demo/web/entry.ts +0 -42
- package/templates/src/demo/web/locales/en-US.json +0 -10
- package/templates/src/demo/web/locales/zh-CN.json +0 -10
- package/templates/src/demo/web/pages/index.tsx +0 -45
- package/templates/src/home/web/entry.ts +0 -49
- package/templates/src/login/web/entry.ts +0 -79
- package/templates/src/notification/web/entry.ts +0 -84
- package/templates/src/personal-center/web/entry.ts +0 -60
- package/templates/src/system/web/entry.ts +0 -108
- /package/templates/src/{home/web → app/web/home}/__client/api.schemas.ts +0 -0
- /package/templates/src/{home/web → app/web/home}/locales/en-US.json +0 -0
- /package/templates/src/{home/web → app/web/home}/locales/zh-CN.json +0 -0
- /package/templates/src/{home/web → app/web/home}/pages/components/bar-chart.tsx +0 -0
- /package/templates/src/{home/web → app/web/home}/pages/components/card-list.tsx +0 -0
- /package/templates/src/{home/web → app/web/home}/pages/components/line-chart.tsx +0 -0
- /package/templates/src/{home/web → app/web/home}/pages/components/pie-chart.tsx +0 -0
- /package/templates/src/{home/web → app/web/home}/pages/index.tsx +0 -0
- /package/templates/src/{login/web → app/web/login}/auth-provider.ts +0 -0
- /package/templates/src/{login/web → app/web/login}/locales/en-US.json +0 -0
- /package/templates/src/{login/web → app/web/login}/locales/zh-CN.json +0 -0
- /package/templates/src/{login/web → app/web/login}/pages/change-password.tsx +0 -0
- /package/templates/src/{login/web → app/web/login}/wecom.ts +0 -0
- /package/templates/src/{notification/web → app/web/notification}/locales/en-US.json +0 -0
- /package/templates/src/{notification/web → app/web/notification}/locales/zh-CN.json +0 -0
- /package/templates/src/{notification/web → app/web/notification}/pages/center/index.tsx +0 -0
- /package/templates/src/{personal-center/web → app/web/personal-center}/__client/api.schemas.ts +0 -0
- /package/templates/src/{personal-center/web → app/web/personal-center}/locales/en-US.json +0 -0
- /package/templates/src/{personal-center/web → app/web/personal-center}/locales/zh-CN.json +0 -0
- /package/templates/src/{personal-center/web → app/web/personal-center}/pages/my-profile/index.tsx +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/departments/index.tsx +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/departments/sync-bar.tsx +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/departments/tree.ts +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/errors.ts +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/forbidden.tsx +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/login-methods/index.tsx +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/oplog/index.tsx +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/roles/index.tsx +0 -0
- /package/templates/src/{system/web → app/web/system}/pages/settings/index.tsx +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// B4:roles 出自 sys_user_role 权威源(users.roles JSON 列已被 0003 移除,D10)——
|
|
3
3
|
// 体验层角色走本资料接口,不进 JWT claims;avatar 读 avatar_base64,email 读 0007 迁移列。
|
|
4
4
|
// 响应一律走 json.ok/json.fail 信封(oj 红线)。
|
|
5
|
-
|
|
5
|
+
const handler = {
|
|
6
6
|
async get() {
|
|
7
7
|
const uid = http.user?.id;
|
|
8
8
|
if (!uid) {
|
|
@@ -35,3 +35,23 @@ export default {
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
};
|
|
38
|
+
|
|
39
|
+
// 出参:登录链用户资料(roles 出自 sys_user_role,permissions 预留恒空)
|
|
40
|
+
handler.get.response = {
|
|
41
|
+
type: "object",
|
|
42
|
+
required: ["id", "avatar", "username", "displayName", "email", "phoneNumber", "description", "roles", "mustChange", "permissions"],
|
|
43
|
+
properties: {
|
|
44
|
+
id: { type: "string" },
|
|
45
|
+
avatar: { type: "string" },
|
|
46
|
+
username: { type: "string" },
|
|
47
|
+
displayName: { type: "string" },
|
|
48
|
+
email: { type: "string" },
|
|
49
|
+
phoneNumber: { type: "string" },
|
|
50
|
+
description: { type: "string" },
|
|
51
|
+
roles: { type: "array", items: { type: "string" } },
|
|
52
|
+
mustChange: { type: "boolean" },
|
|
53
|
+
permissions: { type: "array", items: { type: "string" } },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default handler;
|
|
@@ -4,5 +4,33 @@
|
|
|
4
4
|
import { z } from "@oj-module/runtime";
|
|
5
5
|
|
|
6
6
|
export const schemas = {
|
|
7
|
+
"webGetAsyncRoutesGet": {
|
|
8
|
+
data: z.array(z.object({
|
|
9
|
+
"path": z.string().optional(),
|
|
10
|
+
"component": z.string().optional(),
|
|
11
|
+
"children": z.array(z.object({
|
|
7
12
|
|
|
13
|
+
})).optional()
|
|
14
|
+
})),
|
|
15
|
+
},
|
|
16
|
+
"webHelloGet": {
|
|
17
|
+
data: z.object({
|
|
18
|
+
"message": z.string(),
|
|
19
|
+
"user": z.number().nullable()
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
"webUserInfoGet": {
|
|
23
|
+
data: z.object({
|
|
24
|
+
"id": z.string(),
|
|
25
|
+
"avatar": z.string(),
|
|
26
|
+
"username": z.string(),
|
|
27
|
+
"displayName": z.string(),
|
|
28
|
+
"email": z.string(),
|
|
29
|
+
"phoneNumber": z.string(),
|
|
30
|
+
"description": z.string(),
|
|
31
|
+
"roles": z.array(z.string()),
|
|
32
|
+
"mustChange": z.boolean(),
|
|
33
|
+
"permissions": z.array(z.string())
|
|
34
|
+
}),
|
|
35
|
+
},
|
|
8
36
|
};
|
|
@@ -64,14 +64,22 @@ async function toApiError(e: unknown): Promise<unknown> {
|
|
|
64
64
|
return e;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
export
|
|
67
|
+
export type WebGetAsyncRoutesGetData = z.infer<(typeof schemas)["webGetAsyncRoutesGet"]["data"]>;
|
|
68
|
+
|
|
69
|
+
export async function webGetAsyncRoutesGet(): Promise<WebGetAsyncRoutesGetData> {
|
|
68
70
|
const client = ensureReq();
|
|
69
71
|
try {
|
|
70
|
-
const env = await client.get(`web/get-async-routes`).json<OjEnvelope<
|
|
72
|
+
const env = await client.get(`web/get-async-routes`).json<OjEnvelope<WebGetAsyncRoutesGetData>>();
|
|
71
73
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
72
74
|
if (typeof env.code === "number" && env.code !== 0)
|
|
73
75
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
74
|
-
const data = env.data as
|
|
76
|
+
const data = env.data as WebGetAsyncRoutesGetData;
|
|
77
|
+
if (import.meta.env.DEV) {
|
|
78
|
+
const { schemas } = await import("./api.schemas");
|
|
79
|
+
const r = schemas["webGetAsyncRoutesGet"].data.safeParse(data);
|
|
80
|
+
if (!r.success)
|
|
81
|
+
throw new ContractApiError(-1, `[契约违例] webGetAsyncRoutesGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
82
|
+
}
|
|
75
83
|
return data;
|
|
76
84
|
}
|
|
77
85
|
catch (e) {
|
|
@@ -79,14 +87,22 @@ export async function webGetAsyncRoutesGet(): Promise<unknown> {
|
|
|
79
87
|
}
|
|
80
88
|
}
|
|
81
89
|
|
|
82
|
-
export
|
|
90
|
+
export type WebHelloGetData = z.infer<(typeof schemas)["webHelloGet"]["data"]>;
|
|
91
|
+
|
|
92
|
+
export async function webHelloGet(): Promise<WebHelloGetData> {
|
|
83
93
|
const client = ensureReq();
|
|
84
94
|
try {
|
|
85
|
-
const env = await client.get(`web/hello`).json<OjEnvelope<
|
|
95
|
+
const env = await client.get(`web/hello`).json<OjEnvelope<WebHelloGetData>>();
|
|
86
96
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
87
97
|
if (typeof env.code === "number" && env.code !== 0)
|
|
88
98
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
89
|
-
const data = env.data as
|
|
99
|
+
const data = env.data as WebHelloGetData;
|
|
100
|
+
if (import.meta.env.DEV) {
|
|
101
|
+
const { schemas } = await import("./api.schemas");
|
|
102
|
+
const r = schemas["webHelloGet"].data.safeParse(data);
|
|
103
|
+
if (!r.success)
|
|
104
|
+
throw new ContractApiError(-1, `[契约违例] webHelloGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
105
|
+
}
|
|
90
106
|
return data;
|
|
91
107
|
}
|
|
92
108
|
catch (e) {
|
|
@@ -94,14 +110,22 @@ export async function webHelloGet(): Promise<unknown> {
|
|
|
94
110
|
}
|
|
95
111
|
}
|
|
96
112
|
|
|
97
|
-
export
|
|
113
|
+
export type WebUserInfoGetData = z.infer<(typeof schemas)["webUserInfoGet"]["data"]>;
|
|
114
|
+
|
|
115
|
+
export async function webUserInfoGet(): Promise<WebUserInfoGetData> {
|
|
98
116
|
const client = ensureReq();
|
|
99
117
|
try {
|
|
100
|
-
const env = await client.get(`web/user-info`).json<OjEnvelope<
|
|
118
|
+
const env = await client.get(`web/user-info`).json<OjEnvelope<WebUserInfoGetData>>();
|
|
101
119
|
// 2xx + code!==0 也是业务错误(§6.2 通道 a):oj 不会这么发,但契约机制的价值恰是防漂移
|
|
102
120
|
if (typeof env.code === "number" && env.code !== 0)
|
|
103
121
|
throw new ContractApiError(env.code, env.msg ?? "业务错误(信封 code 非 0)");
|
|
104
|
-
const data = env.data as
|
|
122
|
+
const data = env.data as WebUserInfoGetData;
|
|
123
|
+
if (import.meta.env.DEV) {
|
|
124
|
+
const { schemas } = await import("./api.schemas");
|
|
125
|
+
const r = schemas["webUserInfoGet"].data.safeParse(data);
|
|
126
|
+
if (!r.success)
|
|
127
|
+
throw new ContractApiError(-1, `[契约违例] webUserInfoGet 响应与契约不符:${r.error.issues.map(i => `${i.path.join(".") || "(root)"}: ${i.message}`).join("; ")}`);
|
|
128
|
+
}
|
|
105
129
|
return data;
|
|
106
130
|
}
|
|
107
131
|
catch (e) {
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
"paths": {
|
|
9
9
|
"#/_platform/*": ["./src/_platform/api/*"],
|
|
10
10
|
"#/auth/*": ["./src/auth/api/*"],
|
|
11
|
-
"#/demo/*": ["./src/demo/api/*"],
|
|
12
11
|
"#/home/*": ["./src/home/api/*"],
|
|
13
12
|
"#/notification/*": ["./src/notification/api/*"],
|
|
14
13
|
"#/personal-center/*": ["./src/personal-center/api/*"],
|
package/templates/web.config.ts
CHANGED
|
@@ -10,34 +10,26 @@
|
|
|
10
10
|
* 登记了不存在的前端入口才报错。
|
|
11
11
|
*
|
|
12
12
|
* 注意:这里的登记顺序只影响模块加载顺序,**不决定侧边栏导航顺序**——
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `home` 必须第一个登记(shell 的 "/" 重定向到它)。
|
|
13
|
+
* 菜单顺序由各根路由的 handle.order 决定(≥0 主菜单区升序;<0 底部固定区,
|
|
14
|
+
* pin 在侧边栏底部;同 order 按根 path 字母序)。
|
|
16
15
|
*/
|
|
17
16
|
const allModules = [
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
//
|
|
21
|
-
{ name: "
|
|
22
|
-
// 个人中心:runtime 用户菜单固定导航 /personal-center/my-profile,缺则点击落空
|
|
23
|
-
{ name: "personal-center", entry: "src/personal-center/web/entry.ts" },
|
|
24
|
-
// 通知:onInit 注册 notificationsApi provider(四方法全必填),
|
|
25
|
-
// 通知铃的互动(单条已读/全部已读/清空)由此生效;未登记则永远回落内置只读兜底
|
|
26
|
-
{ name: "notification", entry: "src/notification/web/entry.ts" },
|
|
27
|
-
// 系统管理:用户/成员资格/角色权限/操作日志/站点设置/登录方式(oj 后端 /api/system/*)
|
|
28
|
-
{ name: "system", entry: "src/system/web/entry.ts" },
|
|
17
|
+
// 框架内置页面:首页/登录/个人中心/通知/系统管理聚合成**一个多根模块**。
|
|
18
|
+
// 各根按 handle.order 排序(/home 1、/personal-center 110、/system -100 底部),
|
|
19
|
+
// 与拆分时的菜单逐项一致;/login、/change-password、/notification-center 走 hideInMenu。
|
|
20
|
+
{ name: "app", entry: "src/app/web/entry.ts" },
|
|
29
21
|
// 解决方案市场:第一方能力(消费 _platform 编排面 /api/_platform/market/*,
|
|
30
|
-
// R29
|
|
22
|
+
// R29:第三方方案不得仿照此调用面),默认随脚手架下发。保持独立模块——
|
|
23
|
+
// 可选能力,删目录即可下线。
|
|
31
24
|
{ name: "oj-market", entry: "src/oj-market/web/entry.ts" },
|
|
32
25
|
// #region demo-only
|
|
33
|
-
// 以下为模板内置的演示模块(
|
|
26
|
+
// 以下为模板内置的演示模块(about/access/exception/outside/route-nest),
|
|
34
27
|
// 用于把 templates 当可运行 demo 直接跑;其文件不在 `ojm init` 的
|
|
35
28
|
// init.include.yaml 白名单里,不拷入新工程,故本区间连同这些条目会被
|
|
36
29
|
// init 一并剥离,脚手架产出的配置不会残留指向缺失文件的死条目。
|
|
37
30
|
//
|
|
38
31
|
// 注意:新布局的清单是「扫描 + 覆盖」并集——注释掉不会让它们消失,
|
|
39
32
|
// 扫描仍会捡到 `src/<name>/web/entry.ts`。要「不构建」必须写 `enabled: false`。
|
|
40
|
-
{ name: "demo", entry: "src/demo/web/entry.ts", enabled: false },
|
|
41
33
|
{ name: "about", entry: "src/about/web/entry.ts", enabled: false },
|
|
42
34
|
{ name: "access", entry: "src/access/web/entry.ts", enabled: false },
|
|
43
35
|
{ name: "exception", entry: "src/exception/web/entry.ts", enabled: false },
|
|
@@ -50,4 +42,17 @@ export default {
|
|
|
50
42
|
/** 产物 URL 前缀,留空表示同源相对路径 */
|
|
51
43
|
baseUrl: "",
|
|
52
44
|
modules: allModules,
|
|
45
|
+
/**
|
|
46
|
+
* 生成 client 的归属模块:`api 前缀 → 承载其 __client 的 web 模块`。
|
|
47
|
+
*
|
|
48
|
+
* 多根聚合模块把多个业务域的页面/client 收进 `src/app/web`,故五个 api 前缀的
|
|
49
|
+
* 生成物都落在 `src/app/web/<api 前缀>/__client`(与页面同级,页面相对导入不变)。
|
|
50
|
+
* 不配则回落同名模块(`src/<api 前缀>/web/__client`,历史行为)。
|
|
51
|
+
*/
|
|
52
|
+
clientOwners: {
|
|
53
|
+
"home": "app",
|
|
54
|
+
"personal-center": "app",
|
|
55
|
+
"notification": "app",
|
|
56
|
+
"system": "app",
|
|
57
|
+
},
|
|
53
58
|
};
|
|
@@ -8,9 +8,9 @@
|
|
|
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.2.
|
|
12
|
-
"@oj-module/runtime/contract": "0.2.
|
|
13
|
-
"@oj-module/runtime/contract/errors": "0.2.
|
|
11
|
+
"@oj-module/runtime": "0.2.54",
|
|
12
|
+
"@oj-module/runtime/contract": "0.2.54",
|
|
13
|
+
"@oj-module/runtime/contract/errors": "0.2.54",
|
|
14
14
|
"@plane/kit": "0.1.20",
|
|
15
15
|
"@plane/editor": "0.1.20",
|
|
16
16
|
"antd": "6.6.1",
|