@web-ts-toolkit/express-response-handler 0.31.0 → 0.31.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/index.mjs CHANGED
@@ -1,23 +1,612 @@
1
- import { createHandler } from "./create-handler";
2
- const apiHandler = createHandler();
3
- var index_default = apiHandler;
4
- import { createHandler as createHandler2 } from "./create-handler";
5
- import { ErrorFormats } from "./error-formats";
6
- import { HttpResponse } from "./http-response";
7
- import { CSVResponse } from "./responses/csv";
8
- import { Response } from "./responses";
1
+ // src/create-handler.ts
2
+ import assert from "assert";
3
+ import { isArray as isArray2, isFunction, isPromise } from "@web-ts-toolkit/utils";
4
+
5
+ // src/responses/csv.ts
6
+ import { format } from "@fast-csv/format";
7
+ import { castArray, isBoolean, isPlainObject } from "@web-ts-toolkit/utils";
8
+ var csvResponseBrand = /* @__PURE__ */ Symbol.for("@web-ts-toolkit/express-response-handler.csv-response");
9
+ var isCSVResponse = (value) => {
10
+ if (value instanceof CSVResponse) {
11
+ return true;
12
+ }
13
+ if (typeof value !== "object" || value === null) {
14
+ return false;
15
+ }
16
+ const candidate = value;
17
+ return candidate[csvResponseBrand] === true && typeof candidate.streamCsv === "function";
18
+ };
19
+ var _a;
20
+ _a = csvResponseBrand;
21
+ var CSVResponse = class {
22
+ constructor(dataset = [], options = {}) {
23
+ this[_a] = true;
24
+ this.dataset = castArray(dataset);
25
+ this.filename = options.filename || "download.csv";
26
+ this.processor = options.processor || ((value) => value);
27
+ if (isBoolean(options.headers)) {
28
+ this.headers = options.headers;
29
+ } else if (this.dataset.length > 0) {
30
+ this.headers = isPlainObject(this.dataset[0]);
31
+ }
32
+ }
33
+ streamCsv(res) {
34
+ const stream = format({ headers: this.headers });
35
+ res.set("Content-Type", "text/csv");
36
+ res.set("Content-Disposition", `attachment;filename=${this.filename}`);
37
+ stream.pipe(res);
38
+ stream.on("error", (error) => {
39
+ if (res.destroy) {
40
+ res.destroy(error);
41
+ return;
42
+ }
43
+ res.end();
44
+ });
45
+ stream.on("end", () => res.end());
46
+ this.dataset.forEach((value) => stream.write(this.processor(value)));
47
+ stream.end();
48
+ }
49
+ };
50
+
51
+ // src/responses/index.ts
52
+ var responseBrand = /* @__PURE__ */ Symbol.for("@web-ts-toolkit/express-response-handler.response");
53
+ var isResponse = (value) => {
54
+ if (value instanceof Response) {
55
+ return true;
56
+ }
57
+ if (typeof value !== "object" || value === null) {
58
+ return false;
59
+ }
60
+ const candidate = value;
61
+ return candidate[responseBrand] === true && typeof candidate.statusCode === "number" && "data" in candidate;
62
+ };
63
+ var _a2;
64
+ _a2 = responseBrand;
65
+ var Response = class {
66
+ constructor(statusCode = 200, data) {
67
+ this[_a2] = true;
68
+ this.statusCode = statusCode;
69
+ this.data = data;
70
+ }
71
+ };
72
+
73
+ // src/responses/success.ts
74
+ var OK = class extends Response {
75
+ constructor(data) {
76
+ super(200, data);
77
+ }
78
+ };
79
+ var Created = class extends Response {
80
+ constructor(data) {
81
+ super(201, data);
82
+ }
83
+ };
84
+ var Accepted = class extends Response {
85
+ constructor(data) {
86
+ super(202, data);
87
+ }
88
+ };
89
+ var NonAuthoritativeInfo = class extends Response {
90
+ constructor(data) {
91
+ super(203, data);
92
+ }
93
+ };
94
+ var NoContent = class extends Response {
95
+ constructor() {
96
+ super(204, void 0);
97
+ }
98
+ };
99
+ var ResetContent = class extends Response {
100
+ constructor(data) {
101
+ super(205, data);
102
+ }
103
+ };
104
+ var PartialContent = class extends Response {
105
+ constructor(data) {
106
+ super(206, data);
107
+ }
108
+ };
109
+ var MultiStatus = class extends Response {
110
+ constructor(data) {
111
+ super(207, data);
112
+ }
113
+ };
114
+ var AlreadyReported = class extends Response {
115
+ constructor(data) {
116
+ super(208, data);
117
+ }
118
+ };
119
+ var IMUsed = class extends Response {
120
+ constructor(data) {
121
+ super(226, data);
122
+ }
123
+ };
124
+
125
+ // src/http-response.ts
9
126
  import {
10
- Accepted,
11
- AlreadyReported,
12
- Created,
13
- IMUsed,
14
- MultiStatus,
15
- NoContent,
16
- NonAuthoritativeInfo,
17
- OK,
18
- PartialContent,
19
- ResetContent
20
- } from "./responses/success";
127
+ BadRequestError,
128
+ ConflictError,
129
+ ExpectationFailedError,
130
+ FailedDependencyError,
131
+ ForbiddenError,
132
+ GoneError,
133
+ LengthRequiredError,
134
+ LockedError,
135
+ MethodNotAllowedError,
136
+ MisdirectedRequestError,
137
+ NotAcceptableError,
138
+ NotFoundError,
139
+ PayloadTooLargeError,
140
+ PreconditionFailedError,
141
+ PreconditionRequiredError,
142
+ ProxyAuthRequiredError,
143
+ RequestHeaderFieldsTooLargeError,
144
+ RequestedRangeNotSatisfiableError,
145
+ RequestTimeoutError,
146
+ TeapotError,
147
+ TooManyRequestsError,
148
+ UnauthorizedError,
149
+ UnavailableForLegalReasonsError,
150
+ UnprocessableEntityError,
151
+ UnsupportedMediaTypeError,
152
+ UpgradeRequiredError,
153
+ UriTooLongError
154
+ } from "@web-ts-toolkit/http-errors";
155
+ var HttpResponse = {
156
+ ok: (...args) => new OK(...args),
157
+ created: (...args) => new Created(...args),
158
+ accepted: (...args) => new Accepted(...args),
159
+ nonAuthoritativeInfo: (...args) => new NonAuthoritativeInfo(...args),
160
+ noContent: (...args) => new NoContent(...args),
161
+ resetContent: (...args) => new ResetContent(...args),
162
+ partialContent: (...args) => new PartialContent(...args),
163
+ multiStatus: (...args) => new MultiStatus(...args),
164
+ alreadyReported: (...args) => new AlreadyReported(...args),
165
+ imUsed: (...args) => new IMUsed(...args),
166
+ badRequest: (...args) => new BadRequestError(...args),
167
+ unauthorized: (...args) => new UnauthorizedError(...args),
168
+ forbidden: (...args) => new ForbiddenError(...args),
169
+ notFound: (...args) => new NotFoundError(...args),
170
+ methodNotAllowed: (...args) => new MethodNotAllowedError(...args),
171
+ notAcceptable: (...args) => new NotAcceptableError(...args),
172
+ proxyAuthRequired: (...args) => new ProxyAuthRequiredError(...args),
173
+ requestTimeout: (...args) => new RequestTimeoutError(...args),
174
+ conflict: (...args) => new ConflictError(...args),
175
+ gone: (...args) => new GoneError(...args),
176
+ lengthRequired: (...args) => new LengthRequiredError(...args),
177
+ preconditionFailed: (...args) => new PreconditionFailedError(...args),
178
+ payloadTooLarge: (...args) => new PayloadTooLargeError(...args),
179
+ uriTooLong: (...args) => new UriTooLongError(...args),
180
+ unsupportedMediaType: (...args) => new UnsupportedMediaTypeError(...args),
181
+ requestedRangeNotSatisfiable: (...args) => new RequestedRangeNotSatisfiableError(...args),
182
+ expectationFailed: (...args) => new ExpectationFailedError(...args),
183
+ teapot: (...args) => new TeapotError(...args),
184
+ misdirectedRequest: (...args) => new MisdirectedRequestError(...args),
185
+ unprocessableEntity: (...args) => new UnprocessableEntityError(...args),
186
+ locked: (...args) => new LockedError(...args),
187
+ failedDependency: (...args) => new FailedDependencyError(...args),
188
+ upgradeRequired: (...args) => new UpgradeRequiredError(...args),
189
+ preconditionRequired: (...args) => new PreconditionRequiredError(...args),
190
+ tooManyRequests: (...args) => new TooManyRequestsError(...args),
191
+ requestHeaderFieldsTooLarge: (...args) => new RequestHeaderFieldsTooLargeError(...args),
192
+ unavailableForLegalReasons: (...args) => new UnavailableForLegalReasonsError(...args),
193
+ json: (...args) => new OK(...args),
194
+ csv: (...args) => new CSVResponse(...args)
195
+ };
196
+
197
+ // src/error-format.ts
198
+ import {
199
+ createAip193ErrorInfoDetail,
200
+ getCanonicalStatus,
201
+ toAip193ErrorPayload,
202
+ toRfc9457ErrorPayload
203
+ } from "@web-ts-toolkit/http-errors";
204
+ import { isArray, isPlainObject as isPlainObject2, isString, toStringRecord } from "@web-ts-toolkit/utils";
205
+ var toStatusCode = (status, code, fallbackStatusCode) => {
206
+ if (typeof status === "number") {
207
+ return status;
208
+ }
209
+ return typeof code === "number" ? code : fallbackStatusCode;
210
+ };
211
+ var toOptionalString = (value) => typeof value === "string" ? value : void 0;
212
+ var toMetadata = (value) => {
213
+ return toStringRecord(value);
214
+ };
215
+ var toArray = (value) => {
216
+ if (value === void 0 || value === null) {
217
+ return void 0;
218
+ }
219
+ return isArray(value) ? value : [value];
220
+ };
221
+ var toHttpErrorShape = (error, fallbackDomain) => ({
222
+ statusCode: error.statusCode ?? 500,
223
+ status: error.status,
224
+ message: error.message ?? "",
225
+ reason: error.reason,
226
+ domain: error.domain ?? fallbackDomain,
227
+ metadata: toMetadata(error.metadata),
228
+ details: toArray(error.details),
229
+ errors: error.errors,
230
+ type: error.type,
231
+ title: error.title,
232
+ instance: error.instance
233
+ });
234
+ var toProblemDetailsSource = (result) => {
235
+ if (isPlainObject2(result) && isPlainObject2(result.error)) {
236
+ return result.error;
237
+ }
238
+ return isPlainObject2(result) ? result : void 0;
239
+ };
240
+ var defaultErrorMessageProvider = function(error) {
241
+ const errorLike = error;
242
+ return errorLike.message ?? errorLike._message ?? String(error);
243
+ };
244
+ var toSimpleErrorPayload = (result) => isString(result) ? { message: result } : { ...result };
245
+ var toStructuredHttpErrorPayload = (error, errorDomain) => toAip193ErrorPayload(toHttpErrorShape(error, errorDomain), errorDomain);
246
+ var toRfc9457HttpErrorPayload = (error, errorDomain) => toRfc9457ErrorPayload(toHttpErrorShape(error, errorDomain));
247
+ var toStructuredGenericErrorPayload = (result, errorDomain) => {
248
+ if (isPlainObject2(result) && isPlainObject2(result.error)) {
249
+ const error = result.error;
250
+ const statusCode = typeof error.code === "number" ? error.code : 422;
251
+ const status = typeof error.status === "string" ? error.status : getCanonicalStatus(statusCode);
252
+ const message = typeof error.message === "string" ? error.message : "";
253
+ const details = toArray(error.details);
254
+ return {
255
+ error: {
256
+ code: statusCode,
257
+ status,
258
+ message,
259
+ ...details ? { details } : {}
260
+ }
261
+ };
262
+ }
263
+ if (isPlainObject2(result)) {
264
+ const statusCode = typeof result.code === "number" ? result.code : 422;
265
+ const status = typeof result.status === "string" ? result.status : getCanonicalStatus(statusCode);
266
+ const message = typeof result.message === "string" ? result.message : "";
267
+ const details = toArray(result.details) || [createAip193ErrorInfoDetail(status, errorDomain)];
268
+ return {
269
+ error: {
270
+ code: statusCode,
271
+ status,
272
+ message,
273
+ ...details ? { details } : {}
274
+ }
275
+ };
276
+ }
277
+ return {
278
+ error: {
279
+ code: 422,
280
+ status: getCanonicalStatus(422),
281
+ message: String(result),
282
+ details: [createAip193ErrorInfoDetail(getCanonicalStatus(422), errorDomain)]
283
+ }
284
+ };
285
+ };
286
+ var toRfc9457GenericErrorPayload = (result) => {
287
+ const problem = toProblemDetailsSource(result);
288
+ if (problem) {
289
+ const statusCode = toStatusCode(problem.status, problem.code, 422);
290
+ return toRfc9457ErrorPayload({
291
+ statusCode,
292
+ message: toOptionalString(problem.detail) ?? toOptionalString(problem.message) ?? "",
293
+ errors: problem.errors,
294
+ type: toOptionalString(problem.type),
295
+ title: toOptionalString(problem.title),
296
+ instance: toOptionalString(problem.instance)
297
+ });
298
+ }
299
+ return toRfc9457ErrorPayload({
300
+ statusCode: 422,
301
+ message: String(result)
302
+ });
303
+ };
304
+
305
+ // src/error-formats.ts
306
+ var ErrorFormats = {
307
+ simple: "simple",
308
+ aip193: "aip193",
309
+ rfc9457: "rfc9457"
310
+ };
311
+
312
+ // src/create-handler.ts
313
+ var promisify = (fn) => (value) => Promise.resolve().then(() => fn(value));
314
+ var invokePostHook = (hook, value) => {
315
+ void hook(value).catch(() => void 0);
316
+ };
317
+ var RFC_9457_CONTENT_TYPE = "application/problem+json";
318
+ var shouldSkipResponse = (res, event) => res.headersSent || event.canceled;
319
+ var sendProblemJson = (res, statusCode, payload, contentType) => {
320
+ res.status(statusCode);
321
+ res.set("Content-Type", contentType);
322
+ res.send(payload);
323
+ };
324
+ var sendHttpErrorByFormat = {
325
+ [ErrorFormats.simple]: (res, error) => {
326
+ const payload = { message: error.message ?? "" };
327
+ if (error.errors !== void 0) {
328
+ payload.errors = error.errors;
329
+ }
330
+ res.status(error.statusCode ?? 500).send(payload);
331
+ },
332
+ [ErrorFormats.aip193]: (res, error, domain) => {
333
+ res.status(error.statusCode ?? 500).send(toStructuredHttpErrorPayload(error, domain));
334
+ },
335
+ [ErrorFormats.rfc9457]: (res, error, domain) => {
336
+ sendProblemJson(res, error.statusCode ?? 500, toRfc9457HttpErrorPayload(error, domain), RFC_9457_CONTENT_TYPE);
337
+ }
338
+ };
339
+ var sendGenericErrorByFormat = {
340
+ [ErrorFormats.simple]: (res, result) => {
341
+ res.status(422).send(toSimpleErrorPayload(result));
342
+ },
343
+ [ErrorFormats.aip193]: (res, result, domain) => {
344
+ const payload = toStructuredGenericErrorPayload(result, domain);
345
+ res.status(payload.error.code).send(payload);
346
+ },
347
+ [ErrorFormats.rfc9457]: (res, result) => {
348
+ const payload = toRfc9457GenericErrorPayload(result);
349
+ sendProblemJson(res, payload.status ?? 422, payload, RFC_9457_CONTENT_TYPE);
350
+ }
351
+ };
352
+ var assertMiddleware = (fn) => {
353
+ assert.ok(isFunction(fn), "middleware handler must be a function");
354
+ };
355
+ var normalizeMiddlewareList = (fns) => {
356
+ assert.ok(fns.length > 0, "at least one middleware handler is required");
357
+ if (fns.length > 1) {
358
+ fns.forEach(assertMiddleware);
359
+ return fns;
360
+ }
361
+ if (isArray2(fns[0])) {
362
+ assert.ok(fns[0].length > 0, "at least one middleware handler is required");
363
+ fns[0].forEach(assertMiddleware);
364
+ return fns[0];
365
+ }
366
+ assertMiddleware(fns[0]);
367
+ return [fns[0]];
368
+ };
369
+ function createHandler(options = {}) {
370
+ const errorFormat = options.errorFormat ?? ErrorFormats.simple;
371
+ const errorDomain = options.errorDomain ?? "express-response-handler";
372
+ const rfc9457ContentType = options.rfc9457ContentType ?? RFC_9457_CONTENT_TYPE;
373
+ let errorMessageProvider = defaultErrorMessageProvider;
374
+ let preJson = null;
375
+ let postJson = null;
376
+ let preError = null;
377
+ let postError = null;
378
+ let preJsonHook = null;
379
+ let postJsonHook = null;
380
+ let preErrorHook = null;
381
+ let postErrorHook = null;
382
+ const updateHook = (fn, name, setState, rebuild) => {
383
+ if (fn === null) {
384
+ setState(null, null);
385
+ rebuild();
386
+ return;
387
+ }
388
+ assert.ok(isFunction(fn), `${name} hook must be a function`);
389
+ setState(fn, promisify(fn));
390
+ rebuild();
391
+ };
392
+ const sendBaseJson = function(res, data, event) {
393
+ if (shouldSkipResponse(res, event)) {
394
+ return;
395
+ }
396
+ if (data === void 0) {
397
+ return;
398
+ }
399
+ if (isResponse(data)) {
400
+ res.status(data.statusCode).json(data.data);
401
+ return;
402
+ }
403
+ if (isCSVResponse(data)) {
404
+ data.streamCsv(res);
405
+ return;
406
+ }
407
+ res.json(data);
408
+ };
409
+ const sendBaseError = function(res, err, event) {
410
+ if (shouldSkipResponse(res, event)) {
411
+ return;
412
+ }
413
+ const error = err;
414
+ if (error.statusCode) {
415
+ if (errorFormat === ErrorFormats.rfc9457) {
416
+ sendProblemJson(
417
+ res,
418
+ error.statusCode ?? 500,
419
+ toRfc9457HttpErrorPayload(error, errorDomain),
420
+ rfc9457ContentType
421
+ );
422
+ return;
423
+ }
424
+ sendHttpErrorByFormat[errorFormat](res, error, errorDomain);
425
+ return;
426
+ }
427
+ const result = errorMessageProvider(err);
428
+ if (errorFormat === ErrorFormats.rfc9457) {
429
+ const payload = toRfc9457GenericErrorPayload(result);
430
+ sendProblemJson(res, payload.status ?? 422, payload, rfc9457ContentType);
431
+ return;
432
+ }
433
+ sendGenericErrorByFormat[errorFormat](res, result, errorDomain);
434
+ };
435
+ let sendJson = sendBaseJson;
436
+ let sendError = sendBaseError;
437
+ const rebuildSendJson = () => {
438
+ if (!preJsonHook && !postJsonHook) {
439
+ sendJson = sendBaseJson;
440
+ return;
441
+ }
442
+ sendJson = function(res, data, event) {
443
+ const finalize = () => {
444
+ try {
445
+ sendBaseJson(res, data, event);
446
+ } catch (err) {
447
+ sendError(res, err, event);
448
+ return;
449
+ }
450
+ if (postJsonHook) {
451
+ invokePostHook(postJsonHook, data);
452
+ }
453
+ };
454
+ if (preJsonHook) {
455
+ preJsonHook(data).then(finalize, (err) => sendError(res, err, event));
456
+ return;
457
+ }
458
+ finalize();
459
+ };
460
+ };
461
+ const rebuildSendError = () => {
462
+ if (!preErrorHook && !postErrorHook) {
463
+ sendError = sendBaseError;
464
+ return;
465
+ }
466
+ sendError = function(res, err, event) {
467
+ const finalize = () => {
468
+ sendBaseError(res, err, event);
469
+ if (postErrorHook) {
470
+ invokePostHook(postErrorHook, err);
471
+ }
472
+ };
473
+ if (preErrorHook) {
474
+ preErrorHook(err).then(finalize, (hookErr) => sendBaseError(res, hookErr, event));
475
+ return;
476
+ }
477
+ finalize();
478
+ };
479
+ };
480
+ const handlePromise = function(res, promise, event) {
481
+ Promise.resolve(promise).then((data) => {
482
+ if (event.nextError) {
483
+ sendError(res, event.nextError, event);
484
+ return;
485
+ }
486
+ sendJson(res, data, event);
487
+ }).catch((err) => sendError(res, err, event));
488
+ };
489
+ const handleResult = function(res, result, event) {
490
+ if (shouldSkipResponse(res, event)) {
491
+ return;
492
+ }
493
+ if (event.nextError) {
494
+ sendError(res, event.nextError, event);
495
+ return;
496
+ }
497
+ if (isPromise(result)) {
498
+ handlePromise(res, result, event);
499
+ return;
500
+ }
501
+ sendJson(res, result, event);
502
+ };
503
+ const nextFn = function(event, next) {
504
+ return function(...args) {
505
+ if (args.length === 0) {
506
+ event.canceled = true;
507
+ next();
508
+ return;
509
+ }
510
+ if (args[0] instanceof Error) {
511
+ event.nextError = args[0];
512
+ return;
513
+ }
514
+ event.nextError = new TypeError("next(value) is not supported; return a value instead");
515
+ };
516
+ };
517
+ const routerFn = function(fn) {
518
+ return function(req, res, next) {
519
+ const event = { canceled: false, nextError: null };
520
+ try {
521
+ const result = fn(req, res, nextFn(event, next));
522
+ handleResult(res, result, event);
523
+ } catch (err) {
524
+ if (res.headersSent) {
525
+ return;
526
+ }
527
+ sendError(res, err, event);
528
+ }
529
+ };
530
+ };
531
+ const handleResponse = function(...fns) {
532
+ const middlewares = normalizeMiddlewareList(fns);
533
+ return middlewares.length === 1 ? routerFn(middlewares[0]) : middlewares.map(routerFn);
534
+ };
535
+ return {
536
+ handleResponse,
537
+ handleResult,
538
+ handlePromise,
539
+ HttpResponse,
540
+ createHandler,
541
+ get errorMessageProvider() {
542
+ return errorMessageProvider;
543
+ },
544
+ set errorMessageProvider(fn) {
545
+ assert.ok(isFunction(fn), "error message provider must be a function");
546
+ errorMessageProvider = fn;
547
+ },
548
+ get preJson() {
549
+ return preJson;
550
+ },
551
+ set preJson(fn) {
552
+ updateHook(
553
+ fn,
554
+ "pre-json",
555
+ (syncHook, asyncHook) => {
556
+ preJson = syncHook;
557
+ preJsonHook = asyncHook;
558
+ },
559
+ rebuildSendJson
560
+ );
561
+ },
562
+ get postJson() {
563
+ return postJson;
564
+ },
565
+ set postJson(fn) {
566
+ updateHook(
567
+ fn,
568
+ "post-json",
569
+ (syncHook, asyncHook) => {
570
+ postJson = syncHook;
571
+ postJsonHook = asyncHook;
572
+ },
573
+ rebuildSendJson
574
+ );
575
+ },
576
+ get preError() {
577
+ return preError;
578
+ },
579
+ set preError(fn) {
580
+ updateHook(
581
+ fn,
582
+ "pre-error",
583
+ (syncHook, asyncHook) => {
584
+ preError = syncHook;
585
+ preErrorHook = asyncHook;
586
+ },
587
+ rebuildSendError
588
+ );
589
+ },
590
+ get postError() {
591
+ return postError;
592
+ },
593
+ set postError(fn) {
594
+ updateHook(
595
+ fn,
596
+ "post-error",
597
+ (syncHook, asyncHook) => {
598
+ postError = syncHook;
599
+ postErrorHook = asyncHook;
600
+ },
601
+ rebuildSendError
602
+ );
603
+ }
604
+ };
605
+ }
606
+
607
+ // src/index.ts
608
+ var apiHandler = createHandler();
609
+ var index_default = apiHandler;
21
610
  export {
22
611
  Accepted,
23
612
  AlreadyReported,
@@ -33,6 +622,6 @@ export {
33
622
  PartialContent,
34
623
  ResetContent,
35
624
  Response,
36
- createHandler2 as createHandler,
625
+ createHandler,
37
626
  index_default as default
38
627
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@web-ts-toolkit/express-response-handler",
3
3
  "description": "FastAPI-style return-value response handling for Express",
4
4
  "homepage": "https://web-ts-toolkit.pages.dev/docs/packages/express-response-handler",
5
- "version": "0.31.0",
5
+ "version": "0.31.2",
6
6
  "sideEffects": false,
7
7
  "keywords": [
8
8
  "express",
@@ -51,8 +51,8 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@fast-csv/format": "^5.0.7",
54
- "@web-ts-toolkit/http-errors": "0.31.0",
55
- "@web-ts-toolkit/utils": "0.31.0"
54
+ "@web-ts-toolkit/http-errors": "0.31.2",
55
+ "@web-ts-toolkit/utils": "0.31.2"
56
56
  },
57
57
  "files": [
58
58
  "**/*",
package/public-types.js CHANGED
@@ -16,12 +16,20 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/public-types.ts
19
21
  var public_types_exports = {};
20
22
  __export(public_types_exports, {
21
- ErrorFormats: () => import_error_formats.ErrorFormats
23
+ ErrorFormats: () => ErrorFormats
22
24
  });
23
25
  module.exports = __toCommonJS(public_types_exports);
24
- var import_error_formats = require("./error-formats");
26
+
27
+ // src/error-formats.ts
28
+ var ErrorFormats = {
29
+ simple: "simple",
30
+ aip193: "aip193",
31
+ rfc9457: "rfc9457"
32
+ };
25
33
  // Annotate the CommonJS export names for ESM import in node:
26
34
  0 && (module.exports = {
27
35
  ErrorFormats
package/public-types.mjs CHANGED
@@ -1,4 +1,9 @@
1
- import { ErrorFormats } from "./error-formats";
1
+ // src/error-formats.ts
2
+ var ErrorFormats = {
3
+ simple: "simple",
4
+ aip193: "aip193",
5
+ rfc9457: "rfc9457"
6
+ };
2
7
  export {
3
8
  ErrorFormats
4
9
  };
@@ -9,7 +9,10 @@ type CsvStreamResponse = {
9
9
  destroy?(error?: Error): void;
10
10
  end(): void;
11
11
  };
12
+ declare const csvResponseBrand: unique symbol;
13
+ declare const isCSVResponse: (value: unknown) => value is CSVResponse;
12
14
  declare class CSVResponse {
15
+ readonly [csvResponseBrand] = true;
13
16
  readonly dataset: unknown[];
14
17
  readonly filename: string;
15
18
  readonly processor: CsvProcessor;
@@ -18,4 +21,4 @@ declare class CSVResponse {
18
21
  streamCsv(res: CsvStreamResponse): void;
19
22
  }
20
23
 
21
- export { CSVResponse };
24
+ export { CSVResponse, csvResponseBrand, isCSVResponse };