@kaito-http/core 2.9.4 → 3.0.0-beta.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.
@@ -1,553 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var node_tls = require('node:tls');
6
- var contentType = require('content-type');
7
- var node_stream = require('node:stream');
8
- var consumers = require('node:stream/consumers');
9
- var getRawBody = require('raw-body');
10
- var fmw = require('find-my-way');
11
- var zod = require('zod');
12
- var cookie = require('cookie');
13
- var http = require('node:http');
14
-
15
- function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
16
-
17
- function _interopNamespace(e) {
18
- if (e && e.__esModule) return e;
19
- var n = Object.create(null);
20
- if (e) {
21
- Object.keys(e).forEach(function (k) {
22
- if (k !== 'default') {
23
- var d = Object.getOwnPropertyDescriptor(e, k);
24
- Object.defineProperty(n, k, d.get ? d : {
25
- enumerable: true,
26
- get: function () { return e[k]; }
27
- });
28
- }
29
- });
30
- }
31
- n["default"] = e;
32
- return Object.freeze(n);
33
- }
34
-
35
- var getRawBody__default = /*#__PURE__*/_interopDefault(getRawBody);
36
- var fmw__default = /*#__PURE__*/_interopDefault(fmw);
37
- var http__namespace = /*#__PURE__*/_interopNamespace(http);
38
-
39
- class WrappedError extends Error {
40
- static maybe(maybeError) {
41
- if (maybeError instanceof Error) {
42
- return maybeError;
43
- }
44
- return WrappedError.from(maybeError);
45
- }
46
- static from(data) {
47
- return new WrappedError(data);
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
- class KaitoError extends Error {
55
- constructor(status, message) {
56
- super(message);
57
- this.status = status;
58
- }
59
- }
60
-
61
- function _defineProperty(obj, key, value) {
62
- if (key in obj) {
63
- Object.defineProperty(obj, key, {
64
- value: value,
65
- enumerable: true,
66
- configurable: true,
67
- writable: true
68
- });
69
- } else {
70
- obj[key] = value;
71
- }
72
- return obj;
73
- }
74
-
75
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
76
- try {
77
- var info = gen[key](arg);
78
- var value = info.value;
79
- } catch (error) {
80
- reject(error);
81
- return;
82
- }
83
- if (info.done) {
84
- resolve(value);
85
- } else {
86
- Promise.resolve(value).then(_next, _throw);
87
- }
88
- }
89
- function _asyncToGenerator(fn) {
90
- return function () {
91
- var self = this,
92
- args = arguments;
93
- return new Promise(function (resolve, reject) {
94
- var gen = fn.apply(self, args);
95
- function _next(value) {
96
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
97
- }
98
- function _throw(err) {
99
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
100
- }
101
- _next(undefined);
102
- });
103
- };
104
- }
105
-
106
- function ownKeys(object, enumerableOnly) {
107
- var keys = Object.keys(object);
108
- if (Object.getOwnPropertySymbols) {
109
- var symbols = Object.getOwnPropertySymbols(object);
110
- enumerableOnly && (symbols = symbols.filter(function (sym) {
111
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
112
- })), keys.push.apply(keys, symbols);
113
- }
114
- return keys;
115
- }
116
- function _objectSpread2(target) {
117
- for (var i = 1; i < arguments.length; i++) {
118
- var source = null != arguments[i] ? arguments[i] : {};
119
- i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
120
- _defineProperty(target, key, source[key]);
121
- }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
122
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
123
- });
124
- }
125
- return target;
126
- }
127
-
128
- class KaitoResponse {
129
- constructor(raw) {
130
- this.raw = raw;
131
- }
132
-
133
- /**
134
- * Send a response
135
- * @param key The key of the header
136
- * @param value The value of the header
137
- * @returns The response object
138
- */
139
- header(key, value) {
140
- this.raw.setHeader(key, value);
141
- return this;
142
- }
143
-
144
- /**
145
- * Set the status code of the response
146
- * @param code The status code
147
- * @returns The response object
148
- */
149
- status(code) {
150
- this.raw.statusCode = code;
151
- return this;
152
- }
153
-
154
- /**
155
- * Set a cookie
156
- * @param name The name of the cookie
157
- * @param value The value of the cookie
158
- * @param options The options for the cookie
159
- * @returns The response object
160
- */
161
- cookie(name, value, options) {
162
- this.raw.setHeader('Set-Cookie', cookie.serialize(name, value, options));
163
- return this;
164
- }
165
-
166
- /**
167
- * Send a JSON APIResponse body
168
- * @param data The data to send
169
- * @returns The response object
170
- */
171
- json(data) {
172
- var json = JSON.stringify(data);
173
- this.raw.setHeader('Content-Type', 'application/json');
174
- this.raw.setHeader('Content-Length', Buffer.byteLength(json));
175
- this.raw.end(json);
176
- return this;
177
- }
178
- }
179
-
180
- var getSend = res => (status, response) => {
181
- if (res.raw.headersSent) {
182
- return;
183
- }
184
- res.status(status).json(response);
185
- };
186
- class Router {
187
- static handle(
188
- // Allow for any server to be passed
189
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
190
- server, route, options) {
191
- return _asyncToGenerator(function* () {
192
- var send = getSend(options.res);
193
- try {
194
- var _yield$route$body$par, _route$body;
195
- var rootCtx = yield server.getContext(options.req, options.res);
196
- var ctx = yield route.through(rootCtx);
197
- var body = (_yield$route$body$par = yield (_route$body = route.body) === null || _route$body === void 0 ? void 0 : _route$body.parse(yield getBody(options.req))) !== null && _yield$route$body$par !== void 0 ? _yield$route$body$par : undefined;
198
- var query = route.query ? zod.z.object(route.query).parse(Object.fromEntries(options.req.url.searchParams.entries())) : {};
199
- var result = yield route.run({
200
- ctx,
201
- body,
202
- query,
203
- params: options.params
204
- });
205
- if (options.res.raw.headersSent) {
206
- return {
207
- success: true,
208
- data: result
209
- };
210
- }
211
- send(200, {
212
- success: true,
213
- data: result,
214
- message: 'OK'
215
- });
216
- return {
217
- success: true,
218
- data: result
219
- };
220
- } catch (e) {
221
- var error = WrappedError.maybe(e);
222
- if (error instanceof KaitoError) {
223
- send(error.status, {
224
- success: false,
225
- data: null,
226
- message: error.message
227
- });
228
- return;
229
- }
230
- var {
231
- status,
232
- message
233
- } = yield server.onError({
234
- error,
235
- req: options.req,
236
- res: options.res
237
- }).catch(() => ({
238
- status: 500,
239
- message: 'Internal Server Error'
240
- }));
241
- send(status, {
242
- success: false,
243
- data: null,
244
- message
245
- });
246
- return {
247
- success: false,
248
- data: {
249
- status,
250
- message
251
- }
252
- };
253
- }
254
- })();
255
- }
256
- constructor(routes, options) {
257
- var _this = this;
258
- _defineProperty(this, "add", (method, path, route) => {
259
- var merged = _objectSpread2(_objectSpread2({}, typeof route === 'object' ? route : {
260
- run: route
261
- }), {}, {
262
- method,
263
- path,
264
- through: this.routerOptions.through
265
- });
266
- return new Router([...this.routes, merged], this.routerOptions);
267
- });
268
- _defineProperty(this, "merge", (pathPrefix, other) => {
269
- var newRoutes = other.routes.map(route => _objectSpread2(_objectSpread2({}, route), {}, {
270
- path: "".concat(pathPrefix).concat(route.path)
271
- }));
272
- return new Router([...this.routes, ...newRoutes], this.routerOptions);
273
- });
274
- _defineProperty(this, "freeze", server => {
275
- var instance = fmw__default["default"]({
276
- ignoreTrailingSlash: true,
277
- defaultRoute(req, serverResponse) {
278
- return _asyncToGenerator(function* () {
279
- var _req$url;
280
- var res = new KaitoResponse(serverResponse);
281
- var message = "Cannot ".concat(req.method, " ").concat((_req$url = req.url) !== null && _req$url !== void 0 ? _req$url : '/');
282
- getSend(res)(404, {
283
- success: false,
284
- data: null,
285
- message
286
- });
287
- return {
288
- success: false,
289
- data: {
290
- status: 404,
291
- message
292
- }
293
- };
294
- })();
295
- }
296
- });
297
- var _loop = function _loop(route) {
298
- var handler = /*#__PURE__*/function () {
299
- var _ref = _asyncToGenerator(function* (incomingMessage, serverResponse, params) {
300
- var req = new KaitoRequest(incomingMessage);
301
- var res = new KaitoResponse(serverResponse);
302
- return Router.handle(server, route, {
303
- params,
304
- req,
305
- res
306
- });
307
- });
308
- return function handler(_x, _x2, _x3) {
309
- return _ref.apply(this, arguments);
310
- };
311
- }();
312
- if (route.method === '*') {
313
- instance.all(route.path, handler);
314
- return "continue";
315
- }
316
- instance.on(route.method, route.path, handler);
317
- };
318
- for (var route of this.routes) {
319
- var _ret = _loop(route);
320
- if (_ret === "continue") continue;
321
- }
322
- return instance;
323
- });
324
- _defineProperty(this, "method", method => (path, route) => this.add(method, path, route));
325
- _defineProperty(this, "get", this.method('GET'));
326
- _defineProperty(this, "post", this.method('POST'));
327
- _defineProperty(this, "put", this.method('PUT'));
328
- _defineProperty(this, "patch", this.method('PATCH'));
329
- _defineProperty(this, "delete", this.method('DELETE'));
330
- _defineProperty(this, "head", this.method('HEAD'));
331
- _defineProperty(this, "options", this.method('OPTIONS'));
332
- _defineProperty(this, "through", transform => new Router(this.routes, {
333
- through: function () {
334
- var _through = _asyncToGenerator(function* (context) {
335
- var fromCurrentRouter = yield _this.routerOptions.through(context);
336
- return transform(fromCurrentRouter);
337
- });
338
- function through(_x4) {
339
- return _through.apply(this, arguments);
340
- }
341
- return through;
342
- }()
343
- }));
344
- this.routerOptions = options;
345
- this.routes = routes;
346
- }
347
-
348
- /**
349
- * Adds a new route to the router
350
- * @param method The HTTP method to add a route for
351
- * @param path The path to add a route for
352
- * @param route The route specification to add to this router
353
- * @returns A new router with this route added
354
- */
355
- }
356
- _defineProperty(Router, "create", () => new Router([], {
357
- through: function () {
358
- var _through2 = _asyncToGenerator(function* (context) {
359
- return context;
360
- });
361
- function through(_x5) {
362
- return _through2.apply(this, arguments);
363
- }
364
- return through;
365
- }()
366
- }));
367
-
368
- /**
369
- * @deprecated use `createUtilities` instead
370
- */
371
- function createGetContext(callback) {
372
- return callback;
373
- }
374
-
375
- /**
376
- * A helper function to create typed necessary functions
377
- *
378
- * @example
379
- * ```ts
380
- * const {router, getContext} = createUtilities(async (req, res) => {
381
- * // Return context here
382
- * })
383
- *
384
- * const app = router().get('/', async () => "hello");
385
- *
386
- * const server = createServer({
387
- * router: app,
388
- * getContext,
389
- * // ...
390
- * });
391
- * ```
392
- */
393
- function createUtilities(getContext) {
394
- return {
395
- getContext,
396
- router: () => Router.create()
397
- };
398
- }
399
- function getLastEntryInMultiHeaderValue(headerValue) {
400
- var normalized = Array.isArray(headerValue) ? headerValue.join(',') : headerValue;
401
- var lastIndex = normalized.lastIndexOf(',');
402
- return lastIndex === -1 ? normalized.trim() : normalized.slice(lastIndex + 1).trim();
403
- }
404
- function getBody(_x) {
405
- return _getBody.apply(this, arguments);
406
- }
407
- function _getBody() {
408
- _getBody = _asyncToGenerator(function* (req) {
409
- if (!req.headers['content-type']) {
410
- return null;
411
- }
412
- var buffer = yield getRawBody__default["default"](req.raw);
413
- var {
414
- type
415
- } = contentType.parse(req.headers['content-type']);
416
- switch (type) {
417
- case 'application/json':
418
- {
419
- return consumers.json(node_stream.Readable.from(buffer));
420
- }
421
- default:
422
- {
423
- return null;
424
- }
425
- }
426
- });
427
- return _getBody.apply(this, arguments);
428
- }
429
-
430
- class KaitoRequest {
431
- constructor(raw) {
432
- _defineProperty(this, "_url", null);
433
- this.raw = raw;
434
- }
435
-
436
- /**
437
- * The full URL of the request, including the protocol, hostname, and path.
438
- * Note: does not include the query string or hash
439
- */
440
- get fullURL() {
441
- var _this$raw$url;
442
- return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
443
- }
444
-
445
- /**
446
- * A new URL instance for the full URL of the request.
447
- */
448
- get url() {
449
- if (this._url) {
450
- return this._url;
451
- }
452
- this._url = new URL(this.fullURL);
453
- return this._url;
454
- }
455
-
456
- /**
457
- * The HTTP method of the request.
458
- */
459
- get method() {
460
- if (!this.raw.method) {
461
- throw new Error('Request method is not defined, somehow...');
462
- }
463
- return this.raw.method;
464
- }
465
-
466
- /**
467
- * The protocol of the request, either `http` or `https`.
468
- */
469
- get protocol() {
470
- if (this.raw.socket instanceof node_tls.TLSSocket) {
471
- return this.raw.socket.encrypted ? 'https' : 'http';
472
- }
473
- return 'http';
474
- }
475
-
476
- /**
477
- * The request headers
478
- */
479
- get headers() {
480
- return this.raw.headers;
481
- }
482
-
483
- /**
484
- * The hostname of the request.
485
- */
486
- get hostname() {
487
- var _this$raw$headers$hos, _this$raw$headers$Au;
488
- return (_this$raw$headers$hos = this.raw.headers.host) !== null && _this$raw$headers$hos !== void 0 ? _this$raw$headers$hos : getLastEntryInMultiHeaderValue((_this$raw$headers$Au = this.raw.headers[':authority']) !== null && _this$raw$headers$Au !== void 0 ? _this$raw$headers$Au : []);
489
- }
490
- }
491
-
492
- function createFMWServer(config) {
493
- var _config$rawRoutes;
494
- var router = config.router.freeze(config);
495
- var rawRoutes = (_config$rawRoutes = config.rawRoutes) !== null && _config$rawRoutes !== void 0 ? _config$rawRoutes : {};
496
- for (var method in rawRoutes) {
497
- if (!Object.prototype.hasOwnProperty.call(rawRoutes, method)) {
498
- continue;
499
- }
500
- var routes = rawRoutes[method];
501
- if (!routes || routes.length === 0) {
502
- continue;
503
- }
504
- for (var route of routes) {
505
- if (method === '*') {
506
- router.all(route.path, route.handler);
507
- continue;
508
- }
509
- router[method.toLowerCase()](route.path, route.handler);
510
- }
511
- }
512
- var server = http__namespace.createServer( /*#__PURE__*/function () {
513
- var _ref = _asyncToGenerator(function* (req, res) {
514
- var before;
515
- if (config.before) {
516
- before = yield config.before(req, res);
517
- } else {
518
- before = undefined;
519
- }
520
-
521
- // If the user has sent a response (e.g. replying to CORS), we don't want to do anything else.
522
- if (res.headersSent) {
523
- return;
524
- }
525
- var result = yield router.lookup(req, res);
526
- if ('after' in config && config.after) {
527
- yield config.after(before, result);
528
- }
529
- });
530
- return function (_x, _x2) {
531
- return _ref.apply(this, arguments);
532
- };
533
- }());
534
- return {
535
- server,
536
- fmw: router
537
- };
538
- }
539
- function createServer(config) {
540
- return createFMWServer(config).server;
541
- }
542
-
543
- exports.KaitoError = KaitoError;
544
- exports.KaitoRequest = KaitoRequest;
545
- exports.KaitoResponse = KaitoResponse;
546
- exports.Router = Router;
547
- exports.WrappedError = WrappedError;
548
- exports.createFMWServer = createFMWServer;
549
- exports.createGetContext = createGetContext;
550
- exports.createServer = createServer;
551
- exports.createUtilities = createUtilities;
552
- exports.getBody = getBody;
553
- exports.getLastEntryInMultiHeaderValue = getLastEntryInMultiHeaderValue;