k99 0.6.0 → 0.7.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "k99",
3
3
  "description": "前后端均可用的 web 服务器",
4
- "version": "0.6.0",
4
+ "version": "0.7.0",
5
5
  "dependencies": {},
6
6
  "keywords": [
7
7
  "k99",
@@ -35,7 +35,6 @@
35
35
  "module": "./services.mjs",
36
36
  "unpkg": "./services.min.js",
37
37
  "jsdelivr": "./services.min.js"
38
- },
39
- "./node": "./node/index.cjs"
38
+ }
40
39
  }
41
40
  }
package/services.cjs CHANGED
@@ -1,10 +1,11 @@
1
1
  /*!
2
- * k99 v0.6.0
3
- * (c) 2019-2024 猛火Fierflame
2
+ * k99 v0.7.0
3
+ * (c) 2019-2025 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
6
  'use strict';
7
7
 
8
+ /** @import { Service } from 'k99' */
8
9
  /**
9
10
  *
10
11
  * @param {string} s
@@ -52,7 +53,7 @@ async function parse(request) {
52
53
  } catch { }
53
54
  return null;
54
55
  }
55
- /** @type {import('k99').Service<Promise<any> | null>} */
56
+ /** @type {Service<Promise<any> | null>} */
56
57
  const formBodyService = function (ctx) {
57
58
  const [mime, charset] = ctx.requestType.replace(/\s/g, '').split(';');
58
59
  if (mime !== 'application/x-www-form-urlencoded') { return () => null; }
@@ -63,7 +64,8 @@ const formBodyService = function (ctx) {
63
64
  return () => result;
64
65
  };
65
66
 
66
- /** @type {import('k99').Service<Promise<any> | null>} */
67
+ /** @import { Service } from 'k99' */
68
+ /** @type {Service<Promise<any> | null>} */
67
69
  const jsonBodyService = function (ctx) {
68
70
  const [mime, charset] = ctx.requestType.replace(/\s/g, '').split(';');
69
71
  if (mime !== 'application/json' && mime !== 'text/json') { return () => null; }
package/services.d.ts CHANGED
@@ -1,14 +1,15 @@
1
1
  /*!
2
- * k99 v0.6.0
3
- * (c) 2019-2024 猛火Fierflame
2
+ * k99 v0.7.0
3
+ * (c) 2019-2025 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
- import * as k99 from 'k99';
6
+ import { Service } from 'k99';
7
7
 
8
- /** @type {import('k99').Service<Promise<any> | null>} */
9
- declare const formBodyService: k99.Service<Promise<any> | null>;
8
+ /** @type {Service<Promise<any> | null>} */
9
+ declare const formBodyService: Service<Promise<any> | null>;
10
10
 
11
- /** @type {import('k99').Service<Promise<any> | null>} */
12
- declare const jsonBodyService: k99.Service<Promise<any> | null>;
11
+ /** @import { Service } from 'k99' */
12
+ /** @type {Service<Promise<any> | null>} */
13
+ declare const jsonBodyService: Service<Promise<any> | null>;
13
14
 
14
15
  export { formBodyService, jsonBodyService };
package/services.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * k99 v0.6.0
3
- * (c) 2019-2024 猛火Fierflame
2
+ * k99 v0.7.0
3
+ * (c) 2019-2025 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
6
  (function (global, factory) {
@@ -9,6 +9,7 @@
9
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.k99Services = {}));
10
10
  })(this, (function (exports) { 'use strict';
11
11
 
12
+ /** @import { Service } from 'k99' */
12
13
  /**
13
14
  *
14
15
  * @param {string} s
@@ -56,7 +57,7 @@
56
57
  } catch { }
57
58
  return null;
58
59
  }
59
- /** @type {import('k99').Service<Promise<any> | null>} */
60
+ /** @type {Service<Promise<any> | null>} */
60
61
  const formBodyService = function (ctx) {
61
62
  const [mime, charset] = ctx.requestType.replace(/\s/g, '').split(';');
62
63
  if (mime !== 'application/x-www-form-urlencoded') { return () => null; }
@@ -67,7 +68,8 @@
67
68
  return () => result;
68
69
  };
69
70
 
70
- /** @type {import('k99').Service<Promise<any> | null>} */
71
+ /** @import { Service } from 'k99' */
72
+ /** @type {Service<Promise<any> | null>} */
71
73
  const jsonBodyService = function (ctx) {
72
74
  const [mime, charset] = ctx.requestType.replace(/\s/g, '').split(';');
73
75
  if (mime !== 'application/json' && mime !== 'text/json') { return () => null; }
package/services.min.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * k99 v0.6.0
3
- * (c) 2019-2024 猛火Fierflame
2
+ * k99 v0.7.0
3
+ * (c) 2019-2025 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
6
  !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).k99Services={})}(this,(function(e){"use strict";function n(e){const n=e.indexOf("=");return n<0?[decodeURIComponent(e),""]:[decodeURIComponent(e.substring(0,n)),decodeURIComponent(e.substring(n+1))]}async function t(e){try{const t=await e.text();return t.length?function(e){const t={};for(const o of e.split("&").filter(Boolean)){const[e,r]=n(o);t[e]=e in t?[t[e],r].flat():[r]}return t}(t):null}catch{}return null}e.formBodyService=function(e){const[n,o]=e.requestType.replace(/\s/g,"").split(";");if("application/x-www-form-urlencoded"!==n)return()=>null;if(o&&"charset=UTF-8"!==o)return()=>null;const{request:r}=e;if(r.bodyUsed)return()=>null;const s=t(r);return()=>s},e.jsonBodyService=function(e){const[n,t]=e.requestType.replace(/\s/g,"").split(";");if("application/json"!==n&&"text/json"!==n)return()=>null;if(t&&"charset=UTF-8"!==t)return()=>null;const{request:o}=e;if(o.bodyUsed)return()=>null;const r=o.json();return()=>r}}));
package/services.min.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * k99 v0.6.0
3
- * (c) 2019-2024 猛火Fierflame
2
+ * k99 v0.7.0
3
+ * (c) 2019-2025 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
6
  function n(n){const t=n.indexOf("=");return t<0?[decodeURIComponent(n),""]:[decodeURIComponent(n.substring(0,t)),decodeURIComponent(n.substring(t+1))]}async function t(t){try{const e=await t.text();return e.length?function(t){const e={};for(const o of t.split("&").filter(Boolean)){const[t,r]=n(o);e[t]=t in e?[e[t],r].flat():[r]}return e}(e):null}catch{}return null}const e=function(n){const[e,o]=n.requestType.replace(/\s/g,"").split(";");if("application/x-www-form-urlencoded"!==e)return()=>null;if(o&&"charset=UTF-8"!==o)return()=>null;const{request:r}=n;if(r.bodyUsed)return()=>null;const s=t(r);return()=>s},o=function(n){const[t,e]=n.requestType.replace(/\s/g,"").split(";");if("application/json"!==t&&"text/json"!==t)return()=>null;if(e&&"charset=UTF-8"!==e)return()=>null;const{request:o}=n;if(o.bodyUsed)return()=>null;const r=o.json();return()=>r};export{e as formBodyService,o as jsonBodyService};
package/services.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  /*!
2
- * k99 v0.6.0
3
- * (c) 2019-2024 猛火Fierflame
2
+ * k99 v0.7.0
3
+ * (c) 2019-2025 猛火Fierflame
4
4
  * @license MIT
5
5
  */
6
+ /** @import { Service } from 'k99' */
6
7
  /**
7
8
  *
8
9
  * @param {string} s
@@ -50,7 +51,7 @@ async function parse(request) {
50
51
  } catch { }
51
52
  return null;
52
53
  }
53
- /** @type {import('k99').Service<Promise<any> | null>} */
54
+ /** @type {Service<Promise<any> | null>} */
54
55
  const formBodyService = function (ctx) {
55
56
  const [mime, charset] = ctx.requestType.replace(/\s/g, '').split(';');
56
57
  if (mime !== 'application/x-www-form-urlencoded') { return () => null; }
@@ -61,7 +62,8 @@ const formBodyService = function (ctx) {
61
62
  return () => result;
62
63
  };
63
64
 
64
- /** @type {import('k99').Service<Promise<any> | null>} */
65
+ /** @import { Service } from 'k99' */
66
+ /** @type {Service<Promise<any> | null>} */
65
67
  const jsonBodyService = function (ctx) {
66
68
  const [mime, charset] = ctx.requestType.replace(/\s/g, '').split(';');
67
69
  if (mime !== 'application/json' && mime !== 'text/json') { return () => null; }
package/node/index.cjs DELETED
@@ -1,140 +0,0 @@
1
- /*!
2
- * k99 v0.6.0
3
- * (c) 2019-2024 猛火Fierflame
4
- * @license MIT
5
- */
6
- 'use strict';
7
-
8
- var node_stream = require('node:stream');
9
- var node_http2 = require('node:http2');
10
-
11
- /**
12
- *
13
- * @param {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} req
14
- * @returns {AbortSignal}
15
- */
16
- function createAbortSignal(req) {
17
- const ac = new AbortController();
18
- /**
19
- *
20
- * @param {Error} [err]
21
- * @returns
22
- */
23
- const end = (err) => {
24
- req.off('end', end);
25
- req.off('error', end);
26
- if (!err) { return; }
27
- ac.abort(err);
28
- };
29
- req.on('end', end);
30
- req.on('error', end);
31
-
32
- return ac.signal;
33
- }
34
-
35
- /**
36
- *
37
- * @param {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} req
38
- * @returns {Request}
39
- */
40
- function toWebRequest(req) {
41
- const signal = createAbortSignal(req);
42
- const host = req.headers['host'] || '127.0.0.1';
43
- const url = new URL(req.url || '/', `http://${ host }`);
44
- const method = (req.method || 'GET').toUpperCase();
45
- const headers = new Headers();
46
- for (const [k, v] of Object.entries(req.headers)) {
47
- for (const it of [v].flat()) {
48
- headers.append(k.toLowerCase(), String(it));
49
- }
50
- }
51
- const body = ['GET', 'OPTIONS'].includes(method) ? null : /** @type {any} */(node_stream.Readable.toWeb(req));
52
- // @ts-ignore
53
- return new Request(url, { method, headers, signal, body, duplex: 'half'});
54
- }
55
-
56
- /**
57
- *
58
- * @param {import('node:http').ServerResponse | Http2ServerResponse} res
59
- * @param {Response} response
60
- * @param {(e: any) => void} onError
61
- * @returns
62
- */
63
- async function linkResponse(res, response, onError) {
64
- res.statusCode = response.status;
65
- const {headers} = response;
66
- for (const [k, v] of headers) {
67
- res.setHeader(k, v);
68
- }
69
- const cookies = headers.getSetCookie();
70
- if (cookies.length) {
71
- res.setHeader('set-cookie', cookies);
72
- }
73
- const {body} = response;
74
- if (!body) {
75
- res.end();
76
- return;
77
- }
78
- const readable = node_stream.Readable.fromWeb(/** @type {any} */(body));
79
- readable.on('error', onError);
80
- readable.pipe(res instanceof node_http2.Http2ServerResponse ? res.stream : res);
81
- }
82
-
83
- /**
84
- *
85
- * @param {any} e
86
- */
87
- function echoError(e) {
88
- console.error(e);
89
- }
90
- /**
91
- * @template {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} TReq
92
- * @template {import('node:http').ServerResponse | import('node:http2').Http2ServerResponse} TRes
93
- * @typedef {object} HttpCallbackOptions
94
- * @property {(req: TReq, res: TRes, next?: () => void) => any} [notFound]
95
- * @property {(e: any) => void} [onError]
96
- * @property {boolean} [errorInResponse]
97
- */
98
- /**
99
- *
100
- * @template {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} TReq
101
- * @template {import('node:http').ServerResponse | import('node:http2').Http2ServerResponse} TRes
102
- * @param {(request: Request) => Promise<Response | null>} run
103
- * @param {HttpCallbackOptions<TReq, TRes>} [options]
104
- * @returns {(req: TReq, res: TRes, next?: () => void) => any}
105
- */
106
- function createHttpCallback(run, {
107
- notFound,
108
- onError = echoError,
109
- errorInResponse,
110
- } = {}) {
111
- return function httpCallback(req, res, next) {
112
- return run(toWebRequest(req)).then(r => {
113
- if (r) { return linkResponse(res, r, onError); }
114
- if (notFound) { return notFound(req, res, next); }
115
- if (next) { return next(); }
116
- res.statusCode = 404;
117
- res.end();
118
- }, e => {
119
- res.statusCode = 500;
120
- onError(e);
121
- if (!errorInResponse) {
122
- res.end();
123
- return;
124
- }
125
- /** @type {import('node:stream').Writable} */
126
- const stream =
127
- res instanceof node_http2.Http2ServerResponse ? res.stream : res;
128
- if (e instanceof Error) {
129
- stream.write(`${ e.stack || '' }`);
130
- } else {
131
- stream.write(String(e));
132
- }
133
- res.end();
134
- });
135
- };
136
- }
137
-
138
- exports.createHttpCallback = createHttpCallback;
139
- exports.linkResponse = linkResponse;
140
- exports.toWebRequest = toWebRequest;
package/node/index.d.cts DELETED
@@ -1,52 +0,0 @@
1
- /// <reference types="node" />
2
- /*!
3
- * k99 v0.6.0
4
- * (c) 2019-2024 猛火Fierflame
5
- * @license MIT
6
- */
7
- import * as node_http2 from 'node:http2';
8
- import { Http2ServerResponse } from 'node:http2';
9
- import * as node_http from 'node:http';
10
- import * as http2 from 'http2';
11
- import * as http from 'http';
12
-
13
- /**
14
- *
15
- * @param {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} req
16
- * @returns {Request}
17
- */
18
- declare function toWebRequest(req: node_http.IncomingMessage | node_http2.Http2ServerRequest): Request;
19
-
20
- /**
21
- *
22
- * @param {import('node:http').ServerResponse | Http2ServerResponse} res
23
- * @param {Response} response
24
- * @param {(e: any) => void} onError
25
- * @returns
26
- */
27
- declare function linkResponse(res: node_http.ServerResponse | Http2ServerResponse, response: Response, onError: (e: any) => void): Promise<void>;
28
-
29
- /**
30
- * @template {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} TReq
31
- * @template {import('node:http').ServerResponse | import('node:http2').Http2ServerResponse} TRes
32
- * @typedef {object} HttpCallbackOptions
33
- * @property {(req: TReq, res: TRes, next?: () => void) => any} [notFound]
34
- * @property {(e: any) => void} [onError]
35
- * @property {boolean} [errorInResponse]
36
- */
37
- /**
38
- *
39
- * @template {import('node:http').IncomingMessage | import('node:http2').Http2ServerRequest} TReq
40
- * @template {import('node:http').ServerResponse | import('node:http2').Http2ServerResponse} TRes
41
- * @param {(request: Request) => Promise<Response | null>} run
42
- * @param {HttpCallbackOptions<TReq, TRes>} [options]
43
- * @returns {(req: TReq, res: TRes, next?: () => void) => any}
44
- */
45
- declare function createHttpCallback<TReq extends http.IncomingMessage | http2.Http2ServerRequest, TRes extends http.ServerResponse<http.IncomingMessage> | Http2ServerResponse>(run: (request: Request) => Promise<Response | null>, { notFound, onError, errorInResponse, }?: HttpCallbackOptions<TReq, TRes> | undefined): (req: TReq, res: TRes, next?: () => void) => any;
46
- type HttpCallbackOptions<TReq extends http.IncomingMessage | http2.Http2ServerRequest, TRes extends http.ServerResponse<http.IncomingMessage> | Http2ServerResponse> = {
47
- notFound?: ((req: TReq, res: TRes, next?: () => void) => any) | undefined;
48
- onError?: ((e: any) => void) | undefined;
49
- errorInResponse?: boolean | undefined;
50
- };
51
-
52
- export { createHttpCallback, linkResponse, toWebRequest };