@ublitzjs/core 0.0.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.
- package/README.md +38 -0
- package/USAGE.md +319 -0
- package/cjs/http-codes.cjs +56 -0
- package/cjs/http-headers.cjs +63 -0
- package/cjs/index.cjs +61 -0
- package/logo.png +0 -0
- package/mjs/http-codes.mjs +52 -0
- package/mjs/http-headers.mjs +61 -0
- package/mjs/index.mjs +51 -0
- package/package.json +29 -0
- package/tsconfig.json +41 -0
- package/types/http-codes.d.ts +54 -0
- package/types/http-headers.d.ts +285 -0
- package/types/index.d.ts +170 -0
- package/types/uws-types.d.ts +123 -0
package/mjs/index.mjs
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import uWS from "uWebSockets.js";
|
|
3
|
+
import { Buffer } from "node:buffer";
|
|
4
|
+
export * from "./http-headers.mjs";
|
|
5
|
+
export * from "./http-codes.mjs";
|
|
6
|
+
import { EventEmitter } from "tseep";
|
|
7
|
+
function registerAbort(res) {
|
|
8
|
+
if (typeof res.aborted === "boolean")
|
|
9
|
+
throw new Error("abort already registered");
|
|
10
|
+
res.aborted = false;
|
|
11
|
+
res.emitter = new EventEmitter();
|
|
12
|
+
return res.onAborted(() => {
|
|
13
|
+
res.aborted = true;
|
|
14
|
+
res.emitter.emit("abort");
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
var closure = (param) => param();
|
|
18
|
+
function extendApp(app, ...rest) {
|
|
19
|
+
app.register = function (plugin) {
|
|
20
|
+
return plugin(this), this;
|
|
21
|
+
};
|
|
22
|
+
app.onError = function (fn) {
|
|
23
|
+
return (this._errHandler = fn), this;
|
|
24
|
+
};
|
|
25
|
+
app._startPromises = [];
|
|
26
|
+
app.ready = function () {
|
|
27
|
+
return Promise.all(this._startPromises).then(
|
|
28
|
+
() => (this._startPromises = [])
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
app.route = function (opts, plugins) {
|
|
32
|
+
if (plugins) for (const p of plugins) p(opts, this);
|
|
33
|
+
return this[opts.method](opts.path, opts.controller);
|
|
34
|
+
};
|
|
35
|
+
for (const extension of rest) Object.assign(app, extension);
|
|
36
|
+
return app;
|
|
37
|
+
}
|
|
38
|
+
function toAB(data) {
|
|
39
|
+
var NodeBuf = data instanceof Buffer ? data : Buffer.from(data);
|
|
40
|
+
return NodeBuf.buffer.slice(
|
|
41
|
+
NodeBuf.byteOffset,
|
|
42
|
+
NodeBuf.byteOffset + NodeBuf.byteLength
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
var DeclarativeResponse = uWS.DeclarativeResponse;
|
|
46
|
+
DeclarativeResponse.prototype.writeHeaders = function (headers) {
|
|
47
|
+
for (const key in headers) this.writeHeader(key, headers[key]);
|
|
48
|
+
return this;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export { DeclarativeResponse, extendApp, registerAbort, toAB, closure };
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ublitzjs/core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"exports": {
|
|
5
|
+
"types": "./types/index.d.ts",
|
|
6
|
+
"require": "./cjs/index.cjs",
|
|
7
|
+
"import": "./mjs/index.mjs"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"tseep": "^1.3.1",
|
|
11
|
+
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.52.0"
|
|
12
|
+
},
|
|
13
|
+
"publishConfig": {"access": "public"},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"undici": "^7.10.0",
|
|
16
|
+
"esbuild": "^0.25.4",
|
|
17
|
+
"vitest": "^3.1.1",
|
|
18
|
+
"ws": "^8.18.2"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/ublitzjs/core.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/ublitzjs/core/issues",
|
|
26
|
+
"email": "diril656@gmail.com"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/ublitzjs/core#readme"
|
|
29
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Enable latest features
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "esnext",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
"allowJs": true,
|
|
9
|
+
|
|
10
|
+
// Bundler mode
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"skipLibCheck": false,
|
|
16
|
+
"noLib": false,
|
|
17
|
+
// Best practices
|
|
18
|
+
"strict": true,
|
|
19
|
+
"alwaysStrict": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"removeComments": true,
|
|
22
|
+
|
|
23
|
+
// Some stricter flags (disabled by default)
|
|
24
|
+
"noUnusedLocals": true,
|
|
25
|
+
"allowUnusedLabels": false,
|
|
26
|
+
"strictBuiltinIteratorReturn": true,
|
|
27
|
+
"strictBindCallApply": true,
|
|
28
|
+
"noUnusedParameters": true,
|
|
29
|
+
"noImplicitAny": true,
|
|
30
|
+
"noImplicitReturns": true,
|
|
31
|
+
"noUncheckedIndexedAccess": true,
|
|
32
|
+
"noUncheckedSideEffectImports": true,
|
|
33
|
+
"strictNullChecks": true,
|
|
34
|
+
"noImplicitThis": true,
|
|
35
|
+
"strictPropertyInitialization": true,
|
|
36
|
+
"strictFunctionTypes": true,
|
|
37
|
+
"allowUnreachableCode": false,
|
|
38
|
+
"noImplicitOverride": true,
|
|
39
|
+
"noPropertyAccessFromIndexSignature": false
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { HttpResponse as uwsHttpResponse } from "uWebSockets.js";
|
|
2
|
+
import type { HttpRequest, HttpMethods } from ".";
|
|
3
|
+
/**
|
|
4
|
+
* If something wrong is to content-length, sends 411 code and throws error with a "cause"
|
|
5
|
+
*/
|
|
6
|
+
export function checkContentLength(
|
|
7
|
+
res: uwsHttpResponse,
|
|
8
|
+
req: HttpRequest
|
|
9
|
+
): number;
|
|
10
|
+
/**
|
|
11
|
+
* sends http 400 and throws an Error with "causeForYou"
|
|
12
|
+
*/
|
|
13
|
+
export function badRequest(
|
|
14
|
+
res: uwsHttpResponse,
|
|
15
|
+
error: string,
|
|
16
|
+
causeForYou: string
|
|
17
|
+
): void;
|
|
18
|
+
/**
|
|
19
|
+
* sends http 413 And throws, but doesn't throw an Error
|
|
20
|
+
*/
|
|
21
|
+
export function tooLargeBody(res: uwsHttpResponse, limit: number): void;
|
|
22
|
+
/**
|
|
23
|
+
* Constructs function, which sends http 405 and sets http Allow header with all methods you passed
|
|
24
|
+
*/
|
|
25
|
+
export function seeOtherMethods(
|
|
26
|
+
methodsArr: HttpMethods[]
|
|
27
|
+
): (res: uwsHttpResponse, req: any) => any;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Constructs the function, which sets 404 http code and sends the message you have specified
|
|
31
|
+
*/
|
|
32
|
+
export function notFoundConstructor(
|
|
33
|
+
message?: string
|
|
34
|
+
): (res: uwsHttpResponse, req: any) => any;
|
|
35
|
+
/**
|
|
36
|
+
* code: required content length
|
|
37
|
+
*/
|
|
38
|
+
export var c411: ArrayBuffer;
|
|
39
|
+
/**
|
|
40
|
+
* code: bad request
|
|
41
|
+
*/
|
|
42
|
+
export var c400: ArrayBuffer;
|
|
43
|
+
/**
|
|
44
|
+
* code: payload too large
|
|
45
|
+
*/
|
|
46
|
+
export var c413: ArrayBuffer;
|
|
47
|
+
/**
|
|
48
|
+
* code: method not allowed
|
|
49
|
+
*/
|
|
50
|
+
export var c405: ArrayBuffer;
|
|
51
|
+
/**
|
|
52
|
+
* code: not found
|
|
53
|
+
*/
|
|
54
|
+
export var c404: ArrayBuffer;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import type { HttpResponse } from "./index";
|
|
2
|
+
import type { HttpResponse as uwsHttpResponse } from "uWebSockets.js";
|
|
3
|
+
type helmetHeadersT = {
|
|
4
|
+
/**
|
|
5
|
+
* if client fetched resource, but its MIME type is different - abort request
|
|
6
|
+
*/
|
|
7
|
+
"X-Content-Type-Options": "nosniff";
|
|
8
|
+
/**
|
|
9
|
+
* Safari doesn't support it
|
|
10
|
+
*/
|
|
11
|
+
"X-DNS-Prefetch-Control": "on" | "off";
|
|
12
|
+
/**
|
|
13
|
+
* Sites can use this to avoid clickjacking (<iframe> html tag)
|
|
14
|
+
*/
|
|
15
|
+
"X-Frame-Options": "DENY" | "SAMEORIGIN";
|
|
16
|
+
/**
|
|
17
|
+
* whether you need info about client.
|
|
18
|
+
*/
|
|
19
|
+
"Referrer-Policy":
|
|
20
|
+
| "no-referrer"
|
|
21
|
+
| "no-referrer-when-downgrade"
|
|
22
|
+
| "origin"
|
|
23
|
+
| "origin-when-cross-origin"
|
|
24
|
+
| "same-origin"
|
|
25
|
+
| "strict-origin"
|
|
26
|
+
| "strict-origin-when-cross-origin"
|
|
27
|
+
| "unsafe-url";
|
|
28
|
+
/**
|
|
29
|
+
* usually for Adobe Acrobat or Microsoft Silverlight.
|
|
30
|
+
*/
|
|
31
|
+
"X-Permitted-Cross-Domain-Policies":
|
|
32
|
+
| "none"
|
|
33
|
+
| "master-only"
|
|
34
|
+
| "by-content-type"
|
|
35
|
+
| "by-ftp-filename"
|
|
36
|
+
| "all"
|
|
37
|
+
| "none-this-response";
|
|
38
|
+
/**
|
|
39
|
+
* Whether downloaded files should be run on the client side immediately. For IE8
|
|
40
|
+
*/
|
|
41
|
+
"X-Download-Options": "noopen";
|
|
42
|
+
/**
|
|
43
|
+
* From where should client fetch resources
|
|
44
|
+
*/
|
|
45
|
+
"Cross-Origin-Resource-Policy": "same-site" | "same-origin" | "cross-origin";
|
|
46
|
+
/**
|
|
47
|
+
* whether new page opened via Window.open() should be treated differently for performance reasons
|
|
48
|
+
*/
|
|
49
|
+
"Cross-Origin-Opener-Policy":
|
|
50
|
+
| "unsafe-none"
|
|
51
|
+
| "same-origin-allow-popups"
|
|
52
|
+
| "same-origin"
|
|
53
|
+
| "noopener-allow-popups";
|
|
54
|
+
/**
|
|
55
|
+
* By adding this header you can declare that your site should only load resources that have explicitly opted-in to being loaded across origins.
|
|
56
|
+
* "require-corp" LETS YOU USE new SharedArrayBuffer()
|
|
57
|
+
*/
|
|
58
|
+
"Cross-Origin-Embedder-Policy":
|
|
59
|
+
| "unsafe-none"
|
|
60
|
+
| "require-corp"
|
|
61
|
+
| "credentialless";
|
|
62
|
+
/**
|
|
63
|
+
* similar to COOP, where ?1 is true
|
|
64
|
+
*/
|
|
65
|
+
"Origin-Agent-Cluster": "?0" | "?1";
|
|
66
|
+
};
|
|
67
|
+
type allHeaders = {
|
|
68
|
+
/**
|
|
69
|
+
* Headers, which may change for different responses. Use the same value for all methods of a given url.
|
|
70
|
+
* @example
|
|
71
|
+
* "Content-Type, Content-Length"
|
|
72
|
+
*/
|
|
73
|
+
Vary: string;
|
|
74
|
+
/**
|
|
75
|
+
* confirms that client "really wants" to request that an HTTP client is upgraded to become a WebSocket.
|
|
76
|
+
*/
|
|
77
|
+
"Sec-Websocket-Key": string;
|
|
78
|
+
/**
|
|
79
|
+
* protocol you are communicating by using WebSockets
|
|
80
|
+
* @see https://www.iana.org/assignments/websocket/websocket.xml#subprotocol-name
|
|
81
|
+
*/
|
|
82
|
+
"Sec-Websocket-Protocol": string;
|
|
83
|
+
"Sec-Websocket-Extensions": string;
|
|
84
|
+
Server: string;
|
|
85
|
+
"Set-Cookie": string;
|
|
86
|
+
Upgrade: string;
|
|
87
|
+
"User-Agent": string;
|
|
88
|
+
Origin: string;
|
|
89
|
+
Range: string;
|
|
90
|
+
Location: string;
|
|
91
|
+
"Last-Modified": string;
|
|
92
|
+
Host: string;
|
|
93
|
+
Forwarded: string;
|
|
94
|
+
Cookie: string;
|
|
95
|
+
Allow: string;
|
|
96
|
+
"Access-Control-Request-Headers": string;
|
|
97
|
+
"Access-Control-Request-Method": string;
|
|
98
|
+
/**
|
|
99
|
+
* indicates which content types, expressed as MIME types, the sender is able to understand
|
|
100
|
+
*/
|
|
101
|
+
Accept: string;
|
|
102
|
+
/**
|
|
103
|
+
* You know this one. It is "text/html" or "video/mp4" or whatever
|
|
104
|
+
*/
|
|
105
|
+
"Content-Type": string;
|
|
106
|
+
/**
|
|
107
|
+
* Length in bytes of content, you send or receive.
|
|
108
|
+
* @type number. BUT here it is a string
|
|
109
|
+
*/
|
|
110
|
+
"Content-Length": string;
|
|
111
|
+
/**
|
|
112
|
+
* get it from setCSP()
|
|
113
|
+
*/
|
|
114
|
+
"Content-Security-Policy": string;
|
|
115
|
+
//"Content-Security-Policy-Report-Only":"",
|
|
116
|
+
//"Strict-Transport-Security":`max-age=${60 * 60 * 24 * 365}; includeSubDomains`,
|
|
117
|
+
/**
|
|
118
|
+
* Allowed origins to get the resource. * - all, https://example.com - some website.
|
|
119
|
+
*/
|
|
120
|
+
"Access-Control-Allow-Origin": string;
|
|
121
|
+
/**
|
|
122
|
+
* Allowed headers in the request.
|
|
123
|
+
*/
|
|
124
|
+
"Access-Control-Allow-Headers": string;
|
|
125
|
+
/**
|
|
126
|
+
* CORS version of Allow header
|
|
127
|
+
*/
|
|
128
|
+
"Access-Control-Allow-Methods": string;
|
|
129
|
+
/**
|
|
130
|
+
* How much time the response should be cached.
|
|
131
|
+
* 1) must-revalidate
|
|
132
|
+
* 2) no-cache
|
|
133
|
+
* 3) no-store
|
|
134
|
+
* 4) no-transform
|
|
135
|
+
* 5) public -> cached anyhow
|
|
136
|
+
* 6) private
|
|
137
|
+
* 7) proxy-revalidate
|
|
138
|
+
* 8) max-age=<seconds>
|
|
139
|
+
* 9) s-maxage=<seconds>;
|
|
140
|
+
* @but those below aren't supported everywhere:
|
|
141
|
+
* 1) immutable
|
|
142
|
+
* 2) stale-while-revalidate=<seconds>
|
|
143
|
+
* 3) stale-if-error=<seconds>
|
|
144
|
+
*/
|
|
145
|
+
"Cache-Control": string;
|
|
146
|
+
"Access-Control-Max-Age": string;
|
|
147
|
+
};
|
|
148
|
+
export type BaseHeaders = Partial<
|
|
149
|
+
allHeaders & helmetHeadersT & { [key: string]: string }
|
|
150
|
+
>;
|
|
151
|
+
/**
|
|
152
|
+
* A map containing all headers as ArrayBuffers, so speed remains. There are several use cases of it:
|
|
153
|
+
* 1) Don't define them in requests ( post(res){new HeadersMap({...headers}).prepare().toRes(res)} ). This is slow. Define maps BEFORE actual usage.
|
|
154
|
+
* 2) You can pass them in LightMethod or HeavyMethod in shared property (but handle it manually)
|
|
155
|
+
* 3) As a default use HeadersMap.default. It can't be edited, because it is already "prepared".
|
|
156
|
+
* 4) Don't define them before writing status on request. uWebSockets.js after first written header considers response successful and puts "200" code automatically. Set headers AFTER validation in class controllers (handler function) and after writing status (or don't write it at all. It will be 200).
|
|
157
|
+
*/
|
|
158
|
+
export class HeadersMap<Opts extends BaseHeaders> extends Map {
|
|
159
|
+
public currentHeaders: undefined | Opts;
|
|
160
|
+
constructor(opts: Opts);
|
|
161
|
+
/**
|
|
162
|
+
* remove several headers from this map. Use BEFORE map.prepare(), because it will compare them by location in memory (string !== ArrayBuffer)
|
|
163
|
+
* @example HeadersMap.default.remove("Content-Security-Policy", "X-DNS-Prefetch-Control", ...otherHeaders).prepare()
|
|
164
|
+
*/
|
|
165
|
+
remove(...keys: (keyof Opts)[]): this;
|
|
166
|
+
/**
|
|
167
|
+
* last function before "going to response". It converts all strings to ArrayBuffers, so you should delete unwanted headers before it
|
|
168
|
+
* @returns function, which sets all headers on the response.
|
|
169
|
+
* @example
|
|
170
|
+
* new HeadersMap({...HeadersMap.baseObj,"a":"a"}).remove("a").prepare();
|
|
171
|
+
*/
|
|
172
|
+
prepare(): (res: uwsHttpResponse) => HttpResponse;
|
|
173
|
+
/**
|
|
174
|
+
* write all static headers to response. Use AFTER map.prepare function, if you want speed.
|
|
175
|
+
* @example
|
|
176
|
+
* headersMap.toRes(res);
|
|
177
|
+
* // if you want dynamic headers, use BASE:
|
|
178
|
+
* res.writeHeader(toAB(headerVariable),toAB(value))
|
|
179
|
+
*/
|
|
180
|
+
toRes(res: uwsHttpResponse): HttpResponse;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* obj, containing basic headers, which u can use as a background for own headers
|
|
184
|
+
* @example
|
|
185
|
+
* new HeadersMap({...HeadersMap.baseObj, "ownHeader":"hello world"}).remove("X-Download-Options")
|
|
186
|
+
*/
|
|
187
|
+
static baseObj: helmetHeadersT;
|
|
188
|
+
/**
|
|
189
|
+
* map with default headers
|
|
190
|
+
*/
|
|
191
|
+
static default: (res: uwsHttpResponse) => HttpResponse;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* This function creates Content-Security-Policy string.
|
|
195
|
+
*/
|
|
196
|
+
export function setCSP<T extends CSP>(
|
|
197
|
+
mainCSP: T,
|
|
198
|
+
...remove: (keyof CSP)[]
|
|
199
|
+
): string;
|
|
200
|
+
type CSP = Partial<
|
|
201
|
+
typeof CSPDirs & {
|
|
202
|
+
/**
|
|
203
|
+
* for websites with deprecated urls.
|
|
204
|
+
*/
|
|
205
|
+
"upgrade-insecure-requests": string[];
|
|
206
|
+
}
|
|
207
|
+
>;
|
|
208
|
+
/**
|
|
209
|
+
* Usual CSP directories. If you want more dirs:
|
|
210
|
+
* 1) I will put more in soon
|
|
211
|
+
* 2) use string concatenation (use BASE)
|
|
212
|
+
* @example
|
|
213
|
+
* new HeadersMap({...HeadersMap.baseObj, "Content-Security-Policy":setCSP({...CSPDirs}) + " your-dir: 'self';"})
|
|
214
|
+
*/
|
|
215
|
+
export var CSPDirs: {
|
|
216
|
+
/**
|
|
217
|
+
* basic urls for resources, if other directives are missing
|
|
218
|
+
*/
|
|
219
|
+
"default-src": string[];
|
|
220
|
+
/**
|
|
221
|
+
*used for html <base> tag
|
|
222
|
+
*/
|
|
223
|
+
"base-uri": string[];
|
|
224
|
+
/**
|
|
225
|
+
* urls valid for css at-rule @font-face
|
|
226
|
+
*/
|
|
227
|
+
"font-src": string[];
|
|
228
|
+
/**
|
|
229
|
+
* urls, allowed for <form action=""> action attribute. Forbidden at all='none'
|
|
230
|
+
*/
|
|
231
|
+
"form-action": string[];
|
|
232
|
+
/**
|
|
233
|
+
* urls of sites, WHICH can embed YOUR page via <iframe> etc. 'none' = forbidden at all
|
|
234
|
+
*/
|
|
235
|
+
"frame-ancestors": string[];
|
|
236
|
+
/**
|
|
237
|
+
* valid image urls. 'none' = forbidden at all
|
|
238
|
+
*/
|
|
239
|
+
"img-src": string[];
|
|
240
|
+
/**
|
|
241
|
+
* controls urls of WebSocket, fetch, fetchLater, EventSources and Navigator.sendBeacon functions or ping attribute of <a> tag.
|
|
242
|
+
*/
|
|
243
|
+
"connect-src": string[];
|
|
244
|
+
/**
|
|
245
|
+
* usually stuff it has influence on is deprecated, so put 'none'
|
|
246
|
+
*/
|
|
247
|
+
"object-src": string[];
|
|
248
|
+
/**
|
|
249
|
+
* Urls for script tags. But also it forbids inline js scripts. 'none' - forbidden, 'self' - your site's scripts, 'unsafe-inline' - allows inline scripts
|
|
250
|
+
*/
|
|
251
|
+
"script-src": string[];
|
|
252
|
+
/**
|
|
253
|
+
* More important than "script-src", specifies inline js scripts. 'unsafe-inline' - allow onclick and other inline attributes
|
|
254
|
+
*/
|
|
255
|
+
"script-src-attr": string[];
|
|
256
|
+
/**
|
|
257
|
+
* More important than "script-src", specifies urls for <script> tag. 'none' - forbidden; 'unsafe-inline' - allow <script> tag without src=""; 'unsafe-eval' - for protobufjs;
|
|
258
|
+
*/
|
|
259
|
+
"script-src-elem": string[];
|
|
260
|
+
/**
|
|
261
|
+
* Urls for style tags. But also it forbids inline css styles. 'none' - forbidden, 'self' - your site's styles, 'unsafe-inline' - allows inline styles
|
|
262
|
+
*/
|
|
263
|
+
"style-src": string[];
|
|
264
|
+
/**
|
|
265
|
+
* More important than "style-src", specifies inline css styles.
|
|
266
|
+
*/
|
|
267
|
+
"style-src-attr": string[];
|
|
268
|
+
/**
|
|
269
|
+
* More important than "style-src", specifies urls for <link> tag
|
|
270
|
+
*/
|
|
271
|
+
"style-src-elem": string[];
|
|
272
|
+
/**
|
|
273
|
+
* Trusted Types XSS DOM API names. 'allow-duplicates', 'none'. Works for Chrome and Edge.
|
|
274
|
+
*/
|
|
275
|
+
"trusted-types": string[];
|
|
276
|
+
/**
|
|
277
|
+
* specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts.
|
|
278
|
+
*/
|
|
279
|
+
"worker-src": string[];
|
|
280
|
+
/**
|
|
281
|
+
* specifies valid sources for loading media using the <audio> and <video> elements.
|
|
282
|
+
*/
|
|
283
|
+
"media-src": string[];
|
|
284
|
+
};
|
|
285
|
+
export type lowHeaders = Lowercase<keyof allHeaders>;
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HttpRequest as uwsHttpRequest,
|
|
3
|
+
TemplatedApp,
|
|
4
|
+
HttpResponse as uwsHttpResponse,
|
|
5
|
+
RecognizedString,
|
|
6
|
+
us_socket_context_t,
|
|
7
|
+
} from "uWebSockets.js";
|
|
8
|
+
import { Buffer } from "node:buffer";
|
|
9
|
+
|
|
10
|
+
import { EventEmitter } from "tseep";
|
|
11
|
+
import type { DocumentedWSBehavior } from "./uws-types";
|
|
12
|
+
/**
|
|
13
|
+
* function to effortlessly mark response as aborted AND to attach an event emitter, so that you can easily scale the handler. If you don't need event emitter and only some res.aborted - set it by yourself (no overkill for the handler)
|
|
14
|
+
* @param res
|
|
15
|
+
*/
|
|
16
|
+
export function registerAbort(res: uwsHttpResponse): HttpResponse;
|
|
17
|
+
/**
|
|
18
|
+
* An extended version of uWS.App . It provides you with several features:
|
|
19
|
+
* 1) plugin registration (just like in Fastify);
|
|
20
|
+
* 2) "ready" function and _startPromises array (use it to make your code more asynchronous and safe)
|
|
21
|
+
* 3) "route" function for more descriptive adn extensible way of registering handlers
|
|
22
|
+
* 4) "onError" function (mainly used by @ublitzjs/router)
|
|
23
|
+
*/
|
|
24
|
+
export interface Server extends TemplatedApp {
|
|
25
|
+
/**
|
|
26
|
+
* It is same as plugins in Fastify -> you register some routes in remove file
|
|
27
|
+
* @param plugin
|
|
28
|
+
* @returns itself for chaining methods
|
|
29
|
+
*/
|
|
30
|
+
register(plugin: (server: this) => void): this;
|
|
31
|
+
/** set global _errHandler (in fact it is used only by @ublitzjs/router) */
|
|
32
|
+
onError(fn: (error: Error, res: HttpResponse, data: any) => any): this;
|
|
33
|
+
_errHandler?(error: Error, res: HttpResponse, data: any): any;
|
|
34
|
+
/**some undocumented property in uWS - get it here */
|
|
35
|
+
addChildAppDescriptor(...any: any[]): this;
|
|
36
|
+
/**a function, which awaits all promises inside _startPromises array and then clears it*/
|
|
37
|
+
ready: () => Promise<any[]>;
|
|
38
|
+
/**
|
|
39
|
+
* simple array of promises. You can push several inside and await all of them using server.ready() method
|
|
40
|
+
*/
|
|
41
|
+
_startPromises: Promise<any>[];
|
|
42
|
+
/**
|
|
43
|
+
* this function allows you to create new handlers but more dynamically than uWS. Best use case - development. By default, the first param you pass includes a method, path, and a controller. However you can configure it for additional properties, which can be consumed on startup by second param - plugins
|
|
44
|
+
* @example
|
|
45
|
+
* server.route<onlyHttpMethods, {deprecated:boolean}>({
|
|
46
|
+
* method:"any",
|
|
47
|
+
* path: "/",
|
|
48
|
+
* controller(res){ res.end("hello") },
|
|
49
|
+
* deprecated:true
|
|
50
|
+
* },
|
|
51
|
+
* [
|
|
52
|
+
* (opts)=>{
|
|
53
|
+
* if(opts.deprecated) console.error("DEPRECATION FOUND", opts.path)
|
|
54
|
+
* }
|
|
55
|
+
* ])
|
|
56
|
+
*/
|
|
57
|
+
route<T extends HttpMethods, obj extends object = {}>(
|
|
58
|
+
opts: routeFNOpts<T> & obj,
|
|
59
|
+
plugins?: ((param: typeof opts, server: this) => void)[]
|
|
60
|
+
): this;
|
|
61
|
+
get(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
62
|
+
post(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
63
|
+
options(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
64
|
+
del(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
65
|
+
patch(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
66
|
+
put(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
67
|
+
head(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
68
|
+
connect(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
69
|
+
trace(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
70
|
+
any(pattern: RecognizedString, handler: HttpControllerFn): this;
|
|
71
|
+
}
|
|
72
|
+
export type routeFNOpts<T extends HttpMethods> = {
|
|
73
|
+
method: T;
|
|
74
|
+
path: RecognizedString;
|
|
75
|
+
controller: T extends "ws" ? DocumentedWSBehavior<any> : HttpControllerFn;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Utility for making closures. Exists for organizing code and caching values in non-global scope.
|
|
80
|
+
* @param param
|
|
81
|
+
* @returns what you passed
|
|
82
|
+
*/
|
|
83
|
+
export var closure: <T>(param: () => T) => T;
|
|
84
|
+
/**
|
|
85
|
+
* little more typed response which has:
|
|
86
|
+
* 1) "emitter", that comes from "tseep" package
|
|
87
|
+
* 2) "aborted" flag
|
|
88
|
+
* 3) "finished" flag
|
|
89
|
+
* 4) "collect" function, which comes from original uWS (and isn't documented), but the purpose remains unknown
|
|
90
|
+
*/
|
|
91
|
+
export interface HttpResponse<UserDataForWS extends object = {}>
|
|
92
|
+
extends uwsHttpResponse {
|
|
93
|
+
upgrade<UserData = UserDataForWS>(
|
|
94
|
+
userData: UserData,
|
|
95
|
+
secWebSocketKey: RecognizedString,
|
|
96
|
+
secWebSocketProtocol: RecognizedString,
|
|
97
|
+
secWebSocketExtensions: RecognizedString,
|
|
98
|
+
context: us_socket_context_t
|
|
99
|
+
): void;
|
|
100
|
+
/**
|
|
101
|
+
* This method actually exists in original uWebSockets.js, but is undocumented. I'll put it here for your IDE to be happy
|
|
102
|
+
*/
|
|
103
|
+
collect: (...any: any[]) => any;
|
|
104
|
+
/**
|
|
105
|
+
* An event emitter, which lets you subscribe several listeners to "abort" event OR your own events, defined with Symbol().
|
|
106
|
+
*/
|
|
107
|
+
emitter: EventEmitter<{
|
|
108
|
+
abort: () => void;
|
|
109
|
+
[k: symbol]: (...any: any[]) => void;
|
|
110
|
+
}>;
|
|
111
|
+
/**
|
|
112
|
+
* changes when res.onAborted fires.
|
|
113
|
+
*/
|
|
114
|
+
aborted?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* You should set it manually when ending the response. Particularly useful if some error has fired and you are doubting whether res.aborted is a sufficient flag.
|
|
117
|
+
*/
|
|
118
|
+
finished: boolean;
|
|
119
|
+
}
|
|
120
|
+
/**This HttpRequest is same as original uWS.HttpRequest, but getHeader method is typed for additional tips
|
|
121
|
+
* @example
|
|
122
|
+
* import {lowHeaders} from "ublitzjs"
|
|
123
|
+
* // some handler later
|
|
124
|
+
* req.getHeader<lowHeaders>("content-type")
|
|
125
|
+
*/
|
|
126
|
+
export interface HttpRequest extends uwsHttpRequest {
|
|
127
|
+
getHeader<T extends RecognizedString = RecognizedString>(a: T): string;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type HttpControllerFn = (
|
|
131
|
+
res: HttpResponse,
|
|
132
|
+
req: HttpRequest
|
|
133
|
+
) => any | Promise<any>;
|
|
134
|
+
/**
|
|
135
|
+
* only http methods without "ws"
|
|
136
|
+
*/
|
|
137
|
+
export type onlyHttpMethods =
|
|
138
|
+
| "get"
|
|
139
|
+
| "post"
|
|
140
|
+
| "del"
|
|
141
|
+
| "patch"
|
|
142
|
+
| "put"
|
|
143
|
+
| "head"
|
|
144
|
+
| "trace"
|
|
145
|
+
| "options"
|
|
146
|
+
| "connect"
|
|
147
|
+
| "any";
|
|
148
|
+
/**
|
|
149
|
+
* all httpMethods with "ws" method
|
|
150
|
+
*/
|
|
151
|
+
export type HttpMethods = onlyHttpMethods | "ws"; //NOT A HTTP METHOD, but had to put it here
|
|
152
|
+
type MergeObjects<T extends any[]> = T extends [infer First, ...infer Rest]
|
|
153
|
+
? First & MergeObjects<Rest extends any[] ? Rest : []>
|
|
154
|
+
: {};
|
|
155
|
+
/**
|
|
156
|
+
* extends uWS.App() or uWS.SSLApp. See interface Server
|
|
157
|
+
* @param app uWS.App()
|
|
158
|
+
*/
|
|
159
|
+
export function extendApp<T extends object[]>(
|
|
160
|
+
app: TemplatedApp,
|
|
161
|
+
...rest: T
|
|
162
|
+
): Server & MergeObjects<T>;
|
|
163
|
+
/**
|
|
164
|
+
* conversion to ArrayBuffer ('cause transferring strings to uWS is really slow)
|
|
165
|
+
*/
|
|
166
|
+
export function toAB(data: Buffer | string): ArrayBuffer;
|
|
167
|
+
|
|
168
|
+
export * from "./http-headers";
|
|
169
|
+
export * from "./http-codes";
|
|
170
|
+
export * from "./uws-types";
|