@radatek/microserver 2.0.0 → 2.0.2
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/microserver.d.ts +15 -4
- package/dist/microserver.js +55 -42
- package/package.json +1 -7
package/dist/microserver.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MicroServer
|
|
3
|
-
* @version 2.0.
|
|
3
|
+
* @version 2.0.2
|
|
4
4
|
* @package @radatek/microserver
|
|
5
5
|
* @copyright Darius Kisonas 2022
|
|
6
6
|
* @license MIT
|
|
@@ -31,9 +31,17 @@ export declare class WebSocketError extends Error {
|
|
|
31
31
|
statusCode: number;
|
|
32
32
|
constructor(text?: string, code?: number);
|
|
33
33
|
}
|
|
34
|
+
export type Routes = () => {
|
|
35
|
+
[key: string]: Array<any>;
|
|
36
|
+
} | {
|
|
37
|
+
[key: string]: Array<any>;
|
|
38
|
+
};
|
|
34
39
|
export declare abstract class Plugin {
|
|
40
|
+
name?: string;
|
|
35
41
|
priority?: number;
|
|
36
42
|
handler?(req: ServerRequest, res: ServerResponse, next: Function): void;
|
|
43
|
+
controller?: typeof Controller;
|
|
44
|
+
routes?: () => Routes | Routes;
|
|
37
45
|
constructor(router: Router, ...args: any);
|
|
38
46
|
}
|
|
39
47
|
interface PluginClass {
|
|
@@ -215,6 +223,9 @@ export interface Middleware {
|
|
|
215
223
|
export declare class Router extends EventEmitter {
|
|
216
224
|
server: MicroServer;
|
|
217
225
|
auth?: Auth;
|
|
226
|
+
plugins: {
|
|
227
|
+
[key: string]: Plugin;
|
|
228
|
+
};
|
|
218
229
|
/** @param {MicroServer} server */
|
|
219
230
|
constructor(server: MicroServer);
|
|
220
231
|
/** Handler */
|
|
@@ -272,7 +283,7 @@ export declare class Router extends EventEmitter {
|
|
|
272
283
|
* @param { {[key: string]: Array<any>} } routes list with subroutes: 'METHOD /suburl': [...middlewares]
|
|
273
284
|
* @return {Router} current router
|
|
274
285
|
*/
|
|
275
|
-
|
|
286
|
+
use(...args: any): Router;
|
|
276
287
|
/** Add hook */
|
|
277
288
|
hook(url: string, ...mid: Middleware[]): Router;
|
|
278
289
|
/** Check if middleware allready added */
|
|
@@ -353,7 +364,7 @@ export declare class MicroServer extends EventEmitter {
|
|
|
353
364
|
static plugins: {
|
|
354
365
|
[key: string]: PluginClass;
|
|
355
366
|
};
|
|
356
|
-
plugins: {
|
|
367
|
+
get plugins(): {
|
|
357
368
|
[key: string]: Plugin;
|
|
358
369
|
};
|
|
359
370
|
constructor(config: MicroServerConfig);
|
|
@@ -576,7 +587,7 @@ export declare class FileStore {
|
|
|
576
587
|
/** load json file data */
|
|
577
588
|
load(name: string, autosave?: boolean): Promise<any>;
|
|
578
589
|
/** save data */
|
|
579
|
-
save(name: string, data: any): Promise<
|
|
590
|
+
save(name: string, data: any): Promise<any>;
|
|
580
591
|
/** load all files in directory */
|
|
581
592
|
all(name: string, autosave?: boolean): Promise<{
|
|
582
593
|
[key: string]: any;
|
package/dist/microserver.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MicroServer
|
|
3
|
-
* @version 2.0.
|
|
3
|
+
* @version 2.0.2
|
|
4
4
|
* @package @radatek/microserver
|
|
5
5
|
* @copyright Darius Kisonas 2022
|
|
6
6
|
* @license MIT
|
|
@@ -897,6 +897,7 @@ export class Router extends EventEmitter {
|
|
|
897
897
|
/** @param {MicroServer} server */
|
|
898
898
|
constructor(server) {
|
|
899
899
|
super();
|
|
900
|
+
this.plugins = {};
|
|
900
901
|
this._stack = [];
|
|
901
902
|
this._stackAfter = [];
|
|
902
903
|
this._tree = {};
|
|
@@ -1096,32 +1097,26 @@ export class Router extends EventEmitter {
|
|
|
1096
1097
|
* @param { {[key: string]: Array<any>} } routes list with subroutes: 'METHOD /suburl': [...middlewares]
|
|
1097
1098
|
* @return {Router} current router
|
|
1098
1099
|
*/
|
|
1099
|
-
|
|
1100
|
+
use(...args) {
|
|
1100
1101
|
if (!args[0])
|
|
1101
1102
|
return this;
|
|
1102
|
-
//
|
|
1103
|
+
// use(plugin)
|
|
1103
1104
|
if (args[0] instanceof Plugin)
|
|
1104
1105
|
return this._plugin(args[0]);
|
|
1105
|
-
//
|
|
1106
|
+
// use(pluginid, ...args)
|
|
1106
1107
|
if (typeof args[0] === 'string' && MicroServer.plugins[args[0]]) {
|
|
1107
1108
|
const constructor = MicroServer.plugins[args[0]];
|
|
1108
1109
|
const plugin = new constructor(this, ...args.slice(1));
|
|
1109
1110
|
return this._plugin(plugin);
|
|
1110
1111
|
}
|
|
1112
|
+
// use(PluginClass, ...args)
|
|
1111
1113
|
if (args[0].prototype instanceof Plugin) {
|
|
1112
1114
|
const plugin = new args[0](this, ...args.slice(1));
|
|
1113
1115
|
return this._plugin(plugin);
|
|
1114
1116
|
}
|
|
1117
|
+
// use(middleware)
|
|
1115
1118
|
if (typeof args[0] === 'function') {
|
|
1116
|
-
|
|
1117
|
-
constructor() {
|
|
1118
|
-
super(...arguments);
|
|
1119
|
-
this.priority = args[0].priority;
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
const middleware = new Middleware(this);
|
|
1123
|
-
middleware.handler = args[0];
|
|
1124
|
-
return this._plugin(middleware);
|
|
1119
|
+
return this._middleware(args[0]);
|
|
1125
1120
|
}
|
|
1126
1121
|
let method = '*', url = '/';
|
|
1127
1122
|
if (typeof args[0] === 'string') {
|
|
@@ -1134,13 +1129,13 @@ export class Router extends EventEmitter {
|
|
|
1134
1129
|
throw new Error(`Invalid url ${url}`);
|
|
1135
1130
|
args = args.slice(1);
|
|
1136
1131
|
}
|
|
1137
|
-
//
|
|
1132
|
+
// use('/url', ControllerClass)
|
|
1138
1133
|
if (typeof args[0] === 'function' && args[0].prototype instanceof Controller) {
|
|
1139
1134
|
const routes = args[0].routes();
|
|
1140
1135
|
if (routes)
|
|
1141
1136
|
args[0] = routes;
|
|
1142
1137
|
}
|
|
1143
|
-
//
|
|
1138
|
+
// use('/url', [ ['METHOD /url', ...], {'METHOD } ])
|
|
1144
1139
|
if (Array.isArray(args[0])) {
|
|
1145
1140
|
if (method !== '*')
|
|
1146
1141
|
throw new Error('Invalid router usage');
|
|
@@ -1149,25 +1144,25 @@ export class Router extends EventEmitter {
|
|
|
1149
1144
|
// [methodUrl, ...middlewares]
|
|
1150
1145
|
if (typeof item[0] !== 'string' || !item[0].match(/^(\w+ )?\//))
|
|
1151
1146
|
throw new Error('Url expected');
|
|
1152
|
-
return this.
|
|
1147
|
+
return this.use(item[0].replace(/\//, (url === '/' ? '' : url) + '/'), ...item.slice(1));
|
|
1153
1148
|
}
|
|
1154
1149
|
else
|
|
1155
1150
|
throw new Error('Invalid param');
|
|
1156
1151
|
});
|
|
1157
1152
|
return this;
|
|
1158
1153
|
}
|
|
1159
|
-
//
|
|
1154
|
+
// use('/url', {'METHOD /url': [...middlewares], ... } ])
|
|
1160
1155
|
if (typeof args[0] === 'object' && args[0].constructor === Object) {
|
|
1161
1156
|
if (method !== '*')
|
|
1162
1157
|
throw new Error('Invalid router usage');
|
|
1163
1158
|
for (const [subUrl, subArgs] of Object.entries(args[0])) {
|
|
1164
1159
|
if (!subUrl.match(/^(\w+ )?\//))
|
|
1165
1160
|
throw new Error('Url expected');
|
|
1166
|
-
this.
|
|
1161
|
+
this.use(subUrl.replace(/\//, (url === '/' ? '' : url) + '/'), ...(Array.isArray(subArgs) ? subArgs : [subArgs]));
|
|
1167
1162
|
}
|
|
1168
1163
|
return this;
|
|
1169
1164
|
}
|
|
1170
|
-
//
|
|
1165
|
+
// use('/url', ...middleware)
|
|
1171
1166
|
return this._add(method, url, 'next', args.filter((o) => o));
|
|
1172
1167
|
}
|
|
1173
1168
|
_middleware(middleware) {
|
|
@@ -1176,17 +1171,30 @@ export class Router extends EventEmitter {
|
|
|
1176
1171
|
const priority = (middleware?.priority || 0) - 1;
|
|
1177
1172
|
const stack = priority < -1 ? this._stackAfter : this._stack;
|
|
1178
1173
|
const idx = stack.findIndex(f => 'priority' in f
|
|
1179
|
-
&& priority
|
|
1174
|
+
&& priority >= (f.priority || 0));
|
|
1180
1175
|
stack.splice(idx < 0 ? stack.length : idx, 0, middleware);
|
|
1181
1176
|
return this;
|
|
1182
1177
|
}
|
|
1183
1178
|
_plugin(plugin) {
|
|
1179
|
+
if (plugin.name) {
|
|
1180
|
+
if (this.plugins[plugin.name])
|
|
1181
|
+
throw new Error(`Plugin ${plugin.name} already added`);
|
|
1182
|
+
this.plugins[plugin.name] = plugin;
|
|
1183
|
+
}
|
|
1184
1184
|
if (plugin.handler) {
|
|
1185
1185
|
const middleware = plugin.handler.bind(plugin);
|
|
1186
1186
|
middleware.plugin = plugin;
|
|
1187
1187
|
middleware.priority = plugin.priority;
|
|
1188
1188
|
return this._middleware(middleware);
|
|
1189
1189
|
}
|
|
1190
|
+
if (plugin.routes) {
|
|
1191
|
+
if (typeof plugin.routes === 'function')
|
|
1192
|
+
this.use(plugin.routes());
|
|
1193
|
+
else
|
|
1194
|
+
this.use(plugin.routes);
|
|
1195
|
+
}
|
|
1196
|
+
if (plugin.controller)
|
|
1197
|
+
this.use(plugin.controller);
|
|
1190
1198
|
return this;
|
|
1191
1199
|
}
|
|
1192
1200
|
/** Add hook */
|
|
@@ -1203,10 +1211,10 @@ export class Router extends EventEmitter {
|
|
|
1203
1211
|
}
|
|
1204
1212
|
}
|
|
1205
1213
|
export class MicroServer extends EventEmitter {
|
|
1214
|
+
get plugins() { return this.router.plugins; }
|
|
1206
1215
|
constructor(config) {
|
|
1207
1216
|
super();
|
|
1208
1217
|
this._ready = false;
|
|
1209
|
-
this.plugins = {};
|
|
1210
1218
|
this._methods = {};
|
|
1211
1219
|
let promise = Promise.resolve();
|
|
1212
1220
|
this._init = (f, ...args) => {
|
|
@@ -1226,7 +1234,7 @@ export class MicroServer extends EventEmitter {
|
|
|
1226
1234
|
this.use(config.routes);
|
|
1227
1235
|
for (const key in MicroServer.plugins) {
|
|
1228
1236
|
if (config[key])
|
|
1229
|
-
this.router.
|
|
1237
|
+
this.router.use(MicroServer.plugins[key], config[key]);
|
|
1230
1238
|
}
|
|
1231
1239
|
if (config.listen)
|
|
1232
1240
|
this._init(() => {
|
|
@@ -1432,7 +1440,7 @@ export class MicroServer extends EventEmitter {
|
|
|
1432
1440
|
}
|
|
1433
1441
|
/** Add middleware, routes, etc.. see {Router.add} */
|
|
1434
1442
|
use(...args) {
|
|
1435
|
-
this.router.
|
|
1443
|
+
this.router.use(...args);
|
|
1436
1444
|
return this;
|
|
1437
1445
|
}
|
|
1438
1446
|
/** Default server handler */
|
|
@@ -1581,32 +1589,32 @@ export class MicroServer extends EventEmitter {
|
|
|
1581
1589
|
}
|
|
1582
1590
|
/** Add route, alias to `server.router.add('GET ' + url, ...args)` */
|
|
1583
1591
|
get(url, ...args) {
|
|
1584
|
-
this.router.
|
|
1592
|
+
this.router.use('GET ' + url, ...args);
|
|
1585
1593
|
return this;
|
|
1586
1594
|
}
|
|
1587
1595
|
/** Add route, alias to `server.router.add('POST ' + url, ...args)` */
|
|
1588
1596
|
post(url, ...args) {
|
|
1589
|
-
this.router.
|
|
1597
|
+
this.router.use('POST ' + url, ...args);
|
|
1590
1598
|
return this;
|
|
1591
1599
|
}
|
|
1592
1600
|
/** Add route, alias to `server.router.add('PUT ' + url, ...args)` */
|
|
1593
1601
|
put(url, ...args) {
|
|
1594
|
-
this.router.
|
|
1602
|
+
this.router.use('PUT ' + url, ...args);
|
|
1595
1603
|
return this;
|
|
1596
1604
|
}
|
|
1597
1605
|
/** Add route, alias to `server.router.add('PATCH ' + url, ...args)` */
|
|
1598
1606
|
patch(url, ...args) {
|
|
1599
|
-
this.router.
|
|
1607
|
+
this.router.use('PATCH ' + url, ...args);
|
|
1600
1608
|
return this;
|
|
1601
1609
|
}
|
|
1602
1610
|
/** Add route, alias to `server.router.add('DELETE ' + url, ...args)` */
|
|
1603
1611
|
delete(url, ...args) {
|
|
1604
|
-
this.router.
|
|
1612
|
+
this.router.use('DELETE ' + url, ...args);
|
|
1605
1613
|
return this;
|
|
1606
1614
|
}
|
|
1607
1615
|
/** Add websocket handler, alias to `server.router.add('WEBSOCKET ' + url, ...args)` */
|
|
1608
1616
|
websocket(url, ...args) {
|
|
1609
|
-
this.router.
|
|
1617
|
+
this.router.use('WEBSOCKET ' + url, ...args);
|
|
1610
1618
|
return this;
|
|
1611
1619
|
}
|
|
1612
1620
|
/** Add router hook, alias to `server.router.hook(url, ...args)` */
|
|
@@ -1621,6 +1629,7 @@ class TrustProxyPlugin extends Plugin {
|
|
|
1621
1629
|
constructor(router, options) {
|
|
1622
1630
|
super(router);
|
|
1623
1631
|
this.priority = 110;
|
|
1632
|
+
this.name = 'trustProxy';
|
|
1624
1633
|
this.trustProxy = [];
|
|
1625
1634
|
this.trustProxy = options || [];
|
|
1626
1635
|
}
|
|
@@ -1651,14 +1660,16 @@ class VHostPlugin extends Plugin {
|
|
|
1651
1660
|
super(router);
|
|
1652
1661
|
this.priority = 100;
|
|
1653
1662
|
const server = router.server;
|
|
1654
|
-
if (!server.vhosts)
|
|
1663
|
+
if (!server.vhosts) {
|
|
1655
1664
|
server.vhosts = {};
|
|
1665
|
+
this.name = 'vhost';
|
|
1666
|
+
}
|
|
1656
1667
|
else
|
|
1657
1668
|
this.handler = undefined;
|
|
1658
1669
|
for (const host in options) {
|
|
1659
1670
|
if (!server.vhosts[host])
|
|
1660
1671
|
server.vhosts[host] = new Router(server);
|
|
1661
|
-
server.vhosts[host].
|
|
1672
|
+
server.vhosts[host].use(options[host]);
|
|
1662
1673
|
}
|
|
1663
1674
|
}
|
|
1664
1675
|
handler(req, res, next) {
|
|
@@ -1694,7 +1705,7 @@ class StaticPlugin extends Plugin {
|
|
|
1694
1705
|
this.lastModified = options.lastModified !== false;
|
|
1695
1706
|
this.etag = options.etag !== false;
|
|
1696
1707
|
this.maxAge = options.maxAge;
|
|
1697
|
-
router.
|
|
1708
|
+
router.use('GET /' + (options.path?.replace(/^[.\/]*/, '') || '').replace(/\/$/, '') + '/:path*', this.staticHandler.bind(this));
|
|
1698
1709
|
}
|
|
1699
1710
|
/** Default static files handler */
|
|
1700
1711
|
staticHandler(req, res, next) {
|
|
@@ -1780,7 +1791,7 @@ export class ProxyPlugin extends Plugin {
|
|
|
1780
1791
|
this.validHeaders = { ...ProxyPlugin.validHeaders, ...options?.validHeaders };
|
|
1781
1792
|
if (options.path && options.path !== '/') {
|
|
1782
1793
|
this.handler = undefined;
|
|
1783
|
-
router.
|
|
1794
|
+
router.use(options.path + '/:path*', this.proxyHandler.bind(this));
|
|
1784
1795
|
}
|
|
1785
1796
|
}
|
|
1786
1797
|
/** Default proxy handler */
|
|
@@ -1816,8 +1827,7 @@ export class ProxyPlugin extends Plugin {
|
|
|
1816
1827
|
}
|
|
1817
1828
|
if (this.headers)
|
|
1818
1829
|
Object.assign(reqOptions.headers, this.headers);
|
|
1819
|
-
|
|
1820
|
-
reqOptions.headers.Host = reqOptions.host;
|
|
1830
|
+
reqOptions.setHost = true;
|
|
1821
1831
|
const conn = this.remoteUrl.protocol === 'https:' ? https.request(reqOptions) : http.request(reqOptions);
|
|
1822
1832
|
conn.on('response', (response) => {
|
|
1823
1833
|
res.statusCode = response.statusCode || 502;
|
|
@@ -2144,6 +2154,7 @@ async function login (username, password, salt) {
|
|
|
2144
2154
|
class AuthPlugin extends Plugin {
|
|
2145
2155
|
constructor(router, options) {
|
|
2146
2156
|
super(router);
|
|
2157
|
+
this.name = 'auth';
|
|
2147
2158
|
if (router.auth)
|
|
2148
2159
|
throw new Error('Auth plugin already initialized');
|
|
2149
2160
|
this.options = {
|
|
@@ -2331,7 +2342,7 @@ export class FileStore {
|
|
|
2331
2342
|
data: data
|
|
2332
2343
|
};
|
|
2333
2344
|
this._cache[name] = item;
|
|
2334
|
-
|
|
2345
|
+
this._sync(async () => {
|
|
2335
2346
|
if (this._cache[name] === item) {
|
|
2336
2347
|
this.cleanup();
|
|
2337
2348
|
try {
|
|
@@ -2341,6 +2352,7 @@ export class FileStore {
|
|
|
2341
2352
|
}
|
|
2342
2353
|
}
|
|
2343
2354
|
});
|
|
2355
|
+
return data;
|
|
2344
2356
|
}
|
|
2345
2357
|
/** load all files in directory */
|
|
2346
2358
|
async all(name, autosave = false) {
|
|
@@ -2924,11 +2936,12 @@ export class MicroCollection {
|
|
|
2924
2936
|
});
|
|
2925
2937
|
return count;
|
|
2926
2938
|
}
|
|
2927
|
-
let
|
|
2928
|
-
if (!
|
|
2939
|
+
let doc = this.queryDocument(options.query, this.data[id]);
|
|
2940
|
+
if (!doc) {
|
|
2929
2941
|
if (!options.upsert && !options.new)
|
|
2930
2942
|
throw new InvalidData(`Document not found`);
|
|
2931
|
-
|
|
2943
|
+
doc = { _id: id };
|
|
2944
|
+
this.data[id] = doc;
|
|
2932
2945
|
}
|
|
2933
2946
|
else {
|
|
2934
2947
|
if (options.new)
|
|
@@ -2937,15 +2950,15 @@ export class MicroCollection {
|
|
|
2937
2950
|
if (options.update) {
|
|
2938
2951
|
for (const n in options.update) {
|
|
2939
2952
|
if (!n.startsWith('$'))
|
|
2940
|
-
|
|
2953
|
+
doc[n] = options.update[n];
|
|
2941
2954
|
}
|
|
2942
2955
|
if (options.update.$unset) {
|
|
2943
2956
|
for (const n in options.update.$unset)
|
|
2944
|
-
delete
|
|
2957
|
+
delete doc[n];
|
|
2945
2958
|
}
|
|
2946
2959
|
}
|
|
2947
2960
|
if (this._save)
|
|
2948
|
-
this.data[id] = await this._save(id,
|
|
2961
|
+
this.data[id] = await this._save(id, doc, this) || doc;
|
|
2949
2962
|
return 1;
|
|
2950
2963
|
}
|
|
2951
2964
|
/** Insert one document */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@radatek/microserver",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "HTTP MicroServer",
|
|
5
5
|
"author": "Darius Kisonas",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,11 +20,5 @@
|
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
22
|
"url": "git+https://github.com/radateklt/microserver.git"
|
|
23
|
-
},
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"@types/node": "^22.14.1"
|
|
26
|
-
},
|
|
27
|
-
"scripts": {
|
|
28
|
-
"build": "pnpm --package typescript dlx tsc -d -m nodenext -t es2021 microserver.ts --outDir dist && sed -Ei 's/\\\"use strict\\\";\\n\\n//g' dist/microserver.js && sed -Ei ':a;N;$!ba;s/\\n +private _[^\\n]+//g;s/export \\{\\};//g' dist/microserver.d.ts"
|
|
29
23
|
}
|
|
30
24
|
}
|