@webpieces/http-server 0.4.789 → 0.4.791
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/README.md +20 -12
- package/package.json +5 -5
- package/src/ExpressResponseWriter.d.ts +1 -1
- package/src/ExpressResponseWriter.js +1 -1
- package/src/ExpressResponseWriter.js.map +1 -1
- package/src/ExpressWrapper.d.ts +27 -30
- package/src/ExpressWrapper.js +42 -41
- package/src/ExpressWrapper.js.map +1 -1
- package/src/StreamExpressWrapper.d.ts +1 -4
- package/src/StreamExpressWrapper.js +2 -4
- package/src/StreamExpressWrapper.js.map +1 -1
- package/src/WebpiecesExpressRouter.d.ts +1 -17
- package/src/WebpiecesExpressRouter.js +3 -24
- package/src/WebpiecesExpressRouter.js.map +1 -1
- package/src/WebpiecesMiddleware.d.ts +3 -6
- package/src/WebpiecesMiddleware.js +5 -7
- package/src/WebpiecesMiddleware.js.map +1 -1
- package/src/index.d.ts +0 -2
- package/src/index.js +3 -4
- package/src/index.js.map +1 -1
- package/src/ApiErrorHttpMapper.d.ts +0 -49
- package/src/ApiErrorHttpMapper.js +0 -73
- package/src/ApiErrorHttpMapper.js.map +0 -1
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ApiErrorHttpMapper = void 0;
|
|
4
|
-
const core_util_1 = require("@webpieces/core-util");
|
|
5
|
-
/**
|
|
6
|
-
* HTTP adapter for the transport-neutral API error taxonomy, and the webpieces DEFAULT
|
|
7
|
-
* {@link ErrorTranslators} half on the server: an error in, the exact HTTP response out.
|
|
8
|
-
*
|
|
9
|
-
* An app that registers its own translator declines by DELEGATING here —
|
|
10
|
-
* `new ApiErrorHttpMapper('gui').toResponse(error)`, naming the mode its router uses — so "no
|
|
11
|
-
* translator registered" and "a translator that does not claim this error" produce byte-identical
|
|
12
|
-
* responses.
|
|
13
|
-
*/
|
|
14
|
-
class ApiErrorHttpMapper {
|
|
15
|
-
endUserStatus;
|
|
16
|
-
/**
|
|
17
|
-
* @param endUserStatus - REQUIRED, with no default. A router configured with
|
|
18
|
-
* `setEndUserStatus('edge')` must pass `'edge'` here too when it delegates from its own
|
|
19
|
-
* translator, and a default would make `new ApiErrorHttpMapper()` publish 266 for a
|
|
20
|
-
* delegated end-user error on an edge router with nothing to grep for — a widening that is an
|
|
21
|
-
* ABSENCE rather than a token (`.claude/rules/no-backwards-compat.md`, shim shape #5). Saying
|
|
22
|
-
* the mode out loud keeps the mismatch a thing you can see at the call site.
|
|
23
|
-
*/
|
|
24
|
-
constructor(endUserStatus) {
|
|
25
|
-
this.endUserStatus = endUserStatus;
|
|
26
|
-
}
|
|
27
|
-
boundary = new core_util_1.ApiErrorBoundary();
|
|
28
|
-
genericMessages = new Map([
|
|
29
|
-
[266, 'End User Error'],
|
|
30
|
-
[400, 'Bad Request'],
|
|
31
|
-
[401, 'Unauthorized'],
|
|
32
|
-
[403, 'Forbidden'],
|
|
33
|
-
[404, 'Not Found'],
|
|
34
|
-
[408, 'Request Timeout'],
|
|
35
|
-
[409, 'Conflict'],
|
|
36
|
-
[412, 'Precondition Failed'],
|
|
37
|
-
[415, 'Unsupported Media Type'],
|
|
38
|
-
[422, 'Unprocessable Content'],
|
|
39
|
-
[429, 'Too Many Requests'],
|
|
40
|
-
[500, 'Internal Server Error'],
|
|
41
|
-
[501, 'Not Implemented'],
|
|
42
|
-
[502, 'Bad Gateway'],
|
|
43
|
-
[503, 'Service Unavailable'],
|
|
44
|
-
[504, 'Gateway Timeout'],
|
|
45
|
-
]);
|
|
46
|
-
/**
|
|
47
|
-
* The payload IS the answer. {@link ApiErrorBoundary.encode} has already applied both shared
|
|
48
|
-
* rules — a caller-local `ApiConnectionError` (and every non-`ApiError`) publishes as
|
|
49
|
-
* `implementation`, and only an `ApiEndUserError`'s own message is disclosed — and the payload
|
|
50
|
-
* carries everything HTTP needs after that: `kind`, `statusCode`, `edgeHttpStatus` and
|
|
51
|
-
* `retryAfterSeconds`. So there is no `instanceof` here and nothing re-derived from the raw
|
|
52
|
-
* error; unknown throws and caller-local failures come out as a 500 implementation failure
|
|
53
|
-
* because that is what the payload says.
|
|
54
|
-
*/
|
|
55
|
-
toResponse(error) {
|
|
56
|
-
const payload = this.boundary.encode(error);
|
|
57
|
-
// The boundary never publishes kind 'connection' — that is the whole first rule above — so
|
|
58
|
-
// this is the published subset ApiErrorHttpStatus.codeFor accepts.
|
|
59
|
-
const kind = payload.kind;
|
|
60
|
-
const status = this.endUserStatus === 'edge' && kind === 'end-user'
|
|
61
|
-
? (payload.edgeHttpStatus ?? 400)
|
|
62
|
-
: core_util_1.ApiErrorHttpStatus.codeFor(kind, payload.statusCode);
|
|
63
|
-
const headers = payload.retryAfterSeconds !== undefined
|
|
64
|
-
? [new core_util_1.HttpHeader('retry-after', String(payload.retryAfterSeconds))]
|
|
65
|
-
: [];
|
|
66
|
-
return new core_util_1.HttpResponseDto(new core_util_1.HttpResponseStatus(status, this.genericMessage(status)), headers, payload);
|
|
67
|
-
}
|
|
68
|
-
genericMessage(code) {
|
|
69
|
-
return this.genericMessages.get(code) ?? 'Request Failed';
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
exports.ApiErrorHttpMapper = ApiErrorHttpMapper;
|
|
73
|
-
//# sourceMappingURL=ApiErrorHttpMapper.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ApiErrorHttpMapper.js","sourceRoot":"","sources":["../../../../../packages/http/http-server/src/ApiErrorHttpMapper.ts"],"names":[],"mappings":";;;AAAA,oDAO8B;AAiB9B;;;;;;;;GAQG;AACH,MAAa,kBAAkB;IASE;IAR7B;;;;;;;OAOG;IACH,YAA6B,aAA4B;QAA5B,kBAAa,GAAb,aAAa,CAAe;IAAG,CAAC;IAE5C,QAAQ,GAAG,IAAI,4BAAgB,EAAE,CAAC;IAClC,eAAe,GAAwB,IAAI,GAAG,CAAiB;QAC5E,CAAC,GAAG,EAAE,gBAAgB,CAAC;QACvB,CAAC,GAAG,EAAE,aAAa,CAAC;QACpB,CAAC,GAAG,EAAE,cAAc,CAAC;QACrB,CAAC,GAAG,EAAE,WAAW,CAAC;QAClB,CAAC,GAAG,EAAE,WAAW,CAAC;QAClB,CAAC,GAAG,EAAE,iBAAiB,CAAC;QACxB,CAAC,GAAG,EAAE,UAAU,CAAC;QACjB,CAAC,GAAG,EAAE,qBAAqB,CAAC;QAC5B,CAAC,GAAG,EAAE,wBAAwB,CAAC;QAC/B,CAAC,GAAG,EAAE,uBAAuB,CAAC;QAC9B,CAAC,GAAG,EAAE,mBAAmB,CAAC;QAC1B,CAAC,GAAG,EAAE,uBAAuB,CAAC;QAC9B,CAAC,GAAG,EAAE,iBAAiB,CAAC;QACxB,CAAC,GAAG,EAAE,aAAa,CAAC;QACpB,CAAC,GAAG,EAAE,qBAAqB,CAAC;QAC5B,CAAC,GAAG,EAAE,iBAAiB,CAAC;KAC3B,CAAC,CAAC;IAEH;;;;;;;;OAQG;IACI,UAAU,CAAC,KAAY;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5C,2FAA2F;QAC3F,mEAAmE;QACnE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAqB,CAAC;QAC3C,MAAM,MAAM,GACR,IAAI,CAAC,aAAa,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU;YAChD,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,IAAI,GAAG,CAAC;YACjC,CAAC,CAAC,8BAAkB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QAC/D,MAAM,OAAO,GACT,OAAO,CAAC,iBAAiB,KAAK,SAAS;YACnC,CAAC,CAAC,CAAC,IAAI,sBAAU,CAAC,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACpE,CAAC,CAAC,EAAE,CAAC;QACb,OAAO,IAAI,2BAAe,CACtB,IAAI,8BAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAC3D,OAAO,EACP,OAAO,CACV,CAAC;IACN,CAAC;IAEM,cAAc,CAAC,IAAY;QAC9B,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC;IAC9D,CAAC;CACJ;AA/DD,gDA+DC","sourcesContent":["import {\n ApiErrorBoundary,\n ApiErrorHttpStatus,\n HttpHeader,\n HttpResponseDto,\n HttpResponseStatus,\n PublishedKind,\n} from '@webpieces/core-util';\n\n/**\n * How a server answers an {@link ApiEndUserError}.\n *\n * - `'gui'` (the default): 266. The call succeeded; the GUI (or any webpieces client, including the\n * next server-to-server hop) decodes the error and shows its message. `edgeHttpStatus` is ignored,\n * and still travels in the body so a downstream edge can use it.\n * - `'edge'`: a partner/public REST edge whose published contract promises real 4xx statuses. The\n * response carries `edgeHttpStatus`, or 400 when the thrower set none (still a caller-fixable\n * end-user outcome). Only for the OUTERMOST server: a webpieces client receiving an end-user body at\n * anything other than 266 treats it as a mismatched response, so internal hops stay `'gui'`.\n *\n * Chosen per router with `WebpiecesExpressRouter.setEndUserStatus`.\n */\nexport type EndUserStatus = 'gui' | 'edge';\n\n/**\n * HTTP adapter for the transport-neutral API error taxonomy, and the webpieces DEFAULT\n * {@link ErrorTranslators} half on the server: an error in, the exact HTTP response out.\n *\n * An app that registers its own translator declines by DELEGATING here —\n * `new ApiErrorHttpMapper('gui').toResponse(error)`, naming the mode its router uses — so \"no\n * translator registered\" and \"a translator that does not claim this error\" produce byte-identical\n * responses.\n */\nexport class ApiErrorHttpMapper {\n /**\n * @param endUserStatus - REQUIRED, with no default. A router configured with\n * `setEndUserStatus('edge')` must pass `'edge'` here too when it delegates from its own\n * translator, and a default would make `new ApiErrorHttpMapper()` publish 266 for a\n * delegated end-user error on an edge router with nothing to grep for — a widening that is an\n * ABSENCE rather than a token (`.claude/rules/no-backwards-compat.md`, shim shape #5). Saying\n * the mode out loud keeps the mismatch a thing you can see at the call site.\n */\n constructor(private readonly endUserStatus: EndUserStatus) {}\n\n private readonly boundary = new ApiErrorBoundary();\n private readonly genericMessages: Map<number, string> = new Map<number, string>([\n [266, 'End User Error'],\n [400, 'Bad Request'],\n [401, 'Unauthorized'],\n [403, 'Forbidden'],\n [404, 'Not Found'],\n [408, 'Request Timeout'],\n [409, 'Conflict'],\n [412, 'Precondition Failed'],\n [415, 'Unsupported Media Type'],\n [422, 'Unprocessable Content'],\n [429, 'Too Many Requests'],\n [500, 'Internal Server Error'],\n [501, 'Not Implemented'],\n [502, 'Bad Gateway'],\n [503, 'Service Unavailable'],\n [504, 'Gateway Timeout'],\n ]);\n\n /**\n * The payload IS the answer. {@link ApiErrorBoundary.encode} has already applied both shared\n * rules — a caller-local `ApiConnectionError` (and every non-`ApiError`) publishes as\n * `implementation`, and only an `ApiEndUserError`'s own message is disclosed — and the payload\n * carries everything HTTP needs after that: `kind`, `statusCode`, `edgeHttpStatus` and\n * `retryAfterSeconds`. So there is no `instanceof` here and nothing re-derived from the raw\n * error; unknown throws and caller-local failures come out as a 500 implementation failure\n * because that is what the payload says.\n */\n public toResponse(error: Error): HttpResponseDto {\n const payload = this.boundary.encode(error);\n // The boundary never publishes kind 'connection' — that is the whole first rule above — so\n // this is the published subset ApiErrorHttpStatus.codeFor accepts.\n const kind = payload.kind as PublishedKind;\n const status =\n this.endUserStatus === 'edge' && kind === 'end-user'\n ? (payload.edgeHttpStatus ?? 400)\n : ApiErrorHttpStatus.codeFor(kind, payload.statusCode);\n const headers =\n payload.retryAfterSeconds !== undefined\n ? [new HttpHeader('retry-after', String(payload.retryAfterSeconds))]\n : [];\n return new HttpResponseDto(\n new HttpResponseStatus(status, this.genericMessage(status)),\n headers,\n payload,\n );\n }\n\n public genericMessage(code: number): string {\n return this.genericMessages.get(code) ?? 'Request Failed';\n }\n}\n"]}
|