spooder 3.2.1 → 3.2.3
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 +1 -1
- package/src/api.ts +56 -53
- package/src/cli.ts +29 -28
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -108,6 +108,11 @@ export const ServerStop = {
|
|
|
108
108
|
|
|
109
109
|
type ServerStop = typeof ServerStop[keyof typeof ServerStop];
|
|
110
110
|
|
|
111
|
+
function print_request_info(req: Request, res: Response, url: URL): Response {
|
|
112
|
+
console.log(`[${res.status}] ${req.method} ${url.pathname}`);
|
|
113
|
+
return res;
|
|
114
|
+
}
|
|
115
|
+
|
|
111
116
|
export function serve(port: number) {
|
|
112
117
|
const routes = new Map<string[], RequestHandler>();
|
|
113
118
|
const handlers = new Map<number, StatusCodeHandler>();
|
|
@@ -146,76 +151,74 @@ export function serve(port: number) {
|
|
|
146
151
|
const url = new URL(req.url);
|
|
147
152
|
let status_code = 200;
|
|
148
153
|
|
|
149
|
-
|
|
154
|
+
try {
|
|
155
|
+
const route_array = url.pathname.split('/').filter(e => !(e === '..' || e === '.'));
|
|
156
|
+
let handler: RequestHandler | undefined;
|
|
150
157
|
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
for (const [path, route_handler] of routes) {
|
|
159
|
+
const is_trailing_wildcard = path[path.length - 1] === '*';
|
|
160
|
+
if (!is_trailing_wildcard && path.length !== route_array.length)
|
|
161
|
+
continue;
|
|
153
162
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
continue;
|
|
163
|
+
let match = true;
|
|
164
|
+
for (let i = 0; i < path.length; i++) {
|
|
165
|
+
const path_part = path[i];
|
|
158
166
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const path_part = path[i];
|
|
167
|
+
if (path_part === '*')
|
|
168
|
+
continue;
|
|
162
169
|
|
|
163
|
-
|
|
164
|
-
|
|
170
|
+
if (path_part.startsWith(':')) {
|
|
171
|
+
url.searchParams.append(path_part.slice(1), route_array[i]);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
165
174
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
175
|
+
if (path_part !== route_array[i]) {
|
|
176
|
+
match = false;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
169
179
|
}
|
|
170
180
|
|
|
171
|
-
if (
|
|
172
|
-
|
|
181
|
+
if (match) {
|
|
182
|
+
handler = route_handler;
|
|
173
183
|
break;
|
|
174
184
|
}
|
|
175
185
|
}
|
|
176
186
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
187
|
+
// Check for a handler for the route.
|
|
188
|
+
if (handler !== undefined) {
|
|
189
|
+
const response = await resolve_handler(handler(req, url), status_code, true);
|
|
190
|
+
if (response instanceof Response)
|
|
191
|
+
return print_request_info(req, response, url);
|
|
192
|
+
|
|
193
|
+
// If the handler returned a status code, use that instead.
|
|
194
|
+
status_code = response;
|
|
195
|
+
} else {
|
|
196
|
+
status_code = 404;
|
|
180
197
|
}
|
|
181
|
-
}
|
|
182
198
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
199
|
+
// Fallback to checking for a handler for the status code.
|
|
200
|
+
const status_code_handler = handlers.get(status_code);
|
|
201
|
+
if (status_code_handler !== undefined) {
|
|
202
|
+
const response = await resolve_handler(status_code_handler(req), status_code);
|
|
203
|
+
if (response instanceof Response)
|
|
204
|
+
return print_request_info(req, response, url);
|
|
205
|
+
}
|
|
188
206
|
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
207
|
+
// Fallback to the default handler, if any.
|
|
208
|
+
if (default_handler !== undefined) {
|
|
209
|
+
const response = await resolve_handler(default_handler(req, status_code), status_code);
|
|
210
|
+
if (response instanceof Response)
|
|
211
|
+
return print_request_info(req, response, url);
|
|
212
|
+
}
|
|
194
213
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return response;
|
|
201
|
-
}
|
|
214
|
+
// Fallback to returning a basic response.
|
|
215
|
+
return print_request_info(req, new Response(http.STATUS_CODES[status_code], { status: status_code }), url);
|
|
216
|
+
} catch (e) {
|
|
217
|
+
if (error_handler !== undefined)
|
|
218
|
+
return print_request_info(req, error_handler(e as Error), url);
|
|
202
219
|
|
|
203
|
-
|
|
204
|
-
if (default_handler !== undefined) {
|
|
205
|
-
const response = await resolve_handler(default_handler(req, status_code), status_code);
|
|
206
|
-
if (response instanceof Response)
|
|
207
|
-
return response;
|
|
220
|
+
return print_request_info(req, new Response(http.STATUS_CODES[500], { status: 500 }), url);
|
|
208
221
|
}
|
|
209
|
-
|
|
210
|
-
// Fallback to returning a basic response.
|
|
211
|
-
return new Response(http.STATUS_CODES[status_code], { status: status_code });
|
|
212
|
-
},
|
|
213
|
-
|
|
214
|
-
error(err: Error): Response {
|
|
215
|
-
if (error_handler !== undefined)
|
|
216
|
-
return error_handler(err);
|
|
217
|
-
|
|
218
|
-
return new Response(http.STATUS_CODES[500], { status: 500 });
|
|
219
222
|
}
|
|
220
223
|
});
|
|
221
224
|
|
package/src/cli.ts
CHANGED
|
@@ -36,38 +36,39 @@ async function start_server() {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
Bun.spawn(parse_command_line(config.run), {
|
|
39
|
+
const proc = Bun.spawn(parse_command_line(config.run), {
|
|
40
40
|
cwd: process.cwd(),
|
|
41
41
|
stdout: 'inherit',
|
|
42
|
-
stderr: 'pipe'
|
|
43
|
-
|
|
44
|
-
onExit: (proc, exitCode, signal) => {
|
|
45
|
-
log('server exited with code %d', exitCode);
|
|
46
|
-
|
|
47
|
-
if (exitCode !== null && exitCode > 0) {
|
|
48
|
-
if (proc.stderr !== undefined) {
|
|
49
|
-
const res = new Response(proc.stderr as ReadableStream);
|
|
50
|
-
|
|
51
|
-
res.text().then(async stderr => {
|
|
52
|
-
await dispatch_report('crash: server exited unexpectedly', [{
|
|
53
|
-
exitCode,
|
|
54
|
-
stderr: strip_color_codes(stderr).split(/\r?\n/)
|
|
55
|
-
}]);
|
|
56
|
-
});
|
|
57
|
-
} else {
|
|
58
|
-
dispatch_report('crash: service exited unexpectedly', [{
|
|
59
|
-
exitCode
|
|
60
|
-
}]);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
42
|
+
stderr: 'pipe'
|
|
43
|
+
});
|
|
63
44
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
45
|
+
await proc.exited;
|
|
46
|
+
|
|
47
|
+
const proc_exit_code = proc.exitCode;
|
|
48
|
+
log('server exited with code %s', proc_exit_code);
|
|
49
|
+
|
|
50
|
+
if (proc_exit_code !== 0) {
|
|
51
|
+
if (proc.stderr !== undefined) {
|
|
52
|
+
const res = new Response(proc.stderr as ReadableStream);
|
|
53
|
+
|
|
54
|
+
res.text().then(async stderr => {
|
|
55
|
+
await dispatch_report('crash: server exited unexpectedly', [{
|
|
56
|
+
proc_exit_code,
|
|
57
|
+
stderr: strip_color_codes(stderr).split(/\r?\n/)
|
|
58
|
+
}]);
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
dispatch_report('crash: service exited unexpectedly', [{
|
|
62
|
+
proc_exit_code
|
|
63
|
+
}]);
|
|
69
64
|
}
|
|
70
|
-
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const auto_restart_ms = config.autoRestart;
|
|
68
|
+
if (auto_restart_ms > -1) {
|
|
69
|
+
log('restarting server in %dms', auto_restart_ms);
|
|
70
|
+
setTimeout(start_server, auto_restart_ms);
|
|
71
|
+
}
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
await start_server();
|