@yunzai-ng/core 0.1.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.
Files changed (357) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +51 -0
  3. package/dist/adapter/accounts.d.ts +174 -0
  4. package/dist/adapter/accounts.d.ts.map +1 -0
  5. package/dist/adapter/accounts.js +653 -0
  6. package/dist/adapter/accounts.js.map +1 -0
  7. package/dist/adapter/bots.d.ts +142 -0
  8. package/dist/adapter/bots.d.ts.map +1 -0
  9. package/dist/adapter/bots.js +454 -0
  10. package/dist/adapter/bots.js.map +1 -0
  11. package/dist/adapter/host.d.ts +114 -0
  12. package/dist/adapter/host.d.ts.map +1 -0
  13. package/dist/adapter/host.js +90 -0
  14. package/dist/adapter/host.js.map +1 -0
  15. package/dist/adapter/login.d.ts +174 -0
  16. package/dist/adapter/login.d.ts.map +1 -0
  17. package/dist/adapter/login.js +345 -0
  18. package/dist/adapter/login.js.map +1 -0
  19. package/dist/adapter/registry.d.ts +102 -0
  20. package/dist/adapter/registry.d.ts.map +1 -0
  21. package/dist/adapter/registry.js +150 -0
  22. package/dist/adapter/registry.js.map +1 -0
  23. package/dist/config/core-config.d.ts +151 -0
  24. package/dist/config/core-config.d.ts.map +1 -0
  25. package/dist/config/core-config.js +338 -0
  26. package/dist/config/core-config.js.map +1 -0
  27. package/dist/config/schema.d.ts +449 -0
  28. package/dist/config/schema.d.ts.map +1 -0
  29. package/dist/config/schema.js +871 -0
  30. package/dist/config/schema.js.map +1 -0
  31. package/dist/config/store.d.ts +184 -0
  32. package/dist/config/store.d.ts.map +1 -0
  33. package/dist/config/store.js +428 -0
  34. package/dist/config/store.js.map +1 -0
  35. package/dist/config/yaml.d.ts +23 -0
  36. package/dist/config/yaml.d.ts.map +1 -0
  37. package/dist/config/yaml.js +108 -0
  38. package/dist/config/yaml.js.map +1 -0
  39. package/dist/http/client.d.ts +82 -0
  40. package/dist/http/client.d.ts.map +1 -0
  41. package/dist/http/client.js +658 -0
  42. package/dist/http/client.js.map +1 -0
  43. package/dist/index.d.ts +77 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +94 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/kernel/app.d.ts +244 -0
  48. package/dist/kernel/app.d.ts.map +1 -0
  49. package/dist/kernel/app.js +654 -0
  50. package/dist/kernel/app.js.map +1 -0
  51. package/dist/kernel/kv-sink.d.ts +34 -0
  52. package/dist/kernel/kv-sink.d.ts.map +1 -0
  53. package/dist/kernel/kv-sink.js +25 -0
  54. package/dist/kernel/kv-sink.js.map +1 -0
  55. package/dist/kernel/policy.d.ts +77 -0
  56. package/dist/kernel/policy.d.ts.map +1 -0
  57. package/dist/kernel/policy.js +99 -0
  58. package/dist/kernel/policy.js.map +1 -0
  59. package/dist/kernel/runtime.d.ts +117 -0
  60. package/dist/kernel/runtime.d.ts.map +1 -0
  61. package/dist/kernel/runtime.js +197 -0
  62. package/dist/kernel/runtime.js.map +1 -0
  63. package/dist/kernel/sql-sink.d.ts +36 -0
  64. package/dist/kernel/sql-sink.d.ts.map +1 -0
  65. package/dist/kernel/sql-sink.js +114 -0
  66. package/dist/kernel/sql-sink.js.map +1 -0
  67. package/dist/logger/format.d.ts +67 -0
  68. package/dist/logger/format.d.ts.map +1 -0
  69. package/dist/logger/format.js +218 -0
  70. package/dist/logger/format.js.map +1 -0
  71. package/dist/logger/index.d.ts +97 -0
  72. package/dist/logger/index.d.ts.map +1 -0
  73. package/dist/logger/index.js +363 -0
  74. package/dist/logger/index.js.map +1 -0
  75. package/dist/logger/rotate.d.ts +47 -0
  76. package/dist/logger/rotate.d.ts.map +1 -0
  77. package/dist/logger/rotate.js +242 -0
  78. package/dist/logger/rotate.js.map +1 -0
  79. package/dist/message/segment.d.ts +255 -0
  80. package/dist/message/segment.d.ts.map +1 -0
  81. package/dist/message/segment.js +510 -0
  82. package/dist/message/segment.js.map +1 -0
  83. package/dist/message/split.d.ts +34 -0
  84. package/dist/message/split.d.ts.map +1 -0
  85. package/dist/message/split.js +79 -0
  86. package/dist/message/split.js.map +1 -0
  87. package/dist/message/target.d.ts +29 -0
  88. package/dist/message/target.d.ts.map +1 -0
  89. package/dist/message/target.js +34 -0
  90. package/dist/message/target.js.map +1 -0
  91. package/dist/pipeline/cooldown.d.ts +84 -0
  92. package/dist/pipeline/cooldown.d.ts.map +1 -0
  93. package/dist/pipeline/cooldown.js +94 -0
  94. package/dist/pipeline/cooldown.js.map +1 -0
  95. package/dist/pipeline/dispatch.d.ts +98 -0
  96. package/dist/pipeline/dispatch.d.ts.map +1 -0
  97. package/dist/pipeline/dispatch.js +323 -0
  98. package/dist/pipeline/dispatch.js.map +1 -0
  99. package/dist/pipeline/event.d.ts +130 -0
  100. package/dist/pipeline/event.d.ts.map +1 -0
  101. package/dist/pipeline/event.js +538 -0
  102. package/dist/pipeline/event.js.map +1 -0
  103. package/dist/pipeline/middleware.d.ts +63 -0
  104. package/dist/pipeline/middleware.d.ts.map +1 -0
  105. package/dist/pipeline/middleware.js +174 -0
  106. package/dist/pipeline/middleware.js.map +1 -0
  107. package/dist/pipeline/prompt.d.ts +80 -0
  108. package/dist/pipeline/prompt.d.ts.map +1 -0
  109. package/dist/pipeline/prompt.js +155 -0
  110. package/dist/pipeline/prompt.js.map +1 -0
  111. package/dist/pipeline/router.d.ts +98 -0
  112. package/dist/pipeline/router.d.ts.map +1 -0
  113. package/dist/pipeline/router.js +489 -0
  114. package/dist/pipeline/router.js.map +1 -0
  115. package/dist/platform/detect.d.ts +24 -0
  116. package/dist/platform/detect.d.ts.map +1 -0
  117. package/dist/platform/detect.js +178 -0
  118. package/dist/platform/detect.js.map +1 -0
  119. package/dist/platform/paths.d.ts +38 -0
  120. package/dist/platform/paths.d.ts.map +1 -0
  121. package/dist/platform/paths.js +129 -0
  122. package/dist/platform/paths.js.map +1 -0
  123. package/dist/platform/system.d.ts +71 -0
  124. package/dist/platform/system.d.ts.map +1 -0
  125. package/dist/platform/system.js +242 -0
  126. package/dist/platform/system.js.map +1 -0
  127. package/dist/plugin/context.d.ts +92 -0
  128. package/dist/plugin/context.d.ts.map +1 -0
  129. package/dist/plugin/context.js +573 -0
  130. package/dist/plugin/context.js.map +1 -0
  131. package/dist/plugin/define.d.ts +92 -0
  132. package/dist/plugin/define.d.ts.map +1 -0
  133. package/dist/plugin/define.js +82 -0
  134. package/dist/plugin/define.js.map +1 -0
  135. package/dist/plugin/discover.d.ts +106 -0
  136. package/dist/plugin/discover.d.ts.map +1 -0
  137. package/dist/plugin/discover.js +254 -0
  138. package/dist/plugin/discover.js.map +1 -0
  139. package/dist/plugin/events.d.ts +109 -0
  140. package/dist/plugin/events.d.ts.map +1 -0
  141. package/dist/plugin/events.js +209 -0
  142. package/dist/plugin/events.js.map +1 -0
  143. package/dist/plugin/hooks.d.ts +266 -0
  144. package/dist/plugin/hooks.d.ts.map +1 -0
  145. package/dist/plugin/hooks.js +84 -0
  146. package/dist/plugin/hooks.js.map +1 -0
  147. package/dist/plugin/host.d.ts +160 -0
  148. package/dist/plugin/host.d.ts.map +1 -0
  149. package/dist/plugin/host.js +546 -0
  150. package/dist/plugin/host.js.map +1 -0
  151. package/dist/plugin/market.d.ts +264 -0
  152. package/dist/plugin/market.d.ts.map +1 -0
  153. package/dist/plugin/market.js +700 -0
  154. package/dist/plugin/market.js.map +1 -0
  155. package/dist/plugin/services.d.ts +116 -0
  156. package/dist/plugin/services.d.ts.map +1 -0
  157. package/dist/plugin/services.js +213 -0
  158. package/dist/plugin/services.js.map +1 -0
  159. package/dist/plugin/tar.d.ts +65 -0
  160. package/dist/plugin/tar.d.ts.map +1 -0
  161. package/dist/plugin/tar.js +277 -0
  162. package/dist/plugin/tar.js.map +1 -0
  163. package/dist/render/registry.d.ts +127 -0
  164. package/dist/render/registry.d.ts.map +1 -0
  165. package/dist/render/registry.js +306 -0
  166. package/dist/render/registry.js.map +1 -0
  167. package/dist/scheduler/index.d.ts +67 -0
  168. package/dist/scheduler/index.d.ts.map +1 -0
  169. package/dist/scheduler/index.js +279 -0
  170. package/dist/scheduler/index.js.map +1 -0
  171. package/dist/server/api.d.ts +179 -0
  172. package/dist/server/api.d.ts.map +1 -0
  173. package/dist/server/api.js +602 -0
  174. package/dist/server/api.js.map +1 -0
  175. package/dist/server/auth.d.ts +83 -0
  176. package/dist/server/auth.d.ts.map +1 -0
  177. package/dist/server/auth.js +178 -0
  178. package/dist/server/auth.js.map +1 -0
  179. package/dist/server/browse.d.ts +60 -0
  180. package/dist/server/browse.d.ts.map +1 -0
  181. package/dist/server/browse.js +187 -0
  182. package/dist/server/browse.js.map +1 -0
  183. package/dist/server/files.d.ts +27 -0
  184. package/dist/server/files.d.ts.map +1 -0
  185. package/dist/server/files.js +76 -0
  186. package/dist/server/files.js.map +1 -0
  187. package/dist/server/index.d.ts +189 -0
  188. package/dist/server/index.d.ts.map +1 -0
  189. package/dist/server/index.js +1123 -0
  190. package/dist/server/index.js.map +1 -0
  191. package/dist/server/table.d.ts +105 -0
  192. package/dist/server/table.d.ts.map +1 -0
  193. package/dist/server/table.js +289 -0
  194. package/dist/server/table.js.map +1 -0
  195. package/dist/store/index.d.ts +50 -0
  196. package/dist/store/index.d.ts.map +1 -0
  197. package/dist/store/index.js +120 -0
  198. package/dist/store/index.js.map +1 -0
  199. package/dist/store/json.d.ts +73 -0
  200. package/dist/store/json.d.ts.map +1 -0
  201. package/dist/store/json.js +174 -0
  202. package/dist/store/json.js.map +1 -0
  203. package/dist/store/kv.d.ts +126 -0
  204. package/dist/store/kv.d.ts.map +1 -0
  205. package/dist/store/kv.js +232 -0
  206. package/dist/store/kv.js.map +1 -0
  207. package/dist/store/level.d.ts +103 -0
  208. package/dist/store/level.d.ts.map +1 -0
  209. package/dist/store/level.js +119 -0
  210. package/dist/store/level.js.map +1 -0
  211. package/dist/store/memory.d.ts +61 -0
  212. package/dist/store/memory.d.ts.map +1 -0
  213. package/dist/store/memory.js +94 -0
  214. package/dist/store/memory.js.map +1 -0
  215. package/dist/store/sql.d.ts +142 -0
  216. package/dist/store/sql.d.ts.map +1 -0
  217. package/dist/store/sql.js +246 -0
  218. package/dist/store/sql.js.map +1 -0
  219. package/dist/testing/fake.d.ts +109 -0
  220. package/dist/testing/fake.d.ts.map +1 -0
  221. package/dist/testing/fake.js +196 -0
  222. package/dist/testing/fake.js.map +1 -0
  223. package/dist/testing/index.d.ts +16 -0
  224. package/dist/testing/index.d.ts.map +1 -0
  225. package/dist/testing/index.js +16 -0
  226. package/dist/testing/index.js.map +1 -0
  227. package/dist/testing/mock-adapter.d.ts +205 -0
  228. package/dist/testing/mock-adapter.d.ts.map +1 -0
  229. package/dist/testing/mock-adapter.js +309 -0
  230. package/dist/testing/mock-adapter.js.map +1 -0
  231. package/dist/util/deep.d.ts +108 -0
  232. package/dist/util/deep.d.ts.map +1 -0
  233. package/dist/util/deep.js +275 -0
  234. package/dist/util/deep.js.map +1 -0
  235. package/dist/util/defer.d.ts +107 -0
  236. package/dist/util/defer.d.ts.map +1 -0
  237. package/dist/util/defer.js +163 -0
  238. package/dist/util/defer.js.map +1 -0
  239. package/dist/util/dispose.d.ts +88 -0
  240. package/dist/util/dispose.d.ts.map +1 -0
  241. package/dist/util/dispose.js +143 -0
  242. package/dist/util/dispose.js.map +1 -0
  243. package/dist/util/duration.d.ts +28 -0
  244. package/dist/util/duration.d.ts.map +1 -0
  245. package/dist/util/duration.js +77 -0
  246. package/dist/util/duration.js.map +1 -0
  247. package/dist/util/fs.d.ts +110 -0
  248. package/dist/util/fs.d.ts.map +1 -0
  249. package/dist/util/fs.js +269 -0
  250. package/dist/util/fs.js.map +1 -0
  251. package/dist/util/id.d.ts +49 -0
  252. package/dist/util/id.d.ts.map +1 -0
  253. package/dist/util/id.js +87 -0
  254. package/dist/util/id.js.map +1 -0
  255. package/dist/util/lru.d.ts +74 -0
  256. package/dist/util/lru.d.ts.map +1 -0
  257. package/dist/util/lru.js +156 -0
  258. package/dist/util/lru.js.map +1 -0
  259. package/dist/util/queue.d.ts +64 -0
  260. package/dist/util/queue.d.ts.map +1 -0
  261. package/dist/util/queue.js +147 -0
  262. package/dist/util/queue.js.map +1 -0
  263. package/dist/util/text.d.ts +86 -0
  264. package/dist/util/text.d.ts.map +1 -0
  265. package/dist/util/text.js +182 -0
  266. package/dist/util/text.js.map +1 -0
  267. package/package.json +44 -0
  268. package/src/adapter/accounts.ts +758 -0
  269. package/src/adapter/bots.ts +582 -0
  270. package/src/adapter/host.ts +224 -0
  271. package/src/adapter/login.ts +481 -0
  272. package/src/adapter/registry.ts +202 -0
  273. package/src/config/core-config.test.ts +60 -0
  274. package/src/config/core-config.ts +401 -0
  275. package/src/config/schema.test.ts +179 -0
  276. package/src/config/schema.ts +1036 -0
  277. package/src/config/store.test.ts +245 -0
  278. package/src/config/store.ts +506 -0
  279. package/src/config/yaml.ts +119 -0
  280. package/src/http/client.test.ts +568 -0
  281. package/src/http/client.ts +777 -0
  282. package/src/index.ts +106 -0
  283. package/src/kernel/app.test.ts +267 -0
  284. package/src/kernel/app.ts +843 -0
  285. package/src/kernel/kv-sink.ts +58 -0
  286. package/src/kernel/policy.ts +120 -0
  287. package/src/kernel/runtime.test.ts +542 -0
  288. package/src/kernel/runtime.ts +307 -0
  289. package/src/kernel/sql-sink.ts +154 -0
  290. package/src/logger/format.ts +259 -0
  291. package/src/logger/index.ts +427 -0
  292. package/src/logger/rotate.ts +265 -0
  293. package/src/message/segment.test.ts +335 -0
  294. package/src/message/segment.ts +569 -0
  295. package/src/message/split.ts +97 -0
  296. package/src/message/target.ts +48 -0
  297. package/src/pipeline/cooldown.ts +136 -0
  298. package/src/pipeline/dispatch.ts +419 -0
  299. package/src/pipeline/event.ts +735 -0
  300. package/src/pipeline/middleware.test.ts +426 -0
  301. package/src/pipeline/middleware.ts +199 -0
  302. package/src/pipeline/prompt.ts +212 -0
  303. package/src/pipeline/router.test.ts +432 -0
  304. package/src/pipeline/router.ts +575 -0
  305. package/src/platform/detect.ts +178 -0
  306. package/src/platform/paths.ts +147 -0
  307. package/src/platform/system.test.ts +102 -0
  308. package/src/platform/system.ts +289 -0
  309. package/src/plugin/context.test.ts +459 -0
  310. package/src/plugin/context.ts +757 -0
  311. package/src/plugin/define.test.ts +120 -0
  312. package/src/plugin/define.ts +142 -0
  313. package/src/plugin/discover.test.ts +253 -0
  314. package/src/plugin/discover.ts +353 -0
  315. package/src/plugin/events.test.ts +162 -0
  316. package/src/plugin/events.ts +266 -0
  317. package/src/plugin/hooks.ts +373 -0
  318. package/src/plugin/host.test.ts +696 -0
  319. package/src/plugin/host.ts +738 -0
  320. package/src/plugin/market.test.ts +781 -0
  321. package/src/plugin/market.ts +870 -0
  322. package/src/plugin/services.test.ts +135 -0
  323. package/src/plugin/services.ts +261 -0
  324. package/src/plugin/tar.test.ts +158 -0
  325. package/src/plugin/tar.ts +309 -0
  326. package/src/render/registry.test.ts +127 -0
  327. package/src/render/registry.ts +439 -0
  328. package/src/scheduler/index.ts +357 -0
  329. package/src/server/api.test.ts +802 -0
  330. package/src/server/api.ts +869 -0
  331. package/src/server/auth.ts +201 -0
  332. package/src/server/browse.test.ts +193 -0
  333. package/src/server/browse.ts +240 -0
  334. package/src/server/files.ts +97 -0
  335. package/src/server/index.test.ts +566 -0
  336. package/src/server/index.ts +1386 -0
  337. package/src/server/table.ts +351 -0
  338. package/src/store/index.ts +156 -0
  339. package/src/store/json.ts +198 -0
  340. package/src/store/kv.test.ts +307 -0
  341. package/src/store/kv.ts +256 -0
  342. package/src/store/level.ts +167 -0
  343. package/src/store/memory.ts +109 -0
  344. package/src/store/sql.test.ts +204 -0
  345. package/src/store/sql.ts +324 -0
  346. package/src/testing/fake.ts +297 -0
  347. package/src/testing/index.ts +15 -0
  348. package/src/testing/mock-adapter.ts +588 -0
  349. package/src/util/deep.ts +272 -0
  350. package/src/util/defer.ts +211 -0
  351. package/src/util/dispose.ts +169 -0
  352. package/src/util/duration.ts +82 -0
  353. package/src/util/fs.ts +279 -0
  354. package/src/util/id.ts +94 -0
  355. package/src/util/lru.ts +185 -0
  356. package/src/util/queue.ts +167 -0
  357. package/src/util/text.ts +189 -0
package/src/index.ts ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * 模块职责:`@yunzai-ng/core` 的唯一入口,汇总导出内核各模块的公开符号
3
+ * 依赖方向:只做转发,本身不含逻辑
4
+ * 生命周期:无
5
+ * 注意事项:刻意使用 `export *` 而非逐个列举 —— 手写清单必然与实现脱节,遗漏一个类型
6
+ * 就迫使使用者去 import 内核内部路径。代价是各模块须自我克制:仅 `export`
7
+ * 确实供外部使用的符号。
8
+ *
9
+ * 测试替身(`testing/fake.ts`)**不在此处**,经 `@yunzai-ng/core/testing` 子路径
10
+ * 导出,否则替身实现会进入生产依赖图。
11
+ *
12
+ * 类型定义在 `@yunzai-ng/types`,本包不转发:类型包零运行时依赖,插件的 `.d.ts`
13
+ * 可只引用它而不引入整个内核。
14
+ */
15
+
16
+ /* ────────────────────────────── 内核 ────────────────────────────── */
17
+ export * from "./kernel/app.js"
18
+ export * from "./kernel/runtime.js"
19
+ export * from "./kernel/policy.js"
20
+ export * from "./kernel/sql-sink.js"
21
+ export * from "./kernel/kv-sink.js"
22
+
23
+ /* ────────────────────────────── 插件体系 ────────────────────────────── */
24
+ export * from "./plugin/define.js"
25
+ export * from "./plugin/context.js"
26
+ export * from "./plugin/host.js"
27
+ export * from "./plugin/hooks.js"
28
+ export * from "./plugin/events.js"
29
+ export * from "./plugin/services.js"
30
+ export * from "./plugin/discover.js"
31
+ export * from "./plugin/market.js"
32
+ export * from "./plugin/tar.js"
33
+
34
+ /* ────────────────────────────── 消息 ────────────────────────────── */
35
+ export * from "./message/segment.js"
36
+ export * from "./message/split.js"
37
+ export * from "./message/target.js"
38
+
39
+ /* ────────────────────────────── 管线 ────────────────────────────── */
40
+ export * from "./pipeline/event.js"
41
+ export * from "./pipeline/middleware.js"
42
+ export * from "./pipeline/router.js"
43
+ export * from "./pipeline/cooldown.js"
44
+ export * from "./pipeline/prompt.js"
45
+ export * from "./pipeline/dispatch.js"
46
+
47
+ /* ────────────────────────────── 适配器与账号 ────────────────────────────── */
48
+ // 适配器插件要的是 @yunzai-ng/types 里的 `AdapterProvider` / `BotDriver` 接口,
49
+ // 这里导出的是内核侧的注册表与管理器 —— 给 WebUI 与测试用,插件通常不碰
50
+ export * from "./adapter/registry.js"
51
+ export * from "./adapter/bots.js"
52
+ export * from "./adapter/host.js"
53
+ export * from "./adapter/accounts.js"
54
+ export * from "./adapter/login.js"
55
+
56
+ /* ────────────────────────────── 调度与渲染 ────────────────────────────── */
57
+ export * from "./scheduler/index.js"
58
+ export * from "./render/registry.js"
59
+
60
+ /* ────────────────────────────── 配置 ────────────────────────────── */
61
+ export * from "./config/schema.js"
62
+ export * from "./config/store.js"
63
+ export * from "./config/core-config.js"
64
+ export * from "./config/yaml.js"
65
+
66
+ /* ────────────────────────────── 日志 ────────────────────────────── */
67
+ export * from "./logger/index.js"
68
+ export * from "./logger/format.js"
69
+ export * from "./logger/rotate.js"
70
+
71
+ /* ────────────────────────────── 存储 ────────────────────────────── */
72
+ export * from "./store/index.js"
73
+ export * from "./store/kv.js"
74
+ export * from "./store/sql.js"
75
+ export * from "./store/memory.js"
76
+ export * from "./store/json.js"
77
+ export * from "./store/level.js"
78
+
79
+ /* ────────────────────────────── 网络 ────────────────────────────── */
80
+ export * from "./http/client.js"
81
+
82
+ /* ────────────────────────────── 服务器 ────────────────────────────── */
83
+ export * from "./server/index.js"
84
+ export * from "./server/api.js"
85
+ export * from "./server/auth.js"
86
+ export * from "./server/browse.js"
87
+ export * from "./server/files.js"
88
+ export * from "./server/table.js"
89
+
90
+ /* ────────────────────────────── 平台 ────────────────────────────── */
91
+ export * from "./platform/paths.js"
92
+ export * from "./platform/detect.js"
93
+ export * from "./platform/system.js"
94
+
95
+ /* ────────────────────────────── 工具 ────────────────────────────── */
96
+ // 以下为插件作者最常自行重复实现的工具(切分长文本、LRU、退避重试、脱敏),
97
+ // 一并导出,以免各插件各自实现一份并各自带有缺陷
98
+ export * from "./util/deep.js"
99
+ export * from "./util/defer.js"
100
+ export * from "./util/dispose.js"
101
+ export * from "./util/duration.js"
102
+ export * from "./util/fs.js"
103
+ export * from "./util/id.js"
104
+ export * from "./util/lru.js"
105
+ export * from "./util/queue.js"
106
+ export * from "./util/text.js"
@@ -0,0 +1,267 @@
1
+ /**
2
+ * 模块职责:应用生命周期与装配顺序的测试
3
+ * 依赖方向:测试文件,依赖 kernel/app
4
+ * 生命周期:每个用例一套临时主目录 + 一个应用实例,afterEach 停机并删目录
5
+ * 注意事项:这些用例刻意**不构造任何测试替身** —— 执行的是真实的 `createApp()`:
6
+ * 实际创建目录、读写 YAML、开启 KV、写入日志文件。
7
+ * 装配顺序上的缺陷(日志晚于配置、KV 晚于插件、stop 遗漏某个句柄导致
8
+ * 进程无法退出)均只在真实链路上出现,替身无法覆盖。
9
+ *
10
+ * 夹具中固定 `store.driver: memory` 与 `store.sqlite: false`:
11
+ * 用例待验证的是**装配**,而非存储驱动本身(后者见 store/kv.test.ts),
12
+ * 同时规避 classic-level / better-sqlite3 两个原生模块,
13
+ * 使该组用例在 Termux 一类无法编译原生模块的环境中同样可执行。
14
+ */
15
+ import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from "node:fs/promises"
16
+ import { tmpdir } from "node:os"
17
+ import { join } from "node:path"
18
+ import { afterEach, describe, expect, it } from "vitest"
19
+ import type { CommandInfo } from "@yunzai-ng/types"
20
+ import { SubsystemUnavailableError } from "../plugin/hooks.js"
21
+ import { createApp, type App, type CreateAppOptions } from "./app.js"
22
+
23
+ /** 当前用例的应用实例,afterEach 负责收尾 */
24
+ let current: App | undefined
25
+ /** 当前用例的临时主目录 */
26
+ let root: string | undefined
27
+
28
+ /**
29
+ * 建一个临时主目录并写好内核配置
30
+ * @param extra 追加到 `config/yunzai.yaml` 的 YAML 片段
31
+ * @returns 主目录绝对路径
32
+ */
33
+ async function makeHome(extra = ""): Promise<string> {
34
+ const home = await mkdtemp(join(tmpdir(), "yzng-app-"))
35
+ await mkdir(join(home, "config"), { recursive: true })
36
+ await writeFile(join(home, "config", "yunzai.yaml"), `store:\n driver: memory\n sqlite: false\n${extra}`, "utf8")
37
+ root = home
38
+ return home
39
+ }
40
+
41
+ /**
42
+ * 造一个应用(不启动)
43
+ * @param opts 覆盖参数
44
+ * @param extra 追加的 YAML 片段
45
+ * @returns 应用实例
46
+ */
47
+ async function makeApp(opts: Partial<CreateAppOptions> = {}, extra = ""): Promise<App> {
48
+ const home = await makeHome(extra)
49
+ const app = await createApp({
50
+ home,
51
+ version: "9.9.9-test",
52
+ // 控制台输出关掉:否则 vitest 的输出会被启动横幅刷满
53
+ console: false,
54
+ // 不装文件监听:用例自己调 patch 触发变更,watcher 只会让 afterEach 的
55
+ // rm 在 Windows 上偶发 EBUSY
56
+ watchConfig: false,
57
+ stopTimeout: 300,
58
+ ...opts
59
+ })
60
+ current = app
61
+ return app
62
+ }
63
+
64
+ afterEach(async () => {
65
+ await current?.stop()
66
+ current = undefined
67
+ if (root) await rm(root, { recursive: true, force: true })
68
+ root = undefined
69
+ })
70
+
71
+ describe("createApp", () => {
72
+ it("建好目录布局并读到配置", async () => {
73
+ const app = await makeApp()
74
+
75
+ expect(app.version).toBe("9.9.9-test")
76
+ expect(app.status).toBe("created")
77
+ expect(app.paths.config).toBe(join(app.paths.home, "config"))
78
+ // ensurePaths 应当已经把每个目录都建出来了
79
+ for (const dir of [app.paths.data, app.paths.logs, app.paths.temp, app.paths.plugins, app.paths.cache]) {
80
+ const info = await stat(dir)
81
+ expect(info.isDirectory()).toBe(true)
82
+ }
83
+ expect(app.settings.server.port).toBe(2536)
84
+ expect(app.kv.driver).toBe("memory")
85
+ })
86
+
87
+ it("配置文件里的值覆盖 schema 默认值", async () => {
88
+ const app = await makeApp({}, "server:\n port: 3456\nbot:\n masterQQ:\n - '10001'\n")
89
+
90
+ expect(app.settings.server.port).toBe(3456)
91
+ expect(app.policy.isMaster("10001")).toBe(true)
92
+ expect(app.policy.isMaster("10002")).toBe(false)
93
+ })
94
+
95
+ it("start 广播 app/ready,stop 广播 app/stopping", async () => {
96
+ const app = await makeApp()
97
+ const seen: string[] = []
98
+ app.events.on("app/ready", () => void seen.push("ready"))
99
+ app.events.on("app/stopping", () => void seen.push("stopping"))
100
+
101
+ await app.start()
102
+ expect(app.status).toBe("running")
103
+ expect(seen).toEqual(["ready"])
104
+
105
+ await app.stop()
106
+ expect(app.status).toBe("stopped")
107
+ expect(seen).toEqual(["ready", "stopping"])
108
+ })
109
+
110
+ it("空插件目录也能正常启动", async () => {
111
+ const app = await makeApp()
112
+ const report = await app.start()
113
+
114
+ expect(report.loaded).toEqual([])
115
+ expect(report.failed).toEqual([])
116
+ expect(app.view.plugins.list()).toEqual([])
117
+ })
118
+
119
+ it("重复 start 抛错,重复 stop 幂等", async () => {
120
+ const app = await makeApp()
121
+ await app.start()
122
+
123
+ await expect(app.start()).rejects.toThrow(/不能再次 start/)
124
+
125
+ await app.stop()
126
+ await expect(app.stop()).resolves.toBeUndefined()
127
+ expect(app.status).toBe("stopped")
128
+ })
129
+
130
+ it("日志写进 logs 目录", async () => {
131
+ const app = await makeApp()
132
+ await app.start()
133
+ app.loggerHub.flush()
134
+
135
+ const file = app.loggerHub.file
136
+ expect(file).toBeTruthy()
137
+ expect(file).toContain(app.paths.logs)
138
+ const text = await readFile(file!, "utf8")
139
+ // 启动横幅里带版本号;能读到就说明"日志早于配置就绪"这条链路是通的
140
+ expect(text).toContain("9.9.9-test")
141
+ })
142
+
143
+ it("AppView 是活的:后填的子系统立刻可见", async () => {
144
+ const app = await makeApp()
145
+
146
+ expect(app.view.plugins.commands()).toEqual([])
147
+ expect(app.view.bots.size).toBe(0)
148
+ expect(app.hooks.bots.pick()).toBeUndefined()
149
+
150
+ const cmd: CommandInfo = {
151
+ name: "#ping",
152
+ patterns: ["#ping"],
153
+ plugin: "demo",
154
+ master: false,
155
+ admin: false,
156
+ hidden: false,
157
+ disabled: false
158
+ }
159
+ // 阶段三就是这样接管的:换掉槽里的对象,不碰 app.ts
160
+ app.subsystems.registries = { commands: () => [cmd], tasks: () => [], middlewares: () => [] }
161
+
162
+ expect(app.view.plugins.commands()).toEqual([cmd])
163
+ })
164
+
165
+ it("policy 现读配置:加主人无需重启", async () => {
166
+ const app = await makeApp()
167
+ await app.start()
168
+
169
+ expect(app.policy.isMaster("10086")).toBe(false)
170
+ await expect(app.policy.addMaster("10086")).resolves.toBe(true)
171
+ expect(app.policy.isMaster("10086")).toBe(true)
172
+ // 重复加不算改动
173
+ await expect(app.policy.addMaster("10086")).resolves.toBe(false)
174
+
175
+ // 落盘了才算真的生效
176
+ const yaml = await readFile(join(app.paths.config, "yunzai.yaml"), "utf8")
177
+ expect(yaml).toContain("10086")
178
+
179
+ await expect(app.policy.removeMaster("10086")).resolves.toBe(true)
180
+ expect(app.policy.masters).toEqual([])
181
+ })
182
+
183
+ it("未启用的子系统给出可操作的报错", async () => {
184
+ const app = await makeApp()
185
+
186
+ // sqlite: false → 报错要指名配置项,而不是一句 undefined
187
+ await expect(app.hooks.sql.open("demo", "gacha")).rejects.toThrow(SubsystemUnavailableError)
188
+ await expect(app.hooks.sql.open("demo", "gacha")).rejects.toThrow(/store\.sqlite/)
189
+
190
+ // 阶段四之前服务器是占位实现,视图必须如实反映
191
+ expect(app.view.server.enabled).toBe(false)
192
+ })
193
+
194
+ it("库名带路径分隔符时拒绝打开", async () => {
195
+ const app = await makeApp({}, "")
196
+
197
+ // 越权路径要在校验阶段就挡掉,不能等到 join 之后写到目录外面去
198
+ await expect(app.hooks.sql.open("../etc", "passwd")).rejects.toThrow(/不合法/)
199
+ })
200
+
201
+ it("stop 之后 HTTP 客户端不再可用", async () => {
202
+ const app = await makeApp()
203
+ await app.start()
204
+ await app.stop()
205
+
206
+ // close() 必须是终态:还能发请求就说明连接池被静默重建了,
207
+ // 进程会被 keep-alive 的空闲 socket 吊着退不出去。
208
+ // 断言具体错误文案而非仅断言"抛出异常" —— 无法连接目标端口同样会抛出异常,该情形不应视为通过
209
+ await expect(app.http.get("http://127.0.0.1:1/never")).rejects.toThrow(/已关闭/)
210
+ })
211
+ })
212
+
213
+ describe("面板的挂载归属", () => {
214
+ /** 面板产物目录,afterEach 之外单独清理 */
215
+ let panelDir: string | undefined
216
+
217
+ afterEach(async () => {
218
+ if (panelDir) await rm(panelDir, { recursive: true, force: true })
219
+ panelDir = undefined
220
+ })
221
+
222
+ /**
223
+ * 造一个面板产物目录
224
+ *
225
+ * 由插件显式传给 `ctx.panel()`,内核不再探测任何目录约定。
226
+ * @returns 目录绝对路径
227
+ */
228
+ async function makePanelDir(): Promise<string> {
229
+ const dir = await mkdtemp(join(tmpdir(), "yzng-panel-"))
230
+ await writeFile(join(dir, "index.html"), "<html>面板</html>", "utf8")
231
+ panelDir = dir
232
+ return dir
233
+ }
234
+
235
+ it("无插件提供面板时根路径始终无人接管", async () => {
236
+ const app = await makeApp()
237
+
238
+ expect(app.hooks.server.claimant("/")).toBeUndefined()
239
+
240
+ await app.start()
241
+ // 内核不再自带兜底面板:启动完成后根路径依然无人提供,
242
+ // 使用者得到的是一条指向插件市场的 info,而不是一个空面板
243
+ expect(app.hooks.server.claimant("/")).toBeUndefined()
244
+ })
245
+
246
+ it("插件调用 ctx.panel() 即接管根路径", async () => {
247
+ const dir = await makePanelDir()
248
+ const app = await makeApp()
249
+ const pluginDir = join(app.paths.plugins, "webui")
250
+ await mkdir(pluginDir, { recursive: true })
251
+ await writeFile(
252
+ join(pluginDir, "index.js"),
253
+ `export default {
254
+ name: "webui",
255
+ setup(ctx) { ctx.panel(${JSON.stringify(dir)}) }
256
+ }`,
257
+ "utf8"
258
+ )
259
+
260
+ const report = await app.start()
261
+
262
+ expect(report.loaded).toEqual(["webui"])
263
+ // 归属指向插件,且这是**唯一**的形态:面板由插件提供,内核只做检测,
264
+ // 因此"替换面板前端"不需要改内核
265
+ expect(app.hooks.server.claimant("/")).toBe("plugin:webui")
266
+ })
267
+ })