@downcity/city 1.1.32 → 1.1.39
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/bin/cli/Index.js +8 -3
- package/bin/cli/Index.js.map +1 -1
- package/bin/cli/agent/Init.d.ts.map +1 -1
- package/bin/cli/agent/Init.js +8 -8
- package/bin/cli/agent/Init.js.map +1 -1
- package/bin/cli/agent/Run.d.ts.map +1 -1
- package/bin/cli/agent/Run.js +8 -14
- package/bin/cli/agent/Run.js.map +1 -1
- package/bin/cli/control-plane/ControlPlaneProcess.d.ts.map +1 -1
- package/bin/cli/control-plane/ControlPlaneProcess.js +2 -3
- package/bin/cli/control-plane/ControlPlaneProcess.js.map +1 -1
- package/bin/cli/shared/ChatAuth.d.ts.map +1 -1
- package/bin/cli/shared/ChatAuth.js +5 -7
- package/bin/cli/shared/ChatAuth.js.map +1 -1
- package/bin/cli/shared/ChatManager.d.ts.map +1 -1
- package/bin/cli/shared/ChatManager.js +2 -3
- package/bin/cli/shared/ChatManager.js.map +1 -1
- package/bin/cli/shared/ManagedPluginActionCommands.d.ts +2 -1
- package/bin/cli/shared/ManagedPluginActionCommands.d.ts.map +1 -1
- package/bin/cli/shared/ManagedPluginActionCommands.js +5 -4
- package/bin/cli/shared/ManagedPluginActionCommands.js.map +1 -1
- package/bin/cli/shared/PluginScheduleCommand.d.ts +3 -2
- package/bin/cli/shared/PluginScheduleCommand.d.ts.map +1 -1
- package/bin/cli/shared/PluginScheduleCommand.js +11 -10
- package/bin/cli/shared/PluginScheduleCommand.js.map +1 -1
- package/bin/cli/shared/PluginTargetSupport.d.ts +4 -4
- package/bin/cli/shared/PluginTargetSupport.d.ts.map +1 -1
- package/bin/cli/shared/PluginTargetSupport.js +4 -5
- package/bin/cli/shared/PluginTargetSupport.js.map +1 -1
- package/bin/cli/shared/Plugins.d.ts.map +1 -1
- package/bin/cli/shared/Plugins.js +12 -6
- package/bin/cli/shared/Plugins.js.map +1 -1
- package/bin/control/ChannelAccountApiRoutes.d.ts.map +1 -1
- package/bin/control/ChannelAccountApiRoutes.js +2 -3
- package/bin/control/ChannelAccountApiRoutes.js.map +1 -1
- package/bin/control/ControlGateway.d.ts.map +1 -1
- package/bin/control/ControlGateway.js +3 -2
- package/bin/control/ControlGateway.js.map +1 -1
- package/bin/control/PluginApiRoutes.d.ts.map +1 -1
- package/bin/control/PluginApiRoutes.js +33 -25
- package/bin/control/PluginApiRoutes.js.map +1 -1
- package/bin/control/gateway/AgentActions.d.ts.map +1 -1
- package/bin/control/gateway/AgentActions.js +16 -11
- package/bin/control/gateway/AgentActions.js.map +1 -1
- package/bin/model/runtime/CreateRuntimeModel.d.ts +2 -10
- package/bin/model/runtime/CreateRuntimeModel.d.ts.map +1 -1
- package/bin/model/runtime/CreateRuntimeModel.js +1 -16
- package/bin/model/runtime/CreateRuntimeModel.js.map +1 -1
- package/bin/model/runtime/ExecutionModelBinding.d.ts +46 -0
- package/bin/model/runtime/ExecutionModelBinding.d.ts.map +1 -0
- package/bin/model/runtime/ExecutionModelBinding.js +96 -0
- package/bin/model/runtime/ExecutionModelBinding.js.map +1 -0
- package/bin/process/registry/AgentHostRuntime.d.ts +1 -9
- package/bin/process/registry/AgentHostRuntime.d.ts.map +1 -1
- package/bin/process/registry/AgentHostRuntime.js +1 -155
- package/bin/process/registry/AgentHostRuntime.js.map +1 -1
- package/package.json +3 -2
- package/src/cli/Index.ts +11 -3
- package/src/cli/agent/Init.ts +9 -8
- package/src/cli/agent/Run.ts +8 -13
- package/src/cli/control-plane/ControlPlaneProcess.ts +2 -3
- package/src/cli/shared/ChatAuth.ts +10 -11
- package/src/cli/shared/ChatManager.ts +2 -3
- package/src/cli/shared/ManagedPluginActionCommands.ts +11 -8
- package/src/cli/shared/PluginScheduleCommand.ts +11 -10
- package/src/cli/shared/PluginTargetSupport.ts +6 -7
- package/src/cli/shared/Plugins.ts +16 -10
- package/src/control/ChannelAccountApiRoutes.ts +2 -3
- package/src/control/ControlGateway.ts +3 -2
- package/src/control/PluginApiRoutes.ts +37 -27
- package/src/control/gateway/AgentActions.ts +16 -11
- package/src/model/runtime/CreateRuntimeModel.ts +1 -26
- package/src/model/runtime/ExecutionModelBinding.ts +120 -0
- package/src/process/registry/AgentHostRuntime.ts +1 -163
- package/tsconfig.json +2 -1
- package/bin/platform/chatAuthorization/Store.d.ts +0 -31
- package/bin/platform/chatAuthorization/Store.d.ts.map +0 -1
- package/bin/platform/chatAuthorization/Store.js +0 -145
- package/bin/platform/chatAuthorization/Store.js.map +0 -1
- package/src/platform/chatAuthorization/Store.ts +0 -181
package/tsconfig.json
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"rootDir": "src",
|
|
9
9
|
"paths": {
|
|
10
10
|
"@/*": ["./src/*"],
|
|
11
|
-
"@downcity/agent": ["../agent/bin/index.d.ts"]
|
|
11
|
+
"@downcity/agent": ["../agent/bin/index.d.ts"],
|
|
12
|
+
"@downcity/plugins": ["../plugins/bin/index.d.ts"]
|
|
12
13
|
},
|
|
13
14
|
"strict": true,
|
|
14
15
|
"noImplicitAny": false,
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* City 级 chat authorization 配置存储。
|
|
3
|
-
*
|
|
4
|
-
* 关键点(中文)
|
|
5
|
-
* - 静态 chat 授权配置属于 city 维护的项目侧状态。
|
|
6
|
-
* - 这里把配置落在项目 `.downcity/chat/authorization/config.json`。
|
|
7
|
-
* - agent 只消费注入进来的读写能力,不再自己管理这份配置。
|
|
8
|
-
*/
|
|
9
|
-
import type { ChatAuthorizationChannel, ChatAuthorizationConfig } from "@downcity/agent";
|
|
10
|
-
/**
|
|
11
|
-
* 同步读取 chat authorization 配置。
|
|
12
|
-
*/
|
|
13
|
-
export declare function readChatAuthorizationConfigSync(projectRoot: string): ChatAuthorizationConfig;
|
|
14
|
-
/**
|
|
15
|
-
* 读取 chat authorization 配置。
|
|
16
|
-
*/
|
|
17
|
-
export declare function readChatAuthorizationConfig(projectRoot: string): Promise<ChatAuthorizationConfig>;
|
|
18
|
-
/**
|
|
19
|
-
* 覆盖写入 chat authorization 配置。
|
|
20
|
-
*/
|
|
21
|
-
export declare function writeChatAuthorizationConfig(projectRoot: string, nextConfig: ChatAuthorizationConfig): Promise<ChatAuthorizationConfig>;
|
|
22
|
-
/**
|
|
23
|
-
* 设置单个用户角色。
|
|
24
|
-
*/
|
|
25
|
-
export declare function setChatAuthorizationUserRole(params: {
|
|
26
|
-
projectRoot: string;
|
|
27
|
-
channel: ChatAuthorizationChannel;
|
|
28
|
-
userId: string;
|
|
29
|
-
roleId: string;
|
|
30
|
-
}): Promise<ChatAuthorizationConfig>;
|
|
31
|
-
//# sourceMappingURL=Store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Store.d.ts","sourceRoot":"","sources":["../../../src/platform/chatAuthorization/Store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EAGxB,MAAM,iBAAiB,CAAC;AAmHzB;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,WAAW,EAAE,MAAM,GAAG,uBAAuB,CAE5F;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,uBAAuB,CAAC,CAElC;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,uBAAuB,GAClC,OAAO,CAAC,uBAAuB,CAAC,CAElC;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAAC,MAAM,EAAE;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,wBAAwB,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAenC"}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* City 级 chat authorization 配置存储。
|
|
3
|
-
*
|
|
4
|
-
* 关键点(中文)
|
|
5
|
-
* - 静态 chat 授权配置属于 city 维护的项目侧状态。
|
|
6
|
-
* - 这里把配置落在项目 `.downcity/chat/authorization/config.json`。
|
|
7
|
-
* - agent 只消费注入进来的读写能力,不再自己管理这份配置。
|
|
8
|
-
*/
|
|
9
|
-
import fs from "fs-extra";
|
|
10
|
-
import path from "node:path";
|
|
11
|
-
import { CHAT_AUTHORIZATION_CHANNELS, createDefaultChatAuthorizationRoles, } from "@downcity/agent";
|
|
12
|
-
function normalizeText(value) {
|
|
13
|
-
const text = String(value || "").trim();
|
|
14
|
-
return text || undefined;
|
|
15
|
-
}
|
|
16
|
-
function normalizeRoleMap(input) {
|
|
17
|
-
const defaultRoles = createDefaultChatAuthorizationRoles();
|
|
18
|
-
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
19
|
-
return defaultRoles;
|
|
20
|
-
const roles = {};
|
|
21
|
-
for (const [rawRoleId, rawRole] of Object.entries(input)) {
|
|
22
|
-
const roleId = normalizeText(rawRoleId);
|
|
23
|
-
if (!roleId)
|
|
24
|
-
continue;
|
|
25
|
-
const roleObj = rawRole && typeof rawRole === "object" && !Array.isArray(rawRole)
|
|
26
|
-
? rawRole
|
|
27
|
-
: null;
|
|
28
|
-
if (!roleObj)
|
|
29
|
-
continue;
|
|
30
|
-
const builtinRole = defaultRoles[roleId];
|
|
31
|
-
const permissions = Array.isArray(roleObj.permissions)
|
|
32
|
-
? [...new Set(roleObj.permissions.map((item) => normalizeText(item)).filter(Boolean))]
|
|
33
|
-
: [];
|
|
34
|
-
roles[roleId] = {
|
|
35
|
-
roleId,
|
|
36
|
-
name: normalizeText(roleObj.name) || builtinRole?.name || roleId,
|
|
37
|
-
...(normalizeText(roleObj.description) || builtinRole?.description
|
|
38
|
-
? {
|
|
39
|
-
description: normalizeText(roleObj.description) || builtinRole?.description || undefined,
|
|
40
|
-
}
|
|
41
|
-
: {}),
|
|
42
|
-
permissions: permissions,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
if (Object.keys(roles).length === 0)
|
|
46
|
-
return defaultRoles;
|
|
47
|
-
if (!roles.default)
|
|
48
|
-
roles.default = defaultRoles.default;
|
|
49
|
-
return roles;
|
|
50
|
-
}
|
|
51
|
-
function normalizeBindingMap(input, roles) {
|
|
52
|
-
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
53
|
-
return {};
|
|
54
|
-
const out = {};
|
|
55
|
-
for (const [rawId, rawRoleId] of Object.entries(input)) {
|
|
56
|
-
const entityId = normalizeText(rawId);
|
|
57
|
-
const roleId = normalizeText(rawRoleId);
|
|
58
|
-
if (!entityId || !roleId || !roles[roleId])
|
|
59
|
-
continue;
|
|
60
|
-
out[entityId] = roleId;
|
|
61
|
-
}
|
|
62
|
-
return out;
|
|
63
|
-
}
|
|
64
|
-
function normalizeChannelConfig(input, roles) {
|
|
65
|
-
const raw = input && typeof input === "object" && !Array.isArray(input)
|
|
66
|
-
? input
|
|
67
|
-
: {};
|
|
68
|
-
const defaultUserRoleId = normalizeText(raw.defaultUserRoleId) || "default";
|
|
69
|
-
return {
|
|
70
|
-
defaultUserRoleId: roles[defaultUserRoleId] ? defaultUserRoleId : "default",
|
|
71
|
-
userRoles: normalizeBindingMap(raw.userRoles, roles),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
function normalizeAuthorizationConfig(input) {
|
|
75
|
-
const raw = input && typeof input === "object" && !Array.isArray(input)
|
|
76
|
-
? input
|
|
77
|
-
: {};
|
|
78
|
-
const roles = normalizeRoleMap(raw.roles);
|
|
79
|
-
const channels = {};
|
|
80
|
-
for (const channel of CHAT_AUTHORIZATION_CHANNELS) {
|
|
81
|
-
channels[channel] = normalizeChannelConfig(raw.channels?.[channel], roles);
|
|
82
|
-
}
|
|
83
|
-
return { roles, channels };
|
|
84
|
-
}
|
|
85
|
-
function getChatAuthorizationConfigPath(projectRoot) {
|
|
86
|
-
return path.join(projectRoot, ".downcity", "chat", "authorization", "config.json");
|
|
87
|
-
}
|
|
88
|
-
function readConfigFile(projectRoot) {
|
|
89
|
-
const file = getChatAuthorizationConfigPath(projectRoot);
|
|
90
|
-
if (!fs.existsSync(file))
|
|
91
|
-
return normalizeAuthorizationConfig({});
|
|
92
|
-
try {
|
|
93
|
-
return normalizeAuthorizationConfig(fs.readJsonSync(file));
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
return normalizeAuthorizationConfig({});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
function writeConfigFile(projectRoot, config) {
|
|
100
|
-
const file = getChatAuthorizationConfigPath(projectRoot);
|
|
101
|
-
fs.ensureDirSync(path.dirname(file));
|
|
102
|
-
fs.writeJsonSync(file, normalizeAuthorizationConfig(config), { spaces: 2 });
|
|
103
|
-
return normalizeAuthorizationConfig(config);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* 同步读取 chat authorization 配置。
|
|
107
|
-
*/
|
|
108
|
-
export function readChatAuthorizationConfigSync(projectRoot) {
|
|
109
|
-
return readConfigFile(String(projectRoot || "").trim());
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* 读取 chat authorization 配置。
|
|
113
|
-
*/
|
|
114
|
-
export async function readChatAuthorizationConfig(projectRoot) {
|
|
115
|
-
return readChatAuthorizationConfigSync(projectRoot);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* 覆盖写入 chat authorization 配置。
|
|
119
|
-
*/
|
|
120
|
-
export async function writeChatAuthorizationConfig(projectRoot, nextConfig) {
|
|
121
|
-
return writeConfigFile(String(projectRoot || "").trim(), nextConfig);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* 设置单个用户角色。
|
|
125
|
-
*/
|
|
126
|
-
export async function setChatAuthorizationUserRole(params) {
|
|
127
|
-
const projectRoot = String(params.projectRoot || "").trim();
|
|
128
|
-
const userId = normalizeText(params.userId);
|
|
129
|
-
const roleId = normalizeText(params.roleId);
|
|
130
|
-
if (!projectRoot)
|
|
131
|
-
throw new Error("projectRoot is required");
|
|
132
|
-
if (!userId || !roleId)
|
|
133
|
-
throw new Error("userId and roleId are required");
|
|
134
|
-
const next = readConfigFile(projectRoot);
|
|
135
|
-
next.roles = normalizeRoleMap(next.roles);
|
|
136
|
-
if (!next.roles[roleId])
|
|
137
|
-
throw new Error(`Unknown roleId: ${roleId}`);
|
|
138
|
-
next.channels ??= {};
|
|
139
|
-
const channelConfig = normalizeChannelConfig(next.channels[params.channel], next.roles);
|
|
140
|
-
channelConfig.userRoles ??= {};
|
|
141
|
-
channelConfig.userRoles[userId] = roleId;
|
|
142
|
-
next.channels[params.channel] = channelConfig;
|
|
143
|
-
return writeConfigFile(projectRoot, next);
|
|
144
|
-
}
|
|
145
|
-
//# sourceMappingURL=Store.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Store.js","sourceRoot":"","sources":["../../../src/platform/chatAuthorization/Store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* City 级 chat authorization 配置存储。
|
|
3
|
-
*
|
|
4
|
-
* 关键点(中文)
|
|
5
|
-
* - 静态 chat 授权配置属于 city 维护的项目侧状态。
|
|
6
|
-
* - 这里把配置落在项目 `.downcity/chat/authorization/config.json`。
|
|
7
|
-
* - agent 只消费注入进来的读写能力,不再自己管理这份配置。
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import fs from "fs-extra";
|
|
11
|
-
import path from "node:path";
|
|
12
|
-
import type {
|
|
13
|
-
ChatAuthorizationChannel,
|
|
14
|
-
ChatAuthorizationConfig,
|
|
15
|
-
ChatAuthorizationRole,
|
|
16
|
-
ChatChannelAuthorizationConfig,
|
|
17
|
-
} from "@downcity/agent";
|
|
18
|
-
import {
|
|
19
|
-
CHAT_AUTHORIZATION_CHANNELS,
|
|
20
|
-
createDefaultChatAuthorizationRoles,
|
|
21
|
-
} from "@downcity/agent";
|
|
22
|
-
|
|
23
|
-
function normalizeText(value: unknown): string | undefined {
|
|
24
|
-
const text = String(value || "").trim();
|
|
25
|
-
return text || undefined;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function normalizeRoleMap(input: unknown): Record<string, ChatAuthorizationRole> {
|
|
29
|
-
const defaultRoles = createDefaultChatAuthorizationRoles();
|
|
30
|
-
if (!input || typeof input !== "object" || Array.isArray(input)) return defaultRoles;
|
|
31
|
-
const roles: Record<string, ChatAuthorizationRole> = {};
|
|
32
|
-
for (const [rawRoleId, rawRole] of Object.entries(input as Record<string, unknown>)) {
|
|
33
|
-
const roleId = normalizeText(rawRoleId);
|
|
34
|
-
if (!roleId) continue;
|
|
35
|
-
const roleObj =
|
|
36
|
-
rawRole && typeof rawRole === "object" && !Array.isArray(rawRole)
|
|
37
|
-
? (rawRole as {
|
|
38
|
-
name?: unknown;
|
|
39
|
-
description?: unknown;
|
|
40
|
-
permissions?: unknown[];
|
|
41
|
-
})
|
|
42
|
-
: null;
|
|
43
|
-
if (!roleObj) continue;
|
|
44
|
-
const builtinRole = defaultRoles[roleId];
|
|
45
|
-
const permissions = Array.isArray(roleObj.permissions)
|
|
46
|
-
? [...new Set(roleObj.permissions.map((item) => normalizeText(item)).filter(Boolean))]
|
|
47
|
-
: [];
|
|
48
|
-
roles[roleId] = {
|
|
49
|
-
roleId,
|
|
50
|
-
name: normalizeText(roleObj.name) || builtinRole?.name || roleId,
|
|
51
|
-
...(normalizeText(roleObj.description) || builtinRole?.description
|
|
52
|
-
? {
|
|
53
|
-
description:
|
|
54
|
-
normalizeText(roleObj.description) || builtinRole?.description || undefined,
|
|
55
|
-
}
|
|
56
|
-
: {}),
|
|
57
|
-
permissions: permissions as ChatAuthorizationRole["permissions"],
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
if (Object.keys(roles).length === 0) return defaultRoles;
|
|
61
|
-
if (!roles.default) roles.default = defaultRoles.default;
|
|
62
|
-
return roles;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function normalizeBindingMap(
|
|
66
|
-
input: unknown,
|
|
67
|
-
roles: Record<string, ChatAuthorizationRole>,
|
|
68
|
-
): Record<string, string> {
|
|
69
|
-
if (!input || typeof input !== "object" || Array.isArray(input)) return {};
|
|
70
|
-
const out: Record<string, string> = {};
|
|
71
|
-
for (const [rawId, rawRoleId] of Object.entries(input as Record<string, unknown>)) {
|
|
72
|
-
const entityId = normalizeText(rawId);
|
|
73
|
-
const roleId = normalizeText(rawRoleId);
|
|
74
|
-
if (!entityId || !roleId || !roles[roleId]) continue;
|
|
75
|
-
out[entityId] = roleId;
|
|
76
|
-
}
|
|
77
|
-
return out;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function normalizeChannelConfig(
|
|
81
|
-
input: unknown,
|
|
82
|
-
roles: Record<string, ChatAuthorizationRole>,
|
|
83
|
-
): ChatChannelAuthorizationConfig {
|
|
84
|
-
const raw =
|
|
85
|
-
input && typeof input === "object" && !Array.isArray(input)
|
|
86
|
-
? (input as {
|
|
87
|
-
defaultUserRoleId?: unknown;
|
|
88
|
-
userRoles?: unknown;
|
|
89
|
-
})
|
|
90
|
-
: {};
|
|
91
|
-
const defaultUserRoleId = normalizeText(raw.defaultUserRoleId) || "default";
|
|
92
|
-
return {
|
|
93
|
-
defaultUserRoleId: roles[defaultUserRoleId] ? defaultUserRoleId : "default",
|
|
94
|
-
userRoles: normalizeBindingMap(raw.userRoles, roles),
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function normalizeAuthorizationConfig(input: unknown): ChatAuthorizationConfig {
|
|
99
|
-
const raw =
|
|
100
|
-
input && typeof input === "object" && !Array.isArray(input)
|
|
101
|
-
? (input as { roles?: unknown; channels?: Record<string, unknown> })
|
|
102
|
-
: {};
|
|
103
|
-
const roles = normalizeRoleMap(raw.roles);
|
|
104
|
-
const channels: Partial<Record<ChatAuthorizationChannel, ChatChannelAuthorizationConfig>> = {};
|
|
105
|
-
for (const channel of CHAT_AUTHORIZATION_CHANNELS) {
|
|
106
|
-
channels[channel] = normalizeChannelConfig(raw.channels?.[channel], roles);
|
|
107
|
-
}
|
|
108
|
-
return { roles, channels };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function getChatAuthorizationConfigPath(projectRoot: string): string {
|
|
112
|
-
return path.join(projectRoot, ".downcity", "chat", "authorization", "config.json");
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function readConfigFile(projectRoot: string): ChatAuthorizationConfig {
|
|
116
|
-
const file = getChatAuthorizationConfigPath(projectRoot);
|
|
117
|
-
if (!fs.existsSync(file)) return normalizeAuthorizationConfig({});
|
|
118
|
-
try {
|
|
119
|
-
return normalizeAuthorizationConfig(fs.readJsonSync(file));
|
|
120
|
-
} catch {
|
|
121
|
-
return normalizeAuthorizationConfig({});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function writeConfigFile(projectRoot: string, config: ChatAuthorizationConfig): ChatAuthorizationConfig {
|
|
126
|
-
const file = getChatAuthorizationConfigPath(projectRoot);
|
|
127
|
-
fs.ensureDirSync(path.dirname(file));
|
|
128
|
-
fs.writeJsonSync(file, normalizeAuthorizationConfig(config), { spaces: 2 });
|
|
129
|
-
return normalizeAuthorizationConfig(config);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* 同步读取 chat authorization 配置。
|
|
134
|
-
*/
|
|
135
|
-
export function readChatAuthorizationConfigSync(projectRoot: string): ChatAuthorizationConfig {
|
|
136
|
-
return readConfigFile(String(projectRoot || "").trim());
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* 读取 chat authorization 配置。
|
|
141
|
-
*/
|
|
142
|
-
export async function readChatAuthorizationConfig(
|
|
143
|
-
projectRoot: string,
|
|
144
|
-
): Promise<ChatAuthorizationConfig> {
|
|
145
|
-
return readChatAuthorizationConfigSync(projectRoot);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 覆盖写入 chat authorization 配置。
|
|
150
|
-
*/
|
|
151
|
-
export async function writeChatAuthorizationConfig(
|
|
152
|
-
projectRoot: string,
|
|
153
|
-
nextConfig: ChatAuthorizationConfig,
|
|
154
|
-
): Promise<ChatAuthorizationConfig> {
|
|
155
|
-
return writeConfigFile(String(projectRoot || "").trim(), nextConfig);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* 设置单个用户角色。
|
|
160
|
-
*/
|
|
161
|
-
export async function setChatAuthorizationUserRole(params: {
|
|
162
|
-
projectRoot: string;
|
|
163
|
-
channel: ChatAuthorizationChannel;
|
|
164
|
-
userId: string;
|
|
165
|
-
roleId: string;
|
|
166
|
-
}): Promise<ChatAuthorizationConfig> {
|
|
167
|
-
const projectRoot = String(params.projectRoot || "").trim();
|
|
168
|
-
const userId = normalizeText(params.userId);
|
|
169
|
-
const roleId = normalizeText(params.roleId);
|
|
170
|
-
if (!projectRoot) throw new Error("projectRoot is required");
|
|
171
|
-
if (!userId || !roleId) throw new Error("userId and roleId are required");
|
|
172
|
-
const next = readConfigFile(projectRoot);
|
|
173
|
-
next.roles = normalizeRoleMap(next.roles);
|
|
174
|
-
if (!next.roles[roleId]) throw new Error(`Unknown roleId: ${roleId}`);
|
|
175
|
-
next.channels ??= {};
|
|
176
|
-
const channelConfig = normalizeChannelConfig(next.channels[params.channel], next.roles);
|
|
177
|
-
channelConfig.userRoles ??= {};
|
|
178
|
-
channelConfig.userRoles[userId] = roleId;
|
|
179
|
-
next.channels[params.channel] = channelConfig;
|
|
180
|
-
return writeConfigFile(projectRoot, next);
|
|
181
|
-
}
|