yedra 0.14.5 → 0.15.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/dist/routing/app.d.ts +14 -5
- package/dist/routing/app.js +54 -16
- package/package.json +1 -1
package/dist/routing/app.d.ts
CHANGED
|
@@ -11,6 +11,18 @@ 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 = (req: {
|
|
20
|
+
href: string;
|
|
21
|
+
}) => ServeResponse | Promise<ServeResponse>;
|
|
22
|
+
type ServeConfig = {
|
|
23
|
+
dir: string;
|
|
24
|
+
fallback?: string | ServeFallback;
|
|
25
|
+
};
|
|
14
26
|
type ConnectMiddleware = (req: IncomingMessage, res: ServerResponse, next: () => void) => void;
|
|
15
27
|
export declare class Yedra {
|
|
16
28
|
private restRoutes;
|
|
@@ -32,7 +44,7 @@ export declare class Yedra {
|
|
|
32
44
|
url: string;
|
|
33
45
|
}[];
|
|
34
46
|
}): object;
|
|
35
|
-
private static
|
|
47
|
+
private static loadServe;
|
|
36
48
|
private performRequest;
|
|
37
49
|
private middlewareNext;
|
|
38
50
|
listen(port: number, options?: {
|
|
@@ -45,10 +57,7 @@ export declare class Yedra {
|
|
|
45
57
|
path: string;
|
|
46
58
|
get?: () => Promise<string> | string;
|
|
47
59
|
};
|
|
48
|
-
|
|
49
|
-
dir: string;
|
|
50
|
-
fallback?: string;
|
|
51
|
-
};
|
|
60
|
+
serve?: ServeConfig;
|
|
52
61
|
/**
|
|
53
62
|
* Prevents all normal output from Yedra. Mostly useful for tests.
|
|
54
63
|
*/
|
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,25 @@ export class Yedra {
|
|
|
130
149
|
},
|
|
131
150
|
};
|
|
132
151
|
}
|
|
152
|
+
if (serveData.fallback !== undefined) {
|
|
153
|
+
try {
|
|
154
|
+
const response = await serveData.fallback({ href: req.url.href });
|
|
155
|
+
return {
|
|
156
|
+
status: response.status ?? 200,
|
|
157
|
+
body: isUint8Array(response.body)
|
|
158
|
+
? response.body
|
|
159
|
+
: Buffer.from(response.body, 'utf-8'),
|
|
160
|
+
headers: response.headers,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
if (error instanceof HttpError) {
|
|
165
|
+
return Yedra.errorResponse(error.status, error.message);
|
|
166
|
+
}
|
|
167
|
+
console.error(error);
|
|
168
|
+
return Yedra.errorResponse(500, 'Internal Server Error.');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
133
171
|
}
|
|
134
172
|
if (match.invalidMethod) {
|
|
135
173
|
// we found a route, but it did not match the request method
|
|
@@ -168,7 +206,7 @@ export class Yedra {
|
|
|
168
206
|
}
|
|
169
207
|
}
|
|
170
208
|
async listen(port, options) {
|
|
171
|
-
const
|
|
209
|
+
const serveData = await Yedra.loadServe(options?.serve);
|
|
172
210
|
const server = options?.tls === undefined
|
|
173
211
|
? createHttpServer()
|
|
174
212
|
: createHttpsServer({
|
|
@@ -183,7 +221,7 @@ export class Yedra {
|
|
|
183
221
|
counter.increment();
|
|
184
222
|
const url = new URL(req.url, 'http://localhost');
|
|
185
223
|
const begin = Date.now();
|
|
186
|
-
const response = await this.performRequest(
|
|
224
|
+
const response = await this.performRequest(serveData, {
|
|
187
225
|
method: req.method ?? 'GET',
|
|
188
226
|
url,
|
|
189
227
|
body: req,
|