alemonjs 2.1.83-alpha.6 → 2.1.83-alpha.7

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.
@@ -16,7 +16,7 @@ import 'os';
16
16
  import 'flatted';
17
17
  import '../../../../common/cbp/runtime.js';
18
18
  import 'ws';
19
- import { listRuntimeApps, getRuntimeApp, toRuntimeAppSnapshot, listRuntimeAppKoaRouters, hasRuntimeAppCapability, getRuntimeAppKoaRouters } from '../../store.js';
19
+ import { listRuntimeApps, getRuntimeApp, toRuntimeAppSnapshot, listRuntimeAppKoaRouters, hasRuntimeAppCapability, getChildrenApp, getRuntimeAppKoaRouters } from '../../store.js';
20
20
  import { dispatchHttpError } from '../../lifecycle-callbacks.js';
21
21
 
22
22
  const initRequire = () => { };
@@ -38,10 +38,46 @@ const resolvePackageRoot = (startDir) => {
38
38
  const readWebRootConfig = (packageRoot) => {
39
39
  const packageJsonPath = path__default.join(packageRoot, 'package.json');
40
40
  if (!existsSync(packageJsonPath)) {
41
+ if (existsSync(path__default.join(packageRoot, 'dist', 'index.html'))) {
42
+ return 'dist';
43
+ }
41
44
  return '';
42
45
  }
43
46
  const pkg = require$1(packageJsonPath) ?? {};
44
- 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
+ }
45
81
  };
46
82
  const denyRuntimeAppAccess = (ctx, appName, capability) => {
47
83
  const runtimeApp = getRuntimeApp(appName);
@@ -105,63 +141,85 @@ const denyRuntimeAppAccess = (ctx, appName, capability) => {
105
141
  };
106
142
  const dispatchRegisteredKoaRouters = async (ctx) => {
107
143
  const registeredRouters = listRuntimeAppKoaRouters();
108
- for (const item of registeredRouters) {
109
- const runtimeApp = getRuntimeApp(item.name);
110
- 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')) {
111
154
  continue;
112
155
  }
113
- const routers = getRuntimeAppKoaRouters(item.name);
156
+ const registerRouters = getChildrenApp(appName)?.register?.koaRouter;
157
+ const storedRouters = getRuntimeAppKoaRouters(appName);
158
+ const routers = (storedRouters.length
159
+ ? storedRouters
160
+ : (Array.isArray(registerRouters) ? registerRouters : registerRouters ? [registerRouters] : [])).filter(Boolean);
161
+ const aliasBases = appName === 'main' ? ['', '/app'] : ['', `/apps/${appName}`];
114
162
  for (const koaRouter of routers) {
115
- try {
116
- const matchedContext = ctx;
117
- const beforeMatched = Array.isArray(matchedContext.matched) ? matchedContext.matched.length : 0;
118
- const beforeStatus = ctx.status;
119
- const beforeBody = ctx.body;
120
- const beforeMatchedRoute = ctx._matchedRoute;
121
- const beforeRouterPath = ctx.routerPath;
122
- let fallthrough = false;
123
- await koaRouter.routes()(ctx, async () => {
124
- fallthrough = true;
125
- });
126
- const afterMatched = Array.isArray(matchedContext.matched) ? matchedContext.matched.length : 0;
127
- const afterMatchedRoute = ctx._matchedRoute;
128
- const afterRouterPath = ctx.routerPath;
129
- const handled = afterMatched > beforeMatched
130
- || afterMatchedRoute !== beforeMatchedRoute
131
- || afterRouterPath !== beforeRouterPath
132
- || ctx.status !== beforeStatus
133
- || ctx.body !== beforeBody
134
- || !fallthrough;
135
- if (!handled) {
163
+ for (const basePath of aliasBases) {
164
+ const rewrittenPath = matchBasePath(ctx.path, basePath);
165
+ if (!rewrittenPath) {
136
166
  continue;
137
167
  }
138
- await koaRouter.allowedMethods()(ctx, async () => { });
139
- return true;
140
- }
141
- catch (error) {
142
- const handled = await dispatchHttpError({
143
- ctx,
144
- error,
145
- appName: item.name,
146
- path: ctx.path,
147
- method: ctx.method,
148
- kind: 'koa-router'
149
- });
150
- if (handled) {
168
+ try {
169
+ const matchedContext = ctx;
170
+ const beforeMatched = Array.isArray(matchedContext.matched) ? matchedContext.matched.length : 0;
171
+ const beforeStatus = ctx.status;
172
+ const beforeBody = ctx.body;
173
+ const beforeMatchedRoute = ctx._matchedRoute;
174
+ const beforeRouterPath = ctx.routerPath;
175
+ let fallthrough = false;
176
+ await rewriteCtxPath(ctx, rewrittenPath, async () => {
177
+ await koaRouter.routes()(ctx, async () => {
178
+ fallthrough = true;
179
+ });
180
+ });
181
+ const afterMatched = Array.isArray(matchedContext.matched) ? matchedContext.matched.length : 0;
182
+ const afterMatchedRoute = ctx._matchedRoute;
183
+ const afterRouterPath = ctx.routerPath;
184
+ const handled = afterMatched > beforeMatched
185
+ || afterMatchedRoute !== beforeMatchedRoute
186
+ || afterRouterPath !== beforeRouterPath
187
+ || ctx.status !== beforeStatus
188
+ || ctx.body !== beforeBody
189
+ || !fallthrough;
190
+ if (!handled) {
191
+ continue;
192
+ }
193
+ await rewriteCtxPath(ctx, rewrittenPath, async () => {
194
+ await koaRouter.allowedMethods()(ctx, async () => { });
195
+ });
196
+ return true;
197
+ }
198
+ catch (error) {
199
+ const handled = await dispatchHttpError({
200
+ ctx,
201
+ error,
202
+ appName,
203
+ path: ctx.path,
204
+ method: ctx.method,
205
+ kind: 'koa-router'
206
+ });
207
+ if (handled) {
208
+ return true;
209
+ }
210
+ logger.warn({
211
+ code: ResultCode.Fail,
212
+ message: `Error request ${ctx.path}:`,
213
+ data: error instanceof Error ? error.message : String(error)
214
+ });
215
+ ctx.status = 500;
216
+ ctx.body = {
217
+ code: 500,
218
+ message: '处理 Koa Router 请求时发生错误。',
219
+ error: error instanceof Error ? error.message : String(error)
220
+ };
151
221
  return true;
152
222
  }
153
- logger.warn({
154
- code: ResultCode.Fail,
155
- message: `Error request ${ctx.path}:`,
156
- data: error instanceof Error ? error.message : String(error)
157
- });
158
- ctx.status = 500;
159
- ctx.body = {
160
- code: 500,
161
- message: '处理 Koa Router 请求时发生错误。',
162
- error: error instanceof Error ? error.message : String(error)
163
- };
164
- return true;
165
223
  }
166
224
  }
167
225
  }
@@ -221,7 +279,7 @@ router.use(async (ctx, next) => {
221
279
  }
222
280
  await next();
223
281
  });
224
- router.all('app/{*path}', async (ctx) => {
282
+ const handleMainAppRequest = async (ctx) => {
225
283
  if (!process.env.input) {
226
284
  ctx.status = 400;
227
285
  ctx.body = {
@@ -391,11 +449,11 @@ router.all('app/{*path}', async (ctx) => {
391
449
  };
392
450
  }
393
451
  }
394
- });
395
- router.all('app', ctx => {
396
- ctx.redirect('/app/');
397
- });
398
- router.all('apps/:app/{*path}', async (ctx) => {
452
+ };
453
+ router.all('app', handleMainAppRequest);
454
+ router.all('app/', handleMainAppRequest);
455
+ router.all('app/{*path}', handleMainAppRequest);
456
+ const handlePluginAppRequest = async (ctx) => {
399
457
  const appName = ctx.params.app;
400
458
  if (!isValidPackageName(appName)) {
401
459
  ctx.status = 400;
@@ -564,11 +622,9 @@ router.all('apps/:app/{*path}', async (ctx) => {
564
622
  };
565
623
  }
566
624
  }
567
- });
568
- router.all('apps/:name', ctx => {
569
- if (ctx.path === `/apps/${ctx.params.name}`) {
570
- ctx.redirect(`/apps/${ctx.params.name}/`);
571
- }
572
- });
625
+ };
626
+ router.all('apps/:app', handlePluginAppRequest);
627
+ router.all('apps/:app/', handlePluginAppRequest);
628
+ router.all('apps/:app/{*path}', handlePluginAppRequest);
573
629
 
574
630
  export { router as default };
@@ -36,7 +36,7 @@ const getModuelFile = (dir) => {
36
36
  };
37
37
  const formatPath = (pathValue) => {
38
38
  if (!pathValue || pathValue === '/') {
39
- return '/index.html';
39
+ return 'index.html';
40
40
  }
41
41
  const pates = pathValue.split('/');
42
42
  const lastPath = pates[pates.length - 1];
@@ -21,11 +21,20 @@ const resolvePackageRoot = (startDir) => {
21
21
  }
22
22
  return startDir;
23
23
  };
24
+ const detectDefaultWebRoot = (packageRoot) => {
25
+ if (existsSync(join(packageRoot, 'dist', 'index.html'))) {
26
+ return 'dist';
27
+ }
28
+ if (existsSync(join(packageRoot, 'index.html'))) {
29
+ return '';
30
+ }
31
+ return null;
32
+ };
24
33
  const detectWebCapability = (startDir) => {
25
34
  const packageRoot = resolvePackageRoot(startDir);
26
35
  const packageJsonPath = join(packageRoot, 'package.json');
27
36
  if (!existsSync(packageJsonPath)) {
28
- return existsSync(join(packageRoot, 'index.html'));
37
+ return Boolean(detectDefaultWebRoot(packageRoot));
29
38
  }
30
39
  try {
31
40
  const pkg = require$1(packageJsonPath) ?? {};
@@ -36,7 +45,7 @@ const detectWebCapability = (startDir) => {
36
45
  }
37
46
  catch {
38
47
  }
39
- return existsSync(join(packageRoot, 'index.html'));
48
+ return Boolean(detectDefaultWebRoot(packageRoot));
40
49
  };
41
50
  const loadChildren = async (mainPath, appName) => {
42
51
  if (!mainPath || typeof mainPath !== 'string') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alemonjs",
3
- "version": "2.1.83-alpha.6",
3
+ "version": "2.1.83-alpha.7",
4
4
  "description": "bot script",
5
5
  "author": "lemonade",
6
6
  "license": "MIT",