@kaito-http/core 2.3.9 → 2.5.0

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.
@@ -2,35 +2,78 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var http = require('http');
6
- var fmw = require('find-my-way');
7
- var tls = require('tls');
5
+ var node_tls = require('node:tls');
8
6
  var contentType = require('content-type');
9
7
  var getRawBody = require('raw-body');
8
+ var cookie = require('cookie');
9
+ var fmw = require('find-my-way');
10
+ var http = require('node:http');
10
11
 
11
12
  function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
12
13
 
13
14
  function _interopNamespace(e) {
14
- if (e && e.__esModule) return e;
15
- var n = Object.create(null);
16
- if (e) {
17
- Object.keys(e).forEach(function (k) {
18
- if (k !== 'default') {
19
- var d = Object.getOwnPropertyDescriptor(e, k);
20
- Object.defineProperty(n, k, d.get ? d : {
21
- enumerable: true,
22
- get: function () { return e[k]; }
23
- });
24
- }
25
- });
26
- }
27
- n["default"] = e;
28
- return Object.freeze(n);
15
+ if (e && e.__esModule) return e;
16
+ var n = Object.create(null);
17
+ if (e) {
18
+ Object.keys(e).forEach(function (k) {
19
+ if (k !== 'default') {
20
+ var d = Object.getOwnPropertyDescriptor(e, k);
21
+ Object.defineProperty(n, k, d.get ? d : {
22
+ enumerable: true,
23
+ get: function () { return e[k]; }
24
+ });
25
+ }
26
+ });
27
+ }
28
+ n["default"] = e;
29
+ return Object.freeze(n);
29
30
  }
30
31
 
31
- var http__namespace = /*#__PURE__*/_interopNamespace(http);
32
- var fmw__default = /*#__PURE__*/_interopDefault(fmw);
33
32
  var getRawBody__default = /*#__PURE__*/_interopDefault(getRawBody);
33
+ var fmw__default = /*#__PURE__*/_interopDefault(fmw);
34
+ var http__namespace = /*#__PURE__*/_interopNamespace(http);
35
+
36
+ class WrappedError extends Error {
37
+ static maybe(maybeError) {
38
+ if (maybeError instanceof Error) {
39
+ return maybeError;
40
+ }
41
+
42
+ return WrappedError.from(maybeError);
43
+ }
44
+
45
+ static from(data) {
46
+ return new WrappedError(data);
47
+ }
48
+
49
+ constructor(data) {
50
+ super('Something was thrown, but it was not an instance of Error, so a WrappedError was created.');
51
+ this.data = data;
52
+ }
53
+
54
+ }
55
+ class KaitoError extends Error {
56
+ constructor(status, message) {
57
+ super(message);
58
+ this.status = status;
59
+ }
60
+
61
+ }
62
+
63
+ function _defineProperty(obj, key, value) {
64
+ if (key in obj) {
65
+ Object.defineProperty(obj, key, {
66
+ value: value,
67
+ enumerable: true,
68
+ configurable: true,
69
+ writable: true
70
+ });
71
+ } else {
72
+ obj[key] = value;
73
+ }
74
+
75
+ return obj;
76
+ }
34
77
 
35
78
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
36
79
  try {
@@ -68,118 +111,6 @@ function _asyncToGenerator(fn) {
68
111
  };
69
112
  }
70
113
 
71
- function createFMWServer(config) {
72
- var fmw = config.router.toFindMyWay(config);
73
- var server = http__namespace.createServer( /*#__PURE__*/function () {
74
- var _ref = _asyncToGenerator(function* (req, res) {
75
- for (var fn of (_config$before = config.before) !== null && _config$before !== void 0 ? _config$before : []) {
76
- var _config$before;
77
-
78
- // Disabled because we need these to run in order!
79
- // eslint-disable-next-line no-await-in-loop
80
- yield fn(req, res);
81
- }
82
-
83
- if (req.method === 'OPTIONS') {
84
- return;
85
- }
86
-
87
- fmw.lookup(req, res);
88
- });
89
-
90
- return function (_x, _x2) {
91
- return _ref.apply(this, arguments);
92
- };
93
- }());
94
- return {
95
- server,
96
- fmw
97
- };
98
- }
99
- function createServer(config) {
100
- return createFMWServer(config).server;
101
- }
102
-
103
- function _defineProperty(obj, key, value) {
104
- if (key in obj) {
105
- Object.defineProperty(obj, key, {
106
- value: value,
107
- enumerable: true,
108
- configurable: true,
109
- writable: true
110
- });
111
- } else {
112
- obj[key] = value;
113
- }
114
-
115
- return obj;
116
- }
117
-
118
- function ownKeys(object, enumerableOnly) {
119
- var keys = Object.keys(object);
120
-
121
- if (Object.getOwnPropertySymbols) {
122
- var symbols = Object.getOwnPropertySymbols(object);
123
-
124
- if (enumerableOnly) {
125
- symbols = symbols.filter(function (sym) {
126
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
127
- });
128
- }
129
-
130
- keys.push.apply(keys, symbols);
131
- }
132
-
133
- return keys;
134
- }
135
-
136
- function _objectSpread2(target) {
137
- for (var i = 1; i < arguments.length; i++) {
138
- var source = arguments[i] != null ? arguments[i] : {};
139
-
140
- if (i % 2) {
141
- ownKeys(Object(source), true).forEach(function (key) {
142
- _defineProperty(target, key, source[key]);
143
- });
144
- } else if (Object.getOwnPropertyDescriptors) {
145
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
146
- } else {
147
- ownKeys(Object(source)).forEach(function (key) {
148
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
149
- });
150
- }
151
- }
152
-
153
- return target;
154
- }
155
-
156
- class WrappedError extends Error {
157
- static maybe(maybeError) {
158
- if (maybeError instanceof Error) {
159
- return maybeError;
160
- }
161
-
162
- return WrappedError.from(maybeError);
163
- }
164
-
165
- static from(data) {
166
- return new WrappedError(data);
167
- }
168
-
169
- constructor(data) {
170
- super('Something was thrown, but it was not an instance of Error, so a WrappedError was created.');
171
- this.data = data;
172
- }
173
-
174
- }
175
- class KaitoError extends Error {
176
- constructor(status, message) {
177
- super(message);
178
- this.status = status;
179
- }
180
-
181
- }
182
-
183
114
  function createGetContext(callback) {
184
115
  return callback;
185
116
  }
@@ -222,6 +153,7 @@ function _getInput() {
222
153
 
223
154
  default:
224
155
  {
156
+
225
157
  return null;
226
158
  }
227
159
  }
@@ -235,12 +167,21 @@ class KaitoRequest {
235
167
 
236
168
  this.raw = raw;
237
169
  }
170
+ /**
171
+ * The full URL of the request, including the protocol, hostname, and path.
172
+ * Note: does not include the query string or hash
173
+ */
174
+
238
175
 
239
176
  get fullURL() {
240
177
  var _this$raw$url;
241
178
 
242
179
  return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
243
180
  }
181
+ /**
182
+ * A new URL instance for the full URL of the request.
183
+ */
184
+
244
185
 
245
186
  get url() {
246
187
  if (this._url) {
@@ -250,6 +191,10 @@ class KaitoRequest {
250
191
  this._url = new URL(this.fullURL);
251
192
  return this._url;
252
193
  }
194
+ /**
195
+ * The HTTP method of the request.
196
+ */
197
+
253
198
 
254
199
  get method() {
255
200
  if (!this.raw.method) {
@@ -258,18 +203,30 @@ class KaitoRequest {
258
203
 
259
204
  return this.raw.method;
260
205
  }
206
+ /**
207
+ * The protocol of the request, either `http` or `https`.
208
+ */
209
+
261
210
 
262
211
  get protocol() {
263
- if (this.raw.socket instanceof tls.TLSSocket) {
212
+ if (this.raw.socket instanceof node_tls.TLSSocket) {
264
213
  return this.raw.socket.encrypted ? 'https' : 'http';
265
214
  }
266
215
 
267
216
  return 'http';
268
217
  }
218
+ /**
219
+ * The request headers
220
+ */
221
+
269
222
 
270
223
  get headers() {
271
224
  return this.raw.headers;
272
225
  }
226
+ /**
227
+ * The hostname of the request.
228
+ */
229
+
273
230
 
274
231
  get hostname() {
275
232
  var _this$raw$headers$hos, _this$raw$headers$Au;
@@ -283,16 +240,48 @@ class KaitoResponse {
283
240
  constructor(raw) {
284
241
  this.raw = raw;
285
242
  }
243
+ /**
244
+ * Send a response
245
+ * @param key The key of the header
246
+ * @param value The value of the header
247
+ * @returns The response object
248
+ */
249
+
286
250
 
287
251
  header(key, value) {
288
252
  this.raw.setHeader(key, value);
289
253
  return this;
290
254
  }
255
+ /**
256
+ * Set the status code of the response
257
+ * @param code The status code
258
+ * @returns The response object
259
+ */
260
+
291
261
 
292
262
  status(code) {
293
263
  this.raw.statusCode = code;
294
264
  return this;
295
265
  }
266
+ /**
267
+ * Set a cookie
268
+ * @param name The name of the cookie
269
+ * @param value The value of the cookie
270
+ * @param options The options for the cookie
271
+ * @returns The response object
272
+ */
273
+
274
+
275
+ cookie(name, value, options) {
276
+ this.raw.setHeader('Set-Cookie', cookie.serialize(name, value, options));
277
+ return this;
278
+ }
279
+ /**
280
+ * Send a JSON APIResponse body
281
+ * @param data The data to send
282
+ * @returns The response object
283
+ */
284
+
296
285
 
297
286
  json(data) {
298
287
  var json = JSON.stringify(data);
@@ -304,21 +293,129 @@ class KaitoResponse {
304
293
 
305
294
  }
306
295
 
296
+ function ownKeys(object, enumerableOnly) {
297
+ var keys = Object.keys(object);
298
+
299
+ if (Object.getOwnPropertySymbols) {
300
+ var symbols = Object.getOwnPropertySymbols(object);
301
+
302
+ if (enumerableOnly) {
303
+ symbols = symbols.filter(function (sym) {
304
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
305
+ });
306
+ }
307
+
308
+ keys.push.apply(keys, symbols);
309
+ }
310
+
311
+ return keys;
312
+ }
313
+
314
+ function _objectSpread2(target) {
315
+ for (var i = 1; i < arguments.length; i++) {
316
+ var source = arguments[i] != null ? arguments[i] : {};
317
+
318
+ if (i % 2) {
319
+ ownKeys(Object(source), true).forEach(function (key) {
320
+ _defineProperty(target, key, source[key]);
321
+ });
322
+ } else if (Object.getOwnPropertyDescriptors) {
323
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
324
+ } else {
325
+ ownKeys(Object(source)).forEach(function (key) {
326
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
327
+ });
328
+ }
329
+ }
330
+
331
+ return target;
332
+ }
333
+
307
334
  class Router {
308
- static create() {
309
- return new Router({});
335
+ constructor(routes) {
336
+ _defineProperty(this, "add", route => new Router([...this.routes, route]));
337
+
338
+ _defineProperty(this, "merge", (pathPrefix, other) => {
339
+ var newRoutes = other.routes.map(route => _objectSpread2(_objectSpread2({}, route), {}, {
340
+ path: "".concat(pathPrefix).concat(route.path)
341
+ }));
342
+ return new Router([...this.routes, ...newRoutes]);
343
+ });
344
+
345
+ _defineProperty(this, "toFindMyWay", server => {
346
+ var instance = fmw__default["default"]({
347
+ ignoreTrailingSlash: true,
348
+
349
+ defaultRoute(req, serverResponse) {
350
+ return _asyncToGenerator(function* () {
351
+ var _req$url;
352
+
353
+ var res = new KaitoResponse(serverResponse);
354
+ var message = "Cannot ".concat(req.method, " ").concat((_req$url = req.url) !== null && _req$url !== void 0 ? _req$url : '/');
355
+ res.status(404).json({
356
+ success: false,
357
+ data: null,
358
+ message
359
+ });
360
+ return {
361
+ success: false,
362
+ data: {
363
+ status: 404,
364
+ message
365
+ }
366
+ };
367
+ })();
368
+ }
369
+
370
+ });
371
+
372
+ var _loop = function _loop(route) {
373
+ var handler = /*#__PURE__*/function () {
374
+ var _ref = _asyncToGenerator(function* (incomingMessage, serverResponse, params) {
375
+ var req = new KaitoRequest(incomingMessage);
376
+ var res = new KaitoResponse(serverResponse);
377
+ return Router.handle(server, route, {
378
+ params,
379
+ req,
380
+ res
381
+ });
382
+ });
383
+
384
+ return function handler(_x, _x2, _x3) {
385
+ return _ref.apply(this, arguments);
386
+ };
387
+ }();
388
+
389
+ if (route.method === '*') {
390
+ instance.all(route.path, handler);
391
+ return "continue";
392
+ }
393
+
394
+ instance.on(route.method, route.path, handler);
395
+ };
396
+
397
+ for (var route of this.routes) {
398
+ var _ret = _loop(route);
399
+
400
+ if (_ret === "continue") continue;
401
+ }
402
+
403
+ return instance;
404
+ });
405
+
406
+ this.routes = routes;
310
407
  }
311
408
 
312
- static handle(server, options) {
409
+ static handle(server, route, options) {
313
410
  return _asyncToGenerator(function* () {
314
411
  try {
315
- var _options$route$input$, _options$route$input;
412
+ var _route$input$parse, _route$input;
316
413
 
317
- var context = yield server.getContext(options.req, options.res);
414
+ var ctx = yield server.getContext(options.req, options.res);
318
415
  var body = yield getInput(options.req);
319
- var input = (_options$route$input$ = (_options$route$input = options.route.input) === null || _options$route$input === void 0 ? void 0 : _options$route$input.parse(body)) !== null && _options$route$input$ !== void 0 ? _options$route$input$ : undefined;
320
- var result = yield options.route.run({
321
- ctx: context,
416
+ var input = (_route$input$parse = (_route$input = route.input) === null || _route$input === void 0 ? void 0 : _route$input.parse(body)) !== null && _route$input$parse !== void 0 ? _route$input$parse : undefined;
417
+ var result = yield route.run({
418
+ ctx,
322
419
  input,
323
420
  params: options.params
324
421
  });
@@ -327,6 +424,10 @@ class Router {
327
424
  data: result,
328
425
  message: 'OK'
329
426
  });
427
+ return {
428
+ success: true,
429
+ data: result
430
+ };
330
431
  } catch (e) {
331
432
  var error = WrappedError.maybe(e);
332
433
 
@@ -355,163 +456,82 @@ class Router {
355
456
  data: null,
356
457
  message
357
458
  });
459
+ return {
460
+ success: false,
461
+ data: {
462
+ status,
463
+ message
464
+ }
465
+ };
358
466
  }
359
467
  })();
360
468
  }
361
469
 
362
- constructor(routes) {
363
- _defineProperty(this, 'acl', this.make('ACL'));
364
-
365
- _defineProperty(this, 'bind', this.make('BIND'));
366
-
367
- _defineProperty(this, 'checkout', this.make('CHECKOUT'));
368
-
369
- _defineProperty(this, 'connect', this.make('CONNECT'));
370
-
371
- _defineProperty(this, 'copy', this.make('COPY'));
372
-
373
- _defineProperty(this, 'delete', this.make('DELETE'));
374
-
375
- _defineProperty(this, 'get', this.make('GET'));
376
-
377
- _defineProperty(this, 'head', this.make('HEAD'));
378
-
379
- _defineProperty(this, 'link', this.make('LINK'));
380
-
381
- _defineProperty(this, 'lock', this.make('LOCK'));
382
-
383
- _defineProperty(this, 'm_search', this.make('M-SEARCH'));
384
-
385
- _defineProperty(this, 'mkactivity', this.make('MKACTIVITY'));
386
-
387
- _defineProperty(this, 'mkcalendar', this.make('MKCALENDAR'));
388
-
389
- _defineProperty(this, 'mkcol', this.make('MKCOL'));
390
-
391
- _defineProperty(this, 'move', this.make('MOVE'));
392
-
393
- _defineProperty(this, 'notify', this.make('NOTIFY'));
394
-
395
- _defineProperty(this, 'patch', this.make('PATCH'));
396
-
397
- _defineProperty(this, 'post', this.make('POST'));
398
-
399
- _defineProperty(this, 'propfind', this.make('PROPFIND'));
400
-
401
- _defineProperty(this, 'proppatch', this.make('PROPPATCH'));
402
-
403
- _defineProperty(this, 'purge', this.make('PURGE'));
404
-
405
- _defineProperty(this, 'put', this.make('PUT'));
406
-
407
- _defineProperty(this, 'rebind', this.make('REBIND'));
408
-
409
- _defineProperty(this, 'report', this.make('REPORT'));
410
-
411
- _defineProperty(this, 'search', this.make('SEARCH'));
470
+ }
412
471
 
413
- _defineProperty(this, 'source', this.make('SOURCE'));
472
+ _defineProperty(Router, "create", () => new Router([]));
414
473
 
415
- _defineProperty(this, 'subscribe', this.make('SUBSCRIBE'));
474
+ function createFMWServer(config) {
475
+ var _config$rawRoutes;
416
476
 
417
- _defineProperty(this, 'trace', this.make('TRACE'));
477
+ var fmw = config.router.toFindMyWay(config);
478
+ var rawRoutes = (_config$rawRoutes = config.rawRoutes) !== null && _config$rawRoutes !== void 0 ? _config$rawRoutes : {};
418
479
 
419
- _defineProperty(this, 'unbind', this.make('UNBIND'));
480
+ for (var method in rawRoutes) {
481
+ if (!Object.prototype.hasOwnProperty.call(rawRoutes, method)) {
482
+ continue;
483
+ }
420
484
 
421
- _defineProperty(this, 'unlink', this.make('UNLINK'));
485
+ var routes = rawRoutes[method];
422
486
 
423
- _defineProperty(this, 'unlock', this.make('UNLOCK'));
487
+ if (!routes || routes.length === 0) {
488
+ continue;
489
+ }
424
490
 
425
- _defineProperty(this, 'unsubscribe', this.make('UNSUBSCRIBE'));
491
+ for (var route of routes) {
492
+ if (method === '*') {
493
+ fmw.all(route.path, route.handler);
494
+ continue;
495
+ }
426
496
 
427
- this.routes = routes;
497
+ fmw[method.toLowerCase()](route.path, route.handler);
498
+ }
428
499
  }
429
500
 
430
- merge(prefix, router) {
431
- var newRoutes = Object.fromEntries(Object.entries(router.routes).map(_ref => {
432
- var [k, v] = _ref;
433
- return ["".concat(prefix).concat(k), v];
434
- }));
501
+ var server = http__namespace.createServer( /*#__PURE__*/function () {
502
+ var _ref = _asyncToGenerator(function* (req, res) {
503
+ var before;
435
504
 
436
- var merged = _objectSpread2(_objectSpread2({}, this.routes), newRoutes);
505
+ if (config.before) {
506
+ before = yield config.before(req, res);
507
+ } else {
508
+ before = null;
509
+ } // If the user has sent a response (e.g. replying to CORS), we don't want to do anything else.
437
510
 
438
- return this._copy(merged);
439
- }
440
511
 
441
- toFindMyWay(server) {
442
- var _this = this;
443
-
444
- var instance = fmw__default["default"]({
445
- ignoreTrailingSlash: true,
512
+ if (res.headersSent) {
513
+ return;
514
+ }
446
515
 
447
- defaultRoute(req, serverResponse) {
448
- var _req$url;
516
+ var result = yield fmw.lookup(req, res);
449
517
 
450
- var res = new KaitoResponse(serverResponse);
451
- res.status(404).json({
452
- success: false,
453
- data: null,
454
- message: "Cannot ".concat(req.method, " ").concat((_req$url = req.url) !== null && _req$url !== void 0 ? _req$url : '/')
455
- });
518
+ if ('after' in config && config.after) {
519
+ yield config.after(before, result);
456
520
  }
457
-
458
521
  });
459
- var paths = Object.keys(this.routes);
460
-
461
- var _loop = function _loop(path) {
462
- var route = _this.routes[path];
463
- instance.on(route.method, path, /*#__PURE__*/function () {
464
- var _ref2 = _asyncToGenerator(function* (incomingMessage, serverResponse, params) {
465
- var req = new KaitoRequest(incomingMessage);
466
- var res = new KaitoResponse(serverResponse);
467
- yield Router.handle(server, {
468
- route,
469
- params,
470
- req,
471
- res
472
- });
473
- });
474
-
475
- return function (_x, _x2, _x3) {
476
- return _ref2.apply(this, arguments);
477
- };
478
- }());
479
- };
480
-
481
- for (var path of paths) {
482
- _loop(path);
483
- }
484
-
485
- return instance;
486
- }
487
522
 
488
- _copy(routes) {
489
- return new Router(routes);
490
- }
491
-
492
- make(method) {
493
- return (path, route) => {
494
- var addedRoute = _objectSpread2(_objectSpread2({}, route), {}, {
495
- method
496
- }); // `as unknown` is required because otherwise
497
- // this type just gets massive and too slow,
498
- // so we have to write it out specifically
499
-
500
-
501
- var merged = _objectSpread2(_objectSpread2({}, this.routes), {}, {
502
- [path]: addedRoute
503
- });
504
-
505
- return this._copy(merged);
523
+ return function (_x, _x2) {
524
+ return _ref.apply(this, arguments);
506
525
  };
507
- }
508
-
526
+ }());
527
+ return {
528
+ server,
529
+ fmw
530
+ };
531
+ }
532
+ function createServer(config) {
533
+ return createFMWServer(config).server;
509
534
  }
510
- /**
511
- * @deprecated Please use Router#create instead
512
- */
513
-
514
- var createRouter = Router.create;
515
535
 
516
536
  exports.KaitoError = KaitoError;
517
537
  exports.KaitoRequest = KaitoRequest;
@@ -520,7 +540,6 @@ exports.Router = Router;
520
540
  exports.WrappedError = WrappedError;
521
541
  exports.createFMWServer = createFMWServer;
522
542
  exports.createGetContext = createGetContext;
523
- exports.createRouter = createRouter;
524
543
  exports.createServer = createServer;
525
544
  exports.getInput = getInput;
526
545
  exports.getLastEntryInMultiHeaderValue = getLastEntryInMultiHeaderValue;