@anansi/core 0.21.0 → 0.21.2
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/CHANGELOG.md +12 -0
- package/dist/server.js +91 -5
- package/lib/laySpouts.d.ts.map +1 -1
- package/lib/laySpouts.js +9 -5
- package/lib/scripts/laySpouts.js +9 -5
- package/lib/scripts/scripts/serve.js +17 -7
- package/lib/scripts/scripts/ssrErrorHandler.js +82 -0
- package/lib/scripts/scripts/startDevserver.js +18 -4
- package/lib/scripts/serve.d.ts.map +1 -1
- package/lib/scripts/serve.js +17 -7
- package/lib/scripts/ssrErrorHandler.d.ts +26 -0
- package/lib/scripts/ssrErrorHandler.d.ts.map +1 -0
- package/lib/scripts/ssrErrorHandler.js +82 -0
- package/lib/scripts/startDevserver.d.ts.map +1 -1
- package/lib/scripts/startDevserver.js +18 -4
- package/package.json +3 -3
- package/src/laySpouts.tsx +9 -5
- package/src/scripts/__tests__/ssrErrorHandler.test.ts +249 -0
- package/src/scripts/serve.ts +18 -6
- package/src/scripts/ssrErrorHandler.ts +98 -0
- package/src/scripts/startDevserver.ts +19 -3
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for handling SSR errors gracefully
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Extract HTTP status code from an error object.
|
|
7
|
+
* Looks for a `status` property that is a number or parseable string.
|
|
8
|
+
* Returns 500 if no valid status found.
|
|
9
|
+
*/
|
|
10
|
+
export function getErrorStatus(error) {
|
|
11
|
+
if (error && typeof error === 'object' && 'status' in error) {
|
|
12
|
+
const status = error.status;
|
|
13
|
+
if (typeof status === 'number' && status >= 100 && status < 600) {
|
|
14
|
+
return status;
|
|
15
|
+
}
|
|
16
|
+
if (typeof status === 'string') {
|
|
17
|
+
const parsed = parseInt(status, 10);
|
|
18
|
+
if (!isNaN(parsed) && parsed >= 100 && parsed < 600) {
|
|
19
|
+
return parsed;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return 500;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Escape HTML special characters to prevent XSS
|
|
28
|
+
*/
|
|
29
|
+
export function escapeHtml(str) {
|
|
30
|
+
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Render an HTML error page for SSR failures
|
|
34
|
+
*/
|
|
35
|
+
export function renderErrorPage(error, url, statusCode, options = {}) {
|
|
36
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
37
|
+
const stack = error instanceof Error ? error.stack : undefined;
|
|
38
|
+
const {
|
|
39
|
+
showStack = false,
|
|
40
|
+
hint,
|
|
41
|
+
badge
|
|
42
|
+
} = options;
|
|
43
|
+
return `<!DOCTYPE html>
|
|
44
|
+
<html lang="en">
|
|
45
|
+
<head>
|
|
46
|
+
<meta charset="UTF-8">
|
|
47
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
48
|
+
<title>${statusCode} - Server Error</title>
|
|
49
|
+
<style>
|
|
50
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
51
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #1a1a2e; color: #eee; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 2rem; }
|
|
52
|
+
.container { max-width: 800px; width: 100%; }
|
|
53
|
+
h1 { color: #ff6b6b; font-size: 2.5rem; margin-bottom: 1rem; }
|
|
54
|
+
.badge { display: inline-block; background: #4ecdc4; color: #1a1a2e; padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.75rem; font-weight: 600; margin-bottom: 1rem; }
|
|
55
|
+
.url { color: #888; font-size: 0.9rem; margin-bottom: 1.5rem; word-break: break-all; }
|
|
56
|
+
.message { background: #16213e; border-left: 4px solid #ff6b6b; padding: 1rem 1.5rem; border-radius: 0 8px 8px 0; margin-bottom: 1.5rem; }
|
|
57
|
+
.message code { color: #ff6b6b; font-size: 1.1rem; }
|
|
58
|
+
.stack { background: #0f0f23; border-radius: 8px; padding: 1.5rem; overflow-x: auto; font-family: 'Monaco', 'Menlo', monospace; font-size: 0.85rem; line-height: 1.6; color: #aaa; white-space: pre-wrap; word-break: break-word; }
|
|
59
|
+
.retry { margin-top: 2rem; }
|
|
60
|
+
.retry a { color: #4ecdc4; text-decoration: none; padding: 0.75rem 1.5rem; border: 2px solid #4ecdc4; border-radius: 6px; display: inline-block; transition: all 0.2s; }
|
|
61
|
+
.retry a:hover { background: #4ecdc4; color: #1a1a2e; }
|
|
62
|
+
.hint { margin-top: 1.5rem; color: #888; font-size: 0.9rem; }
|
|
63
|
+
</style>
|
|
64
|
+
</head>
|
|
65
|
+
<body>
|
|
66
|
+
<div class="container">
|
|
67
|
+
${badge ? `<span class="badge">${escapeHtml(badge)}</span>` : ''}
|
|
68
|
+
<h1>${statusCode} - Server Error</h1>
|
|
69
|
+
<p class="url">Error rendering: ${escapeHtml(url)}</p>
|
|
70
|
+
<div class="message">
|
|
71
|
+
<code>${escapeHtml(errorMessage)}</code>
|
|
72
|
+
</div>
|
|
73
|
+
${showStack && stack ? `<pre class="stack">${escapeHtml(stack)}</pre>` : ''}
|
|
74
|
+
<div class="retry">
|
|
75
|
+
<a href="${escapeHtml(url)}">Retry</a>
|
|
76
|
+
</div>
|
|
77
|
+
${hint ? `<p class="hint">${escapeHtml(hint)}</p>` : ''}
|
|
78
|
+
</div>
|
|
79
|
+
</body>
|
|
80
|
+
</html>`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJnZXRFcnJvclN0YXR1cyIsImVycm9yIiwic3RhdHVzIiwicGFyc2VkIiwicGFyc2VJbnQiLCJpc05hTiIsImVzY2FwZUh0bWwiLCJzdHIiLCJyZXBsYWNlIiwicmVuZGVyRXJyb3JQYWdlIiwidXJsIiwic3RhdHVzQ29kZSIsIm9wdGlvbnMiLCJlcnJvck1lc3NhZ2UiLCJFcnJvciIsIm1lc3NhZ2UiLCJTdHJpbmciLCJzdGFjayIsInVuZGVmaW5lZCIsInNob3dTdGFjayIsImhpbnQiLCJiYWRnZSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY3JpcHRzL3NzckVycm9ySGFuZGxlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFV0aWxpdGllcyBmb3IgaGFuZGxpbmcgU1NSIGVycm9ycyBncmFjZWZ1bGx5XG4gKi9cblxuLyoqXG4gKiBFeHRyYWN0IEhUVFAgc3RhdHVzIGNvZGUgZnJvbSBhbiBlcnJvciBvYmplY3QuXG4gKiBMb29rcyBmb3IgYSBgc3RhdHVzYCBwcm9wZXJ0eSB0aGF0IGlzIGEgbnVtYmVyIG9yIHBhcnNlYWJsZSBzdHJpbmcuXG4gKiBSZXR1cm5zIDUwMCBpZiBubyB2YWxpZCBzdGF0dXMgZm91bmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRFcnJvclN0YXR1cyhlcnJvcjogdW5rbm93bik6IG51bWJlciB7XG4gIGlmIChlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnICYmICdzdGF0dXMnIGluIGVycm9yKSB7XG4gICAgY29uc3Qgc3RhdHVzID0gKGVycm9yIGFzIHsgc3RhdHVzOiB1bmtub3duIH0pLnN0YXR1cztcbiAgICBpZiAodHlwZW9mIHN0YXR1cyA9PT0gJ251bWJlcicgJiYgc3RhdHVzID49IDEwMCAmJiBzdGF0dXMgPCA2MDApIHtcbiAgICAgIHJldHVybiBzdGF0dXM7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygc3RhdHVzID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgcGFyc2VkID0gcGFyc2VJbnQoc3RhdHVzLCAxMCk7XG4gICAgICBpZiAoIWlzTmFOKHBhcnNlZCkgJiYgcGFyc2VkID49IDEwMCAmJiBwYXJzZWQgPCA2MDApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIDUwMDtcbn1cblxuLyoqXG4gKiBFc2NhcGUgSFRNTCBzcGVjaWFsIGNoYXJhY3RlcnMgdG8gcHJldmVudCBYU1NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUh0bWwoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyXG4gICAgLnJlcGxhY2UoLyYvZywgJyZhbXA7JylcbiAgICAucmVwbGFjZSgvPC9nLCAnJmx0OycpXG4gICAgLnJlcGxhY2UoLz4vZywgJyZndDsnKVxuICAgIC5yZXBsYWNlKC9cIi9nLCAnJnF1b3Q7JylcbiAgICAucmVwbGFjZSgvJy9nLCAnJiMwMzk7Jyk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVuZGVyRXJyb3JQYWdlT3B0aW9ucyB7XG4gIC8qKiBTaG93IHN0YWNrIHRyYWNlIGluIG91dHB1dCAqL1xuICBzaG93U3RhY2s/OiBib29sZWFuO1xuICAvKiogQWRkaXRpb25hbCBoaW50IG1lc3NhZ2UgdG8gZGlzcGxheSAqL1xuICBoaW50Pzogc3RyaW5nO1xuICAvKiogQmFkZ2UgdGV4dCB0byBkaXNwbGF5IChlLmcuLCBcIkRFViBNT0RFXCIpICovXG4gIGJhZGdlPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlbmRlciBhbiBIVE1MIGVycm9yIHBhZ2UgZm9yIFNTUiBmYWlsdXJlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyRXJyb3JQYWdlKFxuICBlcnJvcjogdW5rbm93bixcbiAgdXJsOiBzdHJpbmcsXG4gIHN0YXR1c0NvZGU6IG51bWJlcixcbiAgb3B0aW9uczogUmVuZGVyRXJyb3JQYWdlT3B0aW9ucyA9IHt9LFxuKTogc3RyaW5nIHtcbiAgY29uc3QgZXJyb3JNZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICBjb25zdCBzdGFjayA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5zdGFjayA6IHVuZGVmaW5lZDtcbiAgY29uc3QgeyBzaG93U3RhY2sgPSBmYWxzZSwgaGludCwgYmFkZ2UgfSA9IG9wdGlvbnM7XG5cbiAgcmV0dXJuIGA8IURPQ1RZUEUgaHRtbD5cbjxodG1sIGxhbmc9XCJlblwiPlxuPGhlYWQ+XG4gIDxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPlxuICA8bWV0YSBuYW1lPVwidmlld3BvcnRcIiBjb250ZW50PVwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMFwiPlxuICA8dGl0bGU+JHtzdGF0dXNDb2RlfSAtIFNlcnZlciBFcnJvcjwvdGl0bGU+XG4gIDxzdHlsZT5cbiAgICAqIHsgYm94LXNpemluZzogYm9yZGVyLWJveDsgbWFyZ2luOiAwOyBwYWRkaW5nOiAwOyB9XG4gICAgYm9keSB7IGZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIFJvYm90bywgc2Fucy1zZXJpZjsgYmFja2dyb3VuZDogIzFhMWEyZTsgY29sb3I6ICNlZWU7IG1pbi1oZWlnaHQ6IDEwMHZoOyBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjsgcGFkZGluZzogMnJlbTsgfVxuICAgIC5jb250YWluZXIgeyBtYXgtd2lkdGg6IDgwMHB4OyB3aWR0aDogMTAwJTsgfVxuICAgIGgxIHsgY29sb3I6ICNmZjZiNmI7IGZvbnQtc2l6ZTogMi41cmVtOyBtYXJnaW4tYm90dG9tOiAxcmVtOyB9XG4gICAgLmJhZGdlIHsgZGlzcGxheTogaW5saW5lLWJsb2NrOyBiYWNrZ3JvdW5kOiAjNGVjZGM0OyBjb2xvcjogIzFhMWEyZTsgcGFkZGluZzogMC4yNXJlbSAwLjVyZW07IGJvcmRlci1yYWRpdXM6IDRweDsgZm9udC1zaXplOiAwLjc1cmVtOyBmb250LXdlaWdodDogNjAwOyBtYXJnaW4tYm90dG9tOiAxcmVtOyB9XG4gICAgLnVybCB7IGNvbG9yOiAjODg4OyBmb250LXNpemU6IDAuOXJlbTsgbWFyZ2luLWJvdHRvbTogMS41cmVtOyB3b3JkLWJyZWFrOiBicmVhay1hbGw7IH1cbiAgICAubWVzc2FnZSB7IGJhY2tncm91bmQ6ICMxNjIxM2U7IGJvcmRlci1sZWZ0OiA0cHggc29saWQgI2ZmNmI2YjsgcGFkZGluZzogMXJlbSAxLjVyZW07IGJvcmRlci1yYWRpdXM6IDAgOHB4IDhweCAwOyBtYXJnaW4tYm90dG9tOiAxLjVyZW07IH1cbiAgICAubWVzc2FnZSBjb2RlIHsgY29sb3I6ICNmZjZiNmI7IGZvbnQtc2l6ZTogMS4xcmVtOyB9XG4gICAgLnN0YWNrIHsgYmFja2dyb3VuZDogIzBmMGYyMzsgYm9yZGVyLXJhZGl1czogOHB4OyBwYWRkaW5nOiAxLjVyZW07IG92ZXJmbG93LXg6IGF1dG87IGZvbnQtZmFtaWx5OiAnTW9uYWNvJywgJ01lbmxvJywgbW9ub3NwYWNlOyBmb250LXNpemU6IDAuODVyZW07IGxpbmUtaGVpZ2h0OiAxLjY7IGNvbG9yOiAjYWFhOyB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7IHdvcmQtYnJlYWs6IGJyZWFrLXdvcmQ7IH1cbiAgICAucmV0cnkgeyBtYXJnaW4tdG9wOiAycmVtOyB9XG4gICAgLnJldHJ5IGEgeyBjb2xvcjogIzRlY2RjNDsgdGV4dC1kZWNvcmF0aW9uOiBub25lOyBwYWRkaW5nOiAwLjc1cmVtIDEuNXJlbTsgYm9yZGVyOiAycHggc29saWQgIzRlY2RjNDsgYm9yZGVyLXJhZGl1czogNnB4OyBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IHRyYW5zaXRpb246IGFsbCAwLjJzOyB9XG4gICAgLnJldHJ5IGE6aG92ZXIgeyBiYWNrZ3JvdW5kOiAjNGVjZGM0OyBjb2xvcjogIzFhMWEyZTsgfVxuICAgIC5oaW50IHsgbWFyZ2luLXRvcDogMS41cmVtOyBjb2xvcjogIzg4ODsgZm9udC1zaXplOiAwLjlyZW07IH1cbiAgPC9zdHlsZT5cbjwvaGVhZD5cbjxib2R5PlxuICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyXCI+XG4gICAgJHtiYWRnZSA/IGA8c3BhbiBjbGFzcz1cImJhZGdlXCI+JHtlc2NhcGVIdG1sKGJhZGdlKX08L3NwYW4+YCA6ICcnfVxuICAgIDxoMT4ke3N0YXR1c0NvZGV9IC0gU2VydmVyIEVycm9yPC9oMT5cbiAgICA8cCBjbGFzcz1cInVybFwiPkVycm9yIHJlbmRlcmluZzogJHtlc2NhcGVIdG1sKHVybCl9PC9wPlxuICAgIDxkaXYgY2xhc3M9XCJtZXNzYWdlXCI+XG4gICAgICA8Y29kZT4ke2VzY2FwZUh0bWwoZXJyb3JNZXNzYWdlKX08L2NvZGU+XG4gICAgPC9kaXY+XG4gICAgJHtzaG93U3RhY2sgJiYgc3RhY2sgPyBgPHByZSBjbGFzcz1cInN0YWNrXCI+JHtlc2NhcGVIdG1sKHN0YWNrKX08L3ByZT5gIDogJyd9XG4gICAgPGRpdiBjbGFzcz1cInJldHJ5XCI+XG4gICAgICA8YSBocmVmPVwiJHtlc2NhcGVIdG1sKHVybCl9XCI+UmV0cnk8L2E+XG4gICAgPC9kaXY+XG4gICAgJHtoaW50ID8gYDxwIGNsYXNzPVwiaGludFwiPiR7ZXNjYXBlSHRtbChoaW50KX08L3A+YCA6ICcnfVxuICA8L2Rpdj5cbjwvYm9keT5cbjwvaHRtbD5gO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU8sU0FBU0EsY0FBY0EsQ0FBQ0MsS0FBYyxFQUFVO0VBQ3JELElBQUlBLEtBQUssSUFBSSxPQUFPQSxLQUFLLEtBQUssUUFBUSxJQUFJLFFBQVEsSUFBSUEsS0FBSyxFQUFFO0lBQzNELE1BQU1DLE1BQU0sR0FBSUQsS0FBSyxDQUF5QkMsTUFBTTtJQUNwRCxJQUFJLE9BQU9BLE1BQU0sS0FBSyxRQUFRLElBQUlBLE1BQU0sSUFBSSxHQUFHLElBQUlBLE1BQU0sR0FBRyxHQUFHLEVBQUU7TUFDL0QsT0FBT0EsTUFBTTtJQUNmO0lBQ0EsSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO01BQzlCLE1BQU1DLE1BQU0sR0FBR0MsUUFBUSxDQUFDRixNQUFNLEVBQUUsRUFBRSxDQUFDO01BQ25DLElBQUksQ0FBQ0csS0FBSyxDQUFDRixNQUFNLENBQUMsSUFBSUEsTUFBTSxJQUFJLEdBQUcsSUFBSUEsTUFBTSxHQUFHLEdBQUcsRUFBRTtRQUNuRCxPQUFPQSxNQUFNO01BQ2Y7SUFDRjtFQUNGO0VBQ0EsT0FBTyxHQUFHO0FBQ1o7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTyxTQUFTRyxVQUFVQSxDQUFDQyxHQUFXLEVBQVU7RUFDOUMsT0FBT0EsR0FBRyxDQUNQQyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUN0QkEsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FDckJBLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQ3JCQSxPQUFPLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUN2QkEsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7QUFDNUI7QUFXQTtBQUNBO0FBQ0E7QUFDQSxPQUFPLFNBQVNDLGVBQWVBLENBQzdCUixLQUFjLEVBQ2RTLEdBQVcsRUFDWEMsVUFBa0IsRUFDbEJDLE9BQStCLEdBQUcsQ0FBQyxDQUFDLEVBQzVCO0VBQ1IsTUFBTUMsWUFBWSxHQUFHWixLQUFLLFlBQVlhLEtBQUssR0FBR2IsS0FBSyxDQUFDYyxPQUFPLEdBQUdDLE1BQU0sQ0FBQ2YsS0FBSyxDQUFDO0VBQzNFLE1BQU1nQixLQUFLLEdBQUdoQixLQUFLLFlBQVlhLEtBQUssR0FBR2IsS0FBSyxDQUFDZ0IsS0FBSyxHQUFHQyxTQUFTO0VBQzlELE1BQU07SUFBRUMsU0FBUyxHQUFHLEtBQUs7SUFBRUMsSUFBSTtJQUFFQztFQUFNLENBQUMsR0FBR1QsT0FBTztFQUVsRCxPQUFPO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXRCxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1VLEtBQUssR0FBRyx1QkFBdUJmLFVBQVUsQ0FBQ2UsS0FBSyxDQUFDLFNBQVMsR0FBRyxFQUFFO0FBQ3BFLFVBQVVWLFVBQVU7QUFDcEIsc0NBQXNDTCxVQUFVLENBQUNJLEdBQUcsQ0FBQztBQUNyRDtBQUNBLGNBQWNKLFVBQVUsQ0FBQ08sWUFBWSxDQUFDO0FBQ3RDO0FBQ0EsTUFBTU0sU0FBUyxJQUFJRixLQUFLLEdBQUcsc0JBQXNCWCxVQUFVLENBQUNXLEtBQUssQ0FBQyxRQUFRLEdBQUcsRUFBRTtBQUMvRTtBQUNBLGlCQUFpQlgsVUFBVSxDQUFDSSxHQUFHLENBQUM7QUFDaEM7QUFDQSxNQUFNVSxJQUFJLEdBQUcsbUJBQW1CZCxVQUFVLENBQUNjLElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRTtBQUMzRDtBQUNBO0FBQ0EsUUFBUTtBQUNSIiwiaWdub3JlTGlzdCI6W119
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startDevserver.d.ts","sourceRoot":"","sources":["../../src/scripts/startDevserver.ts"],"names":[],"mappings":";AAmBA,OAAO,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"startDevserver.d.ts","sourceRoot":"","sources":["../../src/scripts/startDevserver.ts"],"names":[],"mappings":";AAmBA,OAAO,mCAAmC,CAAC;AAuB3C,wBAA8B,cAAc,CAC1C,UAAU,EAAE,MAAM,EAClB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,iBA4QlC"}
|
|
@@ -15,6 +15,7 @@ import WebpackDevServer from 'webpack-dev-server';
|
|
|
15
15
|
import 'cross-fetch/dist/node-polyfill.js';
|
|
16
16
|
import { createHybridRequire } from './createHybridRequire.js';
|
|
17
17
|
import { getWebpackConfig } from './getWebpackConfig.js';
|
|
18
|
+
import { getErrorStatus, renderErrorPage } from './ssrErrorHandler.js';
|
|
18
19
|
// run directly from node
|
|
19
20
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
20
21
|
// @ts-ignore
|
|
@@ -88,11 +89,24 @@ export default async function startDevServer(entrypoint, env = {}) {
|
|
|
88
89
|
return path.join(serverJson.outputPath ?? '', 'server.js');
|
|
89
90
|
}
|
|
90
91
|
function handleErrors(fn) {
|
|
91
|
-
return async function (req, res,
|
|
92
|
+
return async function (req, res, _next) {
|
|
92
93
|
try {
|
|
93
94
|
return await fn(req, res);
|
|
94
|
-
} catch (
|
|
95
|
-
|
|
95
|
+
} catch (error) {
|
|
96
|
+
log.error('SSR rendering error:', error);
|
|
97
|
+
|
|
98
|
+
// Return error response with status from error if available
|
|
99
|
+
const expressRes = res;
|
|
100
|
+
if (!expressRes.headersSent) {
|
|
101
|
+
const statusCode = getErrorStatus(error);
|
|
102
|
+
expressRes.status(statusCode);
|
|
103
|
+
expressRes.setHeader('Content-Type', 'text/html');
|
|
104
|
+
expressRes.send(renderErrorPage(error, req.url ?? '/', statusCode, {
|
|
105
|
+
showStack: true,
|
|
106
|
+
badge: 'DEV MODE',
|
|
107
|
+
hint: 'The dev server is still running. Fix the error and retry, or check the console for more details.'
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
96
110
|
}
|
|
97
111
|
};
|
|
98
112
|
}
|
|
@@ -229,4 +243,4 @@ export default async function startDevServer(entrypoint, env = {}) {
|
|
|
229
243
|
});
|
|
230
244
|
runServer();
|
|
231
245
|
}
|
|
232
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJPYmplY3QiLCJoYXNPd24iLCJpdCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImRpc2tGcyIsImNyZWF0ZUZzRnJvbVZvbHVtZSIsIlZvbHVtZSIsInBhdGgiLCJzb3VyY2VNYXBTdXBwb3J0IiwidG1wIiwidWZzIiwicHJvbWlzaWZ5Iiwid2VicGFjayIsImxvZ2dpbmciLCJXZWJwYWNrRGV2U2VydmVyIiwiY3JlYXRlSHlicmlkUmVxdWlyZSIsImdldFdlYnBhY2tDb25maWciLCJpbXBvcnQiLCJtZXRhIiwibWFpbiIsImVudHJ5cG9pbnQiLCJwcm9jZXNzIiwiYXJndiIsImNvbnNvbGUiLCJsb2ciLCJleGl0Iiwic3RhcnREZXZTZXJ2ZXIiLCJzZXJ2ZXJGaWxlQ29udGVudHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInNlcnZlckVudHJ5IiwiZW52Iiwid2VicGFja0NvbmZpZyIsImdldExvZ2dlciIsInZvbHVtZSIsImZzIiwidXNlIiwiZnNSZXF1aXJlIiwicmVhZEZpbGUiLCJob3RFbnRyeSIsImVudHJ5UGF0aCIsImdlbmVyYXRlZEVudHJ5cG9pbnQiLCJmaWxlU3luYyIsInBvc3RmaXgiLCJ3cml0ZVN5bmMiLCJmZCIsImN3ZCIsIndlYnBhY2tDb25maWdzIiwiZW50cnlwYXRoIiwibmFtZSIsIm1vZGUiLCJyZXBsYWNlIiwiQlJPV1NFUlNMSVNUX0VOViIsInRhcmdldCIsImNvbXBpbGVyIiwiZXJyb3IiLCJpbnN0YWxsIiwiaG9va1JlcXVpcmUiLCJnZXRTZXJ2ZXJCdW5kbGUiLCJzZXJ2ZXJTdGF0cyIsInNlcnZlckpzb24iLCJ0b0pzb24iLCJhc3NldHMiLCJqb2luIiwib3V0cHV0UGF0aCIsImhhbmRsZUVycm9ycyIsImZuIiwicmVxIiwicmVzIiwibmV4dCIsIngiLCJpbml0UmVuZGVyIiwicmVuZGVyIiwiYXJncyIsInB1c2giLCJpbXBvcnRSZW5kZXIiLCJzdGF0cyIsImNsaWVudFN0YXRzIiwiY29tcGlsYXRpb24iLCJlcnJvcnMiLCJsZW5ndGgiLCJBcnJheSIsImlzQXJyYXkiLCJpbmZvIiwiY2xpZW50TWFuaWZlc3QiLCJ0aGVuIiwiYnVmIiwidG9TdHJpbmciLCJrZXlzIiwiY2FjaGUiLCJmb3JFYWNoIiwiZGVmYXVsdCIsImJpbmQiLCJ1bmRlZmluZWQiLCJpbml0IiwiZSIsImRldlNlcnZlciIsImRldk1pZGRsZXdhcmUiLCJvdXRwdXRGaWxlU3lzdGVtIiwic2V0dXBNaWRkbGV3YXJlcyIsIm1pZGRsZXdhcmVzIiwiRXJyb3IiLCJvdGhlclJvdXRlcyIsIldFQlBBQ0tfUFVCTElDX1BBVEgiLCJwcm94eSIsImZpbHRlciIsImZsYXRNYXAiLCJjb250ZXh0IiwiYXBwIiwiZ2V0IiwiUmVnRXhwIiwidXJsIiwiZW5kc1dpdGgiLCJzdGF0dXNDb2RlIiwic2V0SGVhZGVyIiwic2VuZCIsInNvY2tldCIsIm9uIiwiY29kZSIsInJ1blNlcnZlciIsInN0YXJ0IiwiaG9va3MiLCJkb25lIiwidGFwIiwibXVsdGlTdGF0cyIsImZpbmRlciIsImZpbGVUZXh0IiwidGV4dFJvd3MiLCJzcGxpdCIsIm1hdGNoIiwic3RhY2siLCJtYXRjaEFsbCIsInJvdyIsIk51bWJlciIsInBhcnNlSW50IiwiY29sIiwiYmFzZW5hbWUiLCJ3cml0ZUZpbGVTeW5jIiwic3RvcFNlcnZlciIsInN0b3AiLCJ3YXJuIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjcmlwdHMvc3RhcnREZXZzZXJ2ZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuT2JqZWN0Lmhhc093biA9XG4gIE9iamVjdC5oYXNPd24gfHxcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi8gZnVuY3Rpb24gaGFzT3duKGl0LCBrZXkpIHtcbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGl0LCBrZXkpO1xuICB9O1xuaW1wb3J0IHR5cGUgeyBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCBkaXNrRnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ2h0dHAnO1xuaW1wb3J0IHsgY3JlYXRlRnNGcm9tVm9sdW1lLCBWb2x1bWUgfSBmcm9tICdtZW1mcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBzb3VyY2VNYXBTdXBwb3J0IGZyb20gJ3NvdXJjZS1tYXAtc3VwcG9ydCc7XG5pbXBvcnQgdG1wIGZyb20gJ3RtcCc7XG5pbXBvcnQgeyB1ZnMgfSBmcm9tICd1bmlvbmZzJztcbmltcG9ydCB7IHByb21pc2lmeSB9IGZyb20gJ3V0aWwnO1xuaW1wb3J0IHdlYnBhY2ssIHsgdHlwZSBDb25maWd1cmF0aW9uLCB0eXBlIE11bHRpQ29uZmlndXJhdGlvbiB9IGZyb20gJ3dlYnBhY2snO1xuaW1wb3J0IGxvZ2dpbmcgZnJvbSAnd2VicGFjay9saWIvbG9nZ2luZy9ydW50aW1lLmpzJztcbmltcG9ydCBXZWJwYWNrRGV2U2VydmVyIGZyb20gJ3dlYnBhY2stZGV2LXNlcnZlcic7XG5cbmltcG9ydCAnY3Jvc3MtZmV0Y2gvZGlzdC9ub2RlLXBvbHlmaWxsLmpzJztcbmltcG9ydCB7IGNyZWF0ZUh5YnJpZFJlcXVpcmUgfSBmcm9tICcuL2NyZWF0ZUh5YnJpZFJlcXVpcmUuanMnO1xuaW1wb3J0IHsgZ2V0V2VicGFja0NvbmZpZyB9IGZyb20gJy4vZ2V0V2VicGFja0NvbmZpZy5qcyc7XG5pbXBvcnQgeyBCb3VuZFJlbmRlciB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vLyBydW4gZGlyZWN0bHkgZnJvbSBub2RlXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4vLyBAdHMtaWdub3JlXG5pZiAoaW1wb3J0Lm1ldGEubWFpbikge1xuICBjb25zdCBlbnRyeXBvaW50ID0gcHJvY2Vzcy5hcmd2WzJdO1xuXG4gIGlmICghZW50cnlwb2ludCkge1xuICAgIGNvbnNvbGUubG9nKGBVc2FnZTogc3RhcnQtYW5hbnNpIDxlbnRyeXBvaW50LWZpbGU+YCk7XG4gICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgfVxuXG4gIHN0YXJ0RGV2U2VydmVyKGVudHJ5cG9pbnQpO1xufVxuXG5sZXQgc2VydmVyRmlsZUNvbnRlbnRzOiBQcm9taXNlPHN0cmluZz4gPSBQcm9taXNlLnJlc29sdmUoJycpO1xubGV0IHNlcnZlckVudHJ5ID0gJyc7XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0RGV2U2VydmVyKFxuICBlbnRyeXBvaW50OiBzdHJpbmcsXG4gIGVudjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbikge1xuICBjb25zdCB3ZWJwYWNrQ29uZmlnID0gYXdhaXQgZ2V0V2VicGFja0NvbmZpZygpO1xuXG4gIGNvbnN0IGxvZyA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKCdhbmFuc2ktZGV2c2VydmVyJyk7XG5cbiAgLy8gU2V0IHVwIGluIG1lbW9yeSBmaWxlc3lzdGVtXG4gIGNvbnN0IHZvbHVtZSA9IG5ldyBWb2x1bWUoKTtcbiAgY29uc3QgZnMgPSBjcmVhdGVGc0Zyb21Wb2x1bWUodm9sdW1lKTtcbiAgdWZzLnVzZShkaXNrRnMpLnVzZShmcyBhcyBhbnkpO1xuXG4gIGNvbnN0IGZzUmVxdWlyZSA9IGNyZWF0ZUh5YnJpZFJlcXVpcmUodWZzKTtcblxuICBjb25zdCByZWFkRmlsZSA9IHByb21pc2lmeSh1ZnMucmVhZEZpbGUpO1xuICAvLyBHZW5lcmF0ZSBhIHRlbXBvcmFyeSBmaWxlIHNvIHdlIGNhbiBob3QgcmVsb2FkIGZyb20gdGhlIHJvb3Qgb2YgdGhlIGFwcGxpY2F0aW9uXG4gIGZ1bmN0aW9uIGhvdEVudHJ5KGVudHJ5UGF0aDogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgLy8gQHRzLWlnbm9yZSBmb3Igc29tZSByZWFzb24gaXQncyBub3QgcGlja2luZyB1cCB0aGF0IG90aGVyIG9wdGlvbnMgYXJlIG9wdGlvbmFsXG4gICAgY29uc3QgZ2VuZXJhdGVkRW50cnlwb2ludCA9IHRtcC5maWxlU3luYyh7IHBvc3RmaXg6ICcuanMnIH0pO1xuICAgIGRpc2tGcy53cml0ZVN5bmMoXG4gICAgICBnZW5lcmF0ZWRFbnRyeXBvaW50LmZkLFxuICAgICAgYFxuICBpbXBvcnQgZW50cnkgZnJvbSBcIiR7cGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGVudHJ5UGF0aCl9XCI7XG5cbiAgaWYgKGltcG9ydC5tZXRhLndlYnBhY2tIb3QpIHtcbiAgICBpbXBvcnQubWV0YS53ZWJwYWNrSG90LmFjY2VwdCgpO1xuICB9XG5cbiAgZXhwb3J0IGRlZmF1bHQgZW50cnk7XG4gICAgYCxcbiAgICApO1xuICAgIHJldHVybiBnZW5lcmF0ZWRFbnRyeXBvaW50O1xuICB9XG5cbiAgY29uc3Qgd2VicGFja0NvbmZpZ3M6IENvbmZpZ3VyYXRpb25bXSA9IFtcbiAgICB3ZWJwYWNrQ29uZmlnKFxuICAgICAge1xuICAgICAgICAuLi5lbnYsXG4gICAgICAgIGVudHJ5cGF0aDogaG90RW50cnkoZW50cnlwb2ludCkubmFtZSxcbiAgICAgICAgbmFtZTogJ2NsaWVudCcsXG4gICAgICB9LFxuICAgICAgeyBtb2RlOiAnZGV2ZWxvcG1lbnQnIH0sXG4gICAgKSxcbiAgICB3ZWJwYWNrQ29uZmlnKFxuICAgICAge1xuICAgICAgICAuLi5lbnYsXG4gICAgICAgIGVudHJ5cGF0aDogZW50cnlwb2ludC5yZXBsYWNlKCcudHN4JywgJy5zZXJ2ZXIudHN4JyksXG4gICAgICAgIG5hbWU6ICdzZXJ2ZXInLFxuICAgICAgICBCUk9XU0VSU0xJU1RfRU5WOiAnY3VycmVudCBub2RlJyxcbiAgICAgIH0sXG4gICAgICB7IG1vZGU6ICdkZXZlbG9wbWVudCcsIHRhcmdldDogJ25vZGUnIH0sXG4gICAgKSxcbiAgXTtcblxuICAvLyBpbml0aWFsaXplIHRoZSB3ZWJwYWNrIGNvbXBpbGVyXG4gIGNvbnN0IGNvbXBpbGVyID0gd2VicGFjayh3ZWJwYWNrQ29uZmlncyBhcyB1bmtub3duIGFzIE11bHRpQ29uZmlndXJhdGlvbik7XG4gIGlmICghY29tcGlsZXIpIHtcbiAgICBsb2cuZXJyb3IoJ0ZhaWxlZCB0byBpbml0aWFsaXplIHRoZSB3ZWJwYWNrIGNvbXBpbGVyJyk7XG4gICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgfVxuXG4gIHNvdXJjZU1hcFN1cHBvcnQuaW5zdGFsbCh7IGhvb2tSZXF1aXJlOiB0cnVlIH0pO1xuXG4gIGZ1bmN0aW9uIGdldFNlcnZlckJ1bmRsZShzZXJ2ZXJTdGF0czogd2VicGFjay5TdGF0cykge1xuICAgIGNvbnN0IHNlcnZlckpzb24gPSBzZXJ2ZXJTdGF0cy50b0pzb24oeyBhc3NldHM6IHRydWUgfSk7XG4gICAgcmV0dXJuIHBhdGguam9pbihzZXJ2ZXJKc29uLm91dHB1dFBhdGggPz8gJycsICdzZXJ2ZXIuanMnKTtcbiAgfVxuICBmdW5jdGlvbiBoYW5kbGVFcnJvcnM8XG4gICAgRiBleHRlbmRzIChcbiAgICAgIHJlcTogUmVxdWVzdCB8IEluY29taW5nTWVzc2FnZSxcbiAgICAgIHJlczogUmVzcG9uc2UgfCBTZXJ2ZXJSZXNwb25zZSxcbiAgICApID0+IFByb21pc2U8dm9pZD4sXG4gID4oZm46IEYpIHtcbiAgICByZXR1cm4gYXN5bmMgZnVuY3Rpb24gKFxuICAgICAgcmVxOiBSZXF1ZXN0IHwgSW5jb21pbmdNZXNzYWdlLFxuICAgICAgcmVzOiBSZXNwb25zZSB8IFNlcnZlclJlc3BvbnNlLFxuICAgICAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuICAgICkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZuKHJlcSwgcmVzKTtcbiAgICAgIH0gY2F0Y2ggKHgpIHtcbiAgICAgICAgbmV4dCh4KTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgbGV0IGluaXRSZW5kZXI6XG4gICAgfCB7IGFyZ3M6IFBhcmFtZXRlcnM8Qm91bmRSZW5kZXI+OyByZXNvbHZlOiAoKSA9PiB2b2lkIH1bXVxuICAgIHwgdW5kZWZpbmVkID0gW107XG4gIGxldCByZW5kZXI6IEJvdW5kUmVuZGVyID0gKC4uLmFyZ3MpID0+XG4gICAgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBpbml0UmVuZGVyPy5wdXNoKHsgYXJncywgcmVzb2x2ZSB9KTtcbiAgICB9KTtcblxuICBmdW5jdGlvbiBpbXBvcnRSZW5kZXIoc3RhdHM6IHdlYnBhY2suU3RhdHNbXSkge1xuICAgIGNvbnN0IFtjbGllbnRTdGF0cywgc2VydmVyU3RhdHNdID0gc3RhdHM7XG4gICAgaWYgKFxuICAgICAgY2xpZW50U3RhdHM/LmNvbXBpbGF0aW9uPy5lcnJvcnM/Lmxlbmd0aCB8fFxuICAgICAgc2VydmVyU3RhdHM/LmNvbXBpbGF0aW9uPy5lcnJvcnM/Lmxlbmd0aFxuICAgICkge1xuICAgICAgbG9nLmVycm9yKCdFcnJvcnMgZm9yIGNsaWVudCBidWlsZDogJyArIGNsaWVudFN0YXRzLmNvbXBpbGF0aW9uLmVycm9ycyk7XG4gICAgICBsb2cuZXJyb3IoJ0Vycm9ycyBmb3Igc2VydmVyIGJ1aWxkOiAnICsgc2VydmVyU3RhdHMuY29tcGlsYXRpb24uZXJyb3JzKTtcbiAgICAgIC8vIGZpcnN0IHRpbWUsIHJhdGhlciB0aGFuIHJlLXJlbmRlclxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoaW5pdFJlbmRlcikpIHtcbiAgICAgICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgICAgIH1cbiAgICAgIGxvZy5lcnJvcignQWJvdmUgY29tcGlsZXIgZXJyb3JzIGJsb2NraW5nIHJlbG9hZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2cuaW5mbygnTGF1bmNoaW5nIFNTUicpO1xuICAgIH1cblxuICAgIC8vIEFTU0VUU1xuICAgIGNvbnN0IGNsaWVudE1hbmlmZXN0ID0gY2xpZW50U3RhdHMudG9Kc29uKCk7XG5cbiAgICBzZXJ2ZXJFbnRyeSA9IGdldFNlcnZlckJ1bmRsZShzZXJ2ZXJTdGF0cyk7XG4gICAgc2VydmVyRmlsZUNvbnRlbnRzID0gcmVhZEZpbGUoc2VydmVyRW50cnkpLnRoZW4oYnVmID0+IGJ1Zi50b1N0cmluZygpKTtcbiAgICAvLyByZWxvYWQgbW9kdWxlc1xuICAgIE9iamVjdC5rZXlzKGZzUmVxdWlyZS5jYWNoZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgZGVsZXRlIGZzUmVxdWlyZS5jYWNoZVtrZXldO1xuICAgIH0pO1xuICAgIHJlbmRlciA9IChmc1JlcXVpcmUoc2VydmVyRW50cnkpIGFzIGFueSkuZGVmYXVsdC5iaW5kKFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgY2xpZW50TWFuaWZlc3QsXG4gICAgKTtcbiAgICAvLyBTRVJWRVIgU0lERSBFTlRSWVBPSU5UXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoaW5pdFJlbmRlcikpIHtcbiAgICAgIGluaXRSZW5kZXIuZm9yRWFjaChhc3luYyBpbml0ID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2cuaW5mbygnUmVzb2x2aW5nIHF1ZXVlZCByZXF1ZXN0cycpO1xuICAgICAgICAgIGF3YWl0IHJlbmRlciguLi5pbml0LmFyZ3MpO1xuICAgICAgICAgIGluaXQucmVzb2x2ZSgpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgbG9nLmVycm9yKCdFcnJvciB3aGVuIGF0dGVtcHRpbmcgdG8gcmVuZGVyIHF1ZXVlZCByZXF1ZXN0cycpO1xuICAgICAgICAgIGxvZy5lcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpbml0UmVuZGVyID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGRldlNlcnZlciA9IG5ldyBXZWJwYWNrRGV2U2VydmVyKFxuICAgIC8vIHdyaXRlIHRvIG1lbW9yeSBmaWxlc3lzdGVtIHNvIHdlIGNhbiBpbXBvcnRcbiAgICB7XG4gICAgICAuLi53ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXIsXG4gICAgICBkZXZNaWRkbGV3YXJlOiB7XG4gICAgICAgIC4uLndlYnBhY2tDb25maWdzWzBdPy5kZXZTZXJ2ZXI/LmRldk1pZGRsZXdhcmUsXG4gICAgICAgIG91dHB1dEZpbGVTeXN0ZW06IHtcbiAgICAgICAgICAuLi5mcyxcbiAgICAgICAgICBqb2luOiBwYXRoLmpvaW4gYXMgYW55LFxuICAgICAgICB9IGFzIGFueSxcbiAgICAgIH0sXG4gICAgICBzZXR1cE1pZGRsZXdhcmVzOiAobWlkZGxld2FyZXMsIGRldlNlcnZlcikgPT4ge1xuICAgICAgICBpZiAoIWRldlNlcnZlcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignd2VicGFjay1kZXYtc2VydmVyIGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBvdGhlclJvdXRlcyA9IFtcbiAgICAgICAgICBwcm9jZXNzLmVudi5XRUJQQUNLX1BVQkxJQ19QQVRILFxuICAgICAgICAgIC4uLih3ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXI/LnByb3h5XG4gICAgICAgICAgICA/LmZpbHRlcihwcm94eSA9PiB0eXBlb2YgcHJveHkgPT09ICdvYmplY3QnKVxuICAgICAgICAgICAgPy5mbGF0TWFwKHByb3h5ID0+IHByb3h5LmNvbnRleHQpID8/IFtdKSxcbiAgICAgICAgXTtcbiAgICAgICAgLy8gc2VydmUgU1NSIGZvciBub24tV0VCUEFDS19QVUJMSUNfUEFUSFxuICAgICAgICBkZXZTZXJ2ZXIuYXBwPy5nZXQoXG4gICAgICAgICAgbmV3IFJlZ0V4cChgXig/ISR7b3RoZXJSb3V0ZXMuam9pbignfCcpfSlgKSxcbiAgICAgICAgICBoYW5kbGVFcnJvcnMoYXN5bmMgZnVuY3Rpb24gKHJlcTogYW55LCByZXM6IGFueSkge1xuICAgICAgICAgICAgaWYgKHJlcS51cmwuZW5kc1dpdGgoJ2Zhdmljb24uaWNvJykpIHtcbiAgICAgICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA0MDQ7XG4gICAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtdHlwZScsICd0ZXh0L2h0bWwnKTtcbiAgICAgICAgICAgICAgcmVzLnNlbmQoJ25vdCBmb3VuZCcpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXMuc29ja2V0Lm9uKCdlcnJvcicsIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgICAgICAgICBsb2cuZXJyb3IoJ0ZhdGFsOicsIGVycm9yKTtcbiAgICAgICAgICAgICAgaWYgKChlcnJvciBhcyBhbnkpLmNvZGUgPT09ICdFQ09OTlJFU0VUJykge1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcihcbiAgICAgICAgICAgICAgICAgICdFQ09OTlJFU0VUIGlzIHVzdWFsbHkgZHVlIHRvIGJyb3dzZXIgY2xvc2luZyB0aGUgY29ubmVjdGlvbicsXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcihyZXEsIHJlcyk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHdlYnBhY2tDb25maWdzWzBdLmRldlNlcnZlcj8uc2V0dXBNaWRkbGV3YXJlcykge1xuICAgICAgICAgIHJldHVybiB3ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXIuc2V0dXBNaWRkbGV3YXJlcyhcbiAgICAgICAgICAgIG1pZGRsZXdhcmVzLFxuICAgICAgICAgICAgZGV2U2VydmVyLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWlkZGxld2FyZXM7XG4gICAgICB9LFxuICAgIH0sXG4gICAgY29tcGlsZXIsXG4gICk7XG4gIGNvbnN0IHJ1blNlcnZlciA9IGFzeW5jICgpID0+IHtcbiAgICBhd2FpdCBkZXZTZXJ2ZXIuc3RhcnQoKTtcbiAgICBkZXZTZXJ2ZXIuY29tcGlsZXIuaG9va3MuZG9uZS50YXAoXG4gICAgICAnQW5hbnNpIFNlcnZlcicsXG4gICAgICAobXVsdGlTdGF0czogd2VicGFjay5NdWx0aVN0YXRzIHwgd2VicGFjay5TdGF0cykgPT4ge1xuICAgICAgICBpZiAoIW11bHRpU3RhdHMpIHtcbiAgICAgICAgICBsb2cuZXJyb3IoJ3N0YXRzIG5vdCBzZW5kJyk7XG4gICAgICAgICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghT2JqZWN0Lmhhc093bihtdWx0aVN0YXRzLCAnc3RhdHMnKSkgcmV0dXJuO1xuICAgICAgICBpZiAoKG11bHRpU3RhdHMgYXMgd2VicGFjay5NdWx0aVN0YXRzKS5zdGF0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGltcG9ydFJlbmRlcigobXVsdGlTdGF0cyBhcyB3ZWJwYWNrLk11bHRpU3RhdHMpLnN0YXRzKTtcbiAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgIGxvZy5lcnJvcignRmFpbGVkIHRvIGxvYWQgc2VydmUgZW50cnlwb2ludCcpO1xuICAgICAgICAgICAgY29uc3QgZmluZGVyID0gbmV3IFJlZ0V4cChgJHtzZXJ2ZXJFbnRyeX06KFtcXFxcZF0rKTooW1xcXFxkXSspYCwgJ2cnKTtcbiAgICAgICAgICAgIHNlcnZlckZpbGVDb250ZW50cy50aGVuKGZpbGVUZXh0ID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdGV4dFJvd3MgPSBmaWxlVGV4dC5zcGxpdCgnXFxuJyk7XG4gICAgICAgICAgICAgIGxvZy5lcnJvcignPj4+IFN0YWNrIENvbnRleHQgW3NlcnZlIGVudHJ5cG9pbnRdIDw8PCcpO1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIGUuc3RhY2subWF0Y2hBbGwoZmluZGVyKSA/PyBbXSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJvdyA9IE51bWJlci5wYXJzZUludChtYXRjaFsxXSk7XG4gICAgICAgICAgICAgICAgY29uc3QgY29sID0gTnVtYmVyLnBhcnNlSW50KG1hdGNoWzJdKTtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IocGF0aC5iYXNlbmFtZShzZXJ2ZXJFbnRyeSkgKyAnICcgKyByb3cgKyAnOicgKyBjb2wpO1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0ZXh0Um93c1tyb3cgLSAyXSk7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKHRleHRSb3dzW3JvdyAtIDFdKTtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoQXJyYXkoY29sKS5qb2luKCcgJykgKyAnXicpO1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0ZXh0Um93c1tyb3ddKTtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodGV4dFJvd3Nbcm93ICsgMV0pO1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0ZXh0Um93c1tyb3cgKyAyXSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgZGlza0ZzLndyaXRlRmlsZVN5bmMoc2VydmVyRW50cnksIGZpbGVUZXh0KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2cuZXJyb3IoJ09ubHkgY29tcGlsZXIgb25lIHN0YXQnKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICApO1xuICB9O1xuICBjb25zdCBzdG9wU2VydmVyID0gYXN5bmMgKCkgPT4ge1xuICAgIGxvZy5pbmZvKCdTdG9wcGluZyBzZXJ2ZXIuLi4nKTtcbiAgICBhd2FpdCBkZXZTZXJ2ZXIuc3RvcCgpO1xuICAgIGxvZy5pbmZvKCdTZXJ2ZXIgY2xvc2VkJyk7XG4gIH07XG5cbiAgcHJvY2Vzcy5vbignU0lHSU5UJywgKCkgPT4ge1xuICAgIGxvZy53YXJuKCdSZWNlaXZlZCBTSUdJTlQsIGRldnNlcnZlciBzaHV0dGluZyBkb3duJyk7XG4gICAgc3RvcFNlcnZlcigpO1xuICAgIHByb2Nlc3MuZXhpdCgtMSk7XG4g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
|
|
246
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJPYmplY3QiLCJoYXNPd24iLCJpdCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImRpc2tGcyIsImNyZWF0ZUZzRnJvbVZvbHVtZSIsIlZvbHVtZSIsInBhdGgiLCJzb3VyY2VNYXBTdXBwb3J0IiwidG1wIiwidWZzIiwicHJvbWlzaWZ5Iiwid2VicGFjayIsImxvZ2dpbmciLCJXZWJwYWNrRGV2U2VydmVyIiwiY3JlYXRlSHlicmlkUmVxdWlyZSIsImdldFdlYnBhY2tDb25maWciLCJnZXRFcnJvclN0YXR1cyIsInJlbmRlckVycm9yUGFnZSIsImltcG9ydCIsIm1ldGEiLCJtYWluIiwiZW50cnlwb2ludCIsInByb2Nlc3MiLCJhcmd2IiwiY29uc29sZSIsImxvZyIsImV4aXQiLCJzdGFydERldlNlcnZlciIsInNlcnZlckZpbGVDb250ZW50cyIsIlByb21pc2UiLCJyZXNvbHZlIiwic2VydmVyRW50cnkiLCJlbnYiLCJ3ZWJwYWNrQ29uZmlnIiwiZ2V0TG9nZ2VyIiwidm9sdW1lIiwiZnMiLCJ1c2UiLCJmc1JlcXVpcmUiLCJyZWFkRmlsZSIsImhvdEVudHJ5IiwiZW50cnlQYXRoIiwiZ2VuZXJhdGVkRW50cnlwb2ludCIsImZpbGVTeW5jIiwicG9zdGZpeCIsIndyaXRlU3luYyIsImZkIiwiY3dkIiwid2VicGFja0NvbmZpZ3MiLCJlbnRyeXBhdGgiLCJuYW1lIiwibW9kZSIsInJlcGxhY2UiLCJCUk9XU0VSU0xJU1RfRU5WIiwidGFyZ2V0IiwiY29tcGlsZXIiLCJlcnJvciIsImluc3RhbGwiLCJob29rUmVxdWlyZSIsImdldFNlcnZlckJ1bmRsZSIsInNlcnZlclN0YXRzIiwic2VydmVySnNvbiIsInRvSnNvbiIsImFzc2V0cyIsImpvaW4iLCJvdXRwdXRQYXRoIiwiaGFuZGxlRXJyb3JzIiwiZm4iLCJyZXEiLCJyZXMiLCJfbmV4dCIsImV4cHJlc3NSZXMiLCJoZWFkZXJzU2VudCIsInN0YXR1c0NvZGUiLCJzdGF0dXMiLCJzZXRIZWFkZXIiLCJzZW5kIiwidXJsIiwic2hvd1N0YWNrIiwiYmFkZ2UiLCJoaW50IiwiaW5pdFJlbmRlciIsInJlbmRlciIsImFyZ3MiLCJwdXNoIiwiaW1wb3J0UmVuZGVyIiwic3RhdHMiLCJjbGllbnRTdGF0cyIsImNvbXBpbGF0aW9uIiwiZXJyb3JzIiwibGVuZ3RoIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5mbyIsImNsaWVudE1hbmlmZXN0IiwidGhlbiIsImJ1ZiIsInRvU3RyaW5nIiwia2V5cyIsImNhY2hlIiwiZm9yRWFjaCIsImRlZmF1bHQiLCJiaW5kIiwidW5kZWZpbmVkIiwiaW5pdCIsImUiLCJkZXZTZXJ2ZXIiLCJkZXZNaWRkbGV3YXJlIiwib3V0cHV0RmlsZVN5c3RlbSIsInNldHVwTWlkZGxld2FyZXMiLCJtaWRkbGV3YXJlcyIsIkVycm9yIiwib3RoZXJSb3V0ZXMiLCJXRUJQQUNLX1BVQkxJQ19QQVRIIiwicHJveHkiLCJmaWx0ZXIiLCJmbGF0TWFwIiwiY29udGV4dCIsImFwcCIsImdldCIsIlJlZ0V4cCIsImVuZHNXaXRoIiwic29ja2V0Iiwib24iLCJjb2RlIiwicnVuU2VydmVyIiwic3RhcnQiLCJob29rcyIsImRvbmUiLCJ0YXAiLCJtdWx0aVN0YXRzIiwiZmluZGVyIiwiZmlsZVRleHQiLCJ0ZXh0Um93cyIsInNwbGl0IiwibWF0Y2giLCJzdGFjayIsIm1hdGNoQWxsIiwicm93IiwiTnVtYmVyIiwicGFyc2VJbnQiLCJjb2wiLCJiYXNlbmFtZSIsIndyaXRlRmlsZVN5bmMiLCJzdG9wU2VydmVyIiwic3RvcCIsIndhcm4iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc2NyaXB0cy9zdGFydERldnNlcnZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIjIS91c3IvYmluL2VudiBub2RlXG5PYmplY3QuaGFzT3duID1cbiAgT2JqZWN0Lmhhc093biB8fFxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqLyBmdW5jdGlvbiBoYXNPd24oaXQsIGtleSkge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG4gIH07XG5pbXBvcnQgdHlwZSB7IE5leHRGdW5jdGlvbiB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IGRpc2tGcyBmcm9tICdmcyc7XG5pbXBvcnQgeyBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlIH0gZnJvbSAnaHR0cCc7XG5pbXBvcnQgeyBjcmVhdGVGc0Zyb21Wb2x1bWUsIFZvbHVtZSB9IGZyb20gJ21lbWZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHNvdXJjZU1hcFN1cHBvcnQgZnJvbSAnc291cmNlLW1hcC1zdXBwb3J0JztcbmltcG9ydCB0bXAgZnJvbSAndG1wJztcbmltcG9ydCB7IHVmcyB9IGZyb20gJ3VuaW9uZnMnO1xuaW1wb3J0IHsgcHJvbWlzaWZ5IH0gZnJvbSAndXRpbCc7XG5pbXBvcnQgd2VicGFjaywgeyB0eXBlIENvbmZpZ3VyYXRpb24sIHR5cGUgTXVsdGlDb25maWd1cmF0aW9uIH0gZnJvbSAnd2VicGFjayc7XG5pbXBvcnQgbG9nZ2luZyBmcm9tICd3ZWJwYWNrL2xpYi9sb2dnaW5nL3J1bnRpbWUuanMnO1xuaW1wb3J0IFdlYnBhY2tEZXZTZXJ2ZXIgZnJvbSAnd2VicGFjay1kZXYtc2VydmVyJztcblxuaW1wb3J0ICdjcm9zcy1mZXRjaC9kaXN0L25vZGUtcG9seWZpbGwuanMnO1xuaW1wb3J0IHsgY3JlYXRlSHlicmlkUmVxdWlyZSB9IGZyb20gJy4vY3JlYXRlSHlicmlkUmVxdWlyZS5qcyc7XG5pbXBvcnQgeyBnZXRXZWJwYWNrQ29uZmlnIH0gZnJvbSAnLi9nZXRXZWJwYWNrQ29uZmlnLmpzJztcbmltcG9ydCB7IGdldEVycm9yU3RhdHVzLCByZW5kZXJFcnJvclBhZ2UgfSBmcm9tICcuL3NzckVycm9ySGFuZGxlci5qcyc7XG5pbXBvcnQgeyBCb3VuZFJlbmRlciB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vLyBydW4gZGlyZWN0bHkgZnJvbSBub2RlXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4vLyBAdHMtaWdub3JlXG5pZiAoaW1wb3J0Lm1ldGEubWFpbikge1xuICBjb25zdCBlbnRyeXBvaW50ID0gcHJvY2Vzcy5hcmd2WzJdO1xuXG4gIGlmICghZW50cnlwb2ludCkge1xuICAgIGNvbnNvbGUubG9nKGBVc2FnZTogc3RhcnQtYW5hbnNpIDxlbnRyeXBvaW50LWZpbGU+YCk7XG4gICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgfVxuXG4gIHN0YXJ0RGV2U2VydmVyKGVudHJ5cG9pbnQpO1xufVxuXG5sZXQgc2VydmVyRmlsZUNvbnRlbnRzOiBQcm9taXNlPHN0cmluZz4gPSBQcm9taXNlLnJlc29sdmUoJycpO1xubGV0IHNlcnZlckVudHJ5ID0gJyc7XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0RGV2U2VydmVyKFxuICBlbnRyeXBvaW50OiBzdHJpbmcsXG4gIGVudjogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbikge1xuICBjb25zdCB3ZWJwYWNrQ29uZmlnID0gYXdhaXQgZ2V0V2VicGFja0NvbmZpZygpO1xuXG4gIGNvbnN0IGxvZyA9IGxvZ2dpbmcuZ2V0TG9nZ2VyKCdhbmFuc2ktZGV2c2VydmVyJyk7XG5cbiAgLy8gU2V0IHVwIGluIG1lbW9yeSBmaWxlc3lzdGVtXG4gIGNvbnN0IHZvbHVtZSA9IG5ldyBWb2x1bWUoKTtcbiAgY29uc3QgZnMgPSBjcmVhdGVGc0Zyb21Wb2x1bWUodm9sdW1lKTtcbiAgdWZzLnVzZShkaXNrRnMpLnVzZShmcyBhcyBhbnkpO1xuXG4gIGNvbnN0IGZzUmVxdWlyZSA9IGNyZWF0ZUh5YnJpZFJlcXVpcmUodWZzKTtcblxuICBjb25zdCByZWFkRmlsZSA9IHByb21pc2lmeSh1ZnMucmVhZEZpbGUpO1xuICAvLyBHZW5lcmF0ZSBhIHRlbXBvcmFyeSBmaWxlIHNvIHdlIGNhbiBob3QgcmVsb2FkIGZyb20gdGhlIHJvb3Qgb2YgdGhlIGFwcGxpY2F0aW9uXG4gIGZ1bmN0aW9uIGhvdEVudHJ5KGVudHJ5UGF0aDogc3RyaW5nKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgLy8gQHRzLWlnbm9yZSBmb3Igc29tZSByZWFzb24gaXQncyBub3QgcGlja2luZyB1cCB0aGF0IG90aGVyIG9wdGlvbnMgYXJlIG9wdGlvbmFsXG4gICAgY29uc3QgZ2VuZXJhdGVkRW50cnlwb2ludCA9IHRtcC5maWxlU3luYyh7IHBvc3RmaXg6ICcuanMnIH0pO1xuICAgIGRpc2tGcy53cml0ZVN5bmMoXG4gICAgICBnZW5lcmF0ZWRFbnRyeXBvaW50LmZkLFxuICAgICAgYFxuICBpbXBvcnQgZW50cnkgZnJvbSBcIiR7cGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIGVudHJ5UGF0aCl9XCI7XG5cbiAgaWYgKGltcG9ydC5tZXRhLndlYnBhY2tIb3QpIHtcbiAgICBpbXBvcnQubWV0YS53ZWJwYWNrSG90LmFjY2VwdCgpO1xuICB9XG5cbiAgZXhwb3J0IGRlZmF1bHQgZW50cnk7XG4gICAgYCxcbiAgICApO1xuICAgIHJldHVybiBnZW5lcmF0ZWRFbnRyeXBvaW50O1xuICB9XG5cbiAgY29uc3Qgd2VicGFja0NvbmZpZ3M6IENvbmZpZ3VyYXRpb25bXSA9IFtcbiAgICB3ZWJwYWNrQ29uZmlnKFxuICAgICAge1xuICAgICAgICAuLi5lbnYsXG4gICAgICAgIGVudHJ5cGF0aDogaG90RW50cnkoZW50cnlwb2ludCkubmFtZSxcbiAgICAgICAgbmFtZTogJ2NsaWVudCcsXG4gICAgICB9LFxuICAgICAgeyBtb2RlOiAnZGV2ZWxvcG1lbnQnIH0sXG4gICAgKSxcbiAgICB3ZWJwYWNrQ29uZmlnKFxuICAgICAge1xuICAgICAgICAuLi5lbnYsXG4gICAgICAgIGVudHJ5cGF0aDogZW50cnlwb2ludC5yZXBsYWNlKCcudHN4JywgJy5zZXJ2ZXIudHN4JyksXG4gICAgICAgIG5hbWU6ICdzZXJ2ZXInLFxuICAgICAgICBCUk9XU0VSU0xJU1RfRU5WOiAnY3VycmVudCBub2RlJyxcbiAgICAgIH0sXG4gICAgICB7IG1vZGU6ICdkZXZlbG9wbWVudCcsIHRhcmdldDogJ25vZGUnIH0sXG4gICAgKSxcbiAgXTtcblxuICAvLyBpbml0aWFsaXplIHRoZSB3ZWJwYWNrIGNvbXBpbGVyXG4gIGNvbnN0IGNvbXBpbGVyID0gd2VicGFjayh3ZWJwYWNrQ29uZmlncyBhcyB1bmtub3duIGFzIE11bHRpQ29uZmlndXJhdGlvbik7XG4gIGlmICghY29tcGlsZXIpIHtcbiAgICBsb2cuZXJyb3IoJ0ZhaWxlZCB0byBpbml0aWFsaXplIHRoZSB3ZWJwYWNrIGNvbXBpbGVyJyk7XG4gICAgcHJvY2Vzcy5leGl0KC0xKTtcbiAgfVxuXG4gIHNvdXJjZU1hcFN1cHBvcnQuaW5zdGFsbCh7IGhvb2tSZXF1aXJlOiB0cnVlIH0pO1xuXG4gIGZ1bmN0aW9uIGdldFNlcnZlckJ1bmRsZShzZXJ2ZXJTdGF0czogd2VicGFjay5TdGF0cykge1xuICAgIGNvbnN0IHNlcnZlckpzb24gPSBzZXJ2ZXJTdGF0cy50b0pzb24oeyBhc3NldHM6IHRydWUgfSk7XG4gICAgcmV0dXJuIHBhdGguam9pbihzZXJ2ZXJKc29uLm91dHB1dFBhdGggPz8gJycsICdzZXJ2ZXIuanMnKTtcbiAgfVxuICBmdW5jdGlvbiBoYW5kbGVFcnJvcnM8XG4gICAgRiBleHRlbmRzIChcbiAgICAgIHJlcTogUmVxdWVzdCB8IEluY29taW5nTWVzc2FnZSxcbiAgICAgIHJlczogUmVzcG9uc2UgfCBTZXJ2ZXJSZXNwb25zZSxcbiAgICApID0+IFByb21pc2U8dm9pZD4sXG4gID4oZm46IEYpIHtcbiAgICByZXR1cm4gYXN5bmMgZnVuY3Rpb24gKFxuICAgICAgcmVxOiBSZXF1ZXN0IHwgSW5jb21pbmdNZXNzYWdlLFxuICAgICAgcmVzOiBSZXNwb25zZSB8IFNlcnZlclJlc3BvbnNlLFxuICAgICAgX25leHQ6IE5leHRGdW5jdGlvbixcbiAgICApIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBmbihyZXEsIHJlcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBsb2cuZXJyb3IoJ1NTUiByZW5kZXJpbmcgZXJyb3I6JywgZXJyb3IpO1xuXG4gICAgICAgIC8vIFJldHVybiBlcnJvciByZXNwb25zZSB3aXRoIHN0YXR1cyBmcm9tIGVycm9yIGlmIGF2YWlsYWJsZVxuICAgICAgICBjb25zdCBleHByZXNzUmVzID0gcmVzIGFzIGFueTtcbiAgICAgICAgaWYgKCFleHByZXNzUmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgICAgY29uc3Qgc3RhdHVzQ29kZSA9IGdldEVycm9yU3RhdHVzKGVycm9yKTtcbiAgICAgICAgICBleHByZXNzUmVzLnN0YXR1cyhzdGF0dXNDb2RlKTtcbiAgICAgICAgICBleHByZXNzUmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvaHRtbCcpO1xuICAgICAgICAgIGV4cHJlc3NSZXMuc2VuZChcbiAgICAgICAgICAgIHJlbmRlckVycm9yUGFnZShlcnJvciwgcmVxLnVybCA/PyAnLycsIHN0YXR1c0NvZGUsIHtcbiAgICAgICAgICAgICAgc2hvd1N0YWNrOiB0cnVlLFxuICAgICAgICAgICAgICBiYWRnZTogJ0RFViBNT0RFJyxcbiAgICAgICAgICAgICAgaGludDogJ1RoZSBkZXYgc2VydmVyIGlzIHN0aWxsIHJ1bm5pbmcuIEZpeCB0aGUgZXJyb3IgYW5kIHJldHJ5LCBvciBjaGVjayB0aGUgY29uc29sZSBmb3IgbW9yZSBkZXRhaWxzLicsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIGxldCBpbml0UmVuZGVyOlxuICAgIHwgeyBhcmdzOiBQYXJhbWV0ZXJzPEJvdW5kUmVuZGVyPjsgcmVzb2x2ZTogKCkgPT4gdm9pZCB9W11cbiAgICB8IHVuZGVmaW5lZCA9IFtdO1xuICBsZXQgcmVuZGVyOiBCb3VuZFJlbmRlciA9ICguLi5hcmdzKSA9PlxuICAgIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgaW5pdFJlbmRlcj8ucHVzaCh7IGFyZ3MsIHJlc29sdmUgfSk7XG4gICAgfSk7XG5cbiAgZnVuY3Rpb24gaW1wb3J0UmVuZGVyKHN0YXRzOiB3ZWJwYWNrLlN0YXRzW10pIHtcbiAgICBjb25zdCBbY2xpZW50U3RhdHMsIHNlcnZlclN0YXRzXSA9IHN0YXRzO1xuICAgIGlmIChcbiAgICAgIGNsaWVudFN0YXRzPy5jb21waWxhdGlvbj8uZXJyb3JzPy5sZW5ndGggfHxcbiAgICAgIHNlcnZlclN0YXRzPy5jb21waWxhdGlvbj8uZXJyb3JzPy5sZW5ndGhcbiAgICApIHtcbiAgICAgIGxvZy5lcnJvcignRXJyb3JzIGZvciBjbGllbnQgYnVpbGQ6ICcgKyBjbGllbnRTdGF0cy5jb21waWxhdGlvbi5lcnJvcnMpO1xuICAgICAgbG9nLmVycm9yKCdFcnJvcnMgZm9yIHNlcnZlciBidWlsZDogJyArIHNlcnZlclN0YXRzLmNvbXBpbGF0aW9uLmVycm9ycyk7XG4gICAgICAvLyBmaXJzdCB0aW1lLCByYXRoZXIgdGhhbiByZS1yZW5kZXJcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGluaXRSZW5kZXIpKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgtMSk7XG4gICAgICB9XG4gICAgICBsb2cuZXJyb3IoJ0Fib3ZlIGNvbXBpbGVyIGVycm9ycyBibG9ja2luZyByZWxvYWQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nLmluZm8oJ0xhdW5jaGluZyBTU1InKTtcbiAgICB9XG5cbiAgICAvLyBBU1NFVFNcbiAgICBjb25zdCBjbGllbnRNYW5pZmVzdCA9IGNsaWVudFN0YXRzLnRvSnNvbigpO1xuXG4gICAgc2VydmVyRW50cnkgPSBnZXRTZXJ2ZXJCdW5kbGUoc2VydmVyU3RhdHMpO1xuICAgIHNlcnZlckZpbGVDb250ZW50cyA9IHJlYWRGaWxlKHNlcnZlckVudHJ5KS50aGVuKGJ1ZiA9PiBidWYudG9TdHJpbmcoKSk7XG4gICAgLy8gcmVsb2FkIG1vZHVsZXNcbiAgICBPYmplY3Qua2V5cyhmc1JlcXVpcmUuY2FjaGUpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGRlbGV0ZSBmc1JlcXVpcmUuY2FjaGVba2V5XTtcbiAgICB9KTtcbiAgICByZW5kZXIgPSAoZnNSZXF1aXJlKHNlcnZlckVudHJ5KSBhcyBhbnkpLmRlZmF1bHQuYmluZChcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGNsaWVudE1hbmlmZXN0LFxuICAgICk7XG4gICAgLy8gU0VSVkVSIFNJREUgRU5UUllQT0lOVFxuICAgIGlmIChBcnJheS5pc0FycmF5KGluaXRSZW5kZXIpKSB7XG4gICAgICBpbml0UmVuZGVyLmZvckVhY2goYXN5bmMgaW5pdCA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbG9nLmluZm8oJ1Jlc29sdmluZyBxdWV1ZWQgcmVxdWVzdHMnKTtcbiAgICAgICAgICBhd2FpdCByZW5kZXIoLi4uaW5pdC5hcmdzKTtcbiAgICAgICAgICBpbml0LnJlc29sdmUoKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGxvZy5lcnJvcignRXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIHJlbmRlciBxdWV1ZWQgcmVxdWVzdHMnKTtcbiAgICAgICAgICBsb2cuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaW5pdFJlbmRlciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBkZXZTZXJ2ZXIgPSBuZXcgV2VicGFja0RldlNlcnZlcihcbiAgICAvLyB3cml0ZSB0byBtZW1vcnkgZmlsZXN5c3RlbSBzbyB3ZSBjYW4gaW1wb3J0XG4gICAge1xuICAgICAgLi4ud2VicGFja0NvbmZpZ3NbMF0uZGV2U2VydmVyLFxuICAgICAgZGV2TWlkZGxld2FyZToge1xuICAgICAgICAuLi53ZWJwYWNrQ29uZmlnc1swXT8uZGV2U2VydmVyPy5kZXZNaWRkbGV3YXJlLFxuICAgICAgICBvdXRwdXRGaWxlU3lzdGVtOiB7XG4gICAgICAgICAgLi4uZnMsXG4gICAgICAgICAgam9pbjogcGF0aC5qb2luIGFzIGFueSxcbiAgICAgICAgfSBhcyBhbnksXG4gICAgICB9LFxuICAgICAgc2V0dXBNaWRkbGV3YXJlczogKG1pZGRsZXdhcmVzLCBkZXZTZXJ2ZXIpID0+IHtcbiAgICAgICAgaWYgKCFkZXZTZXJ2ZXIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3dlYnBhY2stZGV2LXNlcnZlciBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgb3RoZXJSb3V0ZXMgPSBbXG4gICAgICAgICAgcHJvY2Vzcy5lbnYuV0VCUEFDS19QVUJMSUNfUEFUSCxcbiAgICAgICAgICAuLi4od2VicGFja0NvbmZpZ3NbMF0uZGV2U2VydmVyPy5wcm94eVxuICAgICAgICAgICAgPy5maWx0ZXIocHJveHkgPT4gdHlwZW9mIHByb3h5ID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgID8uZmxhdE1hcChwcm94eSA9PiBwcm94eS5jb250ZXh0KSA/PyBbXSksXG4gICAgICAgIF07XG4gICAgICAgIC8vIHNlcnZlIFNTUiBmb3Igbm9uLVdFQlBBQ0tfUFVCTElDX1BBVEhcbiAgICAgICAgZGV2U2VydmVyLmFwcD8uZ2V0KFxuICAgICAgICAgIG5ldyBSZWdFeHAoYF4oPyEke290aGVyUm91dGVzLmpvaW4oJ3wnKX0pYCksXG4gICAgICAgICAgaGFuZGxlRXJyb3JzKGFzeW5jIGZ1bmN0aW9uIChyZXE6IGFueSwgcmVzOiBhbnkpIHtcbiAgICAgICAgICAgIGlmIChyZXEudXJsLmVuZHNXaXRoKCdmYXZpY29uLmljbycpKSB7XG4gICAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNDA0O1xuICAgICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAndGV4dC9odG1sJyk7XG4gICAgICAgICAgICAgIHJlcy5zZW5kKCdub3QgZm91bmQnKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzLnNvY2tldC5vbignZXJyb3InLCAoZXJyb3I6IHVua25vd24pID0+IHtcbiAgICAgICAgICAgICAgbG9nLmVycm9yKCdGYXRhbDonLCBlcnJvcik7XG4gICAgICAgICAgICAgIGlmICgoZXJyb3IgYXMgYW55KS5jb2RlID09PSAnRUNPTk5SRVNFVCcpIHtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAnRUNPTk5SRVNFVCBpcyB1c3VhbGx5IGR1ZSB0byBicm93c2VyIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb24nLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhd2FpdCByZW5kZXIocmVxLCByZXMpO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh3ZWJwYWNrQ29uZmlnc1swXS5kZXZTZXJ2ZXI/LnNldHVwTWlkZGxld2FyZXMpIHtcbiAgICAgICAgICByZXR1cm4gd2VicGFja0NvbmZpZ3NbMF0uZGV2U2VydmVyLnNldHVwTWlkZGxld2FyZXMoXG4gICAgICAgICAgICBtaWRkbGV3YXJlcyxcbiAgICAgICAgICAgIGRldlNlcnZlcixcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1pZGRsZXdhcmVzO1xuICAgICAgfSxcbiAgICB9LFxuICAgIGNvbXBpbGVyLFxuICApO1xuICBjb25zdCBydW5TZXJ2ZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgYXdhaXQgZGV2U2VydmVyLnN0YXJ0KCk7XG4gICAgZGV2U2VydmVyLmNvbXBpbGVyLmhvb2tzLmRvbmUudGFwKFxuICAgICAgJ0FuYW5zaSBTZXJ2ZXInLFxuICAgICAgKG11bHRpU3RhdHM6IHdlYnBhY2suTXVsdGlTdGF0cyB8IHdlYnBhY2suU3RhdHMpID0+IHtcbiAgICAgICAgaWYgKCFtdWx0aVN0YXRzKSB7XG4gICAgICAgICAgbG9nLmVycm9yKCdzdGF0cyBub3Qgc2VuZCcpO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgtMSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIU9iamVjdC5oYXNPd24obXVsdGlTdGF0cywgJ3N0YXRzJykpIHJldHVybjtcbiAgICAgICAgaWYgKChtdWx0aVN0YXRzIGFzIHdlYnBhY2suTXVsdGlTdGF0cykuc3RhdHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpbXBvcnRSZW5kZXIoKG11bHRpU3RhdHMgYXMgd2VicGFjay5NdWx0aVN0YXRzKS5zdGF0cyk7XG4gICAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHNlcnZlIGVudHJ5cG9pbnQnKTtcbiAgICAgICAgICAgIGNvbnN0IGZpbmRlciA9IG5ldyBSZWdFeHAoYCR7c2VydmVyRW50cnl9OihbXFxcXGRdKyk6KFtcXFxcZF0rKWAsICdnJyk7XG4gICAgICAgICAgICBzZXJ2ZXJGaWxlQ29udGVudHMudGhlbihmaWxlVGV4dCA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRleHRSb3dzID0gZmlsZVRleHQuc3BsaXQoJ1xcbicpO1xuICAgICAgICAgICAgICBsb2cuZXJyb3IoJz4+PiBTdGFjayBDb250ZXh0IFtzZXJ2ZSBlbnRyeXBvaW50XSA8PDwnKTtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBtYXRjaCBvZiBlLnN0YWNrLm1hdGNoQWxsKGZpbmRlcikgPz8gW10pIHtcbiAgICAgICAgICAgICAgICBjb25zdCByb3cgPSBOdW1iZXIucGFyc2VJbnQobWF0Y2hbMV0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbCA9IE51bWJlci5wYXJzZUludChtYXRjaFsyXSk7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKHBhdGguYmFzZW5hbWUoc2VydmVyRW50cnkpICsgJyAnICsgcm93ICsgJzonICsgY29sKTtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodGV4dFJvd3Nbcm93IC0gMl0pO1xuICAgICAgICAgICAgICAgIGxvZy5lcnJvcih0ZXh0Um93c1tyb3cgLSAxXSk7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKEFycmF5KGNvbCkuam9pbignICcpICsgJ14nKTtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodGV4dFJvd3Nbcm93XSk7XG4gICAgICAgICAgICAgICAgbG9nLmVycm9yKHRleHRSb3dzW3JvdyArIDFdKTtcbiAgICAgICAgICAgICAgICBsb2cuZXJyb3IodGV4dFJvd3Nbcm93ICsgMl0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGRpc2tGcy53cml0ZUZpbGVTeW5jKHNlcnZlckVudHJ5LCBmaWxlVGV4dCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9nLmVycm9yKCdPbmx5IGNvbXBpbGVyIG9uZSBzdGF0Jyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfTtcbiAgY29uc3Qgc3RvcFNlcnZlciA9IGFzeW5jICgpID0+IHtcbiAgICBsb2cuaW5mbygnU3RvcHBpbmcgc2VydmVyLi4uJyk7XG4gICAgYXdhaXQgZGV2U2VydmVyLnN0b3AoKTtcbiAgICBsb2cuaW5mbygnU2VydmVyIGNsb3NlZCcpO1xuICB9O1xuXG4gIHByb2Nlc3Mub24oJ1NJR0lOVCcsICgpID0+IHtcbiAgICBsb2cud2FybignUmVjZWl2ZWQgU0lHSU5ULCBkZXZzZXJ2ZXIgc2h1dHRpbmcgZG93bicpO1xuICAgIHN0b3BTZXJ2ZXIoKTtcbiAgICBwcm9jZXNzLmV4aXQoLTEpO1xuICB9KTtcblxuICBydW5TZXJ2ZXIoKTtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQUEs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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anansi/core",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.2",
|
|
4
4
|
"description": "React 19 Framework",
|
|
5
5
|
"homepage": "https://github.com/ntucker/anansi/tree/master/packages/core#readme",
|
|
6
6
|
"repository": {
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"@types/compression": "1.8.1",
|
|
72
72
|
"@types/express": "^4.17.17",
|
|
73
73
|
"@types/node": "^24.0.0",
|
|
74
|
-
"@types/react": "19.2.
|
|
74
|
+
"@types/react": "19.2.7",
|
|
75
75
|
"@types/react-dom": "19.2.3",
|
|
76
76
|
"@types/source-map-support": "0.5.10",
|
|
77
77
|
"@types/tmp": "0.2.6",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"core-js-pure": "^3.40.0",
|
|
89
89
|
"cross-fetch": "^4.1.0",
|
|
90
90
|
"enhanced-resolve": "^5.18.3",
|
|
91
|
-
"express": "^4.
|
|
91
|
+
"express": "^4.22.1",
|
|
92
92
|
"fs-require": "^1.6.0",
|
|
93
93
|
"history": "^5.3.0",
|
|
94
94
|
"http-proxy-middleware": "^3.0.5",
|
package/src/laySpouts.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import crypto from 'crypto';
|
|
|
2
2
|
import type { JSX } from 'react';
|
|
3
3
|
import { renderToPipeableStream as reactRender } from 'react-dom/server';
|
|
4
4
|
|
|
5
|
+
import { getErrorStatus } from './scripts/ssrErrorHandler.js';
|
|
5
6
|
import type { Render } from './scripts/types.js';
|
|
6
7
|
import type { ServerProps } from './spouts/types.js';
|
|
7
8
|
|
|
@@ -21,25 +22,28 @@ export default function laySpouts(
|
|
|
21
22
|
const { app } = await spouts({ clientManifest, req, res, nonce });
|
|
22
23
|
|
|
23
24
|
let didError = false;
|
|
25
|
+
let lastError: unknown;
|
|
24
26
|
const { pipe, abort } = reactRender(app, {
|
|
25
27
|
nonce,
|
|
26
28
|
//bootstrapScripts: assets.filter(asset => asset.endsWith('.js')),
|
|
27
29
|
onShellReady() {
|
|
28
30
|
//managers.forEach(manager => manager.cleanup());
|
|
29
31
|
// If something errored before we started streaming, we set the error code appropriately.
|
|
30
|
-
res.statusCode = didError ?
|
|
32
|
+
res.statusCode = didError ? getErrorStatus(lastError) : 200;
|
|
31
33
|
res.setHeader('Content-type', 'text/html');
|
|
32
34
|
pipe(res);
|
|
33
35
|
},
|
|
34
|
-
onShellError() {
|
|
36
|
+
onShellError(e: unknown) {
|
|
35
37
|
didError = true;
|
|
36
|
-
|
|
38
|
+
lastError = e;
|
|
39
|
+
res.statusCode = getErrorStatus(e);
|
|
37
40
|
pipe(res);
|
|
38
41
|
},
|
|
39
|
-
onError(e:
|
|
42
|
+
onError(e: unknown) {
|
|
40
43
|
didError = true;
|
|
44
|
+
lastError = e;
|
|
41
45
|
console.error(e);
|
|
42
|
-
res.statusCode =
|
|
46
|
+
res.statusCode = getErrorStatus(e);
|
|
43
47
|
//pipe(res); Removing this avoids, "React currently only supports piping to one writable stream."
|
|
44
48
|
if (onError) onError(e);
|
|
45
49
|
},
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import {
|
|
2
|
+
escapeHtml,
|
|
3
|
+
getErrorStatus,
|
|
4
|
+
renderErrorPage,
|
|
5
|
+
} from '../ssrErrorHandler';
|
|
6
|
+
|
|
7
|
+
describe('ssrErrorHandler', () => {
|
|
8
|
+
describe('getErrorStatus', () => {
|
|
9
|
+
it('should return 500 for null', () => {
|
|
10
|
+
expect(getErrorStatus(null)).toBe(500);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should return 500 for undefined', () => {
|
|
14
|
+
expect(getErrorStatus(undefined)).toBe(500);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should return 500 for plain Error without status', () => {
|
|
18
|
+
expect(getErrorStatus(new Error('test'))).toBe(500);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should return 500 for string error', () => {
|
|
22
|
+
expect(getErrorStatus('something went wrong')).toBe(500);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should return 500 for number error', () => {
|
|
26
|
+
expect(getErrorStatus(42)).toBe(500);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should extract numeric status from error object', () => {
|
|
30
|
+
expect(getErrorStatus({ status: 404, message: 'Not Found' })).toBe(404);
|
|
31
|
+
expect(getErrorStatus({ status: 429, message: 'Rate Limited' })).toBe(
|
|
32
|
+
429,
|
|
33
|
+
);
|
|
34
|
+
expect(
|
|
35
|
+
getErrorStatus({ status: 503, message: 'Service Unavailable' }),
|
|
36
|
+
).toBe(503);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should extract string status from error object', () => {
|
|
40
|
+
expect(getErrorStatus({ status: '404', message: 'Not Found' })).toBe(404);
|
|
41
|
+
expect(getErrorStatus({ status: '500', message: 'Error' })).toBe(500);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should return 500 for invalid numeric status codes', () => {
|
|
45
|
+
expect(getErrorStatus({ status: 99 })).toBe(500); // too low
|
|
46
|
+
expect(getErrorStatus({ status: 600 })).toBe(500); // too high
|
|
47
|
+
expect(getErrorStatus({ status: -1 })).toBe(500); // negative
|
|
48
|
+
expect(getErrorStatus({ status: 0 })).toBe(500); // zero
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return 500 for invalid string status codes', () => {
|
|
52
|
+
expect(getErrorStatus({ status: '99' })).toBe(500); // too low
|
|
53
|
+
expect(getErrorStatus({ status: '600' })).toBe(500); // too high
|
|
54
|
+
expect(getErrorStatus({ status: 'abc' })).toBe(500); // not a number
|
|
55
|
+
expect(getErrorStatus({ status: '' })).toBe(500); // empty string
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should return 500 for non-number/string status values', () => {
|
|
59
|
+
expect(getErrorStatus({ status: null })).toBe(500);
|
|
60
|
+
expect(getErrorStatus({ status: undefined })).toBe(500);
|
|
61
|
+
expect(getErrorStatus({ status: {} })).toBe(500);
|
|
62
|
+
expect(getErrorStatus({ status: [] })).toBe(500);
|
|
63
|
+
expect(getErrorStatus({ status: true })).toBe(500);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should work with Error objects that have status property', () => {
|
|
67
|
+
const error = new Error('Rate Limited') as Error & { status: number };
|
|
68
|
+
error.status = 429;
|
|
69
|
+
expect(getErrorStatus(error)).toBe(429);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should handle boundary values', () => {
|
|
73
|
+
expect(getErrorStatus({ status: 100 })).toBe(100); // min valid
|
|
74
|
+
expect(getErrorStatus({ status: 599 })).toBe(599); // max valid
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('escapeHtml', () => {
|
|
79
|
+
it('should escape ampersands', () => {
|
|
80
|
+
expect(escapeHtml('foo & bar')).toBe('foo & bar');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should escape less than', () => {
|
|
84
|
+
expect(escapeHtml('<script>')).toBe('<script>');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should escape greater than', () => {
|
|
88
|
+
expect(escapeHtml('a > b')).toBe('a > b');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should escape double quotes', () => {
|
|
92
|
+
expect(escapeHtml('say "hello"')).toBe('say "hello"');
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should escape single quotes', () => {
|
|
96
|
+
expect(escapeHtml("it's")).toBe('it's');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should escape multiple special characters', () => {
|
|
100
|
+
expect(escapeHtml('<script>alert("xss")</script>')).toBe(
|
|
101
|
+
'<script>alert("xss")</script>',
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should return empty string for empty input', () => {
|
|
106
|
+
expect(escapeHtml('')).toBe('');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should not modify strings without special characters', () => {
|
|
110
|
+
expect(escapeHtml('hello world')).toBe('hello world');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('renderErrorPage', () => {
|
|
115
|
+
it('should render basic error page with status code', () => {
|
|
116
|
+
const html = renderErrorPage(new Error('Test error'), '/test', 500);
|
|
117
|
+
|
|
118
|
+
expect(html).toContain('<!DOCTYPE html>');
|
|
119
|
+
expect(html).toContain('<title>500 - Server Error</title>');
|
|
120
|
+
expect(html).toContain('<h1>500 - Server Error</h1>');
|
|
121
|
+
expect(html).toContain('Test error');
|
|
122
|
+
expect(html).toContain('/test');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should render different status codes', () => {
|
|
126
|
+
const html404 = renderErrorPage({ message: 'Not Found' }, '/page', 404);
|
|
127
|
+
const html429 = renderErrorPage({ message: 'Rate Limited' }, '/api', 429);
|
|
128
|
+
|
|
129
|
+
expect(html404).toContain('<title>404 - Server Error</title>');
|
|
130
|
+
expect(html404).toContain('<h1>404 - Server Error</h1>');
|
|
131
|
+
expect(html429).toContain('<title>429 - Server Error</title>');
|
|
132
|
+
expect(html429).toContain('<h1>429 - Server Error</h1>');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should escape URL in output', () => {
|
|
136
|
+
const html = renderErrorPage(
|
|
137
|
+
new Error('error'),
|
|
138
|
+
'/test?foo=<script>',
|
|
139
|
+
500,
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
expect(html).toContain('<script>');
|
|
143
|
+
expect(html).not.toContain('<script>');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should escape error message in output', () => {
|
|
147
|
+
const html = renderErrorPage(
|
|
148
|
+
new Error('<script>alert("xss")</script>'),
|
|
149
|
+
'/test',
|
|
150
|
+
500,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
expect(html).toContain('<script>');
|
|
154
|
+
expect(html).not.toContain('<script>alert');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should show stack trace when showStack is true', () => {
|
|
158
|
+
const error = new Error('Test error');
|
|
159
|
+
const html = renderErrorPage(error, '/test', 500, { showStack: true });
|
|
160
|
+
|
|
161
|
+
expect(html).toContain('<pre class="stack">');
|
|
162
|
+
expect(html).toContain('Error: Test error');
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should hide stack trace when showStack is false', () => {
|
|
166
|
+
const error = new Error('Test error');
|
|
167
|
+
const html = renderErrorPage(error, '/test', 500, { showStack: false });
|
|
168
|
+
|
|
169
|
+
expect(html).not.toContain('<pre class="stack">');
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('should hide stack trace by default', () => {
|
|
173
|
+
const error = new Error('Test error');
|
|
174
|
+
const html = renderErrorPage(error, '/test', 500);
|
|
175
|
+
|
|
176
|
+
expect(html).not.toContain('<pre class="stack">');
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should show badge when provided', () => {
|
|
180
|
+
const html = renderErrorPage(new Error('error'), '/test', 500, {
|
|
181
|
+
badge: 'DEV MODE',
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
expect(html).toContain('<span class="badge">DEV MODE</span>');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should not show badge when not provided', () => {
|
|
188
|
+
const html = renderErrorPage(new Error('error'), '/test', 500);
|
|
189
|
+
|
|
190
|
+
expect(html).not.toContain('class="badge"');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should show hint when provided', () => {
|
|
194
|
+
const html = renderErrorPage(new Error('error'), '/test', 500, {
|
|
195
|
+
hint: 'Try again later',
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
expect(html).toContain('<p class="hint">Try again later</p>');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('should not show hint when not provided', () => {
|
|
202
|
+
const html = renderErrorPage(new Error('error'), '/test', 500);
|
|
203
|
+
|
|
204
|
+
expect(html).not.toContain('class="hint"');
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('should escape badge text', () => {
|
|
208
|
+
const html = renderErrorPage(new Error('error'), '/test', 500, {
|
|
209
|
+
badge: '<script>alert("xss")</script>',
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
expect(html).toContain('<script>');
|
|
213
|
+
expect(html).not.toContain('<script>alert');
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('should escape hint text', () => {
|
|
217
|
+
const html = renderErrorPage(new Error('error'), '/test', 500, {
|
|
218
|
+
hint: '<script>alert("xss")</script>',
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
expect(html).toContain('<script>');
|
|
222
|
+
expect(html).not.toContain('<script>alert');
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should handle string errors', () => {
|
|
226
|
+
const html = renderErrorPage('Something went wrong', '/test', 500);
|
|
227
|
+
|
|
228
|
+
expect(html).toContain('Something went wrong');
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should handle object errors without message', () => {
|
|
232
|
+
const html = renderErrorPage({ code: 'ERR_001' }, '/test', 500);
|
|
233
|
+
|
|
234
|
+
expect(html).toContain('[object Object]');
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
it('should include retry link with correct URL', () => {
|
|
238
|
+
const html = renderErrorPage(new Error('error'), '/my-page', 500);
|
|
239
|
+
|
|
240
|
+
expect(html).toContain('<a href="/my-page">Retry</a>');
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should escape retry link URL', () => {
|
|
244
|
+
const html = renderErrorPage(new Error('error'), '/page?a=1&b=2', 500);
|
|
245
|
+
|
|
246
|
+
expect(html).toContain('href="/page?a=1&b=2"');
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
package/src/scripts/serve.ts
CHANGED
|
@@ -10,12 +10,12 @@ import diskFs from 'fs';
|
|
|
10
10
|
import { Server, IncomingMessage, ServerResponse } from 'http';
|
|
11
11
|
import ora from 'ora';
|
|
12
12
|
import path from 'path';
|
|
13
|
-
import { promisify } from 'util';
|
|
14
13
|
import webpack from 'webpack';
|
|
15
14
|
|
|
16
15
|
import 'cross-fetch/dist/node-polyfill.js';
|
|
17
16
|
import getProxyMiddlewares from './getProxyMiddlewares.js';
|
|
18
17
|
import { getWebpackConfig } from './getWebpackConfig.js';
|
|
18
|
+
import { getErrorStatus, renderErrorPage } from './ssrErrorHandler.js';
|
|
19
19
|
import { Render } from './types.js';
|
|
20
20
|
|
|
21
21
|
// run directly from node
|
|
@@ -45,7 +45,6 @@ export default async function serve(
|
|
|
45
45
|
webpackConfig({}, { mode: 'production' }),
|
|
46
46
|
);
|
|
47
47
|
|
|
48
|
-
const readFile = promisify(diskFs.readFile);
|
|
49
48
|
let server: Server | undefined;
|
|
50
49
|
|
|
51
50
|
function handleErrors<
|
|
@@ -57,12 +56,25 @@ export default async function serve(
|
|
|
57
56
|
return async function (
|
|
58
57
|
req: Request | IncomingMessage,
|
|
59
58
|
res: Response | ServerResponse,
|
|
60
|
-
|
|
59
|
+
_next: NextFunction,
|
|
61
60
|
) {
|
|
62
61
|
try {
|
|
63
62
|
return await fn(req, res);
|
|
64
|
-
} catch (
|
|
65
|
-
|
|
63
|
+
} catch (error: unknown) {
|
|
64
|
+
console.error('SSR rendering error:', error);
|
|
65
|
+
|
|
66
|
+
// Return error response with status from error if available
|
|
67
|
+
const expressRes = res as express.Response;
|
|
68
|
+
if (!expressRes.headersSent) {
|
|
69
|
+
const statusCode = getErrorStatus(error);
|
|
70
|
+
expressRes.status(statusCode);
|
|
71
|
+
expressRes.setHeader('Content-Type', 'text/html');
|
|
72
|
+
expressRes.send(
|
|
73
|
+
renderErrorPage(error, req.url ?? '/', statusCode, {
|
|
74
|
+
showStack: process.env.NODE_ENV !== 'production',
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
}
|
|
66
78
|
}
|
|
67
79
|
};
|
|
68
80
|
}
|
|
@@ -104,7 +116,7 @@ export default async function serve(
|
|
|
104
116
|
) {
|
|
105
117
|
try {
|
|
106
118
|
res.sendFile(assetPath);
|
|
107
|
-
} catch (
|
|
119
|
+
} catch (_e) {
|
|
108
120
|
return next();
|
|
109
121
|
}
|
|
110
122
|
} else {
|