@visulima/error-handler 2.0.0-alpha.30 → 2.0.0-alpha.32

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +38 -23
  3. package/dist/error-handler/fetch-utils.d.ts +3 -0
  4. package/dist/error-handler/fetch-utils.js +1 -0
  5. package/dist/error-handler/html-error-handler.d.ts +44 -3
  6. package/dist/error-handler/html-error-handler.js +50 -10
  7. package/dist/error-handler/json-error-handler.d.ts +1 -1
  8. package/dist/error-handler/json-error-handler.js +1 -1
  9. package/dist/error-handler/jsonapi-error-handler.d.ts +1 -1
  10. package/dist/error-handler/jsonapi-error-handler.js +1 -1
  11. package/dist/error-handler/jsonp-error-handler.d.ts +1 -1
  12. package/dist/error-handler/jsonp-error-handler.js +1 -1
  13. package/dist/error-handler/problem-error-handler.d.ts +1 -1
  14. package/dist/error-handler/problem-error-handler.js +1 -1
  15. package/dist/error-handler/text-error-handler.d.ts +1 -1
  16. package/dist/error-handler/text-error-handler.js +2 -2
  17. package/dist/error-handler/xml-error-handler.d.ts +1 -1
  18. package/dist/error-handler/xml-error-handler.js +1 -1
  19. package/dist/handler/cli-handler.js +2 -2
  20. package/dist/handler/http/create-error-middleware.d.ts +31 -0
  21. package/dist/handler/http/create-error-middleware.js +1 -0
  22. package/dist/handler/http/fetch-handler.d.ts +2 -1
  23. package/dist/handler/http/fetch-handler.js +1 -1
  24. package/dist/handler/http/node-handler.d.ts +2 -1
  25. package/dist/handler/http/node-handler.js +1 -1
  26. package/dist/index.d.ts +12 -4
  27. package/dist/index.js +1 -1
  28. package/dist/packem_shared/add-status-code-to-response-DwELM1q2.js +1 -0
  29. package/dist/packem_shared/cliHandler-BDHu9b4t.js +1 -0
  30. package/dist/packem_shared/createNegotiatedErrorHandler-CcWOSpO5.js +1 -0
  31. package/dist/packem_shared/extractStatusCode-D0UOgNnr.js +1 -0
  32. package/dist/packem_shared/fetchCreateNegotiatedErrorHandler-D9YQ8pOH.js +1 -0
  33. package/dist/packem_shared/fetchHtmlErrorHandler-Cu50Zu5a.js +1 -0
  34. package/dist/packem_shared/get-file-source-By3_8e1o.js +1 -0
  35. package/dist/packem_shared/send-json-fz8r6NBW.js +1 -0
  36. package/dist/packem_shared/sendFetchJson-BNmfrMYp.js +1 -0
  37. package/dist/packem_shared/set-error-headers-g9hns3cZ.js +1 -0
  38. package/dist/packem_shared/{types.d-C763gSYq.d.ts → types.d-Btzbxdod.d.ts} +1 -1
  39. package/package.json +11 -3
  40. package/dist/packem_shared/add-status-code-to-response-Dc6Pvpeh.js +0 -1
  41. package/dist/packem_shared/cliHandler-CeQ8tsGj.js +0 -1
  42. package/dist/packem_shared/createNegotiatedErrorHandler-DlEHBPFw.js +0 -1
  43. package/dist/packem_shared/send-json-DfdjS9Xp.js +0 -1
  44. package/dist/packem_shared/set-error-headers-DT9rVGtW.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,36 @@
1
+ ## @visulima/error-handler [2.0.0-alpha.32](https://github.com/visulima/visulima/compare/@visulima/error-handler@2.0.0-alpha.31...@visulima/error-handler@2.0.0-alpha.32) (2026-06-13)
2
+
3
+ ### Features
4
+
5
+ * **error-handler:** add youch-style dev HTML error inspector ([a06ff59](https://github.com/visulima/visulima/commit/a06ff59c919cf72bc70f5a60a8b7346a3ab68d76))
6
+
7
+ ### Bug Fixes
8
+
9
+ * **error-handler:** escape line separators in JSONP body regex ([3e9c4ab](https://github.com/visulima/visulima/commit/3e9c4ab05ba7e66c16c088a534a3303ba8b8f7e2))
10
+ * **error-handler:** harden jsonp output and stop leaking stack traces ([4559aa8](https://github.com/visulima/visulima/commit/4559aa89bc102f5e2be13f9b61e77f9e1f42b5ca))
11
+ * **error-handler:** harden optional-chain on NODE_ENV read for edge ([4883d90](https://github.com/visulima/visulima/commit/4883d907da3edfc93d1f4b151fe415f57dc606b4))
12
+
13
+ ### Performance Improvements
14
+
15
+ * **error-handler:** lazy-load jsonapi and xml deps ([ecd4fa6](https://github.com/visulima/visulima/commit/ecd4fa6478ee360e4e7a4229bcb56b36f0dd4a8b))
16
+
17
+ ### Tests
18
+
19
+ * tighten error-handler and tabular assertions ([cb72e51](https://github.com/visulima/visulima/commit/cb72e51e9d579fef5c4aef01af8622493bfe30f6))
20
+
21
+
22
+ ### Dependencies
23
+
24
+ * **@visulima/boxen:** upgraded to 3.0.0-alpha.14
25
+ * **@visulima/error:** upgraded to 6.0.0-alpha.33
26
+
27
+ ## @visulima/error-handler [2.0.0-alpha.31](https://github.com/visulima/visulima/compare/@visulima/error-handler@2.0.0-alpha.30...@visulima/error-handler@2.0.0-alpha.31) (2026-06-04)
28
+
29
+
30
+ ### Dependencies
31
+
32
+ * **@visulima/boxen:** upgraded to 3.0.0-alpha.13
33
+
1
34
  ## @visulima/error-handler [2.0.0-alpha.30](https://github.com/visulima/visulima/compare/@visulima/error-handler@2.0.0-alpha.29...@visulima/error-handler@2.0.0-alpha.30) (2026-06-04)
2
35
 
3
36
  ### Bug Fixes
package/README.md CHANGED
@@ -61,6 +61,9 @@ pnpm add @visulima/error-handler
61
61
 
62
62
  ### Node.js HTTP Server
63
63
 
64
+ `httpHandler(error, options?)` is synchronous and returns the `(req, res)`
65
+ request handler — there is no need to `await` it.
66
+
64
67
  ```ts
65
68
  import { createServer } from "node:http";
66
69
  import httpHandler from "@visulima/error-handler/handler/http/node";
@@ -70,10 +73,10 @@ const server = createServer(async (req, res) => {
70
73
  // your app logic...
71
74
  throw new Error("Boom!");
72
75
  } catch (error) {
73
- const handler = await httpHandler(error as Error, {
76
+ const handler = httpHandler(error as Error, {
74
77
  showTrace: process.env.NODE_ENV !== "production",
75
78
  });
76
- return handler(req, res);
79
+ await handler(req, res);
77
80
  }
78
81
  });
79
82
 
@@ -82,27 +85,36 @@ server.listen(3000);
82
85
 
83
86
  ### Express Setup
84
87
 
88
+ Prefer the one-line error middleware instead of wrapping every route in
89
+ `try/catch`. Register `createErrorMiddleware` once and Express will route any
90
+ error (thrown synchronously or passed to `next(error)`) through it:
91
+
85
92
  ```ts
86
93
  import express from "express";
87
- import httpHandler from "@visulima/error-handler/handler/http/node";
94
+ import { createErrorMiddleware } from "@visulima/error-handler";
88
95
 
89
96
  const app = express();
90
97
  app.use(express.json());
91
98
 
92
- app.get("/", async (req, res) => {
93
- try {
94
- throw new Error("Example error");
95
- } catch (error) {
96
- const handler = await httpHandler(error as Error, {
97
- showTrace: process.env.NODE_ENV !== "production",
98
- });
99
- return handler(req, res);
100
- }
99
+ app.get("/", () => {
100
+ throw new Error("Example error");
101
101
  });
102
102
 
103
+ // Must be registered last, after your routes.
104
+ app.use(
105
+ createErrorMiddleware({
106
+ showTrace: process.env.NODE_ENV !== "production",
107
+ }),
108
+ );
109
+
103
110
  app.listen(3000);
104
111
  ```
105
112
 
113
+ > `createErrorMiddleware` is also available as a subpath import:
114
+ > `import createErrorMiddleware from "@visulima/error-handler/handler/middleware";`.
115
+ > If the response has already started streaming (`res.headersSent`) it delegates
116
+ > to `next(error)` so it never double-writes.
117
+
106
118
  ### Hono (Fetch Runtime)
107
119
 
108
120
  ```ts
@@ -118,7 +130,7 @@ app.get("/error", () => {
118
130
  });
119
131
 
120
132
  app.onError(async (error, c) => {
121
- const handler = await fetchHandler(error as Error, {
133
+ const handler = fetchHandler(error as Error, {
122
134
  showTrace: process.env.NODE_ENV !== "production",
123
135
  });
124
136
  return handler(c.req.raw);
@@ -138,7 +150,7 @@ export default {
138
150
  try {
139
151
  throw new Error("Boom");
140
152
  } catch (error) {
141
- const handler = await fetchHandler(error as Error, {
153
+ const handler = fetchHandler(error as Error, {
142
154
  showTrace: process.env.NODE_ENV !== "production",
143
155
  });
144
156
  return handler(request);
@@ -155,7 +167,7 @@ Deno.serve(async (request: Request) => {
155
167
  try {
156
168
  throw new Error("Boom");
157
169
  } catch (error) {
158
- const handler = await fetchHandler(error as Error, {
170
+ const handler = fetchHandler(error as Error, {
159
171
  showTrace: process.env.NODE_ENV !== "production",
160
172
  });
161
173
  return handler(request);
@@ -181,7 +193,7 @@ Add custom handlers for specific content types:
181
193
  ```ts
182
194
  import httpHandler from "@visulima/error-handler/handler/http/node";
183
195
 
184
- const handler = await httpHandler(error, {
196
+ const handler = httpHandler(error, {
185
197
  extraHandlers: [
186
198
  {
187
199
  regex: /application\/yaml/u,
@@ -196,9 +208,11 @@ const handler = await httpHandler(error, {
196
208
 
197
209
  ## API
198
210
 
199
- ### httpHandler(error, options?) => Promise<(req, res) => Promise<void>>
211
+ ### httpHandler(error, options?) => (req, res) => Promise<void>
200
212
 
201
213
  Node.js HTTP handler for Express, Connect, Fastify, Koa, and similar frameworks.
214
+ The factory is synchronous and returns the `(req, res)` request handler — do not
215
+ `await` it.
202
216
 
203
217
  **Parameters:**
204
218
 
@@ -207,15 +221,16 @@ Node.js HTTP handler for Express, Connect, Fastify, Koa, and similar frameworks.
207
221
 
208
222
  **Options:**
209
223
 
210
- - `showTrace?: boolean` - Include stack trace in responses (default: `true`)
224
+ - `showTrace?: boolean` - Include stack trace in responses (default: `process.env.NODE_ENV !== "production"`)
211
225
  - `extraHandlers?: ErrorHandlers` - Custom handlers for specific Accept headers
212
226
  - `errorPage?: string | ((params) => string | Promise<string>)` - Custom HTML error page
213
227
  - `cspNonce?: string` - Content Security Policy nonce for inline styles
214
228
  - `onError?: (error, request, response) => void | Promise<void>` - Callback for custom error logging
215
229
 
216
- ### fetchHandler(error, options?) => Promise<(request) => Promise<Response>>
230
+ ### fetchHandler(error, options?) => (request) => Promise<Response>
217
231
 
218
232
  Fetch API handler for Cloudflare Workers, Deno, Bun, and other Fetch-based runtimes.
233
+ Like `httpHandler`, the factory is synchronous — do not `await` it.
219
234
 
220
235
  **Parameters:**
221
236
 
@@ -267,7 +282,7 @@ const server = createServer(async (req, res) => {
267
282
  try {
268
283
  throw new Error("Test error");
269
284
  } catch (error) {
270
- const handler = await httpHandler(error as Error, {
285
+ const handler = httpHandler(error as Error, {
271
286
  showTrace: process.env.NODE_ENV !== "production",
272
287
  });
273
288
  return handler(req, res);
@@ -280,7 +295,7 @@ const server = createServer(async (req, res) => {
280
295
  ```ts
281
296
  import httpHandler from "@visulima/error-handler/handler/http/node";
282
297
 
283
- const handler = await httpHandler(error, {
298
+ const handler = httpHandler(error, {
284
299
  errorPage: ({ error, statusCode }) =>
285
300
  `<!DOCTYPE html>
286
301
  <html>
@@ -299,7 +314,7 @@ const handler = await httpHandler(error, {
299
314
  ```ts
300
315
  import httpHandler from "@visulima/error-handler/handler/http/node";
301
316
 
302
- const handler = await httpHandler(error, {
317
+ const handler = httpHandler(error, {
303
318
  cspNonce: "nonce-abc123", // Will be added to <style> tags
304
319
  showTrace: process.env.NODE_ENV !== "production",
305
320
  });
@@ -310,7 +325,7 @@ const handler = await httpHandler(error, {
310
325
  ```ts
311
326
  import httpHandler from "@visulima/error-handler/handler/http/node";
312
327
 
313
- const handler = await httpHandler(error, {
328
+ const handler = httpHandler(error, {
314
329
  onError: (error, request, response) => {
315
330
  // Log to your preferred logging service
316
331
  console.error(`[${new Date().toISOString()}] ${request.method} ${request.url} - ${error.message}`);
@@ -0,0 +1,3 @@
1
+ declare const extractStatusCode: (error: unknown, fallback?: number) => number;
2
+ declare const sendFetchJson: (jsonBody: unknown, status: number, contentType?: string) => Response;
3
+ export { extractStatusCode, sendFetchJson };
@@ -0,0 +1 @@
1
+ import{default as a}from"../packem_shared/extractStatusCode-D0UOgNnr.js";import{default as r}from"../packem_shared/sendFetchJson-BNmfrMYp.js";export{a as extractStatusCode,r as sendFetchJson};
@@ -1,6 +1,48 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { a as ErrorHandler } from "../packem_shared/types.d-C763gSYq.js";
3
- type HtmlErrorHandlerOptions = {
2
+ import { E as ErrorHandler } from "../packem_shared/types.d-Btzbxdod.js";
3
+ import { SolutionFinder } from '@visulima/error/solution';
4
+ /**
5
+ * Options that influence how the development HTML error inspector is rendered.
6
+ */
7
+ type HtmlErrorInspectorOptions = {
8
+ /**
9
+ * Permit the underlying code-frame reader to fetch `http(s):`/`data:`
10
+ * stack-frame URLs over the network. Off by default to avoid an SSRF
11
+ * surface; only enable when frame URLs are known to be trusted.
12
+ * @default false
13
+ */
14
+ allowRemoteSources?: boolean;
15
+ /**
16
+ * Number of source lines rendered above the offending line in the code frame.
17
+ * @default 4
18
+ */
19
+ linesAbove?: number;
20
+ /**
21
+ * Number of source lines rendered below the offending line in the code frame.
22
+ * @default 4
23
+ */
24
+ linesBelow?: number;
25
+ /**
26
+ * Extra solution finders to run before the built-in rule-based and
27
+ * error-hint finders. The first finder (sorted by descending priority)
28
+ * that returns a hint wins. Matches the CLI handler's behaviour.
29
+ */
30
+ solutionFinders?: SolutionFinder[];
31
+ };
32
+ /**
33
+ * Builds the inner HTML for the development error inspector: error name +
34
+ * message, a syntax-free code frame for the offending source line, the parsed
35
+ * stack trace (one entry per cause), and a possible-solution hint.
36
+ *
37
+ * All dynamic content is HTML-escaped. This is intended for development output
38
+ * only — callers must keep it off the production path so stack/source are not
39
+ * leaked.
40
+ * @param error The error to render.
41
+ * @param options Inspector rendering options.
42
+ * @returns The escaped inner HTML for the inspector.
43
+ */
44
+ declare const htmlErrorHandler: (options?: HtmlErrorHandlerOptions) => ErrorHandler;
45
+ type HtmlErrorHandlerOptions = HtmlErrorInspectorOptions & {
4
46
  cspNonce?: string;
5
47
  errorPage?: string | ((parameters: {
6
48
  error: Error;
@@ -10,5 +52,4 @@ type HtmlErrorHandlerOptions = {
10
52
  statusCode: number;
11
53
  }) => string | Promise<string>);
12
54
  };
13
- declare const htmlErrorHandler: (options?: HtmlErrorHandlerOptions) => ErrorHandler;
14
55
  export { HtmlErrorHandlerOptions, htmlErrorHandler };
@@ -1,35 +1,75 @@
1
- var l=Object.defineProperty;var n=(e,r)=>l(e,"name",{value:r,configurable:!0});import{getReasonPhrase as c}from"http-status-codes";import{p as m}from"../packem_shared/add-status-code-to-response-Dc6Pvpeh.js";var g=Object.defineProperty,s=n((e,r)=>g(e,"name",{value:r,configurable:!0}),"n");const x=s((e={})=>async(r,d,t)=>{m(t,r),t.setHeader("content-type","text/html; charset=utf-8");const o=c(t.statusCode)||"Error",a=e.cspNonce?` nonce="${e.cspNonce}"`:"";if(e.errorPage){const i=typeof e.errorPage=="function"?await e.errorPage({error:r,reasonPhrase:o,request:d,response:t,statusCode:t.statusCode}):e.errorPage;if(i){t.end(i);return}}t.end(String.raw`<!DOCTYPE html>
1
+ import{getReasonPhrase as x}from"http-status-codes";import{a as u}from"../packem_shared/add-status-code-to-response-DwELM1q2.js";import{codeFrame as v}from"@visulima/error/code-frame";import{getErrorCauses as w}from"@visulima/error/error";import{ruleBasedFinder as k,errorHintFinder as S}from"@visulima/error/solution";import{parseStacktrace as $}from"@visulima/error/stacktrace";import{h as j,a as C}from"../packem_shared/get-file-source-By3_8e1o.js";const A=/^\s*#+\s*/,l=e=>e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;"),z=e=>e.replace(A,"").trim(),M=async(e,r,t,o)=>{const n=[...r,k,S].toSorted((i,s)=>i.priority-s.priority);for(const i of n){if(typeof i.handle!="function")continue;const s=await i.handle(e,{file:t.file??"",language:C(t.file??""),line:t.line??0,snippet:o});if(s)return s}},N=e=>{if(!e.file)return l(e.raw);let r=l(e.file);return e.line!==void 0&&(r+=`:${String(e.line)}`,e.column!==void 0&&(r+=`:${String(e.column)}`)),r},E=e=>{if(e.length===0)return"";const r=e.map(t=>{const o=l(t.methodName??"<anonymous>"),n=N(t);return String.raw`<li class="vis-frame"><span class="vis-frame-method">${o}</span><span class="vis-frame-loc">${n}</span></li>`}).join("");return String.raw`<ol class="vis-frames">${r}</ol>`},B=e=>{if(!e)return"";const r=l(z(e.header??"A possible solution to this error")),t=l(e.body);return String.raw`
2
+ <section class="vis-card vis-solution">
3
+ <h2 class="vis-card-title">💡 ${r}</h2>
4
+ <pre class="vis-solution-body">${t}</pre>
5
+ </section>`},F=async(e,r={})=>{const{allowRemoteSources:t=!1,linesAbove:o=4,linesBelow:n=4,solutionFinders:i=[]}=r,s=w(e)[0]??e,c=$(s),a=c.find(d=>!!d.file)??c[0]??{};let m="",g="";if(a.file&&a.line!==void 0){const d=await j(a.file,{allowRemote:t});if(d){g=d;const h=v(d,{start:{column:a.column,line:a.line}},{linesAbove:o,linesBelow:n});m=String.raw`
6
+ <section class="vis-card">
7
+ <h2 class="vis-card-title">${l(`${a.file}:${String(a.line)}`)}</h2>
8
+ <pre class="vis-codeframe"><code>${l(h)}</code></pre>
9
+ </section>`}}const p=await M(e,i,a,g),f=l(e.name||"Error"),b=l(e.message||""),y=c.length>0?String.raw`
10
+ <section class="vis-card">
11
+ <h2 class="vis-card-title">Stack trace</h2>
12
+ ${E(c)}
13
+ </section>`:"";return String.raw`
14
+ <div class="vis-inspector max-w-6xl mx-auto px-6 mt-8">
15
+ <section class="vis-card vis-headline">
16
+ <span class="vis-error-name">${f}</span>
17
+ <p class="vis-error-message">${b}</p>
18
+ </section>${m}${B(p)}${y}
19
+ </div>`},I=String.raw`
20
+ .vis-inspector { display: flex; flex-direction: column; gap: 1rem; }
21
+ .vis-card { background: #fff; border-radius: .5rem; box-shadow: 0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06); overflow: hidden; }
22
+ .vis-card-title { margin: 0; padding: .75rem 1.5rem; font-size: .8125rem; font-weight: 600; color: #1a202c; border-bottom: 1px solid #edf2f7; word-break: break-word; }
23
+ .vis-headline { padding: 1rem 1.5rem; }
24
+ .vis-error-name { display: inline-block; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: #e53e3e; }
25
+ .vis-error-message { margin: .5rem 0 0; font-size: 1rem; color: #1a202c; word-break: break-word; }
26
+ .vis-codeframe, .vis-solution-body { margin: 0; padding: 1rem 1.5rem; font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: .8125rem; line-height: 1.6; color: #2d3748; white-space: pre; overflow-x: auto; }
27
+ .vis-solution-body { white-space: pre-wrap; word-break: break-word; }
28
+ .vis-frames { margin: 0; padding: 0; list-style: none; }
29
+ .vis-frame { display: flex; flex-direction: column; padding: .5rem 1.5rem; border-bottom: 1px solid #edf2f7; font-family: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-size: .8125rem; }
30
+ .vis-frame:last-child { border-bottom: 0; }
31
+ .vis-frame-method { color: #1a202c; font-weight: 600; }
32
+ .vis-frame-loc { color: #718096; word-break: break-word; }
33
+ @media (prefers-color-scheme: dark) {
34
+ .vis-card { background: #2d3748; }
35
+ .vis-card-title { color: #fff; border-bottom-color: #4a5568; }
36
+ .vis-error-message, .vis-codeframe, .vis-solution-body, .vis-frame-method { color: #e2e8f0; }
37
+ .vis-frame { border-bottom-color: #4a5568; }
38
+ .vis-frame-loc { color: #a0aec0; }
39
+ }`,D=(e={})=>async(r,t,o)=>{u(o,r),o.setHeader("content-type","text/html; charset=utf-8");const n=x(o.statusCode)||"Error",i=e.cspNonce?` nonce="${e.cspNonce}"`:"",{expose:s}=r,c=s?await F(r,{allowRemoteSources:e.allowRemoteSources,linesAbove:e.linesAbove,linesBelow:e.linesBelow,solutionFinders:e.solutionFinders}):"";if(e.errorPage){const a=typeof e.errorPage=="function"?await e.errorPage({error:r,reasonPhrase:n,request:t,response:o,statusCode:o.statusCode}):e.errorPage;if(a){o.end(a);return}}o.end(String.raw`<!DOCTYPE html>
2
40
  <html lang="en">
3
41
  <head>
4
42
  <meta charset="utf-8">
5
43
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
44
 
7
- <title>${o}</title>
45
+ <title>${n}</title>
8
46
  <meta name="robots" content="noindex">
9
47
 
10
- <style${a}>
48
+ <style${i}>
11
49
  /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}code{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-r{border-right-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-xl{max-width:36rem}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.uppercase{text-transform:uppercase}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tracking-wider{letter-spacing:.05em}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}}
12
50
  </style>
13
51
 
14
- <style${a}>
52
+ <style${i}>
15
53
  body {
16
54
  font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
17
55
  }
18
- </style>
56
+ </style>${s?`
57
+ <style${i}>${I}
58
+ </style>`:""}
19
59
  </head>
20
60
  <body class="antialiased">
21
- <div class="relative flex items-center justify-center min-h-screen bg-gray-100 dark:bg-gray-900">
61
+ <div class="relative flex items-center justify-center ${s?"pt-8":"min-h-screen"} bg-gray-100 dark:bg-gray-900">
22
62
  <div class="max-w-xl mx-auto sm:px-6 lg:px-8">
23
63
  <div class="flex items-center justify-center">
24
64
  <div class="px-6 text-lg text-gray-600 dark:text-gray-400 border-r border-gray-400 dark:border-gray-700 tracking-wider font-semibold">
25
- ${t.statusCode}
65
+ ${o.statusCode}
26
66
  </div>
27
67
 
28
68
  <div class="ml-4 text-lg text-gray-600 dark:text-gray-400 uppercase tracking-wider">
29
- ${o}
69
+ ${n}
30
70
  </div>
31
71
  </div>
32
72
  </div>
33
- </div>
73
+ </div>${c}
34
74
  </body>
35
- </html>`)},"htmlErrorHandler");export{x as htmlErrorHandler};
75
+ </html>`)};export{D as htmlErrorHandler};
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { a as ErrorHandler } from "../packem_shared/types.d-C763gSYq.js";
2
+ import { E as ErrorHandler } from "../packem_shared/types.d-Btzbxdod.js";
3
3
  type JsonErrorBody = Record<string, unknown> | unknown[];
4
4
  type JsonErrorFormatter = (parameters: {
5
5
  error: Error;
@@ -1 +1 @@
1
- var f=Object.defineProperty;var a=(e,r)=>f(e,"name",{value:r,configurable:!0});import{getReasonPhrase as i}from"http-status-codes";import{p as u}from"../packem_shared/add-status-code-to-response-Dc6Pvpeh.js";import{s as n}from"../packem_shared/send-json-DfdjS9Xp.js";import{a as d}from"../packem_shared/set-error-headers-DT9rVGtW.js";var g=Object.defineProperty,l=a((e,r)=>g(e,"name",{value:r,configurable:!0}),"n");const h=l((e={})=>async(r,m,s)=>{u(s,r),d(s,r);const{statusCode:t}=s,o=i(t)||"An error occurred";if(e.formatter){const p=await e.formatter({error:r,reasonPhrase:o,request:m,response:s,statusCode:t});n(s,p);return}const{expose:c}=r;n(s,{message:r.message||o,error:o,statusCode:t,...c?{stack:r.stack}:{}})},"jsonErrorHandler");export{h as jsonErrorHandler};
1
+ import{getReasonPhrase as p}from"http-status-codes";import{a as f}from"../packem_shared/add-status-code-to-response-DwELM1q2.js";import{o as a}from"../packem_shared/send-json-fz8r6NBW.js";import{o as i}from"../packem_shared/set-error-headers-g9hns3cZ.js";const h=(t={})=>async(r,m,e)=>{f(e,r),i(e,r);const{statusCode:s}=e,o=p(s)||"An error occurred";if(t.formatter){const c=await t.formatter({error:r,reasonPhrase:o,request:m,response:e,statusCode:s});a(e,c);return}const{expose:n}=r;a(e,{message:r.message||o,error:o,statusCode:s,...n?{stack:r.stack}:{}})};export{h as jsonErrorHandler};
@@ -1,4 +1,4 @@
1
- import { a as ErrorHandler } from "../packem_shared/types.d-C763gSYq.js";
1
+ import { E as ErrorHandler } from "../packem_shared/types.d-Btzbxdod.js";
2
2
  import 'node:http';
3
3
  declare const jsonapiErrorHandler: ErrorHandler;
4
4
  export { jsonapiErrorHandler as default };
@@ -1 +1 @@
1
- var l=Object.defineProperty;var a=(e,o)=>l(e,"name",{value:o,configurable:!0});import{isHttpError as u}from"http-errors";import{getReasonPhrase as n}from"http-status-codes";import i from"ts-japi";import{p as d}from"../packem_shared/add-status-code-to-response-Dc6Pvpeh.js";import{s as t}from"../packem_shared/send-json-DfdjS9Xp.js";import{a as c}from"../packem_shared/set-error-headers-DT9rVGtW.js";var g=Object.defineProperty,m=a((e,o)=>g(e,"name",{value:o,configurable:!0}),"i");const E=m((e,o)=>"statusCode"in e&&typeof e.statusCode=="number"?e.statusCode:"status"in e&&typeof e.status=="number"?e.status:o,"resolveStatusCode"),H=m((e,o,r)=>{if(d(r,e),c(r,e),e instanceof i.JapiError||i.JapiError.isLikeJapiError(e)){const s=new i.ErrorSerializer;t(r,s.serialize(e))}else if(u(e)){const s=E(e,r.statusCode),p="title"in e&&typeof e.title=="string"?e.title:void 0,f="message"in e&&typeof e.message=="string"?e.message:"";t(r,{errors:[{code:s,title:p??n(s),detail:f}]})}else{const{message:s}=e;t(r,{errors:[{code:"500",title:n(r.statusCode),detail:s}]})}},"jsonapiErrorHandler");export{H as default};
1
+ import{isHttpError as f}from"http-errors";import{getReasonPhrase as m}from"http-status-codes";import i from"ts-japi";import{a as p}from"../packem_shared/add-status-code-to-response-DwELM1q2.js";import{o as t}from"../packem_shared/send-json-fz8r6NBW.js";import{o as l}from"../packem_shared/set-error-headers-g9hns3cZ.js";const u=(e,a)=>"statusCode"in e&&typeof e.statusCode=="number"?e.statusCode:"status"in e&&typeof e.status=="number"?e.status:a,J=(e,a,r)=>{if(p(r,e),l(r,e),e instanceof i.JapiError||i.JapiError.isLikeJapiError(e)){const o=new i.ErrorSerializer;t(r,o.serialize(e))}else if(f(e)){const o=u(e,r.statusCode),s="title"in e&&typeof e.title=="string"?e.title:void 0,n="message"in e&&typeof e.message=="string"?e.message:"";t(r,{errors:[{code:o,title:s??m(o),detail:n}]})}else{const{message:o}=e,{statusCode:s}=r;t(r,{errors:[{code:s,title:m(s),detail:o}]})}};export{J as default};
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { a as ErrorHandler } from "../packem_shared/types.d-C763gSYq.js";
2
+ import { E as ErrorHandler } from "../packem_shared/types.d-Btzbxdod.js";
3
3
  declare const jsonpErrorHandler: (options?: JsonpErrorHandlerOptions) => ErrorHandler;
4
4
  type JsonpErrorBody = Record<string, unknown> | unknown[];
5
5
  type JsonpErrorFormatter = (parameters: {
@@ -1 +1 @@
1
- var h=Object.defineProperty;var p=(t,a)=>h(t,"name",{value:a,configurable:!0});import{getReasonPhrase as u}from"http-status-codes";import{p as d}from"../packem_shared/add-status-code-to-response-Dc6Pvpeh.js";import{a as g}from"../packem_shared/set-error-headers-DT9rVGtW.js";var $=Object.defineProperty,P=p((t,a)=>$(t,"name",{value:a,configurable:!0}),"c");const c="callback",y=P((t={})=>async(a,l,e)=>{d(e,a),g(e,a);const{statusCode:s}=e,o=u(s),i=new URL(l.url??"http://localhost","http://localhost"),m=t.callbackParamName??c;let r=i.searchParams.get(m)??c,n;if(t.formatter)n=await t.formatter({error:a,reasonPhrase:o,request:l,response:e,statusCode:s});else{const{expose:f}=a;n={message:a.message||o,error:o,statusCode:s,...f?{stack:a.stack}:{}}}(r.length>64||!/^[A-Za-z_$][\w$.]*$/u.test(r))&&(r=c),e.setHeader("content-type","application/javascript; charset=utf-8"),e.end(`${r}(${JSON.stringify(n)});`)},"jsonpErrorHandler");export{y as jsonpErrorHandler};
1
+ import{getReasonPhrase as f}from"http-status-codes";import{a as h}from"../packem_shared/add-status-code-to-response-DwELM1q2.js";import{o as d}from"../packem_shared/set-error-headers-g9hns3cZ.js";const c="callback",g=/^[A-Za-z_$][\w$.]*$/u,k=(s={})=>async(e,l,t)=>{h(t,e),d(t,e);const{statusCode:o}=t,r=f(o),p=new URL(l.url??"http://localhost","http://localhost"),i=s.callbackParamName??c;let a=p.searchParams.get(i)??c,n;if(s.formatter)n=await s.formatter({error:e,reasonPhrase:r,request:l,response:t,statusCode:o});else{const{expose:u}=e;n={message:e.message||r,error:r,statusCode:o,...u?{stack:e.stack}:{}}}(a.length>64||!g.test(a))&&(a=c),t.setHeader("content-type","application/javascript; charset=utf-8"),t.setHeader("x-content-type-options","nosniff");const m=JSON.stringify(n).replaceAll("\u2028",String.raw`\u2028`).replaceAll("\u2029",String.raw`\u2029`);t.end(`/**/ typeof ${a} === 'function' && ${a}(${m});`)};export{k as jsonpErrorHandler};
@@ -1,4 +1,4 @@
1
- import { a as ErrorHandler } from "../packem_shared/types.d-C763gSYq.js";
1
+ import { E as ErrorHandler } from "../packem_shared/types.d-Btzbxdod.js";
2
2
  import 'node:http';
3
3
  /**
4
4
  * Normalizes errors according to the API Problem spec (RFC 7807).
@@ -1 +1 @@
1
- var y=Object.defineProperty;var i=(e,o)=>y(e,"name",{value:o,configurable:!0});import{isHttpError as c}from"http-errors";import{getReasonPhrase as p}from"http-status-codes";import{p as b}from"../packem_shared/add-status-code-to-response-Dc6Pvpeh.js";import{s as n}from"../packem_shared/send-json-DfdjS9Xp.js";import{a as C}from"../packem_shared/set-error-headers-DT9rVGtW.js";var v=Object.defineProperty,l=i((e,o)=>v(e,"name",{value:o,configurable:!0}),"o");const u="about:blank",g=l((e,o)=>"statusCode"in e&&typeof e.statusCode=="number"?e.statusCode:"status"in e&&typeof e.status=="number"?e.status:o,"resolveStatusCode"),h=l((e,o,t)=>{const{message:a,stack:r}=e;if(c(e)){const m="expose"in e?e.expose:void 0,s=g(e,t.statusCode),d="title"in e&&typeof e.title=="string"?e.title:void 0,f="type"in e&&typeof e.type=="string"?e.type:void 0;t.statusCode=s,C(t,e),n(t,{type:f??u,title:d??p(s),status:s,detail:a,...m?{trace:r}:{}},"application/problem+json")}else b(t,e),n(t,{type:u,title:p(t.statusCode),status:t.statusCode,detail:a,...e.expose?{trace:r}:{}},"application/problem+json")},"problemErrorHandler");export{h as default};
1
+ import{isHttpError as d}from"http-errors";import{getReasonPhrase as p}from"http-status-codes";import{a as f}from"../packem_shared/add-status-code-to-response-DwELM1q2.js";import{o as r}from"../packem_shared/send-json-fz8r6NBW.js";import{o as c}from"../packem_shared/set-error-headers-g9hns3cZ.js";const n="about:blank",y=(t,s)=>"statusCode"in t&&typeof t.statusCode=="number"?t.statusCode:"status"in t&&typeof t.status=="number"?t.status:s,$=(t,s,e)=>{const{message:a,stack:i}=t;if(d(t)){const m="expose"in t?t.expose:void 0,o=y(t,e.statusCode),u="title"in t&&typeof t.title=="string"?t.title:void 0,l="type"in t&&typeof t.type=="string"?t.type:void 0;e.statusCode=o,c(e,t),r(e,{type:l??n,title:u??p(o),status:o,detail:a,...m?{trace:i}:{}},"application/problem+json")}else f(e,t),r(e,{type:n,title:p(e.statusCode),status:e.statusCode,detail:a,...t.expose?{trace:i}:{}},"application/problem+json")};export{$ as default};
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { a as ErrorHandler } from "../packem_shared/types.d-C763gSYq.js";
2
+ import { E as ErrorHandler } from "../packem_shared/types.d-Btzbxdod.js";
3
3
  type TextErrorFormatter = (parameters: {
4
4
  error: Error;
5
5
  reasonPhrase: string;
@@ -1,3 +1,3 @@
1
- var f=Object.defineProperty;var c=(t,e)=>f(t,"name",{value:e,configurable:!0});import{getReasonPhrase as i}from"http-status-codes";import{p as u}from"../packem_shared/add-status-code-to-response-Dc6Pvpeh.js";import{a as l}from"../packem_shared/set-error-headers-DT9rVGtW.js";var x=Object.defineProperty,v=c((t,e)=>x(t,"name",{value:e,configurable:!0}),"m");const E=v((t={})=>async(e,m,r)=>{u(r,e),l(r,e);const{statusCode:o}=r,a=i(o)||"Error";if(r.setHeader("content-type","text/plain; charset=utf-8"),t.formatter){const d=await t.formatter({error:e,reasonPhrase:a,request:m,response:r,statusCode:o});r.end(d);return}const s=e.message||a,{expose:p}=e,n=p?e.stack:void 0;r.end(n?`${s}
1
+ import{getReasonPhrase as i}from"http-status-codes";import{a as d}from"../packem_shared/add-status-code-to-response-DwELM1q2.js";import{o as f}from"../packem_shared/set-error-headers-g9hns3cZ.js";const h=(o={})=>async(e,m,t)=>{d(t,e),f(t,e);const{statusCode:r}=t,s=i(r)||"Error";if(t.setHeader("content-type","text/plain; charset=utf-8"),o.formatter){const c=await o.formatter({error:e,reasonPhrase:s,request:m,response:t,statusCode:r});t.end(c);return}const a=e.message||s,{expose:p}=e,n=p?e.stack:void 0;t.end(n?`${a}
2
2
 
3
- ${n}`:s)},"textErrorHandler");export{E as textErrorHandler};
3
+ ${n}`:a)};export{h as textErrorHandler};
@@ -1,5 +1,5 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { a as ErrorHandler } from "../packem_shared/types.d-C763gSYq.js";
2
+ import { E as ErrorHandler } from "../packem_shared/types.d-Btzbxdod.js";
3
3
  type XmlErrorBody = Record<string, unknown> | unknown[];
4
4
  type XmlErrorFormatter = (parameters: {
5
5
  error: Error;
@@ -1 +1 @@
1
- var c=Object.defineProperty;var s=(t,e)=>c(t,"name",{value:e,configurable:!0});import{getReasonPhrase as p}from"http-status-codes";import{toXML as u}from"jstoxml";import{p as d}from"../packem_shared/add-status-code-to-response-Dc6Pvpeh.js";import{a as X}from"../packem_shared/set-error-headers-DT9rVGtW.js";var f=Object.defineProperty,b=s((t,e)=>f(t,"name",{value:e,configurable:!0}),"l");const h=b((t={})=>async(e,n,o)=>{d(o,e),X(o,e);const{statusCode:r}=o,a=p(r)||"An error occurred";let l;if(t.formatter)l=await t.formatter({error:e,reasonPhrase:a,request:n,response:o,statusCode:r});else{const{expose:i}=e;l={error:{statusCode:r,name:a,message:e.message||a,...i?{stack:e.stack}:{}}}}const m=u(l,{header:t.toXml?.header??t.xmlHeader??!0,indent:t.toXml?.indent??" ",...t.toXml?.attributeReplacements?{attributeReplacements:t.toXml.attributeReplacements}:{},...t.toXml?.attributeFilter?{attributeFilter:t.toXml.attributeFilter}:{},...t.toXml?.attributeExplicitTrue===void 0?{}:{attributeExplicitTrue:t.toXml.attributeExplicitTrue},...t.toXml?.contentMap?{contentMap:t.toXml.contentMap}:{},...t.toXml?.contentReplacements?{contentReplacements:t.toXml.contentReplacements}:{},...t.toXml?.selfCloseTags===void 0?{}:{selfCloseTags:t.toXml.selfCloseTags}});o.setHeader("content-type","application/xml; charset=utf-8"),o.end(m)},"xmlErrorHandler");export{h as xmlErrorHandler};
1
+ import{getReasonPhrase as i}from"http-status-codes";import{toXML as c}from"jstoxml";import{a as p}from"../packem_shared/add-status-code-to-response-DwELM1q2.js";import{o as u}from"../packem_shared/set-error-headers-g9hns3cZ.js";const x=(t={})=>async(e,l,o)=>{p(o,e),u(o,e);const{statusCode:r}=o,a=i(r)||"An error occurred";let s;if(t.formatter)s=await t.formatter({error:e,reasonPhrase:a,request:l,response:o,statusCode:r});else{const{expose:m}=e;s={error:{statusCode:r,name:a,message:e.message||a,...m?{stack:e.stack}:{}}}}const n=c(s,{header:t.toXml?.header??t.xmlHeader??!0,indent:t.toXml?.indent??" ",...t.toXml?.attributeReplacements?{attributeReplacements:t.toXml.attributeReplacements}:{},...t.toXml?.attributeFilter?{attributeFilter:t.toXml.attributeFilter}:{},...t.toXml?.attributeExplicitTrue===void 0?{}:{attributeExplicitTrue:t.toXml.attributeExplicitTrue},...t.toXml?.contentMap?{contentMap:t.toXml.contentMap}:{},...t.toXml?.contentReplacements?{contentReplacements:t.toXml.contentReplacements}:{},...t.toXml?.selfCloseTags===void 0?{}:{selfCloseTags:t.toXml.selfCloseTags}});o.setHeader("content-type","application/xml; charset=utf-8"),o.end(n)};export{x as xmlErrorHandler};
@@ -1,3 +1,3 @@
1
- var o=Object.defineProperty;var a=(r,e)=>o(r,"name",{value:e,configurable:!0});import{buildOutput as i}from"../packem_shared/cliHandler-CeQ8tsGj.js";import{terminalOutput as f}from"../packem_shared/cliHandler-CeQ8tsGj.js";var u=Object.defineProperty,l=a((r,e)=>u(r,"name",{value:e,configurable:!0}),"o");const d=l(async(r,e={})=>{const{errorAnsi:t,solutionBox:n}=await i(r,e);return n===void 0?t:`${t}
1
+ import{buildOutput as n}from"../packem_shared/cliHandler-BDHu9b4t.js";import{terminalOutput as l}from"../packem_shared/cliHandler-BDHu9b4t.js";const e=async(o,i={})=>{const{errorAnsi:r,solutionBox:t}=await n(o,i);return t===void 0?r:`${r}
2
2
 
3
- ${n}`},"ansiHandler");export{d as ansiHandler,f as cliHandler};
3
+ ${t}`};export{e as ansiHandler,l as cliHandler};
@@ -0,0 +1,31 @@
1
+ import { IncomingMessage, ServerResponse } from 'node:http';
2
+ import { HtmlErrorHandlerOptions } from "../../error-handler/html-error-handler.js";
3
+ import { a as ErrorHandlers } from "../../packem_shared/types.d-Btzbxdod.js";
4
+ import '@visulima/error/solution';
5
+ type ErrorMiddlewareOptions = HtmlErrorHandlerOptions & {
6
+ extraHandlers?: ErrorHandlers; /** Callback to handle error logging. */
7
+ onError?: (error: Error, request: IncomingMessage, response: ServerResponse) => void | Promise<void>;
8
+ /** Include stack traces in responses. Defaults to `NODE_ENV !== "production"`. */
9
+ showTrace?: boolean;
10
+ };
11
+ type ErrorMiddleware = (error: Error, request: IncomingMessage, response: ServerResponse, next?: (error?: unknown) => void) => Promise<void>;
12
+ /**
13
+ * Express/Connect-style error middleware.
14
+ *
15
+ * Unlike {@link nodeHandler}, which takes the error at construction time and so
16
+ * has to be rebuilt inside every `catch` block, this returns a four-argument
17
+ * error middleware you register once:
18
+ *
19
+ * ```ts
20
+ * import { createErrorMiddleware } from "@visulima/error-handler";
21
+ *
22
+ * app.use(createErrorMiddleware({ showTrace: "production" !== "production" }));
23
+ * ```
24
+ *
25
+ * The returned function matches the Express/Connect `(err, req, res, next)`
26
+ * signature. If the response has already started streaming
27
+ * (`response.headersSent`), it delegates to `next(error)` so the framework's
28
+ * default handler can close the connection rather than double-writing.
29
+ */
30
+ declare const createErrorMiddleware: (options?: ErrorMiddlewareOptions) => ErrorMiddleware;
31
+ export { type ErrorMiddleware, type ErrorMiddlewareOptions, createErrorMiddleware as default };
@@ -0,0 +1 @@
1
+ import n from"./node-handler.js";const f=(r={})=>async(t,i,a,e)=>{if(a.headersSent){e&&e(t);return}await n(t,r)(i,a)};export{f as default};
@@ -1,6 +1,7 @@
1
1
  import { HtmlErrorHandlerOptions } from "../../error-handler/html-error-handler.js";
2
- import { F as FetchErrorHandlers } from "../../packem_shared/types.d-C763gSYq.js";
2
+ import { F as FetchErrorHandlers } from "../../packem_shared/types.d-Btzbxdod.js";
3
3
  import 'node:http';
4
+ import '@visulima/error/solution';
4
5
  declare const fetchHandler: (error: Error, options?: HtmlErrorHandlerOptions & {
5
6
  extraHandlers?: FetchErrorHandlers;
6
7
  onError?: (error: Error, request: Request) => void | Promise<void>;
@@ -1 +1 @@
1
- var w=Object.defineProperty;var h=(n,e)=>w(n,"name",{value:e,configurable:!0});import{jsonErrorHandler as v}from"../../error-handler/json-error-handler.js";import H from"../../error-handler/jsonapi-error-handler.js";import{jsonpErrorHandler as x}from"../../error-handler/jsonp-error-handler.js";import b from"../../error-handler/problem-error-handler.js";import{textErrorHandler as j}from"../../error-handler/text-error-handler.js";import{xmlErrorHandler as L}from"../../error-handler/xml-error-handler.js";import{htmlErrorHandler as k}from"../../error-handler/html-error-handler.js";var E=Object.defineProperty,p=h((n,e)=>E(n,"name",{value:e,configurable:!0}),"c");class C{static{h(this,"v")}static{p(this,"MockServerResponse")}statusCode=200;headers={};responseBody="";setHeader(e,s){this.headers[e.toLowerCase()]=s}getHeader(e){return this.headers[e.toLowerCase()]}getHeaders(){return{...this.headers}}writeHead(e){this.statusCode=e}write(e){this.responseBody+=e.toString()}end(e){e&&(this.responseBody+=e.toString())}flushHeaders(){}}const S=[{chosen:"text/html",types:["text/html"]},{chosen:"application/vnd.api+json",types:["application/vnd.api+json"]},{chosen:"application/problem+json",types:["application/problem+json"]},{chosen:"application/json",types:["application/json"]},{chosen:"text/plain",types:["text/plain"]},{chosen:"application/javascript",types:["application/javascript","text/javascript"]},{chosen:"application/xml",types:["application/xml","text/xml"]}],O=p(n=>{if(!n)return"text/html";const e=[];for(const o of n.split(",")){const[a,...i]=o.trim().split(";"),d=(a??"").trim().toLowerCase();if(d==="")continue;let r=1;for(const f of i){const[y,g]=f.trim().split("=");if((y??"").trim().toLowerCase()==="q"){const m=Number.parseFloat((g??"").trim());Number.isNaN(m)||(r=m)}}if(r<=0)continue;const[c="",u=""]=d.split("/");e.push({quality:r,subtype:u,type:c})}if(e.length===0)return"text/html";const s=p(o=>{const[a,i]=o.split("/");return e.some(({subtype:d,type:r})=>r==="*"&&d==="*"||r===a&&d==="*"?!0:r===a&&d===i)},"matches");for(const{chosen:o,types:a}of S)if(a.some(i=>s(i)))return o;return"text/html"},"negotiateContentType"),l=p(n=>async(e,s)=>{const o={headers:Object.fromEntries(s.headers.entries()),method:s.method,url:s.url},a=new C;await n(e,o,a);const i={};for(const[d,r]of Object.entries(a.headers))i[d]=Array.isArray(r)?r.join(", "):String(r);return new Response(a.responseBody,{headers:i,status:a.statusCode})},"adaptErrorHandlerToFetch"),M=p((n,e,s)=>async(o,a)=>{const i=a.headers.get("accept"),d=O(i);let r=s??l(b);if(d==="text/html"&&s)r=s;else switch(d){case"application/javascript":{r=l(x());break}case"application/json":{r=l(v());break}case"application/problem+json":{r=l(b);break}case"application/vnd.api+json":{r=l(H);break}case"application/xml":{r=l(L());break}case"text/plain":{r=l(j());break}}for(const{handler:c,regex:u}of n){const f=i??"";if(u.test(f)){r=c;break}}return e?"expose"in o||(o.expose=!0):o.expose=!1,r(o,a)},"createFetchNegotiatedErrorHandler");var A=Object.defineProperty,t=h((n,e)=>A(n,"name",{value:e,configurable:!0}),"e");class N{static{h(this,"b")}static{t(this,"MockServerResponse")}statusCode=200;statusMessage="";headers={};headersSent=!1;writable=!0;finished=!1;writableEnded=!1;writableFinished=!1;writableHighWaterMark=16384;writableLength=0;destroyed=!1;writableCorked=0;readable=!1;readableHighWaterMark=16384;readableLength=0;errored=void 0;closed=!1;readableAborted=!1;readableDidRead=!1;readableEncoding=void 0;readableEnded=!1;readableFlowing=void 0;body="";sendDate=!0;strictContentLength=!1;chunkedEncoding=!1;shouldKeepAlive=!0;useChunkedEncodingByDefault=!0;connection=void 0;socket=void 0;setHeader(e,s){return this.headers[e.toLowerCase()]=s,this}getHeader(e){return this.headers[e.toLowerCase()]}getHeaders(){return{...this.headers}}getHeaderNames(){return Object.keys(this.headers)}hasHeader(e){return e.toLowerCase()in this.headers}removeHeader(e){return delete this.headers[e.toLowerCase()],this}writeHead(e,s,o){this.statusCode=e;let a=o;return typeof s=="string"&&(this.statusMessage=s),typeof s=="object"&&(a=s),a&&Object.assign(this.headers,a),this}write(e){return this.body+=e.toString(),!0}end(e,s,o){return e&&(this.body+=e.toString()),this.finished=!0,this}flushHeaders(){this.headersSent=!0}addListener=t(()=>this,"addListener");on=t(()=>this,"on");once=t(()=>this,"once");removeListener=t(()=>this,"removeListener");off=t(()=>this,"off");removeAllListeners=t(()=>this,"removeAllListeners");setMaxListeners=t(()=>this,"setMaxListeners");getMaxListeners=t(()=>10,"getMaxListeners");listeners=t(()=>[],"listeners");rawListeners=t(()=>[],"rawListeners");emit=t(()=>!1,"emit");eventNames=t(()=>[],"eventNames");listenerCount=t(()=>0,"listenerCount");prependListener=t(()=>this,"prependListener");prependOnceListener=t(()=>this,"prependOnceListener");cork=t(()=>{},"cork");uncork=t(()=>{},"uncork");destroy=t(()=>this,"destroy");read=t(()=>{},"read");setEncoding=t(()=>this,"setEncoding");pause=t(()=>this,"pause");resume=t(()=>this,"resume");isPaused=t(()=>!1,"isPaused");destroySoon=t(()=>this,"destroySoon");pipe=t(()=>({}),"pipe");unpipe=t(()=>this,"unpipe");unshift=t(()=>{},"unshift");wrap=t(()=>this,"wrap");setTimeout=t(()=>this,"setTimeout");assignSocket=t(()=>{},"assignSocket");detachSocket=t(()=>{},"detachSocket");writeContinue=t(()=>{},"writeContinue");writeEarlyHints=t(()=>{},"writeEarlyHints")}const R=t((n={})=>{const e=k(n);return async(s,o)=>{const a={headers:Object.fromEntries(o.headers.entries()),method:o.method,url:o.url},i=new N;await e(s,a,i);const d={"content-type":i.getHeader("content-type")??"text/html; charset=utf-8"};for(const[r,c]of Object.entries(i.headers))r!=="content-type"&&(d[r]=Array.isArray(c)?c.join(", "):String(c));return new Response(i.body,{headers:d,status:i.statusCode})}},"fetchHtmlErrorHandler");var B=Object.defineProperty,F=h((n,e)=>B(n,"name",{value:e,configurable:!0}),"t");const G=F((n,e={})=>{const s=R(e),o=M(e.extraHandlers??[],e.showTrace??!0,s);return async a=>(e.onError&&await e.onError(n,a),o(n,a))},"fetchHandler");export{G as default};
1
+ import s from"../../packem_shared/fetchCreateNegotiatedErrorHandler-D9YQ8pOH.js";import c from"../../packem_shared/fetchHtmlErrorHandler-Cu50Zu5a.js";const i=(o,r={})=>{const a=c(r),n=r.showTrace??globalThis.process?.env?.NODE_ENV!=="production",e=s(r.extraHandlers??[],n,a);return async t=>(r.onError&&await r.onError(o,t),e(o,t))};export{i as default};
@@ -1,6 +1,7 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
2
  import { HtmlErrorHandlerOptions } from "../../error-handler/html-error-handler.js";
3
- import { E as ErrorHandlers } from "../../packem_shared/types.d-C763gSYq.js";
3
+ import { a as ErrorHandlers } from "../../packem_shared/types.d-Btzbxdod.js";
4
+ import '@visulima/error/solution';
4
5
  declare const nodeHandler: (error: Error, options?: HtmlErrorHandlerOptions & {
5
6
  extraHandlers?: ErrorHandlers;
6
7
  onError?: (error: Error, request: IncomingMessage, response: ServerResponse) => void | Promise<void>;
@@ -1 +1 @@
1
- var i=Object.defineProperty;var o=(a,r)=>i(a,"name",{value:r,configurable:!0});import l from"../../packem_shared/createNegotiatedErrorHandler-DlEHBPFw.js";import{htmlErrorHandler as s}from"../../error-handler/html-error-handler.js";var c=Object.defineProperty,m=o((a,r)=>c(a,"name",{value:r,configurable:!0}),"t");const v=m((a,r={})=>{const n=s(r),d=l(r.extraHandlers??[],r.showTrace??!0,n);return async(e,t)=>{r.onError&&await r.onError(a,e,t),await d(a,e,t)}},"nodeHandler");export{v as default};
1
+ import c from"../../packem_shared/createNegotiatedErrorHandler-CcWOSpO5.js";import{htmlErrorHandler as i}from"../../error-handler/html-error-handler.js";const p=(o,r={})=>{const s=i(r),n=r.showTrace??globalThis.process?.env?.NODE_ENV!=="production",e=c(r.extraHandlers??[],n,s);return async(a,t)=>{r.onError&&await r.onError(o,a,t),await e(o,a,t)}};export{p as default};
package/dist/index.d.ts CHANGED
@@ -1,12 +1,20 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { E as ErrorHandlers, a as ErrorHandler } from "./packem_shared/types.d-C763gSYq.js";
3
- export { type A as ApiFormat } from "./packem_shared/types.d-C763gSYq.js";
4
- export { type HtmlErrorHandlerOptions, htmlErrorHandler } from "./error-handler/html-error-handler.js";
2
+ import { a as ErrorHandlers, E as ErrorHandler, F as FetchErrorHandlers } from "./packem_shared/types.d-Btzbxdod.js";
3
+ export type { A as ApiFormat, b as FetchErrorHandler } from "./packem_shared/types.d-Btzbxdod.js";
4
+ import { HtmlErrorHandlerOptions } from "./error-handler/html-error-handler.js";
5
+ export { htmlErrorHandler } from "./error-handler/html-error-handler.js";
5
6
  export { type JsonErrorBody, type JsonErrorFormatter, type JsonErrorHandlerOptions, jsonErrorHandler } from "./error-handler/json-error-handler.js";
6
7
  export { default as jsonapiErrorHandler } from "./error-handler/jsonapi-error-handler.js";
7
8
  export { type JsonpErrorBody, type JsonpErrorFormatter, type JsonpErrorHandlerOptions, jsonpErrorHandler } from "./error-handler/jsonp-error-handler.js";
8
9
  export { default as problemErrorHandler } from "./error-handler/problem-error-handler.js";
9
10
  export { type TextErrorFormatter, type TextErrorHandlerOptions, textErrorHandler } from "./error-handler/text-error-handler.js";
11
+ export { extractStatusCode, sendFetchJson } from "./error-handler/fetch-utils.js";
10
12
  export { type ToXmlOptions, type XmlErrorBody, type XmlErrorFormatter, type XmlErrorHandlerOptions, xmlErrorHandler } from "./error-handler/xml-error-handler.js";
13
+ export { type ErrorMiddlewareOptions, default as createErrorMiddleware } from "./handler/http/create-error-middleware.js";
14
+ export { default as fetchHandler } from "./handler/http/fetch-handler.js";
15
+ export { default as nodeHandler } from "./handler/http/node-handler.js";
16
+ import '@visulima/error/solution';
11
17
  declare const createNegotiatedErrorHandler: (errorHandlers: ErrorHandlers, showTrace: boolean, defaultHtmlHandler?: ErrorHandler) => (error: Error, request: IncomingMessage, response: ServerResponse) => Promise<void>;
12
- export { type ErrorHandler, type ErrorHandlers, createNegotiatedErrorHandler };
18
+ declare const createFetchNegotiatedErrorHandler: (errorHandlers: FetchErrorHandlers, showTrace: boolean, defaultHtmlHandler?: (error: Error, request: Request) => Promise<Response>) => (error: Error, request: Request) => Promise<Response>;
19
+ declare const fetchHtmlErrorHandler: (options?: HtmlErrorHandlerOptions) => (error: Error, request: Request) => Promise<Response>;
20
+ export { type ErrorHandler, type ErrorHandlers, type FetchErrorHandlers, type HtmlErrorHandlerOptions, createNegotiatedErrorHandler, createFetchNegotiatedErrorHandler as fetchCreateNegotiatedErrorHandler, fetchHtmlErrorHandler };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{default as e}from"./packem_shared/createNegotiatedErrorHandler-DlEHBPFw.js";import{htmlErrorHandler as t}from"./error-handler/html-error-handler.js";import{jsonErrorHandler as d}from"./error-handler/json-error-handler.js";import{default as m}from"./error-handler/jsonapi-error-handler.js";import{jsonpErrorHandler as p}from"./error-handler/jsonp-error-handler.js";import{default as E}from"./error-handler/problem-error-handler.js";import{textErrorHandler as s}from"./error-handler/text-error-handler.js";import{xmlErrorHandler as u}from"./error-handler/xml-error-handler.js";export{e as createNegotiatedErrorHandler,t as htmlErrorHandler,d as jsonErrorHandler,m as jsonapiErrorHandler,p as jsonpErrorHandler,E as problemErrorHandler,s as textErrorHandler,u as xmlErrorHandler};
1
+ import{default as o}from"./packem_shared/createNegotiatedErrorHandler-CcWOSpO5.js";import{default as a}from"./packem_shared/fetchCreateNegotiatedErrorHandler-D9YQ8pOH.js";import{default as f}from"./packem_shared/fetchHtmlErrorHandler-Cu50Zu5a.js";import{htmlErrorHandler as m}from"./error-handler/html-error-handler.js";import{jsonErrorHandler as p}from"./error-handler/json-error-handler.js";import{default as s}from"./error-handler/jsonapi-error-handler.js";import{jsonpErrorHandler as u}from"./error-handler/jsonp-error-handler.js";import{default as c}from"./error-handler/problem-error-handler.js";import{textErrorHandler as i}from"./error-handler/text-error-handler.js";import{default as g}from"./packem_shared/extractStatusCode-D0UOgNnr.js";import{default as N}from"./packem_shared/sendFetchJson-BNmfrMYp.js";import{xmlErrorHandler as w}from"./error-handler/xml-error-handler.js";import{default as J}from"./handler/http/create-error-middleware.js";import{default as S}from"./handler/http/fetch-handler.js";import{default as q}from"./handler/http/node-handler.js";export{J as createErrorMiddleware,o as createNegotiatedErrorHandler,g as extractStatusCode,a as fetchCreateNegotiatedErrorHandler,S as fetchHandler,f as fetchHtmlErrorHandler,m as htmlErrorHandler,p as jsonErrorHandler,s as jsonapiErrorHandler,u as jsonpErrorHandler,q as nodeHandler,c as problemErrorHandler,N as sendFetchJson,i as textErrorHandler,w as xmlErrorHandler};
@@ -0,0 +1 @@
1
+ import{StatusCodes as u}from"http-status-codes";const r=(s,o)=>{const e=o,t=Number(e.statusCode??e.status);if(Number.isInteger(t)&&t>=400&&t<=599){s.statusCode=t;return}s.statusCode<400&&(s.statusCode=u.INTERNAL_SERVER_ERROR)};export{r as a};
@@ -0,0 +1 @@
1
+ import{parseStacktrace as c}from"@visulima/error/stacktrace";import{boxen as d}from"@visulima/boxen";import{renderError as p}from"@visulima/error/error";import{h as g,a as b}from"./get-file-source-By3_8e1o.js";import{ruleBasedFinder as y,errorHintFinder as h}from"@visulima/error/solution";const x=t=>t.replace(/^\s*#+\s*/,"").trim(),A=async(t,l,r=!1,n)=>{const s=[...l,y,h].sort((a,e)=>a.priority-e.priority),o=c(t,{frameLimit:1})[0]??{},f=o.file?await g(o.file):"";for(const a of s){const{handle:e,name:i}=a;if(r&&(n??console).log(`[solution-finder] running: ${i??"anonymous"}`),typeof e!="function")continue;const u=await e(t,{file:o.file??"",language:b(o.file??""),line:o.line??0,snippet:f});if(u)return r&&(n??console).log(`[solution-finder] matched: ${i??"anonymous"}`),u}},w=async(t,l,r)=>{const{solutionFinders:n=[],solutionTitle:s,color:o,debug:f=!1,...a}=l,e=p(t,{...a,...o?.codeFrame}),i=await A(t,n,f,r);if(!i)return{errorAnsi:e,solutionBox:void 0};const u=x(i.header??s??"A possible solution to this error"),m=d(i.body,{borderStyle:"round",padding:{top:1,right:2,bottom:1,left:2},margin:{top:0,right:0,bottom:0,left:0},headerText:`💡 ${u}`,headerAlignment:"left",textAlignment:"left",...o?.boxen});return{errorAnsi:e,solutionBox:m}},T=async(t,l={})=>{const{logger:r=console,...n}=l,{errorAnsi:s,solutionBox:o}=await w(t,n,r);r.error(s),o&&(r.log(""),r.log(o))};export{w as buildOutput,T as terminalOutput};
@@ -0,0 +1 @@
1
+ import{Accepts as d}from"@tinyhttp/accepts";import{jsonErrorHandler as b}from"../error-handler/json-error-handler.js";import{jsonpErrorHandler as y}from"../error-handler/jsonp-error-handler.js";import n from"../error-handler/problem-error-handler.js";import{textErrorHandler as h}from"../error-handler/text-error-handler.js";const w=y(),k=b(),v=h();let c,l;const E=async()=>(c??=import("../error-handler/jsonapi-error-handler.js").then(a=>a.default),c),u=async()=>(l??=import("../error-handler/xml-error-handler.js").then(a=>a.xmlErrorHandler()),l),H=async(a,p,e)=>{const o=Object.hasOwn(a,"expose"),r=a.expose;p?"expose"in a||(a.expose=!0):a.expose=!1;try{await e()}finally{o?a.expose=r:delete a.expose}},q=(a,p,e)=>async(o,r,x)=>{const s=new d(r).type(["text/html","application/vnd.api+json","application/problem+json","application/json","text/plain","application/javascript","text/javascript","application/xml","text/xml"]);let t=e??n;if(s==="text/html"&&e)t=e;else switch(s){case"application/javascript":case"text/javascript":{t=w;break}case"application/json":{t=k;break}case"application/problem+json":{t=n;break}case"application/vnd.api+json":{t=await E();break}case"application/xml":case"text/xml":{t=await u();break}case"text/plain":{t=v;break}}for(const{handler:m,regex:j}of a){const i=r.headers.accept??"",f=Array.isArray(i)?i.join(","):i;if(j.test(f)){t=m;break}}await H(o,p,()=>t(o,r,x))};export{q as default};
@@ -0,0 +1 @@
1
+ import{StatusCodes as s}from"http-status-codes";const u=(e,r=s.INTERNAL_SERVER_ERROR)=>{if(!e)return r;const t=Number(e.statusCode??e.status);return Number.isInteger(t)&&t>=400&&t<=599?t:r};export{u as default};
@@ -0,0 +1 @@
1
+ import{jsonErrorHandler as w}from"../error-handler/json-error-handler.js";import{jsonpErrorHandler as g}from"../error-handler/jsonp-error-handler.js";import H from"../error-handler/problem-error-handler.js";import{textErrorHandler as k}from"../error-handler/text-error-handler.js";class v{statusCode=200;headers={};responseBody="";setHeader(t,o){this.headers[t.toLowerCase()]=o}getHeader(t){return this.headers[t.toLowerCase()]}getHeaders(){return{...this.headers}}writeHead(t){this.statusCode=t}write(t){this.responseBody+=t.toString()}end(t){t&&(this.responseBody+=t.toString())}flushHeaders(){}}const C=[{chosen:"text/html",types:["text/html"]},{chosen:"application/vnd.api+json",types:["application/vnd.api+json"]},{chosen:"application/problem+json",types:["application/problem+json"]},{chosen:"application/json",types:["application/json"]},{chosen:"text/plain",types:["text/plain"]},{chosen:"application/javascript",types:["application/javascript","text/javascript"]},{chosen:"application/xml",types:["application/xml","text/xml"]}],E=s=>{if(!s)return"text/html";const t=[];for(const r of s.split(",")){const[n,...e]=r.trim().split(";"),p=(n??"").trim().toLowerCase();if(p==="")continue;let i=1;for(const y of e){const[j,b]=y.trim().split("=");if((j??"").trim().toLowerCase()==="q"){const m=Number.parseFloat((b??"").trim());Number.isNaN(m)||(i=m)}}if(i<=0)continue;const[l="",d=""]=p.split("/");t.push({quality:i,subtype:d,type:l})}if(t.length===0)return"text/html";const o=r=>{const[n,e]=r.split("/");let p=-1;for(const{quality:i,subtype:l,type:d}of t)(d==="*"&&l==="*"||d===n&&l==="*"||d===n&&l===e)&&i>p&&(p=i);return p};let c="text/html",a=-1;for(const{chosen:r,types:n}of C){let e=-1;for(const p of n){const i=o(p);i>e&&(e=i)}e>a&&(a=e,c=r)}return a<0?"text/html":c},h=s=>async(t,o)=>{const c={headers:Object.fromEntries(o.headers.entries()),method:o.method,url:o.url},a=new v;await s(t,c,a);const r={};for(const[n,e]of Object.entries(a.headers))r[n]=Array.isArray(e)?e.join(", "):String(e);return new Response(a.responseBody,{headers:r,status:a.statusCode})},B=h(g()),q=h(w()),f=h(H),L=h(k());let u,x;const N=async()=>(u??=import("../error-handler/jsonapi-error-handler.js").then(s=>h(s.default)),u),O=async()=>(x??=import("../error-handler/xml-error-handler.js").then(s=>h(s.xmlErrorHandler())),x),S=async(s,t,o)=>{const c=Object.hasOwn(s,"expose"),a=s.expose;t?"expose"in s||(s.expose=!0):s.expose=!1;try{return await o()}finally{c?s.expose=a:delete s.expose}},T=(s,t,o)=>async(c,a)=>{const r=a.headers.get("accept"),n=E(r);let e=o??f;if(n==="text/html"&&o)e=o;else switch(n){case"application/javascript":{e=B;break}case"application/json":{e=q;break}case"application/problem+json":{e=f;break}case"application/vnd.api+json":{e=await N();break}case"application/xml":{e=await O();break}case"text/plain":{e=L;break}}for(const{handler:p,regex:i}of s){const l=r??"";if(i.test(l)){e=p;break}}return S(c,t,()=>e(c,a))};export{T as default};
@@ -0,0 +1 @@
1
+ import{htmlErrorHandler as h}from"../error-handler/html-error-handler.js";class l{statusCode=200;statusMessage="";headers={};headersSent=!1;writable=!0;finished=!1;writableEnded=!1;writableFinished=!1;writableHighWaterMark=16384;writableLength=0;destroyed=!1;writableCorked=0;readable=!1;readableHighWaterMark=16384;readableLength=0;errored=void 0;closed=!1;readableAborted=!1;readableDidRead=!1;readableEncoding=void 0;readableEnded=!1;readableFlowing=void 0;body="";sendDate=!0;strictContentLength=!1;chunkedEncoding=!1;shouldKeepAlive=!0;useChunkedEncodingByDefault=!0;connection=void 0;socket=void 0;setHeader(e,t){return this.headers[e.toLowerCase()]=t,this}getHeader(e){return this.headers[e.toLowerCase()]}getHeaders(){return{...this.headers}}getHeaderNames(){return Object.keys(this.headers)}hasHeader(e){return e.toLowerCase()in this.headers}removeHeader(e){return delete this.headers[e.toLowerCase()],this}writeHead(e,t,s){this.statusCode=e;let r=s;return typeof t=="string"&&(this.statusMessage=t),typeof t=="object"&&(r=t),r&&Object.assign(this.headers,r),this}write(e){return this.body+=e.toString(),!0}end(e,t,s){return e&&(this.body+=e.toString()),this.finished=!0,this}flushHeaders(){this.headersSent=!0}addListener=()=>this;on=()=>this;once=()=>this;removeListener=()=>this;off=()=>this;removeAllListeners=()=>this;setMaxListeners=()=>this;getMaxListeners=()=>10;listeners=()=>[];rawListeners=()=>[];emit=()=>!1;eventNames=()=>[];listenerCount=()=>0;prependListener=()=>this;prependOnceListener=()=>this;cork=()=>{};uncork=()=>{};destroy=()=>this;read=()=>{};setEncoding=()=>this;pause=()=>this;resume=()=>this;isPaused=()=>!1;destroySoon=()=>this;pipe=()=>({});unpipe=()=>this;unshift=()=>{};wrap=()=>this;setTimeout=()=>this;assignSocket=()=>{};detachSocket=()=>{};writeContinue=()=>{};writeEarlyHints=()=>{}}const c=(n={})=>{const e=h(n);return async(t,s)=>{const r={headers:Object.fromEntries(s.headers.entries()),method:s.method,url:s.url},a=new l;await e(t,r,a);const d={"content-type":a.getHeader("content-type")??"text/html; charset=utf-8"};for(const[o,i]of Object.entries(a.headers))o!=="content-type"&&(d[o]=Array.isArray(i)?i.join(", "):String(i));return new Response(a.body,{headers:d,status:a.statusCode})}};export{c as default,c as fetchHtmlErrorHandler};
@@ -0,0 +1 @@
1
+ import{createRequire as f}from"node:module";const p=f(import.meta.url),a=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,o=e=>{if(typeof a<"u"&&a.versions&&a.versions.node){const[s,n]=a.versions.node.split(".").map(Number);if(s>22||s===22&&n>=3||s===20&&n>=16)return a.getBuiltinModule(e)}return p(e)},{readFile:l}=o("node:fs/promises"),{isAbsolute:d}=o("node:path"),{fileURLToPath:h}=o("node:url"),m=new Set(["cjs","mjs"]),y=new Set(["cts","mts"]),j=new Set(["mdoc"]),g=e=>{const s=(e.split("?")[0]??e).split(".").pop()?.toLowerCase();if(!s)return"text";if(m.has(s))return"javascript";if(y.has(s))return"typescript";if(j.has(s))return"markdown";switch(s){case"js":return"javascript";case"json":return"json";case"json5":return"json5";case"jsonc":return"jsonc";case"jsx":return"jsx";case"sql":return"sql";case"ts":return"typescript";case"tsx":return"tsx";case"xml":return"xml";case"md":return"markdown";case"mdx":return"mdx";case"svelte":return"svelte";case"vue":return"vue";case"html":return"html";case"css":return"css";case"scss":return"scss";case"less":return"less";case"sass":return"sass";case"stylus":return"stylus";case"styl":return"styl";case"yaml":case"yml":return"yaml";case"toml":return"toml";case"py":return"python";case"go":return"go";case"rs":return"rust";case"rb":return"ruby";case"php":return"php";case"graphql":case"gql":return"graphql";case"dockerfile":return"dockerfile";case"sh":case"bash":return"bash";case"txt":return"text";default:return"text"}},x=50,t=new Map,v=e=>{const s=t.get(e);if(s!==void 0)return t.delete(e),t.set(e,s),s},c=(e,s)=>{if(t.has(e))t.delete(e);else if(t.size>=x){const n=t.keys().next().value;n!==void 0&&t.delete(n)}t.set(e,s)},_=async(e,s={})=>{const{allowRemote:n=!1}=s,u=v(e);if(u!==void 0)return u;if(e.startsWith("file:"))try{const r=await l(h(e),"utf8");return c(e,r),r}catch{return}if(/^(?:https?|data):/.test(e)){if(!n)return;try{const r=await fetch(e);if(!r.ok)return;const i=await r.text();return c(e,i),i}catch{return}}if(d(e))try{const r=await l(e,"utf8");return c(e,r),r}catch{return}};export{g as a,_ as h};
@@ -0,0 +1 @@
1
+ const o=(t,e,n="application/json; charset=utf-8")=>{t.setHeader("content-type",n),t.end(JSON.stringify(e))};export{o};
@@ -0,0 +1 @@
1
+ const a=(t,s,e="application/json; charset=utf-8")=>Response.json(t,{headers:{"content-type":e},status:s});export{a as default};
@@ -0,0 +1 @@
1
+ const t=(r,s)=>{const e=s.headers??{};Object.keys(e).forEach(o=>{r.setHeader(o,e[o])})};export{t as o};
@@ -10,4 +10,4 @@ type FetchErrorHandlers = {
10
10
  regex: RegExp;
11
11
  }[];
12
12
  type ApiFormat = "jsonapi" | "problem" | "html";
13
- export { ApiFormat as A, ErrorHandlers as E, FetchErrorHandlers as F, ErrorHandler as a };
13
+ export { ApiFormat as A, ErrorHandler as E, FetchErrorHandlers as F, ErrorHandlers as a, FetchErrorHandler as b };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@visulima/error-handler",
3
- "version": "2.0.0-alpha.30",
3
+ "version": "2.0.0-alpha.32",
4
4
  "description": "Error handlers for use in development and production environments.",
5
5
  "keywords": [
6
6
  "anolilab",
@@ -71,6 +71,10 @@
71
71
  "types": "./dist/handler/http/node-handler.d.ts",
72
72
  "default": "./dist/handler/http/node-handler.js"
73
73
  },
74
+ "./handler/middleware": {
75
+ "types": "./dist/handler/http/create-error-middleware.d.ts",
76
+ "default": "./dist/handler/http/create-error-middleware.js"
77
+ },
74
78
  "./handler/http/hono": {
75
79
  "types": "./dist/handler/http/fetch-handler.d.ts",
76
80
  "default": "./dist/handler/http/fetch-handler.js"
@@ -123,6 +127,10 @@
123
127
  "types": "./dist/error-handler/xml-error-handler.d.ts",
124
128
  "default": "./dist/error-handler/xml-error-handler.js"
125
129
  },
130
+ "./error-handler/fetch-utils": {
131
+ "types": "./dist/error-handler/fetch-utils.d.ts",
132
+ "default": "./dist/error-handler/fetch-utils.js"
133
+ },
126
134
  "./package.json": "./package.json"
127
135
  },
128
136
  "files": [
@@ -132,8 +140,8 @@
132
140
  ],
133
141
  "dependencies": {
134
142
  "@tinyhttp/accepts": "^2.3.0",
135
- "@visulima/boxen": "3.0.0-alpha.12",
136
- "@visulima/error": "6.0.0-alpha.32",
143
+ "@visulima/boxen": "3.0.0-alpha.14",
144
+ "@visulima/error": "6.0.0-alpha.33",
137
145
  "http-errors": "^2.0.1",
138
146
  "http-status-codes": "^2.3.0",
139
147
  "jstoxml": "^7.1.0",
@@ -1 +0,0 @@
1
- var a=Object.defineProperty;var r=(e,t)=>a(e,"name",{value:t,configurable:!0});import{StatusCodes as u}from"http-status-codes";var d=Object.defineProperty,n=r((e,t)=>d(e,"name",{value:t,configurable:!0}),"s");const i=n((e,t)=>{const o=t,s=Number(o.statusCode??o.status);if(Number.isInteger(s)&&s>=400&&s<=599){e.statusCode=s;return}e.statusCode<400&&(e.statusCode=u.INTERNAL_SERVER_ERROR)},"addStatusCodeToResponse");export{i as p};
@@ -1 +0,0 @@
1
- var h=Object.defineProperty;var c=(e,r)=>h(e,"name",{value:r,configurable:!0});import{createRequire as y}from"node:module";import{parseStacktrace as v}from"@visulima/error/stacktrace";import{boxen as x}from"@visulima/boxen";import{renderError as w}from"@visulima/error/error";import{ruleBasedFinder as F,errorHintFinder as B}from"@visulima/error/solution";const b=y(import.meta.url),u=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,p=c(e=>{if(typeof u<"u"&&u.versions&&u.versions.node){const[r,t]=u.versions.node.split(".").map(Number);if(r>22||r===22&&t>=3||r===20&&t>=16)return u.getBuiltinModule(e)}return b(e)},"__cjs_getBuiltinModule"),{readFile:_}=p("node:fs/promises"),{fileURLToPath:O}=p("node:url");var T=Object.defineProperty,A=c((e,r)=>T(e,"name",{value:r,configurable:!0}),"r");const q=["cjs","mjs"],P=["mdoc"],S=A(e=>{const r=(e.split("?")[0]??e).split(".").pop()?.toLowerCase();if(!r||q.includes(r))return"javascript";if(P.includes(r))return"markdown";switch(r){case"js":case"cjs":case"mjs":return"javascript";case"json":return"json";case"json5":return"json5";case"jsonc":return"jsonc";case"jsx":return"jsx";case"sql":return"sql";case"ts":case"cts":case"mts":return"typescript";case"tsx":return"tsx";case"xml":return"xml";case"md":return"markdown";case"mdx":return"mdx";case"svelte":return"svelte";case"vue":return"vue";case"html":return"html";case"css":return"css";case"scss":return"scss";case"less":return"less";case"sass":return"sass";case"stylus":return"stylus";case"styl":return"styl";case"txt":return"text";default:return"javascript"}},"findLanguageBasedOnExtension");var k=Object.defineProperty,m=c((e,r)=>k(e,"name",{value:r,configurable:!0}),"o");const l=new Map,L=m(async e=>{if(/^(?:http|https|file|data):/.test(e)){if(l.has(e))return l.get(e);if(e.startsWith("file:"))try{const r=O(e),t=await _(r,"utf8");return l.set(e,t),t}catch{return}try{const r=await fetch(e);if(!r.ok)return;const t=await r.text();return l.set(e,t),t}catch{return}}},"getFileSource");m(()=>{l.clear()},"clearFileSourceCache");var C=Object.defineProperty,f=c((e,r)=>C(e,"name",{value:r,configurable:!0}),"d");const M=f(e=>e.replace(/^\s*#+\s*/,"").trim(),"sanitizeTitle"),R=f(async(e,r,t=!1)=>{const a=[...r,F,B],s=v(e,{frameLimit:1})[0]??{};for await(const o of a.sort((i,n)=>i.priority-n.priority)){const{handle:i}=o;if(typeof i!="function")continue;const n=await i(e,{file:s.file??"",language:S(s.file??""),line:s.line??0,snippet:s.file?await L(s.file):""});if(n)return n}},"runSolutionFinders"),$=f(async(e,r)=>{const{solutionFinders:t=[],solutionTitle:a,color:s,debug:o=!1,...i}=r,n=w(e,{...i,...s?.codeFrame}),d=await R(e,t,o);if(!d)return{errorAnsi:n,solutionBox:void 0};const g=M(d.header??a??"A possible solution to this error"),j=x(d.body,{borderStyle:"round",padding:{top:1,right:2,bottom:1,left:2},margin:{top:0,right:0,bottom:0,left:0},headerText:`💡 ${g}`,headerAlignment:"left",textAlignment:"left",...s?.boxen});return{errorAnsi:n,solutionBox:j}},"buildOutput"),D=f(async(e,r={})=>{const{logger:t=console,...a}=r,{errorAnsi:s,solutionBox:o}=await $(e,a);t.error(s),o&&(t.log(""),t.log(o))},"terminalOutput");export{$ as buildOutput,D as terminalOutput};
@@ -1 +0,0 @@
1
- var j=Object.defineProperty;var n=(r,e)=>j(r,"name",{value:e,configurable:!0});import{Accepts as d}from"@tinyhttp/accepts";import{jsonErrorHandler as b}from"../error-handler/json-error-handler.js";import v from"../error-handler/jsonapi-error-handler.js";import{jsonpErrorHandler as k}from"../error-handler/jsonp-error-handler.js";import c from"../error-handler/problem-error-handler.js";import{textErrorHandler as E}from"../error-handler/text-error-handler.js";import{xmlErrorHandler as h}from"../error-handler/xml-error-handler.js";var g=Object.defineProperty,u=n((r,e)=>g(r,"name",{value:e,configurable:!0}),"i");const q=u((r,e,o)=>async(t,p,l)=>{const s=new d(p).type(["text/html","application/vnd.api+json","application/problem+json","application/json","text/plain","application/javascript","text/javascript","application/xml","text/xml"]);let a=o??c;if(s==="text/html"&&o)a=o;else switch(s){case"application/javascript":case"text/javascript":{a=k();break}case"application/json":{a=b();break}case"application/problem+json":{a=c;break}case"application/vnd.api+json":{a=v;break}case"application/xml":case"text/xml":{a=h();break}case"text/plain":{a=E();break}}for(const{handler:m,regex:x}of r){const i=p.headers.accept??"",f=Array.isArray(i)?i.join(","):i;if(x.test(f)){a=m;break}}e?"expose"in t||(t.expose=!0):t.expose=!1,await a(t,p,l)},"createNegotiatedErrorHandler");export{q as default};
@@ -1 +0,0 @@
1
- var a=Object.defineProperty;var t=(e,n)=>a(e,"name",{value:n,configurable:!0});var o=Object.defineProperty,s=t((e,n)=>o(e,"name",{value:n,configurable:!0}),"n");const i=s((e,n,r="application/json; charset=utf-8")=>{e.setHeader("content-type",r),e.end(JSON.stringify(n))},"sendJson");export{i as s};
@@ -1 +0,0 @@
1
- var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});var n=Object.defineProperty,s=o((e,r)=>n(e,"name",{value:r,configurable:!0}),"o");const b=s((e,r)=>{const a=r.headers??{};Object.keys(a).forEach(t=>{e.setHeader(t,a[t])})},"setErrorHeaders");export{b as a};