yedra 0.14.5 → 0.15.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/dist/routing/app.d.ts +12 -5
- package/dist/routing/app.js +45 -16
- package/package.json +1 -1
package/dist/routing/app.d.ts
CHANGED
|
@@ -11,6 +11,16 @@ declare class Context {
|
|
|
11
11
|
constructor(server: Server, wss: WebSocketServer, counter: Counter);
|
|
12
12
|
stop(): Promise<void>;
|
|
13
13
|
}
|
|
14
|
+
type ServeResponse = {
|
|
15
|
+
status?: number;
|
|
16
|
+
body: Uint8Array | string;
|
|
17
|
+
headers?: Record<string, string>;
|
|
18
|
+
};
|
|
19
|
+
type ServeFallback = () => ServeResponse | Promise<ServeResponse>;
|
|
20
|
+
type ServeConfig = {
|
|
21
|
+
dir: string;
|
|
22
|
+
fallback?: string | ServeFallback;
|
|
23
|
+
};
|
|
14
24
|
type ConnectMiddleware = (req: IncomingMessage, res: ServerResponse, next: () => void) => void;
|
|
15
25
|
export declare class Yedra {
|
|
16
26
|
private restRoutes;
|
|
@@ -32,7 +42,7 @@ export declare class Yedra {
|
|
|
32
42
|
url: string;
|
|
33
43
|
}[];
|
|
34
44
|
}): object;
|
|
35
|
-
private static
|
|
45
|
+
private static loadServe;
|
|
36
46
|
private performRequest;
|
|
37
47
|
private middlewareNext;
|
|
38
48
|
listen(port: number, options?: {
|
|
@@ -45,10 +55,7 @@ export declare class Yedra {
|
|
|
45
55
|
path: string;
|
|
46
56
|
get?: () => Promise<string> | string;
|
|
47
57
|
};
|
|
48
|
-
|
|
49
|
-
dir: string;
|
|
50
|
-
fallback?: string;
|
|
51
|
-
};
|
|
58
|
+
serve?: ServeConfig;
|
|
52
59
|
/**
|
|
53
60
|
* Prevents all normal output from Yedra. Mostly useful for tests.
|
|
54
61
|
*/
|
package/dist/routing/app.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createServer as createHttpServer } from 'node:http';
|
|
|
3
3
|
import { createServer as createHttpsServer } from 'node:https';
|
|
4
4
|
import { extname, join } from 'node:path';
|
|
5
5
|
import { URL } from 'node:url';
|
|
6
|
+
import { isUint8Array } from 'node:util/types';
|
|
6
7
|
import mime from 'mime';
|
|
7
8
|
import { WebSocketServer } from 'ws';
|
|
8
9
|
import { Counter } from '../util/counter.js';
|
|
@@ -82,14 +83,17 @@ export class Yedra {
|
|
|
82
83
|
paths,
|
|
83
84
|
};
|
|
84
85
|
}
|
|
85
|
-
static async
|
|
86
|
-
if (
|
|
87
|
-
return
|
|
86
|
+
static async loadServe(config) {
|
|
87
|
+
if (config === undefined) {
|
|
88
|
+
return {
|
|
89
|
+
files: new Map(),
|
|
90
|
+
fallback: undefined,
|
|
91
|
+
};
|
|
88
92
|
}
|
|
89
93
|
const staticFiles = new Map();
|
|
90
|
-
const files = await readdir(
|
|
94
|
+
const files = await readdir(config.dir, { recursive: true });
|
|
91
95
|
await Promise.all(files.map(async (file) => {
|
|
92
|
-
const absolute = join(
|
|
96
|
+
const absolute = join(config.dir, file);
|
|
93
97
|
if (!(await stat(absolute)).isFile()) {
|
|
94
98
|
return;
|
|
95
99
|
}
|
|
@@ -99,16 +103,30 @@ export class Yedra {
|
|
|
99
103
|
mime: mime.getType(extname(file)) ?? 'application/octet-stream',
|
|
100
104
|
});
|
|
101
105
|
}));
|
|
102
|
-
if (
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
if (config.fallback) {
|
|
107
|
+
if (typeof config.fallback === 'string') {
|
|
108
|
+
const data = await readFile(config.fallback);
|
|
109
|
+
staticFiles.set('__fallback', {
|
|
110
|
+
data,
|
|
111
|
+
mime: mime.getType(extname(config.fallback)) ??
|
|
112
|
+
'application/octet-stream',
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
files: staticFiles,
|
|
116
|
+
fallback: undefined,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
files: staticFiles,
|
|
121
|
+
fallback: config.fallback,
|
|
122
|
+
};
|
|
108
123
|
}
|
|
109
|
-
return
|
|
124
|
+
return {
|
|
125
|
+
files: staticFiles,
|
|
126
|
+
fallback: undefined,
|
|
127
|
+
};
|
|
110
128
|
}
|
|
111
|
-
async performRequest(
|
|
129
|
+
async performRequest(serveData, req) {
|
|
112
130
|
if (req.method !== 'GET' &&
|
|
113
131
|
req.method !== 'POST' &&
|
|
114
132
|
req.method !== 'PUT' &&
|
|
@@ -120,7 +138,8 @@ export class Yedra {
|
|
|
120
138
|
// no matching route found
|
|
121
139
|
if (req.method === 'GET') {
|
|
122
140
|
// look for a static file
|
|
123
|
-
const staticFile =
|
|
141
|
+
const staticFile = serveData.files.get(req.url.pathname) ??
|
|
142
|
+
serveData.files.get('__fallback');
|
|
124
143
|
if (staticFile !== undefined) {
|
|
125
144
|
return {
|
|
126
145
|
status: 200,
|
|
@@ -130,6 +149,16 @@ export class Yedra {
|
|
|
130
149
|
},
|
|
131
150
|
};
|
|
132
151
|
}
|
|
152
|
+
if (serveData.fallback !== undefined) {
|
|
153
|
+
const response = await serveData.fallback();
|
|
154
|
+
return {
|
|
155
|
+
status: response.status ?? 200,
|
|
156
|
+
body: isUint8Array(response.body)
|
|
157
|
+
? response.body
|
|
158
|
+
: Buffer.from(response.body, 'utf-8'),
|
|
159
|
+
headers: response.headers,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
133
162
|
}
|
|
134
163
|
if (match.invalidMethod) {
|
|
135
164
|
// we found a route, but it did not match the request method
|
|
@@ -168,7 +197,7 @@ export class Yedra {
|
|
|
168
197
|
}
|
|
169
198
|
}
|
|
170
199
|
async listen(port, options) {
|
|
171
|
-
const
|
|
200
|
+
const serveData = await Yedra.loadServe(options?.serve);
|
|
172
201
|
const server = options?.tls === undefined
|
|
173
202
|
? createHttpServer()
|
|
174
203
|
: createHttpsServer({
|
|
@@ -183,7 +212,7 @@ export class Yedra {
|
|
|
183
212
|
counter.increment();
|
|
184
213
|
const url = new URL(req.url, 'http://localhost');
|
|
185
214
|
const begin = Date.now();
|
|
186
|
-
const response = await this.performRequest(
|
|
215
|
+
const response = await this.performRequest(serveData, {
|
|
187
216
|
method: req.method ?? 'GET',
|
|
188
217
|
url,
|
|
189
218
|
body: req,
|