@koishi-ce/client 1.0.0
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/app/assets/logo.png +0 -0
- package/app/home/home.vue +51 -0
- package/app/home/index.ts +18 -0
- package/app/home/welcome.en-US.yml +9 -0
- package/app/home/welcome.vue +111 -0
- package/app/home/welcome.zh-CN.yml +9 -0
- package/app/index.html +13 -0
- package/app/index.scss +64 -0
- package/app/index.ts +32 -0
- package/app/layout/header.vue +187 -0
- package/app/layout/index.ts +15 -0
- package/app/layout/layout.vue +194 -0
- package/app/layout/menu-item.vue +60 -0
- package/app/settings/index.ts +39 -0
- package/app/settings/settings.vue +82 -0
- package/app/settings/theme.vue +123 -0
- package/app/shims.d.ts +1 -0
- package/app/status/index.ts +21 -0
- package/app/status/loading.vue +23 -0
- package/app/status/status.vue +56 -0
- package/app/styles/element.scss +217 -0
- package/app/styles/hc.scss +35 -0
- package/app/styles/index.scss +140 -0
- package/app/styles/index.ts +30 -0
- package/app/styles/layout.scss +92 -0
- package/app/theme/activity/button.vue +97 -0
- package/app/theme/activity/index.vue +119 -0
- package/app/theme/activity/item.vue +185 -0
- package/app/theme/activity/separator.vue +163 -0
- package/app/theme/activity/utils.ts +27 -0
- package/app/theme/blank.vue +24 -0
- package/app/theme/index.ts +37 -0
- package/app/theme/index.vue +34 -0
- package/app/theme/menu/index.vue +26 -0
- package/app/theme/menu/menu-item.vue +58 -0
- package/app/theme/menu/menu.vue +45 -0
- package/app/theme/status.vue +45 -0
- package/app/tsconfig.json +15 -0
- package/client/components/chat/image.vue +20 -0
- package/client/components/chat/overlay.vue +231 -0
- package/client/components/chat/utils.ts +6 -0
- package/client/components/common/index.ts +11 -0
- package/client/components/common/k-button.vue +127 -0
- package/client/components/common/k-hint.vue +62 -0
- package/client/components/common/k-tab.vue +50 -0
- package/client/components/dynamic.vue +61 -0
- package/client/components/icons/activity/default.vue +6 -0
- package/client/components/icons/activity/ellipsis.vue +6 -0
- package/client/components/icons/activity/home.vue +13 -0
- package/client/components/icons/activity/moon.vue +6 -0
- package/client/components/icons/activity/settings.vue +6 -0
- package/client/components/icons/activity/sun.vue +6 -0
- package/client/components/icons/index.ts +133 -0
- package/client/components/icons/style.scss +3 -0
- package/client/components/icons/svg/arrow-left.vue +6 -0
- package/client/components/icons/svg/arrow-right.vue +6 -0
- package/client/components/icons/svg/box-open.vue +6 -0
- package/client/components/icons/svg/check-full.vue +6 -0
- package/client/components/icons/svg/chevron-down.vue +6 -0
- package/client/components/icons/svg/chevron-left.vue +6 -0
- package/client/components/icons/svg/chevron-right.vue +6 -0
- package/client/components/icons/svg/chevron-up.vue +6 -0
- package/client/components/icons/svg/clipboard-list.vue +6 -0
- package/client/components/icons/svg/edit.vue +6 -0
- package/client/components/icons/svg/exclamation-full.vue +6 -0
- package/client/components/icons/svg/expand.vue +6 -0
- package/client/components/icons/svg/file-archive.vue +6 -0
- package/client/components/icons/svg/filter.vue +6 -0
- package/client/components/icons/svg/github.vue +6 -0
- package/client/components/icons/svg/gitlab.vue +6 -0
- package/client/components/icons/svg/info-full.vue +6 -0
- package/client/components/icons/svg/koishi.vue +6 -0
- package/client/components/icons/svg/link.vue +6 -0
- package/client/components/icons/svg/paper-plane.vue +6 -0
- package/client/components/icons/svg/question-empty.vue +6 -0
- package/client/components/icons/svg/redo.vue +6 -0
- package/client/components/icons/svg/search-minus.vue +6 -0
- package/client/components/icons/svg/search-plus.vue +6 -0
- package/client/components/icons/svg/search.vue +6 -0
- package/client/components/icons/svg/star-empty.vue +6 -0
- package/client/components/icons/svg/star-full.vue +6 -0
- package/client/components/icons/svg/start.vue +6 -0
- package/client/components/icons/svg/tag.vue +6 -0
- package/client/components/icons/svg/times-full.vue +6 -0
- package/client/components/icons/svg/tools.vue +6 -0
- package/client/components/icons/svg/undo.vue +6 -0
- package/client/components/icons/svg/user.vue +6 -0
- package/client/components/index.ts +75 -0
- package/client/components/layout/card.vue +69 -0
- package/client/components/layout/content.vue +37 -0
- package/client/components/layout/empty.vue +41 -0
- package/client/components/layout/index.ts +15 -0
- package/client/components/layout/tab-group.vue +45 -0
- package/client/components/layout/tab-item.vue +35 -0
- package/client/components/link.ts +39 -0
- package/client/components/perms.vue +73 -0
- package/client/components/slot.ts +95 -0
- package/client/context.ts +143 -0
- package/client/data.ts +178 -0
- package/client/index.ts +76 -0
- package/client/plugins/action.ts +251 -0
- package/client/plugins/i18n.ts +43 -0
- package/client/plugins/loader.ts +154 -0
- package/client/plugins/router.ts +278 -0
- package/client/plugins/setting.ts +217 -0
- package/client/plugins/theme.ts +134 -0
- package/client/shims.d.ts +55 -0
- package/client/tsconfig.json +15 -0
- package/client/utils.ts +36 -0
- package/global.d.ts +24 -0
- package/lib/bin.d.ts +1 -0
- package/lib/bin.mjs +112 -0
- package/lib/client-CaTn_gVG.mjs +125 -0
- package/lib/index.d.ts +20 -0
- package/lib/index.mjs +2 -0
- package/lib/src-Bxzzi1Rx.mjs +160 -0
- package/lib/yaml-UzQbvquH.mjs +23 -0
- package/package.json +66 -0
- package/src/bin.ts +61 -0
- package/src/index.ts +280 -0
- package/src/yaml.ts +22 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @koishi-ce/client 构建入口。
|
|
3
|
+
*
|
|
4
|
+
* 提供两个编程式 API(本仓库的前端构建没有 vite 配置文件,全部在此完成):
|
|
5
|
+
* - `build(root)`:构建单个 webui 插件的前端(`<插件目录>/client/` → `dist/`),
|
|
6
|
+
* 由 `koishi-console` CLI(src/bin.ts)暴露给各插件使用;
|
|
7
|
+
* - `createServer(baseDir)`:创建开发模式的 vite 中间件服务器。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { mkdir, rm } from "node:fs/promises";
|
|
12
|
+
import { resolve } from "node:path";
|
|
13
|
+
import vue from "@vitejs/plugin-vue";
|
|
14
|
+
import * as vite from "vite";
|
|
15
|
+
import { yaml } from "./yaml.ts";
|
|
16
|
+
|
|
17
|
+
// vite 8 基于 rolldown,rollup 已不在依赖树中;这里按实际消费的字段
|
|
18
|
+
// 局部声明构建产物类型(替代原先的 `import type { RollupOutput }`)
|
|
19
|
+
interface BuildResult {
|
|
20
|
+
output: Array<{
|
|
21
|
+
fileName: string;
|
|
22
|
+
type: string;
|
|
23
|
+
source?: string | Uint8Array;
|
|
24
|
+
code?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 将全部工作区包名映射到其源码目录,行为对齐根 tsconfig 的 paths 别名。
|
|
29
|
+
// 没有被任何工作区包依赖的插件(如 plugin-logger)不会出现在 node_modules
|
|
30
|
+
// 的链接里,bundler 无法按包名解析,必须显式提供这层映射。
|
|
31
|
+
async function collectWorkspaceAliases(): Promise<Record<string, string>> {
|
|
32
|
+
// 源码形态(src/)与产物形态(lib/)都在包根下一级,上跳四级到仓库根一致
|
|
33
|
+
const repoRoot = resolve(import.meta.dir, "../../../..").replace(/\\/g, "/");
|
|
34
|
+
const manifest = await Bun.file(`${repoRoot}/package.json`).json();
|
|
35
|
+
const aliases: Record<string, string> = {};
|
|
36
|
+
for (const pattern of manifest.workspaces ?? []) {
|
|
37
|
+
// scanSync 产出的相对路径在 Windows 上是反斜杠,统一归一化为正斜杠
|
|
38
|
+
const files = new Bun.Glob(`${pattern}/package.json`).scanSync({
|
|
39
|
+
cwd: repoRoot,
|
|
40
|
+
});
|
|
41
|
+
for (const file of files) {
|
|
42
|
+
const rel = file.replaceAll("\\", "/");
|
|
43
|
+
const dir = `${repoRoot}/${rel.slice(0, -"/package.json".length)}`;
|
|
44
|
+
try {
|
|
45
|
+
const { name } = await Bun.file(`${dir}/package.json`).json();
|
|
46
|
+
if (!name) continue;
|
|
47
|
+
// 控制台前端语境下,裸包名对到浏览器端入口(替代上游 lib 的 browser
|
|
48
|
+
// 导出条件);`<name>/src` 子路径对到源码目录,供共享代码引用;
|
|
49
|
+
// `<name>/client` 子路径对到浏览器端入口(上游生态以该子路径跨插件
|
|
50
|
+
// 引用彼此的 client API,如 market 引用 config 的 EnvInfo 类型,
|
|
51
|
+
// 上游与 npm 产物的 exports 均未声明它,同样靠仓库内别名解析)。
|
|
52
|
+
// 子路径键必须先插入——别名解析按插入序取首个命中项
|
|
53
|
+
const clientEntry = `${dir}/client/index.ts`;
|
|
54
|
+
if (existsSync(`${dir}/src`)) aliases[`${name}/src`] = `${dir}/src`;
|
|
55
|
+
if (existsSync(clientEntry)) aliases[`${name}/client`] = clientEntry;
|
|
56
|
+
aliases[name] = existsSync(clientEntry) ? clientEntry : `${dir}/src`;
|
|
57
|
+
} catch {}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return aliases;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const workspaceAliases = await collectWorkspaceAliases();
|
|
64
|
+
|
|
65
|
+
// 虚拟子路径 "schemastery-vue/client" 的运行时载体(补齐真实包缺失的
|
|
66
|
+
// SchemaBase 具名导出)绝对路径,从 components 包的工作区别名推导;
|
|
67
|
+
// 类型面由根 tsconfig.client.json 的 paths 解析到 schemastery-vue-client.ts
|
|
68
|
+
const runtimeShimPath = (
|
|
69
|
+
workspaceAliases["@koishi-ce/components"] ?? ""
|
|
70
|
+
).replace(/client\/index\.ts$/, "client/schemastery-vue-runtime.ts");
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 构建单个 webui 插件的前端产物。
|
|
74
|
+
*
|
|
75
|
+
* @param root 插件目录(无 `client/` 子目录时视为该插件没有前端,直接跳过)
|
|
76
|
+
* @param config 额外的 vite 配置,逐层合并覆盖下方默认值
|
|
77
|
+
*/
|
|
78
|
+
export async function build(root: string, config: vite.UserConfig = {}) {
|
|
79
|
+
if (!existsSync(`${root}/client`)) return;
|
|
80
|
+
|
|
81
|
+
// 产物约定:固定写入插件目录下的 dist/,清空后重建
|
|
82
|
+
const outDir = `${root}/dist`;
|
|
83
|
+
if (existsSync(outDir)) {
|
|
84
|
+
await rm(outDir, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
await mkdir(outDir, { recursive: true });
|
|
87
|
+
|
|
88
|
+
const results = (await vite.build(
|
|
89
|
+
vite.mergeConfig(
|
|
90
|
+
{
|
|
91
|
+
root,
|
|
92
|
+
build: {
|
|
93
|
+
write: false,
|
|
94
|
+
outDir: "dist",
|
|
95
|
+
assetsDir: "",
|
|
96
|
+
minify: true,
|
|
97
|
+
emptyOutDir: true,
|
|
98
|
+
commonjsOptions: {
|
|
99
|
+
strictRequires: true,
|
|
100
|
+
},
|
|
101
|
+
lib: {
|
|
102
|
+
entry: `${root}/client/index.ts`,
|
|
103
|
+
fileName: "index",
|
|
104
|
+
formats: ["es"],
|
|
105
|
+
},
|
|
106
|
+
rollupOptions: {
|
|
107
|
+
makeAbsoluteExternalsRelative: true,
|
|
108
|
+
// unocss 全局模式插件在扫描阶段会对 "virtual:uno.css" 二次
|
|
109
|
+
// resolve 并误报为多文件导入(单构建内即触发,与并发无关),
|
|
110
|
+
// 仓库侧无法根治,直接静默
|
|
111
|
+
onwarn(warning, warn) {
|
|
112
|
+
if (
|
|
113
|
+
warning.message.includes("is being imported multiple times")
|
|
114
|
+
) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
warn(warning);
|
|
118
|
+
},
|
|
119
|
+
// 运行时由宿主控制台提供的共享依赖(vue.js / client.js 等),
|
|
120
|
+
// 不打入插件产物,插件在浏览器中向宿主索取
|
|
121
|
+
external: [
|
|
122
|
+
"vue",
|
|
123
|
+
"vue-router",
|
|
124
|
+
"@vueuse/core",
|
|
125
|
+
"@koishi-ce/client",
|
|
126
|
+
],
|
|
127
|
+
output: {
|
|
128
|
+
format: "iife",
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
plugins: [
|
|
133
|
+
vue(),
|
|
134
|
+
yaml(),
|
|
135
|
+
(
|
|
136
|
+
await import("unocss/vite")
|
|
137
|
+
).default({
|
|
138
|
+
presets: [
|
|
139
|
+
(
|
|
140
|
+
await import("unocss/preset-mini")
|
|
141
|
+
).default({
|
|
142
|
+
preflight: false,
|
|
143
|
+
}),
|
|
144
|
+
],
|
|
145
|
+
}),
|
|
146
|
+
],
|
|
147
|
+
resolve: {
|
|
148
|
+
alias: {
|
|
149
|
+
...workspaceAliases,
|
|
150
|
+
// 插件侧不打包 vue-i18n 本体,运行时复用宿主 client 包
|
|
151
|
+
// 再导出的实例(配合上面的 external 生效)
|
|
152
|
+
"vue-i18n": "@koishi-ce/client",
|
|
153
|
+
// 组件库同样经由宿主 client 包提供,避免每个插件
|
|
154
|
+
// 都把整套组件库重复打进产物
|
|
155
|
+
"@koishi-ce/components": "@koishi-ce/client",
|
|
156
|
+
// market 插件的 client 依赖 npm 包 @koishijs/market(上游以
|
|
157
|
+
// 源码发布的组件库),其内部以 npm 名引用组件库;重定向到
|
|
158
|
+
// 本仓库同版本(1.5.22)components 源码,避免 npm 版整套
|
|
159
|
+
// 组件库被打进插件产物
|
|
160
|
+
"@koishijs/components": workspaceAliases["@koishi-ce/components"],
|
|
161
|
+
// 虚拟子路径的运行时载体(补齐真实包缺失的 SchemaBase
|
|
162
|
+
// 具名导出);类型面由 tsconfig.client.json 的 paths
|
|
163
|
+
// 解析到 schemastery-vue-client.ts
|
|
164
|
+
"schemastery-vue/client": runtimeShimPath,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
define: {
|
|
168
|
+
"process.env.NODE_ENV": '"production"',
|
|
169
|
+
},
|
|
170
|
+
} as vite.InlineConfig,
|
|
171
|
+
config,
|
|
172
|
+
),
|
|
173
|
+
)) as BuildResult[];
|
|
174
|
+
|
|
175
|
+
// build.write: false 让构建结果留在内存里,由这里手动落盘,
|
|
176
|
+
// 以便对文件名和 JS 产物做后处理
|
|
177
|
+
for (const item of results[0]?.output ?? []) {
|
|
178
|
+
// lib es 格式的产物名是 index.mjs,统一改名为 index.js
|
|
179
|
+
// (rolldown 的 output 条目是冻结对象,不能原地改写)
|
|
180
|
+
const fileName = item.fileName === "index.mjs" ? "index.js" : item.fileName;
|
|
181
|
+
const dest = `${root}/dist/${fileName}`;
|
|
182
|
+
if (item.type === "asset") {
|
|
183
|
+
if (item.source === undefined) continue;
|
|
184
|
+
await Bun.write(dest, item.source);
|
|
185
|
+
} else if (item.code !== undefined) {
|
|
186
|
+
// JS 产物再过一次 rolldown 的 minify:仅压缩空白、不动标识符
|
|
187
|
+
// (compress/mangle 均由上面的 minify: true 完成),oxc 原生按
|
|
188
|
+
// UTF-8 输出,中文等非 ASCII 字符不会被转义成 \u 序列。
|
|
189
|
+
// 替代已废弃的 transformWithEsbuild(其 minifyWhitespace+charset
|
|
190
|
+
// 组合在此等价于 compress:false + mangle:false 的默认 codegen)
|
|
191
|
+
const { code } = await vite.minify(dest, item.code, {
|
|
192
|
+
compress: false,
|
|
193
|
+
mangle: false,
|
|
194
|
+
});
|
|
195
|
+
await Bun.write(dest, code);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* 创建开发模式下的 vite dev server(middlewareMode,不监听独立端口,
|
|
202
|
+
* 由宿主 HTTP 服务挂载到 `/vite/` 前缀下)。
|
|
203
|
+
*
|
|
204
|
+
* @param baseDir 用于圈定文件访问范围的工作区根目录
|
|
205
|
+
* @param config 额外的 vite 配置
|
|
206
|
+
* @returns vite 的 ViteDevServer 实例
|
|
207
|
+
*/
|
|
208
|
+
export async function createServer(
|
|
209
|
+
baseDir: string,
|
|
210
|
+
config: vite.InlineConfig = {},
|
|
211
|
+
) {
|
|
212
|
+
// 开发模式下以本包的 app/ 宿主应用为入口
|
|
213
|
+
// (源码 src/ 与产物 lib/ 都在包根下一级,相对定位两者一致)
|
|
214
|
+
const root = resolve(import.meta.dir, "../app");
|
|
215
|
+
return vite.createServer(
|
|
216
|
+
vite.mergeConfig(
|
|
217
|
+
{
|
|
218
|
+
root,
|
|
219
|
+
base: "/vite/",
|
|
220
|
+
server: {
|
|
221
|
+
middlewareMode: true,
|
|
222
|
+
fs: {
|
|
223
|
+
allow: [vite.searchForWorkspaceRoot(baseDir)],
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
plugins: [
|
|
227
|
+
vue(),
|
|
228
|
+
yaml(),
|
|
229
|
+
(await import("unocss/vite")).default({
|
|
230
|
+
presets: [
|
|
231
|
+
(await import("unocss/preset-mini")).default({
|
|
232
|
+
preflight: false,
|
|
233
|
+
}),
|
|
234
|
+
],
|
|
235
|
+
}),
|
|
236
|
+
],
|
|
237
|
+
resolve: {
|
|
238
|
+
// 强制这些依赖全局单实例,避免不同副本并存导致
|
|
239
|
+
// (例如多个 vue 实例)运行异常
|
|
240
|
+
dedupe: [
|
|
241
|
+
"vue",
|
|
242
|
+
"vue-demi",
|
|
243
|
+
"vue-router",
|
|
244
|
+
"element-plus",
|
|
245
|
+
"@vueuse/core",
|
|
246
|
+
"@popperjs/core",
|
|
247
|
+
"marked",
|
|
248
|
+
"xss",
|
|
249
|
+
],
|
|
250
|
+
alias: {
|
|
251
|
+
// 向后兼容:旧式插件以相对路径引用宿主共享包
|
|
252
|
+
"../client.js": "@koishi-ce/client",
|
|
253
|
+
"../vue.js": "vue",
|
|
254
|
+
"../vue-router.js": "vue-router",
|
|
255
|
+
"../vueuse.js": "@vueuse/core",
|
|
256
|
+
// 虚拟子路径的运行时载体(同 build 的别名说明)
|
|
257
|
+
"schemastery-vue/client": runtimeShimPath,
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
optimizeDeps: {
|
|
261
|
+
include: [
|
|
262
|
+
"vue",
|
|
263
|
+
"vue-router",
|
|
264
|
+
"element-plus",
|
|
265
|
+
"@vueuse/core",
|
|
266
|
+
"@popperjs/core",
|
|
267
|
+
"marked",
|
|
268
|
+
"xss",
|
|
269
|
+
],
|
|
270
|
+
},
|
|
271
|
+
build: {
|
|
272
|
+
rollupOptions: {
|
|
273
|
+
input: `${root}/index.html`,
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
} as vite.InlineConfig,
|
|
277
|
+
config,
|
|
278
|
+
),
|
|
279
|
+
);
|
|
280
|
+
}
|
package/src/yaml.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* .yml/.yaml → JS 模块的 vite 转换插件(替代 @maikolib/vite-plugin-yaml)。
|
|
5
|
+
*
|
|
6
|
+
* 构建脚本统一以 Bun 执行,YAML 解析走 Bun 内置的 Bun.YAML,不再引入 js-yaml
|
|
7
|
+
* (其 4.1.0 版本存在 GHSA-52cp-r559-cp3m / GHSA-5p4m-2wfm-xmqj 高危通告)。
|
|
8
|
+
* 行为对齐原插件:默认导出解析结果,不产出 sourcemap 映射。
|
|
9
|
+
*/
|
|
10
|
+
export function yaml(): Plugin {
|
|
11
|
+
return {
|
|
12
|
+
name: "vite:transform-yaml",
|
|
13
|
+
transform(code, id) {
|
|
14
|
+
if (!/\.ya?ml$/.test(id)) return null;
|
|
15
|
+
const data = Bun.YAML.parse(code);
|
|
16
|
+
return {
|
|
17
|
+
code: `const data = ${JSON.stringify(data)};\nexport default data;`,
|
|
18
|
+
map: { mappings: "" },
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|