@yumerijs/core 2.0.12 → 2.0.14
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 -1
- package/dist/context.js +12 -1
- package/dist/server.js +50 -68
- package/dist/session.d.ts +31 -1
- package/dist/session.js +44 -4
- package/package.json +1 -1
package/dist/context.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ interface Plugin {
|
|
|
9
9
|
depend: Array<string>;
|
|
10
10
|
provide: Array<string>;
|
|
11
11
|
}
|
|
12
|
+
export interface Components {
|
|
13
|
+
}
|
|
12
14
|
/**
|
|
13
15
|
* 插件上下文对象
|
|
14
16
|
* 每个插件一个 Context,用于管理插件注册的命令、路由、事件、组件和中间件
|
|
@@ -23,6 +25,7 @@ export declare class Context {
|
|
|
23
25
|
private childContexts;
|
|
24
26
|
private childPlugins;
|
|
25
27
|
private i18ns;
|
|
28
|
+
component: Components;
|
|
26
29
|
/** 插件名称 */
|
|
27
30
|
pluginname: string;
|
|
28
31
|
/**
|
|
@@ -30,7 +33,13 @@ export declare class Context {
|
|
|
30
33
|
* @param core Core 实例
|
|
31
34
|
* @param pluginname 插件名称
|
|
32
35
|
*/
|
|
33
|
-
constructor(core: Core, pluginname: string);
|
|
36
|
+
constructor(core: Core, pluginname: string, injections?: Record<string, any>);
|
|
37
|
+
/**
|
|
38
|
+
* 注入依赖
|
|
39
|
+
* @param name 依赖名称
|
|
40
|
+
* @param value 依赖值
|
|
41
|
+
*/
|
|
42
|
+
inject(name: string, value: any): void;
|
|
34
43
|
/**
|
|
35
44
|
* 注册路由
|
|
36
45
|
* @param path 路由路径
|
|
@@ -72,6 +81,7 @@ export declare class Context {
|
|
|
72
81
|
emit(event: string, ...args: any[]): Promise<void>;
|
|
73
82
|
/**
|
|
74
83
|
* 获取组件实例
|
|
84
|
+
* @deprecated
|
|
75
85
|
* @param name 组件名称
|
|
76
86
|
*/
|
|
77
87
|
getComponent(name: string): any;
|
package/dist/context.js
CHANGED
|
@@ -16,6 +16,7 @@ class Context {
|
|
|
16
16
|
childContexts = [];
|
|
17
17
|
childPlugins = new Map();
|
|
18
18
|
i18ns = [];
|
|
19
|
+
component;
|
|
19
20
|
/** 插件名称 */
|
|
20
21
|
pluginname;
|
|
21
22
|
/**
|
|
@@ -23,10 +24,19 @@ class Context {
|
|
|
23
24
|
* @param core Core 实例
|
|
24
25
|
* @param pluginname 插件名称
|
|
25
26
|
*/
|
|
26
|
-
constructor(core, pluginname) {
|
|
27
|
+
constructor(core, pluginname, injections = {}) {
|
|
27
28
|
this.core = core;
|
|
28
29
|
this.pluginname = pluginname;
|
|
29
30
|
this.childPlugins = new Map();
|
|
31
|
+
this.component = injections;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 注入依赖
|
|
35
|
+
* @param name 依赖名称
|
|
36
|
+
* @param value 依赖值
|
|
37
|
+
*/
|
|
38
|
+
inject(name, value) {
|
|
39
|
+
this.component[name] = value;
|
|
30
40
|
}
|
|
31
41
|
/**
|
|
32
42
|
* 注册路由
|
|
@@ -99,6 +109,7 @@ class Context {
|
|
|
99
109
|
}
|
|
100
110
|
/**
|
|
101
111
|
* 获取组件实例
|
|
112
|
+
* @deprecated
|
|
102
113
|
* @param name 组件名称
|
|
103
114
|
*/
|
|
104
115
|
getComponent(name) {
|
package/dist/server.js
CHANGED
|
@@ -45,6 +45,9 @@ const path = __importStar(require("path"));
|
|
|
45
45
|
const url_1 = require("url");
|
|
46
46
|
const mime = __importStar(require("mime-types"));
|
|
47
47
|
const logger = new logger_1.Logger('server');
|
|
48
|
+
function isStream(value) {
|
|
49
|
+
return value && typeof value.pipe === "function";
|
|
50
|
+
}
|
|
48
51
|
class Server {
|
|
49
52
|
core;
|
|
50
53
|
port;
|
|
@@ -112,81 +115,60 @@ class Server {
|
|
|
112
115
|
const session = this.createSession(ip, cookies, res, req, pathname, { protocol: 'http', header: req.headers });
|
|
113
116
|
const route = this.core.getRoute(pathname);
|
|
114
117
|
const rootroute = this.core.getRoute('root');
|
|
115
|
-
|
|
116
|
-
const matched = await this.core.executeRoute(
|
|
118
|
+
const handleRoute = async (routePath) => {
|
|
119
|
+
const matched = await this.core.executeRoute(routePath, session, queryParams);
|
|
117
120
|
if (!matched) {
|
|
118
121
|
this.serveStaticFile(pathname, res);
|
|
122
|
+
return;
|
|
119
123
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (this.enableCors) {
|
|
146
|
-
head['Access-Control-Allow-Origin'] = '*';
|
|
147
|
-
}
|
|
148
|
-
res.writeHead(session.status ?? 200, head);
|
|
124
|
+
if (session.responseHandled)
|
|
125
|
+
return;
|
|
126
|
+
const head = { ...session.head };
|
|
127
|
+
head['Set-Cookie'] = Object.entries(session.newCookie).map(([name, cookie]) => {
|
|
128
|
+
let cookieString = `${name}=${cookie.value}`;
|
|
129
|
+
if (cookie.options.expires)
|
|
130
|
+
cookieString += `; Expires=${cookie.options.expires.toUTCString()}`;
|
|
131
|
+
if (cookie.options.path)
|
|
132
|
+
cookieString += `; Path=${cookie.options.path}`;
|
|
133
|
+
if (cookie.options.domain)
|
|
134
|
+
cookieString += `; Domain=${cookie.options.domain}`;
|
|
135
|
+
if (cookie.options.secure)
|
|
136
|
+
cookieString += `; Secure`;
|
|
137
|
+
if (cookie.options.httpOnly)
|
|
138
|
+
cookieString += `; HttpOnly`;
|
|
139
|
+
if (cookie.options.sameSite)
|
|
140
|
+
cookieString += `; SameSite=${cookie.options.sameSite}`;
|
|
141
|
+
return cookieString;
|
|
142
|
+
});
|
|
143
|
+
if (this.enableCors) {
|
|
144
|
+
head['Access-Control-Allow-Origin'] = '*';
|
|
145
|
+
}
|
|
146
|
+
res.writeHead(session.status ?? 200, head);
|
|
147
|
+
switch (session.restype) {
|
|
148
|
+
case 'plain':
|
|
149
149
|
res.end(session.body);
|
|
150
|
-
|
|
150
|
+
break;
|
|
151
|
+
case 'buffer':
|
|
152
|
+
res.end(session.body);
|
|
153
|
+
break;
|
|
154
|
+
case 'json':
|
|
155
|
+
res.end(JSON.stringify(session.body));
|
|
156
|
+
break;
|
|
157
|
+
case 'stream':
|
|
158
|
+
if (isStream(session.body)) {
|
|
159
|
+
const stream = session.body;
|
|
160
|
+
stream.pipe(res);
|
|
161
|
+
}
|
|
162
|
+
break;
|
|
163
|
+
default:
|
|
164
|
+
res.end(session.body); // fallback
|
|
151
165
|
}
|
|
166
|
+
};
|
|
167
|
+
if (route && route.allowedMethods.includes(req.method ?? 'GET')) {
|
|
168
|
+
await handleRoute(pathname);
|
|
152
169
|
}
|
|
153
170
|
else if (rootroute && rootroute.allowedMethods.includes(req.method ?? 'GET')) {
|
|
154
|
-
|
|
155
|
-
if (!matched) {
|
|
156
|
-
this.serveStaticFile(pathname, res);
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
if (!session.responseHandled) {
|
|
160
|
-
let head = session.head;
|
|
161
|
-
head['Set-Cookie'] = Object.entries(session.newCookie).map(([name, cookie]) => {
|
|
162
|
-
let cookieString = `${name}=${cookie.value}`;
|
|
163
|
-
if (cookie.options.expires) {
|
|
164
|
-
cookieString += `; Expires=${cookie.options.expires.toUTCString()}`;
|
|
165
|
-
}
|
|
166
|
-
if (cookie.options.path) {
|
|
167
|
-
cookieString += `; Path=${cookie.options.path}`;
|
|
168
|
-
}
|
|
169
|
-
if (cookie.options.domain) {
|
|
170
|
-
cookieString += `; Domain=${cookie.options.domain}`;
|
|
171
|
-
}
|
|
172
|
-
if (cookie.options.secure) {
|
|
173
|
-
cookieString += `; Secure`;
|
|
174
|
-
}
|
|
175
|
-
if (cookie.options.httpOnly) {
|
|
176
|
-
cookieString += `; HttpOnly`;
|
|
177
|
-
}
|
|
178
|
-
if (cookie.options.sameSite) {
|
|
179
|
-
cookieString += `; SameSite=${cookie.options.sameSite}`;
|
|
180
|
-
}
|
|
181
|
-
return cookieString;
|
|
182
|
-
});
|
|
183
|
-
if (this.enableCors) {
|
|
184
|
-
head['Access-Control-Allow-Origin'] = '*';
|
|
185
|
-
}
|
|
186
|
-
res.writeHead(session.status ?? 200, head);
|
|
187
|
-
res.end(session.body);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
171
|
+
await handleRoute('root');
|
|
190
172
|
}
|
|
191
173
|
else {
|
|
192
174
|
this.serveStaticFile(pathname, res);
|
package/dist/session.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
**/
|
|
6
6
|
import { Server } from './server';
|
|
7
7
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
8
|
+
import { Stream } from "stream";
|
|
8
9
|
type ParsedParams = Record<string, string | string[] | undefined>;
|
|
9
10
|
export interface Client {
|
|
10
11
|
req: IncomingMessage;
|
|
@@ -34,6 +35,13 @@ export interface StaticCacheOptions {
|
|
|
34
35
|
smaxAge?: number;
|
|
35
36
|
etagType?: 'md5' | 'sha1' | 'sha256' | 'sha512';
|
|
36
37
|
}
|
|
38
|
+
type ResType = "plain" | "json" | "stream" | "buffer";
|
|
39
|
+
interface BodyMap {
|
|
40
|
+
plain: string;
|
|
41
|
+
json: Record<string, any>;
|
|
42
|
+
stream: Stream;
|
|
43
|
+
buffer: Buffer;
|
|
44
|
+
}
|
|
37
45
|
export declare class Session {
|
|
38
46
|
ip: string;
|
|
39
47
|
cookie: Record<string, string>;
|
|
@@ -46,7 +54,8 @@ export declare class Session {
|
|
|
46
54
|
}>;
|
|
47
55
|
head: Record<string, any>;
|
|
48
56
|
status: number;
|
|
49
|
-
|
|
57
|
+
private _restype;
|
|
58
|
+
private _body;
|
|
50
59
|
properties?: Record<string, any>;
|
|
51
60
|
client: Client;
|
|
52
61
|
server: Server;
|
|
@@ -61,6 +70,10 @@ export declare class Session {
|
|
|
61
70
|
* @param query 请求字符串
|
|
62
71
|
*/
|
|
63
72
|
constructor(ip: string, cookie: Record<string, string>, server: Server, req?: IncomingMessage, res?: ServerResponse, pathname?: string, query?: Record<string, string>);
|
|
73
|
+
response<T extends ResType>(body: BodyMap[T], type?: T): void;
|
|
74
|
+
get restype(): ResType;
|
|
75
|
+
get body(): string;
|
|
76
|
+
set body(value: string);
|
|
64
77
|
setCookie(name: string, value: string, options?: CookieOptions): void;
|
|
65
78
|
/**
|
|
66
79
|
* 解析 Accept-Language 字符串为排序后的语言数组
|
|
@@ -104,7 +117,24 @@ export declare class Session {
|
|
|
104
117
|
* @param option 选项
|
|
105
118
|
*/
|
|
106
119
|
setCache(option: CacheOptions): void;
|
|
120
|
+
/**
|
|
121
|
+
* 设置静态文件
|
|
122
|
+
* @param content 文件内容
|
|
123
|
+
* @param option 选项
|
|
124
|
+
*/
|
|
107
125
|
static(content: string, option: CacheOptions): void;
|
|
126
|
+
/**
|
|
127
|
+
* 发送静态文件
|
|
128
|
+
* @param path 文件路径
|
|
129
|
+
* @param option 缓存选项
|
|
130
|
+
* @returns void
|
|
131
|
+
*/
|
|
108
132
|
file(path: string, option: StaticCacheOptions): void;
|
|
133
|
+
/**
|
|
134
|
+
* 发送普通文件
|
|
135
|
+
* @param path 文件路径
|
|
136
|
+
* @param isStream 是否流式传输
|
|
137
|
+
*/
|
|
138
|
+
sendFile(path: string, isStream?: boolean): void;
|
|
109
139
|
}
|
|
110
140
|
export {};
|
package/dist/session.js
CHANGED
|
@@ -54,7 +54,8 @@ class Session {
|
|
|
54
54
|
newCookie = {};
|
|
55
55
|
head = {};
|
|
56
56
|
status = 200;
|
|
57
|
-
|
|
57
|
+
_restype = "plain";
|
|
58
|
+
_body;
|
|
58
59
|
properties = {};
|
|
59
60
|
client = null;
|
|
60
61
|
server;
|
|
@@ -108,6 +109,20 @@ class Session {
|
|
|
108
109
|
this.setCookie('lang', this.languages.join(','));
|
|
109
110
|
}
|
|
110
111
|
}
|
|
112
|
+
response(body, type = 'text') {
|
|
113
|
+
this._restype = type;
|
|
114
|
+
this._body = body;
|
|
115
|
+
}
|
|
116
|
+
get restype() {
|
|
117
|
+
return this._restype;
|
|
118
|
+
}
|
|
119
|
+
get body() {
|
|
120
|
+
return this._body;
|
|
121
|
+
}
|
|
122
|
+
set body(value) {
|
|
123
|
+
this._body = value;
|
|
124
|
+
this._restype = "plain"; // 自动把 restype 设成 plain
|
|
125
|
+
}
|
|
111
126
|
setCookie(name, value, options = {}) {
|
|
112
127
|
if (options.path === undefined) {
|
|
113
128
|
options.path = '/';
|
|
@@ -293,7 +308,7 @@ class Session {
|
|
|
293
308
|
*/
|
|
294
309
|
setCache(option) {
|
|
295
310
|
if (option.etag)
|
|
296
|
-
this.head['ETag'] =
|
|
311
|
+
this.head['ETag'] = `${option.etag}`;
|
|
297
312
|
if (option.modified)
|
|
298
313
|
this.head['Last-Modified'] = option.modified.toUTCString();
|
|
299
314
|
let control = [];
|
|
@@ -310,6 +325,11 @@ class Session {
|
|
|
310
325
|
if (option.expires)
|
|
311
326
|
this.head['Expires'] = option.expires.toUTCString();
|
|
312
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* 设置静态文件
|
|
330
|
+
* @param content 文件内容
|
|
331
|
+
* @param option 选项
|
|
332
|
+
*/
|
|
313
333
|
static(content, option) {
|
|
314
334
|
// 先查看用户是否在询问文件修改情况
|
|
315
335
|
if (this.client.headers['If-Modified-Since']) {
|
|
@@ -326,8 +346,14 @@ class Session {
|
|
|
326
346
|
}
|
|
327
347
|
}
|
|
328
348
|
this.setCache(option);
|
|
329
|
-
this.
|
|
349
|
+
this.response(content);
|
|
330
350
|
}
|
|
351
|
+
/**
|
|
352
|
+
* 发送静态文件
|
|
353
|
+
* @param path 文件路径
|
|
354
|
+
* @param option 缓存选项
|
|
355
|
+
* @returns void
|
|
356
|
+
*/
|
|
331
357
|
file(path, option) {
|
|
332
358
|
if (this.client.headers['If-Modified-Since']) {
|
|
333
359
|
const modified = new Date(this.client.headers['If-Modified-Since']);
|
|
@@ -353,7 +379,21 @@ class Session {
|
|
|
353
379
|
smaxAge: option.smaxAge,
|
|
354
380
|
cacheControl: 'public'
|
|
355
381
|
});
|
|
356
|
-
this.
|
|
382
|
+
this.response(fs_1.default.createReadStream(path), 'stream');
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* 发送普通文件
|
|
386
|
+
* @param path 文件路径
|
|
387
|
+
* @param isStream 是否流式传输
|
|
388
|
+
*/
|
|
389
|
+
sendFile(path, isStream = false) {
|
|
390
|
+
if (isStream) {
|
|
391
|
+
this.setMime('application/octet-stream');
|
|
392
|
+
this.response(fs_1.default.createReadStream(path), 'stream');
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
this.response(fs_1.default.readFileSync(path), 'buffer');
|
|
396
|
+
}
|
|
357
397
|
}
|
|
358
398
|
}
|
|
359
399
|
exports.Session = Session;
|