@yumerijs/core 2.2.2 → 3.0.0-alpha.1
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/dist/context.d.ts +11 -4
- package/dist/context.js +21 -8
- package/dist/core.d.ts +9 -8
- package/dist/core.js +41 -12
- package/dist/route.d.ts +11 -2
- package/dist/route.js +147 -5
- package/dist/server.d.ts +22 -4
- package/dist/server.js +33 -30
- package/dist/session.d.ts +176 -75
- package/dist/session.js +226 -229
- package/package.json +1 -1
package/dist/context.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ interface Plugin {
|
|
|
10
10
|
provide: Array<string>;
|
|
11
11
|
}
|
|
12
12
|
export interface Components {
|
|
13
|
+
[key: string]: any;
|
|
13
14
|
}
|
|
14
15
|
/**
|
|
15
16
|
* 插件上下文对象
|
|
@@ -27,7 +28,7 @@ export declare class Context {
|
|
|
27
28
|
private i18ns;
|
|
28
29
|
component: Components;
|
|
29
30
|
renderer?: IRenderer;
|
|
30
|
-
|
|
31
|
+
module: any;
|
|
31
32
|
childpath: string;
|
|
32
33
|
/** 插件名称 */
|
|
33
34
|
pluginname: string;
|
|
@@ -36,7 +37,7 @@ export declare class Context {
|
|
|
36
37
|
* @param core Core 实例
|
|
37
38
|
* @param pluginname 插件名称
|
|
38
39
|
*/
|
|
39
|
-
constructor(core: Core, pluginname: string,
|
|
40
|
+
constructor(core: Core, pluginname: string, module?: any, injections?: Record<string, any>);
|
|
40
41
|
/**
|
|
41
42
|
* 注入依赖
|
|
42
43
|
* @param name 依赖名称
|
|
@@ -101,10 +102,16 @@ export declare class Context {
|
|
|
101
102
|
fork(name?: string, path?: string): Context;
|
|
102
103
|
/**
|
|
103
104
|
* 注册子插件
|
|
104
|
-
* @param
|
|
105
|
+
* @param module 插件模块
|
|
105
106
|
* @param config 插件配置
|
|
106
107
|
*/
|
|
107
|
-
apply(
|
|
108
|
+
apply(module: Plugin, config: any): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* 快速注册子插件(自动 fork)
|
|
111
|
+
* @param module 插件模块
|
|
112
|
+
* @param config 插件配置
|
|
113
|
+
*/
|
|
114
|
+
plugin(module: Plugin, config?: any): Promise<Context>;
|
|
108
115
|
/**
|
|
109
116
|
* 注册 i18n
|
|
110
117
|
* @param content 内容(可以是嵌套对象或单个key)
|
package/dist/context.js
CHANGED
|
@@ -16,7 +16,7 @@ export class Context {
|
|
|
16
16
|
i18ns = [];
|
|
17
17
|
component;
|
|
18
18
|
renderer;
|
|
19
|
-
|
|
19
|
+
module;
|
|
20
20
|
childpath = '/';
|
|
21
21
|
/** 插件名称 */
|
|
22
22
|
pluginname;
|
|
@@ -25,9 +25,9 @@ export class Context {
|
|
|
25
25
|
* @param core Core 实例
|
|
26
26
|
* @param pluginname 插件名称
|
|
27
27
|
*/
|
|
28
|
-
constructor(core, pluginname,
|
|
28
|
+
constructor(core, pluginname, module, injections = {}) {
|
|
29
29
|
this.core = core;
|
|
30
|
-
this.
|
|
30
|
+
this.module = module;
|
|
31
31
|
this.pluginname = pluginname;
|
|
32
32
|
this.childPlugins = new Map();
|
|
33
33
|
this.component = injections;
|
|
@@ -145,15 +145,28 @@ export class Context {
|
|
|
145
145
|
}
|
|
146
146
|
/**
|
|
147
147
|
* 注册子插件
|
|
148
|
-
* @param
|
|
148
|
+
* @param module 插件模块
|
|
149
149
|
* @param config 插件配置
|
|
150
150
|
*/
|
|
151
|
-
async apply(
|
|
152
|
-
if (!
|
|
151
|
+
async apply(module, config) {
|
|
152
|
+
if (!module)
|
|
153
153
|
return;
|
|
154
154
|
const ctx = this.fork();
|
|
155
|
-
await plugin
|
|
156
|
-
this.childPlugins.set(ctx,
|
|
155
|
+
await this.core.plugin(module, ctx, config);
|
|
156
|
+
this.childPlugins.set(ctx, module);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* 快速注册子插件(自动 fork)
|
|
160
|
+
* @param module 插件模块
|
|
161
|
+
* @param config 插件配置
|
|
162
|
+
*/
|
|
163
|
+
async plugin(module, config = {}) {
|
|
164
|
+
if (!module)
|
|
165
|
+
return;
|
|
166
|
+
const ctx = this.fork();
|
|
167
|
+
await this.core.plugin(module, ctx, config);
|
|
168
|
+
this.childPlugins.set(ctx, module);
|
|
169
|
+
return ctx;
|
|
157
170
|
}
|
|
158
171
|
/**
|
|
159
172
|
* 注册 i18n
|
package/dist/core.d.ts
CHANGED
|
@@ -16,12 +16,12 @@ interface Plugin {
|
|
|
16
16
|
provide: Array<string>;
|
|
17
17
|
}
|
|
18
18
|
export interface CoreOptions {
|
|
19
|
-
port
|
|
20
|
-
host
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
port?: number;
|
|
20
|
+
host?: string;
|
|
21
|
+
enableCors?: boolean;
|
|
22
|
+
enableWs?: boolean;
|
|
23
|
+
lang?: string[];
|
|
24
|
+
skipcheckUpdates?: boolean;
|
|
25
25
|
}
|
|
26
26
|
export declare const coreConfigSchema: Schema<CoreOptions>;
|
|
27
27
|
export declare const enum PluginStatus {
|
|
@@ -44,12 +44,13 @@ export declare class Core {
|
|
|
44
44
|
loader: any;
|
|
45
45
|
renderers: Map<string, IRenderer>;
|
|
46
46
|
pluginRenderers: Map<string, string>;
|
|
47
|
-
constructor(loader?: any, coreConfig?: CoreOptions,
|
|
47
|
+
constructor(loader?: any, coreConfig?: CoreOptions, loggersetCore?: boolean, splash?: boolean);
|
|
48
|
+
checkUpdate(): Promise<void>;
|
|
48
49
|
addRenderer(renderer: IRenderer): void;
|
|
49
50
|
getRendererForPlugin(pluginName: string): string | undefined;
|
|
50
51
|
runCore(): Promise<void>;
|
|
51
52
|
getShortPluginName(pluginName: string): string;
|
|
52
|
-
plugin(
|
|
53
|
+
plugin(module: Plugin, context: Context, config: Config): Promise<void>;
|
|
53
54
|
registerComponent(name: string, component: any): void;
|
|
54
55
|
getComponent(name: string): any;
|
|
55
56
|
unregisterComponent(name: string): void;
|
package/dist/core.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import { Schema } from './config.js';
|
|
2
|
+
import { Schema, fallback } from './config.js';
|
|
3
3
|
import { Logger } from './logger.js';
|
|
4
4
|
import { Route } from './route.js';
|
|
5
5
|
import { Hook } from './hook.js';
|
|
6
6
|
import { Server as CoreServer } from './server.js';
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
const version = JSON.parse(await fs.promises.readFile(new URL('../package.json', import.meta.url), 'utf-8')).version;
|
|
7
9
|
export const coreConfigSchema = Schema.object({
|
|
8
10
|
port: Schema.number('监听端口').default(14510),
|
|
9
11
|
host: Schema.string('监听地址').default('0.0.0.0'),
|
|
10
|
-
staticDir: Schema.string('静态目录').default('public'),
|
|
11
12
|
enableCors: Schema.boolean('启用跨域').default(false),
|
|
12
13
|
enableWs: Schema.boolean('启用 WebSocket').default(false),
|
|
13
14
|
lang: Schema.array(Schema.string(), '语言列表').default(['zh', 'en']),
|
|
15
|
+
skipcheckUpdates: Schema.boolean('启动时检查更新').default(false)
|
|
14
16
|
});
|
|
15
17
|
export class Core {
|
|
16
18
|
emitter = new EventEmitter();
|
|
@@ -25,12 +27,32 @@ export class Core {
|
|
|
25
27
|
loader;
|
|
26
28
|
renderers = new Map();
|
|
27
29
|
pluginRenderers = new Map(); // Stores which plugin uses which renderer
|
|
28
|
-
constructor(loader, coreConfig,
|
|
29
|
-
this.coreConfig = coreConfig
|
|
30
|
+
constructor(loader, coreConfig = {}, loggersetCore = true, splash = true) {
|
|
31
|
+
this.coreConfig = fallback(coreConfigSchema, coreConfig);
|
|
30
32
|
this.loader = loader;
|
|
31
|
-
if (
|
|
33
|
+
if (splash)
|
|
34
|
+
this.logger.info('Welcome to use Yumeri ver.' + version);
|
|
35
|
+
if (!this.coreConfig.skipcheckUpdates)
|
|
36
|
+
this.checkUpdate();
|
|
37
|
+
if (loggersetCore)
|
|
32
38
|
Logger.setCore(this);
|
|
33
39
|
}
|
|
40
|
+
async checkUpdate() {
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch('https://registry.npmjs.org/yumeri/latest');
|
|
43
|
+
if (!response.ok)
|
|
44
|
+
return;
|
|
45
|
+
const { version: latest } = await response.json();
|
|
46
|
+
if (latest !== version) {
|
|
47
|
+
this.logger.info(`There is new version for Yumeri: ${version} -> ${latest}`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
this.logger.error('Error while checking updates: ', error.message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
34
56
|
addRenderer(renderer) {
|
|
35
57
|
if (this.renderers.has(renderer.name)) {
|
|
36
58
|
this.logger.warn(`Renderer "${renderer.name}" is already registered and will be overwritten.`);
|
|
@@ -46,7 +68,6 @@ export class Core {
|
|
|
46
68
|
host: this.coreConfig.host || '0.0.0.0',
|
|
47
69
|
enableCors: this.coreConfig.enableCors || false,
|
|
48
70
|
enableWs: this.coreConfig.enableWs || false,
|
|
49
|
-
staticDir: this.coreConfig.staticDir || 'public',
|
|
50
71
|
});
|
|
51
72
|
await this.server.start();
|
|
52
73
|
}
|
|
@@ -60,12 +81,20 @@ export class Core {
|
|
|
60
81
|
}
|
|
61
82
|
return pluginName;
|
|
62
83
|
}
|
|
63
|
-
async plugin(
|
|
84
|
+
async plugin(module, context, config) {
|
|
64
85
|
const shortName = this.getShortPluginName(context.pluginname);
|
|
65
|
-
context.
|
|
86
|
+
context.module = module;
|
|
87
|
+
// 自动依赖注入
|
|
88
|
+
const depend = module.depend || [];
|
|
89
|
+
for (const name of depend) {
|
|
90
|
+
const component = this.getComponent(name);
|
|
91
|
+
if (component) {
|
|
92
|
+
context.inject(name, component);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
66
95
|
this.logger.info(`apply plugin ${shortName}`);
|
|
67
|
-
if (
|
|
68
|
-
await
|
|
96
|
+
if (module.apply) {
|
|
97
|
+
await module.apply(context, config);
|
|
69
98
|
}
|
|
70
99
|
}
|
|
71
100
|
registerComponent(name, component) {
|
|
@@ -123,7 +152,7 @@ export class Core {
|
|
|
123
152
|
async executeRoute(pathname, session, queryParams) {
|
|
124
153
|
for (const routePath in this.routes) {
|
|
125
154
|
const route = this.routes[routePath];
|
|
126
|
-
const result = route.match(pathname);
|
|
155
|
+
const result = route.match(pathname, session.client?.headers?.host);
|
|
127
156
|
if (result) {
|
|
128
157
|
try {
|
|
129
158
|
this.emit('request:start', {
|
|
@@ -151,7 +180,7 @@ export class Core {
|
|
|
151
180
|
}
|
|
152
181
|
else {
|
|
153
182
|
const start = Date.now();
|
|
154
|
-
await route.executeHandler(session, queryParams, result.pathParams);
|
|
183
|
+
await route.executeHandler(session, queryParams, result.pathParams, result.hostParams);
|
|
155
184
|
this.emit('route:end', {
|
|
156
185
|
path: pathname,
|
|
157
186
|
route: routePath,
|
package/dist/route.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export declare class Route {
|
|
|
25
25
|
allowedMethods: string[];
|
|
26
26
|
ws: WebSocketServer;
|
|
27
27
|
context: Context;
|
|
28
|
+
private routehost;
|
|
28
29
|
/**
|
|
29
30
|
* 创建路由
|
|
30
31
|
* @param path 路由路径
|
|
@@ -37,6 +38,12 @@ export declare class Route {
|
|
|
37
38
|
* @returns this
|
|
38
39
|
*/
|
|
39
40
|
action(handler: RouteHandler): this;
|
|
41
|
+
/**
|
|
42
|
+
* 设置允许的host
|
|
43
|
+
* @param host host列表
|
|
44
|
+
* @returns this
|
|
45
|
+
*/
|
|
46
|
+
host(host: string[] | string): this;
|
|
40
47
|
/**
|
|
41
48
|
* 挂载中间件
|
|
42
49
|
* @param middleware 中间件
|
|
@@ -46,11 +53,13 @@ export declare class Route {
|
|
|
46
53
|
/**
|
|
47
54
|
* 匹配路由
|
|
48
55
|
* @param pathname 请求路径
|
|
56
|
+
* @param host 请求host
|
|
49
57
|
* @returns 匹配结果
|
|
50
58
|
*/
|
|
51
|
-
match(pathname: string): {
|
|
59
|
+
match(pathname: string, host?: string): {
|
|
52
60
|
params: Record<string, string | undefined>;
|
|
53
61
|
pathParams: string[];
|
|
62
|
+
hostParams: Record<string, string>;
|
|
54
63
|
} | null;
|
|
55
64
|
/**
|
|
56
65
|
* 执行路由处理器
|
|
@@ -58,7 +67,7 @@ export declare class Route {
|
|
|
58
67
|
* @param params 查询参数
|
|
59
68
|
* @param pathParams 路由参数
|
|
60
69
|
*/
|
|
61
|
-
executeHandler(session: Session, params: URLSearchParams, pathParams: string[]): Promise<void>;
|
|
70
|
+
executeHandler(session: Session, params: URLSearchParams, pathParams: string[], hostParams: Record<string, string>): Promise<void>;
|
|
62
71
|
/**
|
|
63
72
|
* 设置可用方法
|
|
64
73
|
* @param methods 可用方法
|
package/dist/route.js
CHANGED
|
@@ -22,6 +22,23 @@ function parsePatternToSegments(pattern) {
|
|
|
22
22
|
}
|
|
23
23
|
return { segments, params };
|
|
24
24
|
}
|
|
25
|
+
function parseHostToSegments(hostPattern) {
|
|
26
|
+
// 移除可能的空格,按 . 分割
|
|
27
|
+
const parts = hostPattern.split('.');
|
|
28
|
+
return parts.map(part => {
|
|
29
|
+
// 简单的参数解析逻辑
|
|
30
|
+
if (part.startsWith(':')) {
|
|
31
|
+
const lastChar = part[part.length - 1];
|
|
32
|
+
const hasModifier = ['?', '+', '*'].includes(lastChar);
|
|
33
|
+
return {
|
|
34
|
+
type: 'param',
|
|
35
|
+
name: hasModifier ? part.slice(1, -1) : part.slice(1),
|
|
36
|
+
modifier: hasModifier ? lastChar : '',
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return { type: 'static', value: part };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
25
42
|
/**
|
|
26
43
|
* Route class using segment-based matching (no fragile capture-group-index mapping).
|
|
27
44
|
* Behavior matches the SimpleRouter in the webpage:
|
|
@@ -39,6 +56,7 @@ export class Route {
|
|
|
39
56
|
allowedMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'];
|
|
40
57
|
ws = null;
|
|
41
58
|
context;
|
|
59
|
+
routehost = null;
|
|
42
60
|
/**
|
|
43
61
|
* 创建路由
|
|
44
62
|
* @param path 路由路径
|
|
@@ -60,6 +78,20 @@ export class Route {
|
|
|
60
78
|
this.handler = handler;
|
|
61
79
|
return this;
|
|
62
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* 设置允许的host
|
|
83
|
+
* @param host host列表
|
|
84
|
+
* @returns this
|
|
85
|
+
*/
|
|
86
|
+
host(host) {
|
|
87
|
+
if (typeof host === 'string') {
|
|
88
|
+
this.routehost = [host];
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.routehost = host;
|
|
92
|
+
}
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
63
95
|
/**
|
|
64
96
|
* 挂载中间件
|
|
65
97
|
* @param middleware 中间件
|
|
@@ -72,9 +104,117 @@ export class Route {
|
|
|
72
104
|
/**
|
|
73
105
|
* 匹配路由
|
|
74
106
|
* @param pathname 请求路径
|
|
107
|
+
* @param host 请求host
|
|
75
108
|
* @returns 匹配结果
|
|
76
109
|
*/
|
|
77
|
-
match(pathname) {
|
|
110
|
+
match(pathname, host) {
|
|
111
|
+
let hostParams = {};
|
|
112
|
+
// Host 匹配逻辑开始
|
|
113
|
+
if (this.routehost && this.routehost.length > 0) {
|
|
114
|
+
if (!host)
|
|
115
|
+
return null; // 如果设置了 host 限制但没有传入 host,直接失败
|
|
116
|
+
const actualHost = host.toLowerCase().split(':')[0]; // 移除端口并转小写
|
|
117
|
+
const hostParts = actualHost.split('.');
|
|
118
|
+
let hostMatched = false;
|
|
119
|
+
for (const pattern of this.routehost) {
|
|
120
|
+
const hSegments = parseHostToSegments(pattern); // 这里的 parsePattern 应该和你 path 解析逻辑一致
|
|
121
|
+
let hi = 0; // pattern segment index
|
|
122
|
+
let hj = 0; // actual host parts index
|
|
123
|
+
let tempParams = {};
|
|
124
|
+
let possible = true;
|
|
125
|
+
while (hi < hSegments.length) {
|
|
126
|
+
const seg = hSegments[hi];
|
|
127
|
+
const nextSegIsStatic = !!hSegments[hi + 1] && hSegments[hi + 1].type === 'static';
|
|
128
|
+
if (seg.type === 'static') {
|
|
129
|
+
if (hj >= hostParts.length || hostParts[hj] !== seg.value.toLowerCase()) {
|
|
130
|
+
possible = false;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
hi++;
|
|
134
|
+
hj++;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// 参数匹配逻辑 (:, ?, +, *)
|
|
138
|
+
switch (seg.modifier) {
|
|
139
|
+
case '': // required single
|
|
140
|
+
if (hj >= hostParts.length) {
|
|
141
|
+
possible = false;
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
tempParams[seg.name] = hostParts[hj];
|
|
145
|
+
hi++;
|
|
146
|
+
hj++;
|
|
147
|
+
break;
|
|
148
|
+
case '?': // optional single
|
|
149
|
+
if (hj < hostParts.length) {
|
|
150
|
+
if (nextSegIsStatic && hostParts[hj] === hSegments[hi + 1].value.toLowerCase()) {
|
|
151
|
+
tempParams[seg.name] = undefined;
|
|
152
|
+
hi++;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
tempParams[seg.name] = hostParts[hj];
|
|
156
|
+
hj++;
|
|
157
|
+
hi++;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
tempParams[seg.name] = undefined;
|
|
162
|
+
hi++;
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
case '+': // required multi
|
|
166
|
+
if (hj >= hostParts.length) {
|
|
167
|
+
possible = false;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
let endP = hostParts.length;
|
|
171
|
+
if (nextSegIsStatic) {
|
|
172
|
+
let found = hostParts.indexOf(hSegments[hi + 1].value.toLowerCase(), hj);
|
|
173
|
+
if (found === -1) {
|
|
174
|
+
possible = false;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
endP = found;
|
|
178
|
+
}
|
|
179
|
+
if (endP === hj) {
|
|
180
|
+
possible = false;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
tempParams[seg.name] = hostParts.slice(hj, endP).join('.');
|
|
184
|
+
hj = endP;
|
|
185
|
+
hi++;
|
|
186
|
+
break;
|
|
187
|
+
case '*': // optional multi
|
|
188
|
+
let endS = hostParts.length;
|
|
189
|
+
if (nextSegIsStatic) {
|
|
190
|
+
let found = hostParts.indexOf(hSegments[hi + 1].value.toLowerCase(), hj);
|
|
191
|
+
if (found !== -1)
|
|
192
|
+
endS = found;
|
|
193
|
+
}
|
|
194
|
+
const val = hostParts.slice(hj, endS).join('.');
|
|
195
|
+
tempParams[seg.name] = val === '' ? undefined : val;
|
|
196
|
+
hj = endS;
|
|
197
|
+
hi++;
|
|
198
|
+
break;
|
|
199
|
+
default:
|
|
200
|
+
possible = false;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
if (!possible)
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (possible && hj === hostParts.length) {
|
|
208
|
+
hostMatched = true;
|
|
209
|
+
hostParams = tempParams;
|
|
210
|
+
break; // 只要匹配到一个 host pattern 就行
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (!hostMatched)
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
// Host 匹配逻辑结束
|
|
217
|
+
// 路由匹配逻辑开始
|
|
78
218
|
if (pathname.startsWith('/')) {
|
|
79
219
|
// normalize pathname: remove leading/trailing slashes
|
|
80
220
|
const normPath = pathname.replace(/^\/+|\/+$/g, '');
|
|
@@ -198,10 +338,12 @@ export class Route {
|
|
|
198
338
|
// after finishing pattern, path must be fully consumed (no extra segments)
|
|
199
339
|
if (j !== parts.length)
|
|
200
340
|
return null;
|
|
201
|
-
|
|
341
|
+
const result = { params, pathParams, hostParams };
|
|
342
|
+
return result;
|
|
202
343
|
}
|
|
203
344
|
else if (pathname.startsWith('root') && this.path == pathname) {
|
|
204
|
-
|
|
345
|
+
const result = { params: { pathname }, pathParams: [pathname], hostParams };
|
|
346
|
+
return result;
|
|
205
347
|
}
|
|
206
348
|
return null;
|
|
207
349
|
}
|
|
@@ -211,9 +353,9 @@ export class Route {
|
|
|
211
353
|
* @param params 查询参数
|
|
212
354
|
* @param pathParams 路由参数
|
|
213
355
|
*/
|
|
214
|
-
async executeHandler(session, params, pathParams) {
|
|
356
|
+
async executeHandler(session, params, pathParams, hostParams) {
|
|
215
357
|
if (this.handler) {
|
|
216
|
-
await this.handler(session, params, ...pathParams);
|
|
358
|
+
await this.handler(session, params, ...pathParams, ...Object.values(hostParams));
|
|
217
359
|
}
|
|
218
360
|
}
|
|
219
361
|
/**
|
package/dist/server.d.ts
CHANGED
|
@@ -1,24 +1,42 @@
|
|
|
1
1
|
import { Core } from './core.js';
|
|
2
|
+
/** 服务器配置接口 */
|
|
2
3
|
export interface ServerConfig {
|
|
4
|
+
/** 监听端口 */
|
|
3
5
|
port: number;
|
|
6
|
+
/** 监听主机 */
|
|
4
7
|
host: string;
|
|
8
|
+
/** 是否启用跨域 */
|
|
5
9
|
enableCors: boolean;
|
|
6
|
-
|
|
10
|
+
/** 是否启用 WebSocket */
|
|
7
11
|
enableWs: boolean;
|
|
8
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* 核心服务器类
|
|
15
|
+
* 负责底层 HTTP 请求的监听、分发和响应
|
|
16
|
+
*/
|
|
9
17
|
export declare class Server {
|
|
10
18
|
core: Core;
|
|
11
19
|
private port;
|
|
12
20
|
private host;
|
|
13
21
|
private enableCors;
|
|
14
|
-
private staticDir;
|
|
15
22
|
private httpServer;
|
|
16
23
|
constructor(core: Core, config?: Partial<ServerConfig>);
|
|
17
|
-
|
|
24
|
+
/**
|
|
25
|
+
* 创建一个新的会话对象
|
|
26
|
+
*/
|
|
18
27
|
private createSession;
|
|
28
|
+
/**
|
|
29
|
+
* 解析请求中的 Cookie
|
|
30
|
+
*/
|
|
19
31
|
private parseCookies;
|
|
32
|
+
/**
|
|
33
|
+
* 获取客户端真实 IP
|
|
34
|
+
*/
|
|
20
35
|
private getClientIP;
|
|
21
|
-
|
|
36
|
+
/**
|
|
37
|
+
* 启动服务器
|
|
38
|
+
*/
|
|
22
39
|
start(): Promise<void>;
|
|
40
|
+
/** 停止服务器 */
|
|
23
41
|
stop(): void;
|
|
24
42
|
}
|