@derivesome/server 1.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/.package.json.~undo-tree~ +4 -0
- package/.tsconfig.json.~undo-tree~ +4 -0
- package/CLAUDE.md +51 -0
- package/dist/cjs/app.d.ts +25 -0
- package/dist/cjs/app.d.ts.map +1 -0
- package/dist/cjs/app.js +221 -0
- package/dist/cjs/app.js.map +1 -0
- package/dist/cjs/common/index.d.ts +3 -0
- package/dist/cjs/common/index.d.ts.map +1 -0
- package/dist/cjs/common/index.js +19 -0
- package/dist/cjs/common/index.js.map +1 -0
- package/dist/cjs/common/is.d.ts +2 -0
- package/dist/cjs/common/is.d.ts.map +1 -0
- package/dist/cjs/common/is.js +14 -0
- package/dist/cjs/common/is.js.map +1 -0
- package/dist/cjs/common/types.d.ts +7 -0
- package/dist/cjs/common/types.d.ts.map +1 -0
- package/dist/cjs/common/types.js +3 -0
- package/dist/cjs/common/types.js.map +1 -0
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/meta-provider.d.ts +5 -0
- package/dist/cjs/meta-provider.d.ts.map +1 -0
- package/dist/cjs/meta-provider.js +3 -0
- package/dist/cjs/meta-provider.js.map +1 -0
- package/dist/cjs/request-method.d.ts +2 -0
- package/dist/cjs/request-method.d.ts.map +1 -0
- package/dist/cjs/request-method.js +3 -0
- package/dist/cjs/request-method.js.map +1 -0
- package/dist/cjs/request-response.d.ts +13 -0
- package/dist/cjs/request-response.d.ts.map +1 -0
- package/dist/cjs/request-response.js +57 -0
- package/dist/cjs/request-response.js.map +1 -0
- package/dist/cjs/response.d.ts +40 -0
- package/dist/cjs/response.d.ts.map +1 -0
- package/dist/cjs/response.js +58 -0
- package/dist/cjs/response.js.map +1 -0
- package/dist/cjs/route-handler.d.ts +20 -0
- package/dist/cjs/route-handler.d.ts.map +1 -0
- package/dist/cjs/route-handler.js +3 -0
- package/dist/cjs/route-handler.js.map +1 -0
- package/dist/cjs/route.d.ts +17 -0
- package/dist/cjs/route.d.ts.map +1 -0
- package/dist/cjs/route.js +3 -0
- package/dist/cjs/route.js.map +1 -0
- package/dist/esm/app.d.ts +25 -0
- package/dist/esm/app.d.ts.map +1 -0
- package/dist/esm/app.js +221 -0
- package/dist/esm/app.js.map +1 -0
- package/dist/esm/common/index.d.ts +3 -0
- package/dist/esm/common/index.d.ts.map +1 -0
- package/dist/esm/common/index.js +19 -0
- package/dist/esm/common/index.js.map +1 -0
- package/dist/esm/common/is.d.ts +2 -0
- package/dist/esm/common/is.d.ts.map +1 -0
- package/dist/esm/common/is.js +14 -0
- package/dist/esm/common/is.js.map +1 -0
- package/dist/esm/common/types.d.ts +7 -0
- package/dist/esm/common/types.d.ts.map +1 -0
- package/dist/esm/common/types.js +3 -0
- package/dist/esm/common/types.js.map +1 -0
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +25 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/meta-provider.d.ts +5 -0
- package/dist/esm/meta-provider.d.ts.map +1 -0
- package/dist/esm/meta-provider.js +3 -0
- package/dist/esm/meta-provider.js.map +1 -0
- package/dist/esm/request-method.d.ts +2 -0
- package/dist/esm/request-method.d.ts.map +1 -0
- package/dist/esm/request-method.js +3 -0
- package/dist/esm/request-method.js.map +1 -0
- package/dist/esm/request-response.d.ts +13 -0
- package/dist/esm/request-response.d.ts.map +1 -0
- package/dist/esm/request-response.js +57 -0
- package/dist/esm/request-response.js.map +1 -0
- package/dist/esm/response.d.ts +40 -0
- package/dist/esm/response.d.ts.map +1 -0
- package/dist/esm/response.js +58 -0
- package/dist/esm/response.js.map +1 -0
- package/dist/esm/route-handler.d.ts +20 -0
- package/dist/esm/route-handler.d.ts.map +1 -0
- package/dist/esm/route-handler.js +3 -0
- package/dist/esm/route-handler.js.map +1 -0
- package/dist/esm/route.d.ts +17 -0
- package/dist/esm/route.d.ts.map +1 -0
- package/dist/esm/route.js +3 -0
- package/dist/esm/route.js.map +1 -0
- package/package.json +48 -0
- package/package.json~ +54 -0
- package/src/.app.ts.~undo-tree~ +55 -0
- package/src/.index.ts.~undo-tree~ +9 -0
- package/src/.meta-provider.ts.~undo-tree~ +19 -0
- package/src/.method.ts.~undo-tree~ +6 -0
- package/src/.request-method.ts.~undo-tree~ +6 -0
- package/src/.request-response.ts.~undo-tree~ +233 -0
- package/src/.request.ts.~undo-tree~ +6 -0
- package/src/.response.ts.~undo-tree~ +168 -0
- package/src/.route-handler.ts.~undo-tree~ +53 -0
- package/src/.route-params.ts.~undo-tree~ +6 -0
- package/src/.route.ts.~undo-tree~ +5 -0
- package/src/app.test.ts +245 -0
- package/src/app.ts +272 -0
- package/src/app.ts~ +277 -0
- package/src/common/.index.ts.~undo-tree~ +9 -0
- package/src/common/.is.ts.~undo-tree~ +5 -0
- package/src/common/.types.ts.~undo-tree~ +31 -0
- package/src/common/index.ts +2 -0
- package/src/common/index.ts~ +1 -0
- package/src/common/is.ts +6 -0
- package/src/common/is.ts~ +0 -0
- package/src/common/types.ts +9 -0
- package/src/common/types.ts~ +13 -0
- package/src/index.ts +8 -0
- package/src/index.ts~ +8 -0
- package/src/meta-provider.ts +10 -0
- package/src/meta-provider.ts~ +5 -0
- package/src/method.ts~ +0 -0
- package/src/request-method.ts +1 -0
- package/src/request-method.ts~ +1 -0
- package/src/request-response.ts +63 -0
- package/src/request-response.ts~ +63 -0
- package/src/request.ts~ +0 -0
- package/src/response.ts +100 -0
- package/src/response.ts~ +49 -0
- package/src/route-handler.ts +45 -0
- package/src/route-handler.ts~ +37 -0
- package/src/route-params.ts~ +0 -0
- package/src/route.ts +37 -0
- package/src/route.ts~ +37 -0
- package/tsconfig.cjs.json +10 -0
- package/tsconfig.cjs.json~ +0 -0
- package/tsconfig.esm.json +10 -0
- package/tsconfig.esm.json~ +10 -0
- package/tsconfig.json +22 -0
- package/tsconfig.json~ +22 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types';
|
package/src/common/is.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const isPlainObject = (x: any): x is Record<PropertyKey, unknown> => {
|
|
2
|
+
if (x === null || typeof x === "undefined") return false;
|
|
3
|
+
if (Array.isArray(x)) return false;
|
|
4
|
+
if (x instanceof Date) return false;
|
|
5
|
+
return Object.getPrototypeOf(x) === Object.prototype;
|
|
6
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type TupleOf<T> = [...T[], T] | [T, ...T[]] | [T];
|
|
2
|
+
|
|
3
|
+
export type Arrayish<T> = TupleOf<T> | Array<T>;
|
|
4
|
+
|
|
5
|
+
export type UnknownRecord = Record<string, unknown>;
|
|
6
|
+
export type LooseRecord = Record<string, any>;
|
|
7
|
+
|
|
8
|
+
export type UnknownArray = Array<unknown>;
|
|
9
|
+
export type LooseArray = Array<any>;
|
package/src/index.ts
ADDED
package/src/index.ts~
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { UnknownRecord } from "./common";
|
|
2
|
+
import { Request, Response } from "./request-response";
|
|
3
|
+
import { RouteHandlerContext } from "./route-handler";
|
|
4
|
+
|
|
5
|
+
export type MetaProvider<
|
|
6
|
+
NextMeta extends UnknownRecord = UnknownRecord,
|
|
7
|
+
PrevMeta extends UnknownRecord = UnknownRecord,
|
|
8
|
+
> = (
|
|
9
|
+
ctx: RouteHandlerContext<Request, Response, PrevMeta>,
|
|
10
|
+
) => NextMeta | Promise<NextMeta>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { UnknownRecord } from "./common";
|
|
2
|
+
import { Request, Response } from "./request-response";
|
|
3
|
+
import { RouteHandlerContext } from "./route-handler";
|
|
4
|
+
|
|
5
|
+
export type MetaProvider<NextMeta extends UnknownRecord = UnknownRecord, PrevMeta extends UnknownRecord = UnknownRecord> = (ctx: RouteHandlerContext<Request, Response, PrevMeta>) => ((PrevMeta & NextMeta) | Promise<PrevMeta & NextMeta>)
|
package/src/method.ts~
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type RequestMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
2
|
+
|
|
3
|
+
export class Request {
|
|
4
|
+
raw: IncomingMessage;
|
|
5
|
+
body: any = {};
|
|
6
|
+
|
|
7
|
+
constructor(raw: IncomingMessage) {
|
|
8
|
+
this.raw = raw;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get method(): string {
|
|
12
|
+
return (this.raw.method || "GET").toUpperCase();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get headers(): IncomingHttpHeaders {
|
|
16
|
+
return this.raw.headers;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private readBody(limit: number = 1_048_576 * 2): Promise<string> {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const chunks: Buffer[] = [];
|
|
22
|
+
let size = 0;
|
|
23
|
+
|
|
24
|
+
this.raw.addListener("data", (chunk) => {
|
|
25
|
+
size += chunk.length;
|
|
26
|
+
if (size > limit) {
|
|
27
|
+
this.raw.destroy();
|
|
28
|
+
reject(new Error("Body too large"));
|
|
29
|
+
} else {
|
|
30
|
+
chunks.push(chunk);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
this.raw.addListener("end", () =>
|
|
35
|
+
resolve(Buffer.concat(chunks).toString()),
|
|
36
|
+
);
|
|
37
|
+
this.raw.addListener("error", reject);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async run() {
|
|
42
|
+
switch (this.method) {
|
|
43
|
+
case "POST":
|
|
44
|
+
case "PUT":
|
|
45
|
+
case "PATCH":
|
|
46
|
+
{
|
|
47
|
+
const data = await this.readBody();
|
|
48
|
+
try {
|
|
49
|
+
this.body = JSON.parse(data);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
console.error(e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
default:
|
|
56
|
+
{
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface Response extends ServerResponse {}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
2
|
+
|
|
3
|
+
export class Request {
|
|
4
|
+
raw: IncomingMessage;
|
|
5
|
+
body: any = {};
|
|
6
|
+
|
|
7
|
+
constructor(raw: IncomingMessage) {
|
|
8
|
+
this.raw = raw;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get method(): string {
|
|
12
|
+
return (this.raw.method || "GET").toUpperCase();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get headers(): IncomingHttpHeaders {
|
|
16
|
+
return this.raw.headers;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private readBody(limit: number = 1_048_576 * 2): Promise<string> {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
const chunks: Buffer[] = [];
|
|
22
|
+
let size = 0;
|
|
23
|
+
|
|
24
|
+
this.raw.addListener("data", (chunk) => {
|
|
25
|
+
size += chunk.length;
|
|
26
|
+
if (size > limit) {
|
|
27
|
+
this.raw.destroy();
|
|
28
|
+
reject(new Error("Body too large"));
|
|
29
|
+
} else {
|
|
30
|
+
chunks.push(chunk);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
this.raw.addListener("end", () =>
|
|
35
|
+
resolve(Buffer.concat(chunks).toString()),
|
|
36
|
+
);
|
|
37
|
+
this.raw.addListener("error", reject);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async run() {
|
|
42
|
+
switch (this.method) {
|
|
43
|
+
case "POST":
|
|
44
|
+
case "PUT":
|
|
45
|
+
case "PATCH":
|
|
46
|
+
{
|
|
47
|
+
const data = await this.readBody();
|
|
48
|
+
try {
|
|
49
|
+
this.body = JSON.parse(data);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
console.error(e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
default:
|
|
56
|
+
{
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface Response extends ServerResponse {}
|
package/src/request.ts~
ADDED
|
File without changes
|
package/src/response.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { LooseArray, LooseRecord } from "./common";
|
|
2
|
+
import { Readable } from "node:stream";
|
|
3
|
+
|
|
4
|
+
export interface ResponseBase<Type extends string> {
|
|
5
|
+
statusCode: number;
|
|
6
|
+
type: Type;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ResponseJSON extends ResponseBase<"json"> {
|
|
10
|
+
contentType: "application/json";
|
|
11
|
+
payload: LooseRecord | LooseArray;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ResponseText extends ResponseBase<"text"> {
|
|
15
|
+
contentType: "text/html";
|
|
16
|
+
payload: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ResponseFile extends ResponseBase<"file"> {
|
|
20
|
+
filePath: string;
|
|
21
|
+
contentType: string | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ResponseBinary extends ResponseBase<"binary"> {
|
|
25
|
+
contentType: string;
|
|
26
|
+
payload: Buffer | Uint8Array;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface ResponseStream extends ResponseBase<"stream"> {
|
|
30
|
+
contentType: string;
|
|
31
|
+
stream: Readable;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type AnyResponse =
|
|
35
|
+
| ResponseJSON
|
|
36
|
+
| ResponseText
|
|
37
|
+
| ResponseFile
|
|
38
|
+
| ResponseBinary
|
|
39
|
+
| ResponseStream;
|
|
40
|
+
|
|
41
|
+
export class ResponseBuilder<Resp extends AnyResponse = AnyResponse> {
|
|
42
|
+
resp: Resp;
|
|
43
|
+
|
|
44
|
+
constructor(resp: Resp) {
|
|
45
|
+
this.resp = resp;
|
|
46
|
+
}
|
|
47
|
+
status(code: number): this {
|
|
48
|
+
this.resp.statusCode = code;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class ResponseMaker {
|
|
54
|
+
json(payload: LooseRecord | LooseArray): ResponseBuilder {
|
|
55
|
+
return new ResponseBuilder({
|
|
56
|
+
type: "json",
|
|
57
|
+
contentType: "application/json",
|
|
58
|
+
payload: payload,
|
|
59
|
+
statusCode: 200,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
text(payload: string): ResponseBuilder {
|
|
63
|
+
return new ResponseBuilder({
|
|
64
|
+
type: "text",
|
|
65
|
+
contentType: "text/html",
|
|
66
|
+
payload: payload,
|
|
67
|
+
statusCode: 200,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
stream(
|
|
71
|
+
stream: Readable,
|
|
72
|
+
contentType: string,
|
|
73
|
+
): ResponseBuilder<ResponseStream> {
|
|
74
|
+
return new ResponseBuilder<ResponseStream>({
|
|
75
|
+
type: "stream",
|
|
76
|
+
contentType,
|
|
77
|
+
stream,
|
|
78
|
+
statusCode: 200,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
binary(
|
|
82
|
+
payload: Buffer | Uint8Array,
|
|
83
|
+
contentType: string,
|
|
84
|
+
): ResponseBuilder<ResponseBinary> {
|
|
85
|
+
return new ResponseBuilder<ResponseBinary>({
|
|
86
|
+
type: "binary",
|
|
87
|
+
contentType,
|
|
88
|
+
payload,
|
|
89
|
+
statusCode: 200,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
file(filePath: string, contentType?: string): ResponseBuilder<ResponseFile> {
|
|
93
|
+
return new ResponseBuilder<ResponseFile>({
|
|
94
|
+
type: "file",
|
|
95
|
+
filePath,
|
|
96
|
+
contentType: contentType ?? null,
|
|
97
|
+
statusCode: 200,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
package/src/response.ts~
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { LooseArray, LooseRecord } from "./common";
|
|
2
|
+
|
|
3
|
+
export interface ResponseBase<Type extends string> {
|
|
4
|
+
statusCode: number;
|
|
5
|
+
type: Type;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ResponseJSON extends ResponseBase<"json"> {
|
|
9
|
+
contentType: "application/json";
|
|
10
|
+
payload: LooseRecord | LooseArray;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ResponseText extends ResponseBase<"text"> {
|
|
14
|
+
contentType: "text/html";
|
|
15
|
+
payload: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type AnyResponse = ResponseJSON | ResponseText;
|
|
19
|
+
|
|
20
|
+
export class ResponseBuilder<Resp extends AnyResponse = AnyResponse> {
|
|
21
|
+
resp: Resp;
|
|
22
|
+
|
|
23
|
+
constructor(resp: Resp) {
|
|
24
|
+
this.resp = resp;
|
|
25
|
+
}
|
|
26
|
+
status(code: number): this {
|
|
27
|
+
this.resp.statusCode = code;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class ResponseMaker {
|
|
33
|
+
json(payload: LooseRecord | LooseArray): ResponseBuilder {
|
|
34
|
+
return new ResponseBuilder({
|
|
35
|
+
type: "json",
|
|
36
|
+
contentType: "application/json",
|
|
37
|
+
payload: payload,
|
|
38
|
+
statusCode: 200,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
text(payload: string): ResponseBuilder {
|
|
42
|
+
return new ResponseBuilder({
|
|
43
|
+
type: "text",
|
|
44
|
+
contentType: "text/html",
|
|
45
|
+
payload: payload,
|
|
46
|
+
statusCode: 200,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { OutputOfShape, ShapeMapping } from "shapedef";
|
|
2
|
+
import { LooseArray, LooseRecord, UnknownRecord } from "./common";
|
|
3
|
+
import { Request, Response } from "./request-response";
|
|
4
|
+
import { ResponseBuilder, ResponseMaker } from "./response";
|
|
5
|
+
|
|
6
|
+
export type ExtractParams<Path extends string> =
|
|
7
|
+
Path extends `${string}:${infer Param}/${infer Rest}` ?
|
|
8
|
+
{ [K in Param]: string } & ExtractParams<Rest>
|
|
9
|
+
: Path extends `${string}:${infer Param}` ? { [K in Param]: string }
|
|
10
|
+
: {};
|
|
11
|
+
|
|
12
|
+
export type RouteHandlerContext<
|
|
13
|
+
Req extends Request = Request,
|
|
14
|
+
Res extends Response = Response,
|
|
15
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
16
|
+
Args extends ShapeMapping<any> | null = ShapeMapping<any> | null,
|
|
17
|
+
Params extends Record<string, string> = Record<string, string>,
|
|
18
|
+
> = {
|
|
19
|
+
req: Req;
|
|
20
|
+
res: Res;
|
|
21
|
+
meta: Meta;
|
|
22
|
+
args: OutputOfShape<Args>;
|
|
23
|
+
params: Params;
|
|
24
|
+
R: ResponseMaker;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type RouteHandlerReturn =
|
|
28
|
+
| void
|
|
29
|
+
| Promise<void>
|
|
30
|
+
| LooseRecord
|
|
31
|
+
| Promise<LooseRecord>
|
|
32
|
+
| LooseArray
|
|
33
|
+
| Promise<LooseArray>
|
|
34
|
+
| ResponseBuilder
|
|
35
|
+
| Promise<ResponseBuilder>;
|
|
36
|
+
|
|
37
|
+
export type RouteHandler<
|
|
38
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
39
|
+
Args extends ShapeMapping<any> | null = ShapeMapping<any> | null,
|
|
40
|
+
Params extends Record<string, string> = Record<string, string>,
|
|
41
|
+
Req extends Request = Request,
|
|
42
|
+
Res extends Response = Response,
|
|
43
|
+
Ctx extends RouteHandlerContext<Req, Res, Meta, Args, Params> =
|
|
44
|
+
RouteHandlerContext<Req, Res, Meta, Args, Params>,
|
|
45
|
+
> = (ctx: Ctx) => RouteHandlerReturn;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { OutputOfShape, ShapeMapping } from "shapedef";
|
|
2
|
+
import { LooseArray, LooseRecord, UnknownRecord } from "./common";
|
|
3
|
+
import { Request, Response } from "./request-response";
|
|
4
|
+
import { ResponseBuilder, ResponseMaker } from "./response";
|
|
5
|
+
|
|
6
|
+
export type ExtractParams<Path extends string> =
|
|
7
|
+
Path extends `${string}:${infer Param}/${infer Rest}`
|
|
8
|
+
? { [K in Param]: string } & ExtractParams<Rest>
|
|
9
|
+
: Path extends `${string}:${infer Param}`
|
|
10
|
+
? { [K in Param]: string }
|
|
11
|
+
: {};
|
|
12
|
+
|
|
13
|
+
export type RouteHandlerContext<
|
|
14
|
+
Req extends Request = Request,
|
|
15
|
+
Res extends Response = Response,
|
|
16
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
17
|
+
Args extends ShapeMapping<any> | null = ShapeMapping<any> | null,
|
|
18
|
+
Params extends Record<string, string> = Record<string, string>
|
|
19
|
+
> = {
|
|
20
|
+
req: Req;
|
|
21
|
+
res: Res;
|
|
22
|
+
meta: Meta;
|
|
23
|
+
args: OutputOfShape<Args>;
|
|
24
|
+
params: Params;
|
|
25
|
+
R: ResponseMaker;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type RouteHandlerReturn = void | Promise<void> | LooseRecord | Promise<LooseRecord> | LooseArray | Promise<LooseArray> | ResponseBuilder | Promise<ResponseBuilder>;
|
|
29
|
+
|
|
30
|
+
export type RouteHandler<
|
|
31
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
32
|
+
Args extends ShapeMapping<any> | null = ShapeMapping<any> | null,
|
|
33
|
+
Params extends Record<string, string> = Record<string, string>,
|
|
34
|
+
Req extends Request = Request,
|
|
35
|
+
Res extends Response = Response,
|
|
36
|
+
Ctx extends RouteHandlerContext<Req, Res, Meta, Args, Params> = RouteHandlerContext<Req, Res, Meta, Args, Params>,
|
|
37
|
+
> = (ctx: Ctx) => RouteHandlerReturn;
|
|
File without changes
|
package/src/route.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ShapeMapping } from "shapedef";
|
|
2
|
+
import { UnknownRecord } from "./common";
|
|
3
|
+
import { RequestMethod } from "./request-method";
|
|
4
|
+
import { ExtractParams, RouteHandler } from "./route-handler";
|
|
5
|
+
|
|
6
|
+
export type Route<
|
|
7
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
8
|
+
Args extends ShapeMapping<any> = ShapeMapping<any>,
|
|
9
|
+
Method extends RequestMethod = RequestMethod,
|
|
10
|
+
Path extends string = string,
|
|
11
|
+
Handler extends RouteHandler<Meta, Args, ExtractParams<Path>> = RouteHandler<
|
|
12
|
+
Meta,
|
|
13
|
+
Args,
|
|
14
|
+
ExtractParams<Path>
|
|
15
|
+
>,
|
|
16
|
+
> = {
|
|
17
|
+
method: Method;
|
|
18
|
+
path: Path;
|
|
19
|
+
handler: Handler;
|
|
20
|
+
args: Args | null;
|
|
21
|
+
mergeParams?: boolean | undefined | null;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type RouteWithoutArgs<
|
|
25
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
26
|
+
Method extends RequestMethod = RequestMethod,
|
|
27
|
+
Path extends string = string,
|
|
28
|
+
Handler extends RouteHandler<Meta, null, ExtractParams<Path>> = RouteHandler<
|
|
29
|
+
Meta,
|
|
30
|
+
null,
|
|
31
|
+
ExtractParams<Path>
|
|
32
|
+
>,
|
|
33
|
+
> = {
|
|
34
|
+
method: Method;
|
|
35
|
+
path: Path;
|
|
36
|
+
handler: Handler;
|
|
37
|
+
};
|
package/src/route.ts~
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ShapeMapping } from "shapedef";
|
|
2
|
+
import { UnknownRecord } from "./common";
|
|
3
|
+
import { RequestMethod } from "./request-method";
|
|
4
|
+
import { ExtractParams, RouteHandler } from "./route-handler";
|
|
5
|
+
|
|
6
|
+
export type Route<
|
|
7
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
8
|
+
Args extends ShapeMapping<any> = ShapeMapping<any>,
|
|
9
|
+
Method extends RequestMethod = RequestMethod,
|
|
10
|
+
Path extends string = string,
|
|
11
|
+
Handler extends RouteHandler<Meta, Args, ExtractParams<Path>> = RouteHandler<
|
|
12
|
+
Meta,
|
|
13
|
+
Args,
|
|
14
|
+
ExtractParams<Path>
|
|
15
|
+
>,
|
|
16
|
+
> = {
|
|
17
|
+
method: Method;
|
|
18
|
+
path: Path;
|
|
19
|
+
handler: Handler;
|
|
20
|
+
args: Args | null;
|
|
21
|
+
mergeParams?: boolean | undefined | null;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type RouteWithoutArgs<
|
|
25
|
+
Meta extends UnknownRecord = UnknownRecord,
|
|
26
|
+
Method extends RequestMethod = RequestMethod,
|
|
27
|
+
Path extends string = string,
|
|
28
|
+
Handler extends RouteHandler<Meta, null, ExtractParams<Path>> = RouteHandler<
|
|
29
|
+
Meta,
|
|
30
|
+
null,
|
|
31
|
+
ExtractParams<Path>
|
|
32
|
+
>,
|
|
33
|
+
> = {
|
|
34
|
+
method: Method;
|
|
35
|
+
path: Path;
|
|
36
|
+
handler: Handler;
|
|
37
|
+
};
|
|
File without changes
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": "./src",
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"module": "nodenext",
|
|
6
|
+
"target": "esnext",
|
|
7
|
+
"lib": ["esnext", "dom", "dom.iterable"],
|
|
8
|
+
"types": ["node"],
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"noUncheckedIndexedAccess": true,
|
|
13
|
+
"exactOptionalPropertyTypes": true,
|
|
14
|
+
"strict": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"esModuleInterop": true,
|
|
17
|
+
"noUncheckedSideEffectImports": true,
|
|
18
|
+
"moduleDetection": "force",
|
|
19
|
+
"skipLibCheck": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["./src/**/*.ts"]
|
|
22
|
+
}
|
package/tsconfig.json~
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": "./src",
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"module": "nodenext",
|
|
6
|
+
"target": "esnext",
|
|
7
|
+
"lib": ["esnext", "dom", "dom.iterable"],
|
|
8
|
+
"types": ["node"],
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"noUncheckedIndexedAccess": true,
|
|
13
|
+
"exactOptionalPropertyTypes": true,
|
|
14
|
+
"strict": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"esModuleInterop": true,
|
|
17
|
+
"noUncheckedSideEffectImports": true,
|
|
18
|
+
"moduleDetection": "force",
|
|
19
|
+
"skipLibCheck": true
|
|
20
|
+
},
|
|
21
|
+
"include": ["./src/**/*.ts"]
|
|
22
|
+
}
|