@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.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * MicroServer
3
- * @version 2.0.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
- add(...args: any): Router;
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<void>;
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;
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * MicroServer
3
- * @version 2.0.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
- add(...args) {
1100
+ use(...args) {
1100
1101
  if (!args[0])
1101
1102
  return this;
1102
- // add(plugin)
1103
+ // use(plugin)
1103
1104
  if (args[0] instanceof Plugin)
1104
1105
  return this._plugin(args[0]);
1105
- // add(pluginid, ...args)
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
- class Middleware extends Plugin {
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
- // add('/url', ControllerClass)
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
- // add('/url', [ ['METHOD /url', ...], {'METHOD } ])
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.add(item[0].replace(/\//, (url === '/' ? '' : url) + '/'), ...item.slice(1));
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
- // add('/url', {'METHOD /url': [...middlewares], ... } ])
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.add(subUrl.replace(/\//, (url === '/' ? '' : url) + '/'), ...(Array.isArray(subArgs) ? subArgs : [subArgs]));
1161
+ this.use(subUrl.replace(/\//, (url === '/' ? '' : url) + '/'), ...(Array.isArray(subArgs) ? subArgs : [subArgs]));
1167
1162
  }
1168
1163
  return this;
1169
1164
  }
1170
- // add('/url', ...middleware)
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 > (f.priority || 0));
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.add(MicroServer.plugins[key], config[key]);
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.add(...args);
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.add('GET ' + url, ...args);
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.add('POST ' + url, ...args);
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.add('PUT ' + url, ...args);
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.add('PATCH ' + url, ...args);
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.add('DELETE ' + url, ...args);
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.add('WEBSOCKET ' + url, ...args);
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].add(options[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.add('GET /' + (options.path?.replace(/^[.\/]*/, '') || '').replace(/\/$/, '') + '/:path*', this.staticHandler.bind(this));
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.add(options.path + '/:path*', this.proxyHandler.bind(this));
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
- if (!reqOptions.headers.Host && !reqOptions.headers.host)
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
- return this._sync(async () => {
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 oldData = this.queryDocument(options.query, this.data[id]);
2928
- if (!oldData) {
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
- oldData = { _id: id };
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
- oldData[n] = options.update[n];
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 oldData[n];
2957
+ delete doc[n];
2945
2958
  }
2946
2959
  }
2947
2960
  if (this._save)
2948
- this.data[id] = await this._save(id, this.data[id], this) || this.data[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.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
  }