alemonjs 2.1.83 → 2.1.84

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 (235) hide show
  1. package/lib/{app → application}/define-children.js +2 -1
  2. package/lib/{app → application/format}/message-api.d.ts +2 -2
  3. package/lib/{app → application/format}/message-api.js +12 -4
  4. package/lib/{app → application/format}/message-format-old.d.ts +1 -1
  5. package/lib/{app → application/format}/message-format.d.ts +1 -2
  6. package/lib/{app → application/format}/message-format.js +0 -2
  7. package/lib/{app/hook-use → application/hooks}/announce.js +4 -3
  8. package/lib/{app/hook-use → application/hooks}/channel.js +4 -3
  9. package/lib/{app/hook-use → application/hooks}/client.d.ts +1 -1
  10. package/lib/{app/hook-use → application/hooks}/client.js +4 -11
  11. package/lib/{app/hook-use → application/hooks}/common.d.ts +7 -7
  12. package/lib/{app/hook-use → application/hooks}/common.js +9 -8
  13. package/lib/{app/hook-use → application/hooks}/event.js +1 -1
  14. package/lib/{app/hook-use → application/hooks}/guild.js +4 -3
  15. package/lib/{app/hook-use → application/hooks}/history.js +4 -3
  16. package/lib/{app/hook-use → application/hooks}/me.js +12 -7
  17. package/lib/{app/hook-use → application/hooks}/media.d.ts +3 -3
  18. package/lib/{app/hook-use → application/hooks}/media.js +4 -3
  19. package/lib/{app/hook-use → application/hooks}/member.js +4 -3
  20. package/lib/{app/hook-use → application/hooks}/mention.js +4 -3
  21. package/lib/{app/hook-use → application/hooks}/message.js +6 -5
  22. package/lib/{app/hook-use → application/hooks}/permission.js +4 -3
  23. package/lib/{app/hook-use → application/hooks}/reaction.js +4 -3
  24. package/lib/{app/hook-use → application/hooks}/request.js +12 -7
  25. package/lib/{app/hook-use → application/hooks}/role.js +4 -3
  26. package/lib/{app/hook-use → application/hooks}/subscribe.js +4 -4
  27. package/lib/{app/hook-use → application/hooks}/user.js +12 -7
  28. package/lib/application/index.d.ts +29 -0
  29. package/lib/application/index.js +58 -0
  30. package/lib/{app → application}/router/dsl.d.ts +1 -1
  31. package/lib/{app → application}/router/dsl.js +13 -9
  32. package/lib/{cbp → application/runtime/cbp}/connects/client.d.ts +1 -1
  33. package/lib/{cbp → application/runtime/cbp}/connects/client.js +43 -50
  34. package/lib/application/runtime/cbp/index.d.ts +3 -0
  35. package/lib/application/runtime/cbp/index.js +3 -0
  36. package/lib/application/runtime/cbp/processor/actions.d.ts +3 -0
  37. package/lib/application/runtime/cbp/processor/actions.js +58 -0
  38. package/lib/application/runtime/cbp/processor/api.d.ts +3 -0
  39. package/lib/application/runtime/cbp/processor/api.js +58 -0
  40. package/lib/application/runtime/cbp/processor/request-registry.d.ts +8 -0
  41. package/lib/application/runtime/cbp/processor/request-registry.js +6 -0
  42. package/lib/application/runtime/client-runtime.d.ts +1 -0
  43. package/lib/application/runtime/client-runtime.js +95 -0
  44. package/lib/{app → application/runtime}/event-error.d.ts +1 -1
  45. package/lib/{app → application/runtime}/event-error.js +1 -1
  46. package/lib/{app → application/runtime}/event-group.d.ts +1 -1
  47. package/lib/{app → application/runtime}/event-middleware.d.ts +1 -1
  48. package/lib/{app → application/runtime}/event-middleware.js +1 -1
  49. package/lib/{app → application/runtime}/event-processor-callHandler.d.ts +1 -1
  50. package/lib/{app → application/runtime}/event-processor-callHandler.js +8 -1
  51. package/lib/{app → application/runtime}/event-processor-cycle.d.ts +1 -1
  52. package/lib/{app → application/runtime}/event-processor-cycleFiles.d.ts +1 -1
  53. package/lib/{app → application/runtime}/event-processor-cycleFiles.js +2 -2
  54. package/lib/{app → application/runtime}/event-processor-cycleRoute.d.ts +1 -1
  55. package/lib/{app → application/runtime}/event-processor-cycleRoute.js +9 -2
  56. package/lib/{app → application/runtime}/event-processor-event.d.ts +1 -1
  57. package/lib/{app → application/runtime}/event-processor-middleware.d.ts +1 -1
  58. package/lib/{app → application/runtime}/event-processor-subscribe.d.ts +1 -1
  59. package/lib/{app → application/runtime}/event-processor-subscribe.js +9 -2
  60. package/lib/{app → application/runtime}/event-processor.d.ts +1 -1
  61. package/lib/{app → application/runtime}/event-processor.js +4 -3
  62. package/lib/{app → application/runtime}/event-response.d.ts +1 -1
  63. package/lib/{app → application/runtime}/event-utils.d.ts +1 -1
  64. package/lib/{app → application/runtime}/event-utils.js +2 -2
  65. package/lib/{app → application/runtime}/hook-event-context.d.ts +2 -2
  66. package/lib/{app → application/runtime}/hook-event-context.js +2 -2
  67. package/lib/application/runtime/http/index.d.ts +4 -0
  68. package/lib/application/runtime/http/index.js +4 -0
  69. package/lib/application/runtime/http/routers/hello.html.d.ts +4 -0
  70. package/lib/application/runtime/http/routers/hello.html.js +376 -0
  71. package/lib/{server → application/runtime/http}/routers/router.js +131 -54
  72. package/lib/{server → application/runtime/http}/routers/utils.d.ts +1 -1
  73. package/lib/{server → application/runtime/http}/routers/utils.js +7 -7
  74. package/lib/{server/main.js → application/runtime/http-server.js} +2 -6
  75. package/lib/{app → application/runtime}/lifecycle-callbacks.d.ts +1 -1
  76. package/lib/{app → application/runtime}/lifecycle-callbacks.js +2 -7
  77. package/lib/{app/load_modules → application/runtime/load-modules}/load.js +2 -2
  78. package/lib/{app/load_modules → application/runtime/load-modules}/loadChild.js +14 -5
  79. package/lib/{app → application/runtime}/schedule-store.d.ts +1 -1
  80. package/lib/{app → application/runtime}/schedule-store.js +1 -1
  81. package/lib/{app → application/runtime}/store.d.ts +14 -19
  82. package/lib/{app → application/runtime}/store.js +8 -103
  83. package/lib/application/schedule.d.ts +17 -0
  84. package/lib/{app/api → application}/schedule.js +1 -1
  85. package/lib/client.d.ts +1 -1
  86. package/lib/client.js +1 -117
  87. package/lib/common/cbp/constants.d.ts +11 -0
  88. package/lib/common/cbp/constants.js +13 -0
  89. package/lib/{cbp/connects/connect.js → common/cbp/heartbeat.js} +3 -6
  90. package/lib/common/cbp/normalize.d.ts +16 -0
  91. package/lib/common/cbp/normalize.js +324 -0
  92. package/lib/common/cbp/runtime.d.ts +2 -0
  93. package/lib/common/cbp/runtime.js +10 -0
  94. package/lib/common/cbp/typings.d.ts +159 -0
  95. package/lib/{cbp/connects/base.js → common/cbp/ws-connector.js} +7 -9
  96. package/lib/{core → common}/config.d.ts +2 -2
  97. package/lib/{core → common}/config.js +5 -4
  98. package/lib/common/identity.d.ts +11 -0
  99. package/lib/common/identity.js +34 -0
  100. package/lib/common/index.d.ts +15 -0
  101. package/lib/common/index.js +14 -0
  102. package/lib/common/logger.d.ts +6 -0
  103. package/lib/common/logger.js +99 -0
  104. package/lib/common/result.d.ts +7 -0
  105. package/lib/common/result.js +19 -0
  106. package/lib/{core → common}/utils.d.ts +3 -18
  107. package/lib/{core → common}/utils.js +6 -49
  108. package/lib/{core → common}/variable.js +1 -1
  109. package/lib/core/cbp/index.d.ts +1 -0
  110. package/lib/core/cbp/index.js +1 -0
  111. package/lib/core/cbp/processor/config.d.ts +8 -0
  112. package/lib/core/cbp/processor/config.js +29 -0
  113. package/lib/{cbp → core/cbp}/routers/hello.html.js +1 -1
  114. package/lib/{cbp → core/cbp}/server/main.js +57 -35
  115. package/lib/{cbp → core/cbp}/server/testone.d.ts +1 -1
  116. package/lib/{cbp → core/cbp}/server/testone.js +8 -2
  117. package/lib/core/index.d.ts +1 -3
  118. package/lib/core/index.js +1 -3
  119. package/lib/core/process/index.d.ts +3 -0
  120. package/lib/{process → core/process}/index.js +0 -1
  121. package/lib/{process → core/process}/ipc-bridge.js +16 -2
  122. package/lib/{process → core/process}/module.js +13 -4
  123. package/lib/{process → core/process}/platform.js +12 -3
  124. package/lib/core/start.d.ts +2 -0
  125. package/lib/core/start.js +76 -0
  126. package/lib/global.d.ts +4 -3
  127. package/lib/index.d.ts +10 -2
  128. package/lib/index.js +74 -54
  129. package/lib/main.d.ts +1 -2
  130. package/lib/main.js +1 -76
  131. package/lib/{cbp/connects/platform.d.ts → platform/cbp-platform.d.ts} +2 -2
  132. package/lib/{cbp/connects/platform.js → platform/cbp-platform.js} +52 -75
  133. package/lib/{app → platform}/define-platform.js +2 -0
  134. package/lib/platform/event-value.d.ts +7 -0
  135. package/lib/platform/event-value.js +5 -0
  136. package/lib/platform/index.d.ts +5 -0
  137. package/lib/platform/index.js +5 -0
  138. package/lib/types/actions.d.ts +20 -1
  139. package/lib/types/apis.d.ts +2 -1
  140. package/lib/types/client/index.d.ts +1 -1
  141. package/lib/types/cycle/index.d.ts +1 -1
  142. package/lib/types/event/index.d.ts +1 -1
  143. package/lib/types/subscribe/index.d.ts +1 -1
  144. package/package.json +22 -1
  145. package/lib/app/api/schedule.d.ts +0 -17
  146. package/lib/app/index.d.ts +0 -25
  147. package/lib/app/index.js +0 -47
  148. package/lib/cbp/index.d.ts +0 -3
  149. package/lib/cbp/index.js +0 -3
  150. package/lib/cbp/processor/actions.d.ts +0 -3
  151. package/lib/cbp/processor/actions.js +0 -48
  152. package/lib/cbp/processor/api.d.ts +0 -3
  153. package/lib/cbp/processor/api.js +0 -48
  154. package/lib/cbp/processor/config.d.ts +0 -29
  155. package/lib/cbp/processor/config.js +0 -52
  156. package/lib/cbp/typings.d.ts +0 -20
  157. package/lib/process/index.d.ts +0 -4
  158. package/lib/server/routers/hello.html.d.ts +0 -2
  159. package/lib/server/routers/hello.html.js +0 -31
  160. /package/lib/{app → application}/define-children.d.ts +0 -0
  161. /package/lib/{app → application}/define-middleware.d.ts +0 -0
  162. /package/lib/{app → application}/define-middleware.js +0 -0
  163. /package/lib/{app → application}/define-response.d.ts +0 -0
  164. /package/lib/{app → application}/define-response.js +0 -0
  165. /package/lib/{app → application}/define-router.d.ts +0 -0
  166. /package/lib/{app → application}/define-router.js +0 -0
  167. /package/lib/{app → application}/expose.d.ts +0 -0
  168. /package/lib/{app → application}/expose.js +0 -0
  169. /package/lib/{app → application/format}/message-format-old.js +0 -0
  170. /package/lib/{app/hook-use → application/hooks}/announce.d.ts +0 -0
  171. /package/lib/{app/hook-use → application/hooks}/channel.d.ts +0 -0
  172. /package/lib/{app/hook-use → application/hooks}/event.d.ts +0 -0
  173. /package/lib/{app/hook-use → application/hooks}/guild.d.ts +0 -0
  174. /package/lib/{app/hook-use → application/hooks}/history.d.ts +0 -0
  175. /package/lib/{app/hook-use → application/hooks}/index.d.ts +0 -0
  176. /package/lib/{app/hook-use → application/hooks}/index.js +0 -0
  177. /package/lib/{app/hook-use → application/hooks}/me.d.ts +0 -0
  178. /package/lib/{app/hook-use → application/hooks}/member.d.ts +0 -0
  179. /package/lib/{app/hook-use → application/hooks}/mention.d.ts +0 -0
  180. /package/lib/{app/hook-use → application/hooks}/message.d.ts +0 -0
  181. /package/lib/{app/hook-use → application/hooks}/permission.d.ts +0 -0
  182. /package/lib/{app/hook-use → application/hooks}/reaction.d.ts +0 -0
  183. /package/lib/{app/hook-use → application/hooks}/request.d.ts +0 -0
  184. /package/lib/{app/hook-use → application/hooks}/role.d.ts +0 -0
  185. /package/lib/{app/hook-use → application/hooks}/route.d.ts +0 -0
  186. /package/lib/{app/hook-use → application/hooks}/route.js +0 -0
  187. /package/lib/{app/hook-use → application/hooks}/subscribe.d.ts +0 -0
  188. /package/lib/{app/hook-use → application/hooks}/user.d.ts +0 -0
  189. /package/lib/{app → application}/router/fallback.d.ts +0 -0
  190. /package/lib/{app → application}/router/fallback.js +0 -0
  191. /package/lib/{app → application}/router/main.d.ts +0 -0
  192. /package/lib/{app → application}/router/main.js +0 -0
  193. /package/lib/{app → application}/router/parser.d.ts +0 -0
  194. /package/lib/{app → application}/router/parser.js +0 -0
  195. /package/lib/{app → application}/router/types.d.ts +0 -0
  196. /package/lib/{app → application}/router/types.js +0 -0
  197. /package/lib/{app → application}/router/validator.d.ts +0 -0
  198. /package/lib/{app → application}/router/validator.js +0 -0
  199. /package/lib/{cbp → application/runtime/cbp}/processor/transport.d.ts +0 -0
  200. /package/lib/{cbp → application/runtime/cbp}/processor/transport.js +0 -0
  201. /package/lib/{app → application/runtime}/event-group.js +0 -0
  202. /package/lib/{app → application/runtime}/event-processor-cycle.js +0 -0
  203. /package/lib/{app → application/runtime}/event-processor-event.js +0 -0
  204. /package/lib/{app → application/runtime}/event-processor-middleware.js +0 -0
  205. /package/lib/{app → application/runtime}/event-response.js +0 -0
  206. /package/lib/{server → application/runtime/http}/routers/middleware.d.ts +0 -0
  207. /package/lib/{server → application/runtime/http}/routers/middleware.js +0 -0
  208. /package/lib/{cbp → application/runtime/http}/routers/router.d.ts +0 -0
  209. /package/lib/{server/main.d.ts → application/runtime/http-server.d.ts} +0 -0
  210. /package/lib/{app/load_modules → application/runtime/load-modules}/index.d.ts +0 -0
  211. /package/lib/{app/load_modules → application/runtime/load-modules}/index.js +0 -0
  212. /package/lib/{app/load_modules → application/runtime/load-modules}/load.d.ts +0 -0
  213. /package/lib/{app/load_modules → application/runtime/load-modules}/loadChild.d.ts +0 -0
  214. /package/lib/{app/config.d.ts → application/runtime/subscribe-status.d.ts} +0 -0
  215. /package/lib/{app/config.js → application/runtime/subscribe-status.js} +0 -0
  216. /package/lib/{app → common}/SinglyLinkedList.d.ts +0 -0
  217. /package/lib/{app → common}/SinglyLinkedList.js +0 -0
  218. /package/lib/{cbp/connects/connect.d.ts → common/cbp/heartbeat.d.ts} +0 -0
  219. /package/lib/{cbp → common/cbp}/typings.js +0 -0
  220. /package/lib/{cbp/connects/base.d.ts → common/cbp/ws-connector.d.ts} +0 -0
  221. /package/lib/{process → common}/direct-channel.d.ts +0 -0
  222. /package/lib/{process → common}/direct-channel.js +0 -0
  223. /package/lib/{core → common}/react.d.ts +0 -0
  224. /package/lib/{core → common}/react.js +0 -0
  225. /package/lib/{core → common}/variable.d.ts +0 -0
  226. /package/lib/{cbp → core/cbp}/routers/hello.html.d.ts +0 -0
  227. /package/lib/{server → core/cbp}/routers/router.d.ts +0 -0
  228. /package/lib/{cbp → core/cbp}/routers/router.js +0 -0
  229. /package/lib/{cbp → core/cbp}/server/main.d.ts +0 -0
  230. /package/lib/{process → core/process}/ipc-bridge.d.ts +0 -0
  231. /package/lib/{process → core/process}/module.d.ts +0 -0
  232. /package/lib/{process → core/process}/platform.d.ts +0 -0
  233. /package/lib/{app → platform}/define-platform.d.ts +0 -0
  234. /package/lib/{app → platform}/event-format.d.ts +0 -0
  235. /package/lib/{app → platform}/event-format.js +0 -0
@@ -0,0 +1,376 @@
1
+ const escapeHtml = (value) => String(value).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
2
+ const appHref = (app) => {
3
+ return app.kind === 'main' ? '/app' : `/apps/${app.name}`;
4
+ };
5
+ const appTags = (app) => {
6
+ const tags = [app.kind === 'main' ? '主应用' : '插件'];
7
+ if (app.capabilities.web) {
8
+ tags.push('页面');
9
+ }
10
+ if (app.capabilities.httpApi) {
11
+ tags.push('接口');
12
+ }
13
+ if (app.capabilities.event) {
14
+ tags.push('事件');
15
+ }
16
+ if (app.capabilities.expose) {
17
+ tags.push('Expose');
18
+ }
19
+ return tags;
20
+ };
21
+ const renderCard = (app) => {
22
+ const href = appHref(app);
23
+ const tags = appTags(app)
24
+ .map(tag => `<span class="app-tag">${escapeHtml(tag)}</span>`)
25
+ .join('');
26
+ const desc = app.kind === 'main' ? '访问主应用页面、接口与默认资源。' : '访问插件页面、接口与公开入口。';
27
+ return `
28
+ <a
29
+ class="app-card"
30
+ href="${escapeHtml(href)}"
31
+ data-app-id="${escapeHtml(app.name)}"
32
+ data-app-kind="${escapeHtml(app.kind)}"
33
+ data-app-href="${escapeHtml(href)}"
34
+ >
35
+ <div class="app-card__top">
36
+ <div>
37
+ <p class="app-eyebrow">${app.kind === 'main' ? 'Main App' : 'Plugin App'}</p>
38
+ <h2 class="app-title">${escapeHtml(app.name)}</h2>
39
+ </div>
40
+ <div class="app-rank">
41
+ <span class="app-rank__label">热度</span>
42
+ <span class="app-rank__value" data-click-count>0</span>
43
+ </div>
44
+ </div>
45
+ <p class="app-desc">${escapeHtml(desc)}</p>
46
+ <div class="app-tags">${tags}</div>
47
+ <div class="app-card__bottom">
48
+ <span class="app-link">${escapeHtml(href)}</span>
49
+ <span class="app-action">进入</span>
50
+ </div>
51
+ </a>
52
+ `;
53
+ };
54
+ const renderEmpty = () => {
55
+ return `
56
+ <div class="empty-state">
57
+ <p class="empty-state__title">当前没有可展示的应用。</p>
58
+ <p class="empty-state__desc">请先加载主应用或插件,再刷新本页查看入口。</p>
59
+ </div>
60
+ `;
61
+ };
62
+ const renderHelloHtml = (apps) => {
63
+ const visibleApps = apps
64
+ .filter(app => app.enabled && app.status === 'ready' && (app.capabilities.web || app.capabilities.httpApi))
65
+ .sort((left, right) => {
66
+ if (left.kind === 'main' && right.kind !== 'main') {
67
+ return -1;
68
+ }
69
+ if (left.kind !== 'main' && right.kind === 'main') {
70
+ return 1;
71
+ }
72
+ return left.name.localeCompare(right.name);
73
+ });
74
+ const cards = visibleApps.length ? visibleApps.map(renderCard).join('') : renderEmpty();
75
+ const payload = JSON.stringify(visibleApps.map(app => ({
76
+ id: app.name,
77
+ href: appHref(app),
78
+ kind: app.kind
79
+ })));
80
+ return `<!DOCTYPE html>
81
+ <html lang="zh-CN">
82
+ <head>
83
+ <meta charset="utf-8" />
84
+ <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
85
+ <title>ALemonJS 应用入口</title>
86
+ <style>
87
+ :root {
88
+ --bg: #f3efe5;
89
+ --panel: rgba(255, 251, 245, 0.88);
90
+ --panel-strong: #fffaf2;
91
+ --text: #17212b;
92
+ --muted: #6a7684;
93
+ --line: rgba(23, 33, 43, 0.08);
94
+ --accent: #d96c28;
95
+ --accent-strong: #a54a13;
96
+ --shadow: 0 24px 60px rgba(47, 35, 20, 0.12);
97
+ }
98
+ * { box-sizing: border-box; }
99
+ html, body { margin: 0; min-height: 100%; }
100
+ body {
101
+ font-family: "SF Pro Display", "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
102
+ color: var(--text);
103
+ background:
104
+ radial-gradient(circle at top left, rgba(217, 108, 40, 0.18), transparent 28%),
105
+ radial-gradient(circle at right center, rgba(78, 140, 124, 0.14), transparent 26%),
106
+ linear-gradient(180deg, #f8f4ec 0%, var(--bg) 100%);
107
+ }
108
+ .page {
109
+ width: min(1680px, calc(100vw - 32px));
110
+ margin: 0 auto;
111
+ padding: clamp(28px, 4vw, 56px) 0 64px;
112
+ }
113
+ .hero {
114
+ position: relative;
115
+ overflow: hidden;
116
+ padding: clamp(28px, 4vw, 56px);
117
+ border-radius: 32px;
118
+ background: linear-gradient(135deg, rgba(255, 250, 242, 0.95), rgba(255, 244, 231, 0.88));
119
+ border: 1px solid rgba(255, 255, 255, 0.72);
120
+ box-shadow: var(--shadow);
121
+ }
122
+ .hero::after {
123
+ content: "";
124
+ position: absolute;
125
+ inset: auto -8% -48% auto;
126
+ width: min(38vw, 520px);
127
+ aspect-ratio: 1;
128
+ border-radius: 999px;
129
+ background: radial-gradient(circle, rgba(217, 108, 40, 0.18), transparent 62%);
130
+ pointer-events: none;
131
+ }
132
+ .hero-kicker {
133
+ margin: 0 0 12px;
134
+ font-size: clamp(14px, 1.2vw, 18px);
135
+ letter-spacing: 0.18em;
136
+ text-transform: uppercase;
137
+ color: var(--accent-strong);
138
+ }
139
+ .hero-title {
140
+ margin: 0;
141
+ max-width: 12ch;
142
+ font-size: clamp(40px, 7vw, 86px);
143
+ line-height: 0.95;
144
+ letter-spacing: -0.04em;
145
+ }
146
+ .hero-desc {
147
+ margin: 18px 0 0;
148
+ max-width: 56rem;
149
+ font-size: clamp(18px, 2vw, 28px);
150
+ line-height: 1.6;
151
+ color: var(--muted);
152
+ }
153
+ .hero-meta {
154
+ display: flex;
155
+ flex-wrap: wrap;
156
+ gap: 14px;
157
+ margin-top: 28px;
158
+ }
159
+ .hero-pill {
160
+ display: inline-flex;
161
+ align-items: center;
162
+ gap: 10px;
163
+ padding: 12px 18px;
164
+ border-radius: 999px;
165
+ background: rgba(255, 255, 255, 0.78);
166
+ border: 1px solid rgba(23, 33, 43, 0.08);
167
+ font-size: clamp(14px, 1.4vw, 18px);
168
+ }
169
+ .hero-pill strong {
170
+ color: var(--accent-strong);
171
+ }
172
+ .section-head {
173
+ display: flex;
174
+ align-items: end;
175
+ justify-content: space-between;
176
+ gap: 20px;
177
+ margin: 28px 0 18px;
178
+ padding: 0 6px;
179
+ }
180
+ .section-title {
181
+ margin: 0;
182
+ font-size: clamp(28px, 3vw, 42px);
183
+ }
184
+ .section-note {
185
+ margin: 0;
186
+ font-size: clamp(14px, 1.3vw, 18px);
187
+ color: var(--muted);
188
+ }
189
+ .app-grid {
190
+ display: grid;
191
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
192
+ gap: 18px;
193
+ }
194
+ .app-card {
195
+ display: flex;
196
+ flex-direction: column;
197
+ gap: 18px;
198
+ min-height: 280px;
199
+ padding: 24px;
200
+ border-radius: 28px;
201
+ text-decoration: none;
202
+ color: inherit;
203
+ background: var(--panel);
204
+ border: 1px solid var(--line);
205
+ box-shadow: 0 14px 40px rgba(30, 37, 44, 0.08);
206
+ transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
207
+ }
208
+ .app-card:hover {
209
+ transform: translateY(-4px);
210
+ border-color: rgba(217, 108, 40, 0.28);
211
+ box-shadow: 0 24px 50px rgba(30, 37, 44, 0.12);
212
+ }
213
+ .app-card__top,
214
+ .app-card__bottom {
215
+ display: flex;
216
+ align-items: center;
217
+ justify-content: space-between;
218
+ gap: 16px;
219
+ }
220
+ .app-eyebrow {
221
+ margin: 0 0 8px;
222
+ font-size: 13px;
223
+ letter-spacing: 0.16em;
224
+ text-transform: uppercase;
225
+ color: var(--accent-strong);
226
+ }
227
+ .app-title {
228
+ margin: 0;
229
+ font-size: clamp(28px, 2.8vw, 38px);
230
+ line-height: 1;
231
+ }
232
+ .app-desc {
233
+ margin: 0;
234
+ font-size: clamp(16px, 1.4vw, 20px);
235
+ line-height: 1.7;
236
+ color: var(--muted);
237
+ }
238
+ .app-tags {
239
+ display: flex;
240
+ flex-wrap: wrap;
241
+ gap: 10px;
242
+ }
243
+ .app-tag {
244
+ padding: 8px 12px;
245
+ border-radius: 999px;
246
+ background: rgba(217, 108, 40, 0.1);
247
+ color: var(--accent-strong);
248
+ font-size: 14px;
249
+ }
250
+ .app-rank {
251
+ min-width: 84px;
252
+ text-align: right;
253
+ }
254
+ .app-rank__label,
255
+ .app-link {
256
+ display: block;
257
+ font-size: 13px;
258
+ color: var(--muted);
259
+ }
260
+ .app-rank__value {
261
+ font-size: clamp(24px, 2vw, 30px);
262
+ font-weight: 700;
263
+ }
264
+ .app-action {
265
+ padding: 12px 18px;
266
+ border-radius: 999px;
267
+ background: #1d2d38;
268
+ color: #fff;
269
+ font-size: 15px;
270
+ }
271
+ .empty-state {
272
+ padding: 32px;
273
+ border-radius: 28px;
274
+ background: var(--panel-strong);
275
+ border: 1px dashed rgba(23, 33, 43, 0.16);
276
+ }
277
+ .empty-state__title {
278
+ margin: 0;
279
+ font-size: 24px;
280
+ }
281
+ .empty-state__desc {
282
+ margin: 10px 0 0;
283
+ color: var(--muted);
284
+ font-size: 16px;
285
+ }
286
+ @media (max-width: 820px) {
287
+ .page { width: min(100vw - 20px, 100%); padding-top: 18px; }
288
+ .hero { border-radius: 24px; padding: 22px; }
289
+ .section-head { align-items: start; flex-direction: column; }
290
+ .app-card { min-height: 0; padding: 20px; border-radius: 22px; }
291
+ .app-card__top,
292
+ .app-card__bottom { align-items: start; flex-direction: column; }
293
+ .app-rank { text-align: left; min-width: 0; }
294
+ }
295
+ </style>
296
+ </head>
297
+ <body>
298
+ <main class="page">
299
+ <section class="hero">
300
+ <p class="hero-kicker">ALemonJS Launchpad</p>
301
+ <h1 class="hero-title">阿柠檬机器人</h1>
302
+ </section>
303
+ <section>
304
+ <div class="section-head">
305
+ <div>
306
+ <h2 class="section-title">应用列表</h2>
307
+ </div>
308
+ </div>
309
+ <div class="app-grid" id="app-grid">${cards}</div>
310
+ </section>
311
+ </main>
312
+ <script>
313
+ (() => {
314
+ const storageKey = 'alemonjs:launchpad:clicks';
315
+ const apps = ${payload};
316
+ const grid = document.getElementById('app-grid');
317
+ if (!grid) return;
318
+
319
+ const readClicks = () => {
320
+ try {
321
+ return JSON.parse(localStorage.getItem(storageKey) || '{}');
322
+ } catch {
323
+ return {};
324
+ }
325
+ };
326
+
327
+ const writeClicks = (value) => {
328
+ localStorage.setItem(storageKey, JSON.stringify(value));
329
+ };
330
+
331
+ const scoreOf = (id, clicks) => Number(clicks[id] || 0);
332
+ const clicks = readClicks();
333
+ const cards = Array.from(grid.querySelectorAll('[data-app-id]'));
334
+
335
+ const refreshCounts = () => {
336
+ cards.forEach((card) => {
337
+ const id = card.getAttribute('data-app-id') || '';
338
+ const node = card.querySelector('[data-click-count]');
339
+ if (node) {
340
+ node.textContent = String(scoreOf(id, clicks));
341
+ }
342
+ });
343
+ };
344
+
345
+ const sortCards = () => {
346
+ cards
347
+ .sort((left, right) => {
348
+ const leftId = left.getAttribute('data-app-id') || '';
349
+ const rightId = right.getAttribute('data-app-id') || '';
350
+ const diff = scoreOf(rightId, clicks) - scoreOf(leftId, clicks);
351
+ if (diff !== 0) return diff;
352
+ return leftId.localeCompare(rightId);
353
+ })
354
+ .forEach(card => grid.appendChild(card));
355
+ };
356
+
357
+ cards.forEach((card) => {
358
+ card.addEventListener('click', () => {
359
+ const id = card.getAttribute('data-app-id') || '';
360
+ clicks[id] = scoreOf(id, clicks) + 1;
361
+ writeClicks(clicks);
362
+ refreshCounts();
363
+ sortCards();
364
+ });
365
+ });
366
+
367
+ refreshCounts();
368
+ sortCards();
369
+ })();
370
+ </script>
371
+ </body>
372
+ </html>`;
373
+ };
374
+ var hello_html = renderHelloHtml([]);
375
+
376
+ export { hello_html as default, renderHelloHtml };
@@ -2,15 +2,22 @@ import KoaRouter from 'koa-router';
2
2
  import fs__default, { existsSync } from 'fs';
3
3
  import path__default, { join, dirname } from 'path';
4
4
  import mime from 'mime-types';
5
- import hello from './hello.html.js';
5
+ import { renderHelloHtml } from './hello.html.js';
6
6
  import { safePath, getModuelFile, formatPath, isValidPackageName } from './utils.js';
7
7
  import { collectMiddlewares, runMiddlewares } from './middleware.js';
8
8
  import module$1 from 'module';
9
- import { ResultCode } from '../../core/variable.js';
10
9
  import 'yaml';
11
- import '../../core/utils.js';
12
- import { listRuntimeApps, getRuntimeApp, toRuntimeAppSnapshot, listRuntimeAppKoaRouters, hasRuntimeAppCapability, getRuntimeAppKoaRouters } from '../../app/store.js';
13
- import { dispatchHttpError } from '../../app/lifecycle-callbacks.js';
10
+ import '../../../../common/logger.js';
11
+ import { ResultCode } from '../../../../common/variable.js';
12
+ import '../../../../common/utils.js';
13
+ import 'net';
14
+ import 'v8';
15
+ import 'os';
16
+ import 'flatted';
17
+ import '../../../../common/cbp/runtime.js';
18
+ import 'ws';
19
+ import { listRuntimeApps, getRuntimeApp, toRuntimeAppSnapshot, listRuntimeAppKoaRouters, hasRuntimeAppCapability, getChildrenApp, getRuntimeAppKoaRouters } from '../../store.js';
20
+ import { dispatchHttpError } from '../../lifecycle-callbacks.js';
14
21
 
15
22
  const initRequire = () => { };
16
23
  initRequire.resolve = () => '';
@@ -31,14 +38,50 @@ const resolvePackageRoot = (startDir) => {
31
38
  const readWebRootConfig = (packageRoot) => {
32
39
  const packageJsonPath = path__default.join(packageRoot, 'package.json');
33
40
  if (!existsSync(packageJsonPath)) {
41
+ if (existsSync(path__default.join(packageRoot, 'dist', 'index.html'))) {
42
+ return 'dist';
43
+ }
34
44
  return '';
35
45
  }
36
46
  const pkg = require$1(packageJsonPath) ?? {};
37
- return pkg?.alemonjs?.web?.root ?? '';
47
+ const configuredRoot = pkg?.alemonjs?.web?.root ?? '';
48
+ if (typeof configuredRoot === 'string' && configuredRoot.trim()) {
49
+ return configuredRoot;
50
+ }
51
+ if (existsSync(path__default.join(packageRoot, 'dist', 'index.html'))) {
52
+ return 'dist';
53
+ }
54
+ return '';
55
+ };
56
+ const matchBasePath = (requestPath, basePath) => {
57
+ if (!basePath) {
58
+ return requestPath;
59
+ }
60
+ if (requestPath === basePath) {
61
+ return '/';
62
+ }
63
+ if (requestPath.startsWith(`${basePath}/`)) {
64
+ return requestPath.slice(basePath.length) || '/';
65
+ }
66
+ return '';
67
+ };
68
+ const rewriteCtxPath = async (ctx, nextPath, handler) => {
69
+ const search = ctx.querystring ? `?${ctx.querystring}` : '';
70
+ const originalUrl = ctx.url;
71
+ const originalReqUrl = ctx.req.url;
72
+ ctx.url = `${nextPath}${search}`;
73
+ ctx.req.url = `${nextPath}${search}`;
74
+ try {
75
+ await handler();
76
+ }
77
+ finally {
78
+ ctx.url = originalUrl;
79
+ ctx.req.url = originalReqUrl;
80
+ }
38
81
  };
39
82
  const denyRuntimeAppAccess = (ctx, appName, capability) => {
40
83
  const runtimeApp = getRuntimeApp(appName);
41
- if (!runtimeApp || !runtimeApp.enabled) {
84
+ if (!runtimeApp?.enabled) {
42
85
  ctx.status = 404;
43
86
  ctx.body = {
44
87
  code: 404,
@@ -98,47 +141,83 @@ const denyRuntimeAppAccess = (ctx, appName, capability) => {
98
141
  };
99
142
  const dispatchRegisteredKoaRouters = async (ctx) => {
100
143
  const registeredRouters = listRuntimeAppKoaRouters();
101
- for (const item of registeredRouters) {
102
- const runtimeApp = getRuntimeApp(item.name);
103
- if (!runtimeApp || !runtimeApp.enabled || runtimeApp.status !== 'ready' || !hasRuntimeAppCapability(item.name, 'httpApi')) {
144
+ const candidates = new Set(registeredRouters.map(item => item.name));
145
+ const runtimeApps = listRuntimeApps();
146
+ runtimeApps.forEach(item => {
147
+ if (item.capabilities?.httpApi) {
148
+ candidates.add(item.name);
149
+ }
150
+ });
151
+ for (const appName of candidates) {
152
+ const runtimeApp = getRuntimeApp(appName);
153
+ if (!runtimeApp || !runtimeApp.enabled || runtimeApp.status !== 'ready' || !hasRuntimeAppCapability(appName, 'httpApi')) {
104
154
  continue;
105
155
  }
106
- const routers = getRuntimeAppKoaRouters(item.name);
156
+ const registerRouters = getChildrenApp(appName)?.register?.koaRouter;
157
+ const storedRouters = getRuntimeAppKoaRouters(appName);
158
+ const routers = (storedRouters.length ? storedRouters : Array.isArray(registerRouters) ? registerRouters : registerRouters ? [registerRouters] : []).filter(Boolean);
159
+ const aliasBases = appName === 'main' ? ['', '/app'] : ['', `/apps/${appName}`];
107
160
  for (const koaRouter of routers) {
108
- try {
109
- const beforeMatched = Array.isArray(ctx.matched) ? ctx.matched.length : 0;
110
- await koaRouter.routes()(ctx, async () => { });
111
- const afterMatched = Array.isArray(ctx.matched) ? ctx.matched.length : 0;
112
- if (afterMatched <= beforeMatched) {
161
+ for (const basePath of aliasBases) {
162
+ const rewrittenPath = matchBasePath(ctx.path, basePath);
163
+ if (!rewrittenPath) {
113
164
  continue;
114
165
  }
115
- await koaRouter.allowedMethods()(ctx, async () => { });
116
- return true;
117
- }
118
- catch (error) {
119
- const handled = await dispatchHttpError({
120
- ctx,
121
- error,
122
- appName: item.name,
123
- path: ctx.path,
124
- method: ctx.method,
125
- kind: 'koa-router'
126
- });
127
- if (handled) {
166
+ try {
167
+ const matchedContext = ctx;
168
+ const beforeMatched = Array.isArray(matchedContext.matched) ? matchedContext.matched.length : 0;
169
+ const beforeStatus = ctx.status;
170
+ const beforeBody = ctx.body;
171
+ const beforeMatchedRoute = ctx._matchedRoute;
172
+ const beforeRouterPath = ctx.routerPath;
173
+ let fallthrough = false;
174
+ await rewriteCtxPath(ctx, rewrittenPath, async () => {
175
+ await koaRouter.routes()(ctx, async () => {
176
+ fallthrough = true;
177
+ });
178
+ });
179
+ const afterMatched = Array.isArray(matchedContext.matched) ? matchedContext.matched.length : 0;
180
+ const afterMatchedRoute = ctx._matchedRoute;
181
+ const afterRouterPath = ctx.routerPath;
182
+ const handled = afterMatched > beforeMatched ||
183
+ afterMatchedRoute !== beforeMatchedRoute ||
184
+ afterRouterPath !== beforeRouterPath ||
185
+ ctx.status !== beforeStatus ||
186
+ ctx.body !== beforeBody ||
187
+ !fallthrough;
188
+ if (!handled) {
189
+ continue;
190
+ }
191
+ await rewriteCtxPath(ctx, rewrittenPath, async () => {
192
+ await koaRouter.allowedMethods()(ctx, async () => { });
193
+ });
194
+ return true;
195
+ }
196
+ catch (error) {
197
+ const handled = await dispatchHttpError({
198
+ ctx,
199
+ error,
200
+ appName,
201
+ path: ctx.path,
202
+ method: ctx.method,
203
+ kind: 'koa-router'
204
+ });
205
+ if (handled) {
206
+ return true;
207
+ }
208
+ logger.warn({
209
+ code: ResultCode.Fail,
210
+ message: `Error request ${ctx.path}:`,
211
+ data: error instanceof Error ? error.message : String(error)
212
+ });
213
+ ctx.status = 500;
214
+ ctx.body = {
215
+ code: 500,
216
+ message: '处理 Koa Router 请求时发生错误。',
217
+ error: error instanceof Error ? error.message : String(error)
218
+ };
128
219
  return true;
129
220
  }
130
- logger.warn({
131
- code: ResultCode.Fail,
132
- message: `Error request ${ctx.path}:`,
133
- data: error instanceof Error ? error.message : String(error)
134
- });
135
- ctx.status = 500;
136
- ctx.body = {
137
- code: 500,
138
- message: '处理 Koa Router 请求时发生错误。',
139
- error: error instanceof Error ? error.message : String(error)
140
- };
141
- return true;
142
221
  }
143
222
  }
144
223
  }
@@ -147,7 +226,7 @@ const dispatchRegisteredKoaRouters = async (ctx) => {
147
226
  router.get('/', ctx => {
148
227
  ctx.status = 200;
149
228
  ctx.set('Content-Type', 'text/html; charset=utf-8');
150
- ctx.body = hello;
229
+ ctx.body = renderHelloHtml(listRuntimeApps());
151
230
  });
152
231
  router.get('api/online', ctx => {
153
232
  ctx.status = 200;
@@ -198,7 +277,7 @@ router.use(async (ctx, next) => {
198
277
  }
199
278
  await next();
200
279
  });
201
- router.all('app/{*path}', async (ctx) => {
280
+ const handleMainAppRequest = async (ctx) => {
202
281
  if (!process.env.input) {
203
282
  ctx.status = 400;
204
283
  ctx.body = {
@@ -368,11 +447,11 @@ router.all('app/{*path}', async (ctx) => {
368
447
  };
369
448
  }
370
449
  }
371
- });
372
- router.all('app', ctx => {
373
- ctx.redirect('/app/');
374
- });
375
- router.all('apps/:app/{*path}', async (ctx) => {
450
+ };
451
+ router.all('app', handleMainAppRequest);
452
+ router.all('app/', handleMainAppRequest);
453
+ router.all('app/{*path}', handleMainAppRequest);
454
+ const handlePluginAppRequest = async (ctx) => {
376
455
  const appName = ctx.params.app;
377
456
  if (!isValidPackageName(appName)) {
378
457
  ctx.status = 400;
@@ -541,11 +620,9 @@ router.all('apps/:app/{*path}', async (ctx) => {
541
620
  };
542
621
  }
543
622
  }
544
- });
545
- router.all('apps/:name', ctx => {
546
- if (ctx.path === `/apps/${ctx.params.name}`) {
547
- ctx.redirect(`/apps/${ctx.params.name}/`);
548
- }
549
- });
623
+ };
624
+ router.all('apps/:app', handlePluginAppRequest);
625
+ router.all('apps/:app/', handlePluginAppRequest);
626
+ router.all('apps/:app/{*path}', handlePluginAppRequest);
550
627
 
551
628
  export { router as default };
@@ -1,4 +1,4 @@
1
1
  export declare const safePath: (root: string, untrusted: string) => string | null;
2
2
  export declare const isValidPackageName: (name: string) => boolean;
3
3
  export declare const getModuelFile: (dir: string) => string;
4
- export declare const formatPath: (path: string) => string;
4
+ export declare const formatPath: (pathValue: string) => string;
@@ -34,17 +34,17 @@ const getModuelFile = (dir) => {
34
34
  }
35
35
  return '';
36
36
  };
37
- const formatPath = (path) => {
38
- if (!path || path === '/') {
39
- return '/index.html';
37
+ const formatPath = (pathValue) => {
38
+ if (!pathValue || pathValue === '/') {
39
+ return 'index.html';
40
40
  }
41
- const pates = path.split('/');
41
+ const pates = pathValue.split('/');
42
42
  const lastPath = pates[pates.length - 1];
43
43
  if (lastPath.includes('.')) {
44
- return path;
44
+ return pathValue;
45
45
  }
46
- path += '.html';
47
- return path;
46
+ pathValue += '.html';
47
+ return pathValue;
48
48
  };
49
49
 
50
50
  export { formatPath, getModuelFile, isValidPackageName, safePath };
@@ -1,11 +1,7 @@
1
1
  import Koa from 'koa';
2
2
  import koaCors from '@koa/cors';
3
- import router from './routers/router.js';
4
- import { ResultCode } from '../core/variable.js';
5
- import 'fs';
6
- import 'path';
7
- import 'yaml';
8
- import '../core/utils.js';
3
+ import router from './http/routers/router.js';
4
+ import { ResultCode } from '../../common/variable.js';
9
5
 
10
6
  const createServer = (port, listeningListener) => {
11
7
  try {
@@ -1,4 +1,4 @@
1
- import type { EventFinishedContext, EventStartContext, HttpErrorContext, RuntimeStatusChangeContext } from '../types';
1
+ import type { EventFinishedContext, EventStartContext, HttpErrorContext, RuntimeStatusChangeContext } from '../../types/index.js';
2
2
  export declare const dispatchEventStart: (context: EventStartContext) => Promise<void>;
3
3
  export declare const dispatchEventFinished: (context: EventFinishedContext) => Promise<void>;
4
4
  export declare const dispatchHttpError: (context: HttpErrorContext) => Promise<boolean>;