@webpieces/core-util 0.4.803 → 0.4.804
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/http/ApiCallInfo.d.ts +11 -3
- package/src/http/ApiCallInfo.js.map +1 -1
- package/src/http/HttpEndpointOptions.d.ts +37 -0
- package/src/http/HttpEndpointOptions.js.map +1 -1
- package/src/http/api-type.d.ts +71 -0
- package/src/http/api-type.js +108 -0
- package/src/http/api-type.js.map +1 -0
- package/src/http/numeric-field-decorators.d.ts +65 -0
- package/src/http/numeric-field-decorators.js +58 -0
- package/src/http/numeric-field-decorators.js.map +1 -0
- package/src/index.d.ts +5 -1
- package/src/index.js +20 -4
- package/src/index.js.map +1 -1
package/package.json
CHANGED
|
@@ -31,7 +31,15 @@ import { ApiMethodInfo } from './ApiMethodInfo';
|
|
|
31
31
|
* Per CLAUDE.md: data-only structures are classes, not interfaces.
|
|
32
32
|
*/
|
|
33
33
|
/** Which half of the exchange this tag describes: the outgoing 'request' or the returning 'response'. */
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Which HALF of one api call a log line describes.
|
|
36
|
+
*
|
|
37
|
+
* Renamed from `ApiType`, which collided with the `@ApiType(...)` CONTRACT decorator and read as if
|
|
38
|
+
* it were about the kind of API rather than the direction of one line. Per
|
|
39
|
+
* `.claude/rules/no-backwards-compat.md` the old spelling is deleted rather than aliased, so a caller
|
|
40
|
+
* on the old name stops compiling and the error names this one.
|
|
41
|
+
*/
|
|
42
|
+
export type ApiCallDirection = 'request' | 'response';
|
|
35
43
|
/**
|
|
36
44
|
* Response outcome. 'success' covers 2xx AND user errors (400/401/403/404/266 — a successfully
|
|
37
45
|
* handled "you made a mistake"); 'failure' is a genuine server error. See {@link LogApiCallImpl.isUserError}.
|
|
@@ -43,7 +51,7 @@ export declare class ApiCallInfo {
|
|
|
43
51
|
/** The call identity (side, apiClass, methodName, controllerName) — surfaces nested under
|
|
44
52
|
* `jsonPayload.api.method`. */
|
|
45
53
|
readonly method: ApiMethodInfo;
|
|
46
|
-
readonly type:
|
|
54
|
+
readonly type: ApiCallDirection;
|
|
47
55
|
/** Response only — undefined on the 'request' tag. */
|
|
48
56
|
readonly result?: ApiResult | undefined;
|
|
49
57
|
/**
|
|
@@ -76,7 +84,7 @@ export declare class ApiCallInfo {
|
|
|
76
84
|
constructor(
|
|
77
85
|
/** The call identity (side, apiClass, methodName, controllerName) — surfaces nested under
|
|
78
86
|
* `jsonPayload.api.method`. */
|
|
79
|
-
method: ApiMethodInfo, type:
|
|
87
|
+
method: ApiMethodInfo, type: ApiCallDirection,
|
|
80
88
|
/** Response only — undefined on the 'request' tag. */
|
|
81
89
|
result?: ApiResult | undefined,
|
|
82
90
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiCallInfo.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/ApiCallInfo.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ApiCallInfo.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/ApiCallInfo.ts"],"names":[],"mappings":";;;AAsDA,MAAa,WAAW;IAIP;IACA;IAEA;IAYA;IAUA;IAGA;IAEA;IAjCb;IACI;oCACgC;IACvB,MAAqB,EACrB,IAAsB;IAC/B,sDAAsD;IAC7C,MAAkB;IAC3B;;;;;;;;;;OAUG;IACM,UAAmB;IAC5B;;;;;;;;OAQG;IACM,WAAoB;IAC7B;yFACqF;IAC5E,YAAqB;IAC9B,4FAA4F;IACnF,aAAsB;QA9BtB,WAAM,GAAN,MAAM,CAAe;QACrB,SAAI,GAAJ,IAAI,CAAkB;QAEtB,WAAM,GAAN,MAAM,CAAY;QAYlB,eAAU,GAAV,UAAU,CAAS;QAUnB,gBAAW,GAAX,WAAW,CAAS;QAGpB,iBAAY,GAAZ,YAAY,CAAS;QAErB,kBAAa,GAAb,aAAa,CAAS;IAChC,CAAC;CACP;AApCD,kCAoCC","sourcesContent":["import { ApiMethodInfo } from './ApiMethodInfo';\n\n/**\n * ApiCallInfo - the structured tag stamped into RequestContext around every API call\n * (by {@link LogApiCallImpl}), so ANY log line emitted during the call inherits a filterable\n * `api` object rather than only the req/resp text lines.\n *\n * The node logging backends (winston/bunyan) read this struct out of context via\n * `RequestContext.buildStructuredLogFields()` and emit it AS AN OBJECT under `jsonPayload.api`,\n * which unlocks GCP Cloud Logging filters like:\n * - `jsonPayload.api.method.side=\"client\"` — every outbound call this process made\n * - `jsonPayload.api.method.side=\"server\"` — every inbound call it handled\n * - `jsonPayload.api.method.apiClass=\"SaveApi\"` — one logical method, BOTH sides (client + server)\n * - `jsonPayload.api.result=\"failure\"` — failed exchanges only\n * - `jsonPayload.api.durationMs>1000` — slow calls, either side\n * - `jsonPayload.api.responseSize>100000` — the fat responses (the ones that get chunked)\n * - `jsonPayload.api.responseCount>100` — responses containing many logical items\n * - `jsonPayload.api:*` — \"API traffic only\" (tracing + the recorder)\n *\n * IMPORTANT: the field names here (and on the nested {@link ApiMethodInfo}) ARE the GCP field names —\n * rename a field and the filter renames with it. The identity lives NESTED under `api.method`\n * (`api.method.{side,apiClass,methodName,controllerName}`); `api.type` and `api.result` sit at the top.\n *\n * NOTE: the request `httpMethod`/`path` are NOT here — an inbound request stamps them as the separate\n * top-level logged keys `jsonPayload.httpMethod` / `jsonPayload.requestPath` (see\n * {@link WebpiecesCoreHeaders} + `RequestContextHeaders.fillFromRequest`). Outbound client calls have\n * no inbound path, so they carry only the `api` identity.\n *\n * Per-hop only: the underlying `API_CALL_INFO` ContextKey is NOT transferred over the wire, so a\n * downstream server stamps its own `side:'server'` rather than inheriting the caller's `side:'client'`.\n *\n * Per CLAUDE.md: data-only structures are classes, not interfaces.\n */\n\n/** Which half of the exchange this tag describes: the outgoing 'request' or the returning 'response'. */\n/**\n * Which HALF of one api call a log line describes.\n *\n * Renamed from `ApiType`, which collided with the `@ApiType(...)` CONTRACT decorator and read as if\n * it were about the kind of API rather than the direction of one line. Per\n * `.claude/rules/no-backwards-compat.md` the old spelling is deleted rather than aliased, so a caller\n * on the old name stops compiling and the error names this one.\n */\nexport type ApiCallDirection = 'request' | 'response';\n\n/**\n * Response outcome. 'success' covers 2xx AND user errors (400/401/403/404/266 — a successfully\n * handled \"you made a mistake\"); 'failure' is a genuine server error. See {@link LogApiCallImpl.isUserError}.\n */\nexport type ApiResult = 'success' | 'failure';\n\n/** Re-exported from {@link ApiMethodInfo} (its true home) so existing `ApiSide` imports keep working. */\nexport type { ApiSide } from './ApiMethodInfo';\n\nexport class ApiCallInfo {\n constructor(\n /** The call identity (side, apiClass, methodName, controllerName) — surfaces nested under\n * `jsonPayload.api.method`. */\n readonly method: ApiMethodInfo,\n readonly type: ApiCallDirection,\n /** Response only — undefined on the 'request' tag. */\n readonly result?: ApiResult,\n /**\n * Wall-clock milliseconds the call took. RESPONSE tag only (undefined on 'request') — a\n * request has no duration yet. Present on BOTH the success and failure paths, so\n * `jsonPayload.api.durationMs>1000 AND api.result=\"failure\"` finds slow failures.\n *\n * There is deliberately no `statusCode` beside this. LogApiCall runs deep in the stack over\n * in-process calls, pubsub handlers, and cloud-task enqueues — none of which have an HTTP\n * status — and business logic must not know about HTTP. `result` (see {@link ApiResult}) is\n * the transport-neutral outcome, exactly as {@link LogApiCallImpl.isUserError} classifies by\n * portable Error TYPE rather than by status code.\n */\n readonly durationMs?: number,\n /**\n * Bytes of the serialized request DTO. Stamped on BOTH tags: the 'request' tag reports it as\n * soon as it is known, and the 'response' tag repeats it so one record shows the whole\n * exchange (`api.requestSize` + `api.responseSize` without a join).\n *\n * This is the TOTAL size of the body, measured BEFORE any log chunking — chunking is a\n * transport concern handled by the GCP backends, and a body split across 3 records still\n * reports its one true size here.\n */\n readonly requestSize?: number,\n /** Bytes of the serialized response. RESPONSE tag only, and only when the call succeeded —\n * a thrown error produced no response body to measure. Total size, pre-chunking. */\n readonly responseSize?: number,\n /** Number of logical items in a successful response. RESPONSE tag only, opt-in per call. */\n readonly responseCount?: number,\n ) {}\n}\n"]}
|
|
@@ -51,6 +51,43 @@ export interface EndpointOptions {
|
|
|
51
51
|
* have to say out loud, so `grep -rn background` lists every endpoint webpieces stops logging.
|
|
52
52
|
*/
|
|
53
53
|
background?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* This route is NOT part of the CUSTOMER-facing contract. `public-openapi.json` — the document a
|
|
56
|
+
* customer gets, and the only one a publish path uploads — contains no path, no operation, no
|
|
57
|
+
* schema and no prose for it. It is not "rendered with a flag set", it is absent.
|
|
58
|
+
*
|
|
59
|
+
* It is still in `full-private-openapi.json`, and still in `mcp-openapi.json` when it carries
|
|
60
|
+
* `@WpMcpTool`. The reason it is withheld belongs in the method's JSDoc, which is where every
|
|
61
|
+
* other piece of its documentation already lives.
|
|
62
|
+
*
|
|
63
|
+
* WHY A BOOLEAN HERE IS NOT SHIM SHAPE #5, given that `@ApiType` exists precisely to avoid a
|
|
64
|
+
* falsy default meaning "publish": the two operate at different levels and the default here is
|
|
65
|
+
* NOT the permissive one. A contract reaches customers only by declaring
|
|
66
|
+
* `@ApiType(..., EXTERNAL_CUSTOMER)` — one deliberate token per contract — and `hidden` only ever
|
|
67
|
+
* SUBTRACTS from what that token already granted. Omitting it on a contract nobody published to
|
|
68
|
+
* customers publishes nothing. The per-method case it exists for is real and cannot be said at
|
|
69
|
+
* class level: a NEW endpoint on an already-published API, built on main before it is announced.
|
|
70
|
+
*
|
|
71
|
+
* Default false, and `grep -rn "hidden: true"` lists every method withheld from customers.
|
|
72
|
+
*
|
|
73
|
+
* HIDING IS A DOCUMENTATION DECISION AND NEVER AN ACCESS-CONTROL ONE. The route is served exactly
|
|
74
|
+
* as before and is still reachable by anything holding its credential — including an agent, if it
|
|
75
|
+
* also carries `@WpMcpTool`. Declare its authorization as loudly as a published one.
|
|
76
|
+
*/
|
|
77
|
+
hidden?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* This operation may touch systems OUTSIDE this service — a payment processor, a partner's API,
|
|
80
|
+
* the physical world. It feeds MCP's `openWorldHint`, and it is rendered as a sentence in the
|
|
81
|
+
* operation's description so a human integrating against the document sees it too.
|
|
82
|
+
*
|
|
83
|
+
* DEFAULT FALSE, deliberately unlike the MCP specification's own `true` default. MCP defaults to
|
|
84
|
+
* "open world" because it cannot know; webpieces CAN know, because the author of the endpoint is
|
|
85
|
+
* right here. Defaulting to `true` would make the interesting case the silent one and the boring
|
|
86
|
+
* case the one you have to type, which is backwards — and an agent told that every endpoint might
|
|
87
|
+
* reach the outside world has been told nothing. `grep -rn "openWorld: true"` lists the ones that
|
|
88
|
+
* genuinely do.
|
|
89
|
+
*/
|
|
90
|
+
openWorld?: boolean;
|
|
54
91
|
}
|
|
55
92
|
/** An external endpoint must also identify the outside system that calls it. */
|
|
56
93
|
export interface ExternalEndpointOptions extends EndpointOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HttpEndpointOptions.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/HttpEndpointOptions.ts"],"names":[],"mappings":";;;AAGA,8EAA8E;AAC9E,IAAK,sBAIJ;AAJD,WAAK,sBAAsB;IACvB,uCAAa,CAAA;IACb,+DAAqC,CAAA;IACrC,yCAAe,CAAA;AACnB,CAAC,EAJI,sBAAsB,KAAtB,sBAAsB,QAI1B;AAED,wDAAwD;AAC3C,QAAA,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC;AACnC,QAAA,gBAAgB,GAAG,sBAAsB,CAAC,gBAAgB,CAAC;AAC3D,QAAA,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC","sourcesContent":["import { ExternalSystemKind } from './external-caller';\nimport { EndpointResponseType } from './HttpContract';\n\n/** Nominal backing keeps raw string literals out of endpoint declarations. */\nenum EndpointOperationValue {\n READ = 'read',\n WRITE_IDEMPOTENT = 'write-idempotent',\n WRITE = 'write',\n}\n\n/** Short, statically importable decorator arguments. */\nexport const READ = EndpointOperationValue.READ;\nexport const WRITE_IDEMPOTENT = EndpointOperationValue.WRITE_IDEMPOTENT;\nexport const WRITE = EndpointOperationValue.WRITE;\n\n/** The side-effect contract callers use to decide whether repeating an operation is safe. */\nexport type EndpointOperation = typeof READ | typeof WRITE_IDEMPOTENT | typeof WRITE;\n\n/** Options for one `@Endpoint`, stored parallel to the method-to-path metadata. */\nexport interface EndpointOptions {\n /** Return only a JSON body (default), or the full transport-neutral status/header/body value. */\n responseType?: EndpointResponseType;\n /**\n * Parse the request body as application/x-www-form-urlencoded instead of JSON. The request\n * DTO must be flat; urlencoded has no nesting. Default false = JSON.\n */\n formPost?: boolean;\n /**\n * Retain the verbatim request bytes and absolute URL for a `@WpAuthWebhook` callback to verify.\n * This is retention, not new buffering: the Express adapter already accumulates the body.\n *\n * `@WpAuthWebhook` requires this option at wiring time. It combines with `formPost` for vendors\n * that sign flat form bodies, e.g. `{ formPost: true, rawBody: true }`.\n */\n rawBody?: boolean;\n /**\n * This route is plumbing the USER did not ask for — a log shipper, a heartbeat, a telemetry\n * flush. It is not progress to report, and it must not be logged as an api call, because the\n * line it would write is itself the thing being shipped.\n *\n * Rides the route metadata for the same reason {@link formPost} and {@link rawBody} do: the\n * consumer branches on the ROUTE, without knowing the apiClass/methodName. Two consumers read\n * it today — {@link LogApiCallImpl} emits no `[API-*-req]`/`[API-*-resp-*]` line for the call,\n * and an app's `RequestLifecycleListener` can skip its progress bar and its own RPC\n * instrumentation.\n *\n * WHY a declaration and not a suppression switch: shipping a log over a logged transport logs\n * about shipping logs. The two mechanisms that do not know the endpoint both failed in prod\n * (see #976) — a wall-clock \"we are shipping\" boolean swallowed unrelated lines including an\n * error alarm, and a logger-name allowlist was incomplete by construction the moment anyone\n * added a logger, producing a steady-state 4-lines-per-second request loop on an idle page.\n * The ENDPOINT is the only stable, declarative fact, so it is where the decision belongs.\n *\n * Default false: absent means the ordinary, fully-logged route. The quiet path is the one you\n * have to say out loud, so `grep -rn background` lists every endpoint webpieces stops logging.\n */\n background?: boolean;\n}\n\n/** An external endpoint must also identify the outside system that calls it. */\nexport interface ExternalEndpointOptions extends EndpointOptions {\n /** The outside system (`'twilio'`) — graph identity, not display text. */\n calledBy: string;\n /** What that caller is; picks its graph shape. Defaults to `'saas'`. */\n callerKind?: ExternalSystemKind;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"HttpEndpointOptions.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/HttpEndpointOptions.ts"],"names":[],"mappings":";;;AAGA,8EAA8E;AAC9E,IAAK,sBAIJ;AAJD,WAAK,sBAAsB;IACvB,uCAAa,CAAA;IACb,+DAAqC,CAAA;IACrC,yCAAe,CAAA;AACnB,CAAC,EAJI,sBAAsB,KAAtB,sBAAsB,QAI1B;AAED,wDAAwD;AAC3C,QAAA,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC;AACnC,QAAA,gBAAgB,GAAG,sBAAsB,CAAC,gBAAgB,CAAC;AAC3D,QAAA,KAAK,GAAG,sBAAsB,CAAC,KAAK,CAAC","sourcesContent":["import { ExternalSystemKind } from './external-caller';\nimport { EndpointResponseType } from './HttpContract';\n\n/** Nominal backing keeps raw string literals out of endpoint declarations. */\nenum EndpointOperationValue {\n READ = 'read',\n WRITE_IDEMPOTENT = 'write-idempotent',\n WRITE = 'write',\n}\n\n/** Short, statically importable decorator arguments. */\nexport const READ = EndpointOperationValue.READ;\nexport const WRITE_IDEMPOTENT = EndpointOperationValue.WRITE_IDEMPOTENT;\nexport const WRITE = EndpointOperationValue.WRITE;\n\n/** The side-effect contract callers use to decide whether repeating an operation is safe. */\nexport type EndpointOperation = typeof READ | typeof WRITE_IDEMPOTENT | typeof WRITE;\n\n/** Options for one `@Endpoint`, stored parallel to the method-to-path metadata. */\nexport interface EndpointOptions {\n /** Return only a JSON body (default), or the full transport-neutral status/header/body value. */\n responseType?: EndpointResponseType;\n /**\n * Parse the request body as application/x-www-form-urlencoded instead of JSON. The request\n * DTO must be flat; urlencoded has no nesting. Default false = JSON.\n */\n formPost?: boolean;\n /**\n * Retain the verbatim request bytes and absolute URL for a `@WpAuthWebhook` callback to verify.\n * This is retention, not new buffering: the Express adapter already accumulates the body.\n *\n * `@WpAuthWebhook` requires this option at wiring time. It combines with `formPost` for vendors\n * that sign flat form bodies, e.g. `{ formPost: true, rawBody: true }`.\n */\n rawBody?: boolean;\n /**\n * This route is plumbing the USER did not ask for — a log shipper, a heartbeat, a telemetry\n * flush. It is not progress to report, and it must not be logged as an api call, because the\n * line it would write is itself the thing being shipped.\n *\n * Rides the route metadata for the same reason {@link formPost} and {@link rawBody} do: the\n * consumer branches on the ROUTE, without knowing the apiClass/methodName. Two consumers read\n * it today — {@link LogApiCallImpl} emits no `[API-*-req]`/`[API-*-resp-*]` line for the call,\n * and an app's `RequestLifecycleListener` can skip its progress bar and its own RPC\n * instrumentation.\n *\n * WHY a declaration and not a suppression switch: shipping a log over a logged transport logs\n * about shipping logs. The two mechanisms that do not know the endpoint both failed in prod\n * (see #976) — a wall-clock \"we are shipping\" boolean swallowed unrelated lines including an\n * error alarm, and a logger-name allowlist was incomplete by construction the moment anyone\n * added a logger, producing a steady-state 4-lines-per-second request loop on an idle page.\n * The ENDPOINT is the only stable, declarative fact, so it is where the decision belongs.\n *\n * Default false: absent means the ordinary, fully-logged route. The quiet path is the one you\n * have to say out loud, so `grep -rn background` lists every endpoint webpieces stops logging.\n */\n background?: boolean;\n /**\n * This route is NOT part of the CUSTOMER-facing contract. `public-openapi.json` — the document a\n * customer gets, and the only one a publish path uploads — contains no path, no operation, no\n * schema and no prose for it. It is not \"rendered with a flag set\", it is absent.\n *\n * It is still in `full-private-openapi.json`, and still in `mcp-openapi.json` when it carries\n * `@WpMcpTool`. The reason it is withheld belongs in the method's JSDoc, which is where every\n * other piece of its documentation already lives.\n *\n * WHY A BOOLEAN HERE IS NOT SHIM SHAPE #5, given that `@ApiType` exists precisely to avoid a\n * falsy default meaning \"publish\": the two operate at different levels and the default here is\n * NOT the permissive one. A contract reaches customers only by declaring\n * `@ApiType(..., EXTERNAL_CUSTOMER)` — one deliberate token per contract — and `hidden` only ever\n * SUBTRACTS from what that token already granted. Omitting it on a contract nobody published to\n * customers publishes nothing. The per-method case it exists for is real and cannot be said at\n * class level: a NEW endpoint on an already-published API, built on main before it is announced.\n *\n * Default false, and `grep -rn \"hidden: true\"` lists every method withheld from customers.\n *\n * HIDING IS A DOCUMENTATION DECISION AND NEVER AN ACCESS-CONTROL ONE. The route is served exactly\n * as before and is still reachable by anything holding its credential — including an agent, if it\n * also carries `@WpMcpTool`. Declare its authorization as loudly as a published one.\n */\n hidden?: boolean;\n /**\n * This operation may touch systems OUTSIDE this service — a payment processor, a partner's API,\n * the physical world. It feeds MCP's `openWorldHint`, and it is rendered as a sentence in the\n * operation's description so a human integrating against the document sees it too.\n *\n * DEFAULT FALSE, deliberately unlike the MCP specification's own `true` default. MCP defaults to\n * \"open world\" because it cannot know; webpieces CAN know, because the author of the endpoint is\n * right here. Defaulting to `true` would make the interesting case the silent one and the boring\n * case the one you have to type, which is backwards — and an agent told that every endpoint might\n * reach the outside world has been told nothing. `grep -rn \"openWorld: true\"` lists the ones that\n * genuinely do.\n */\n openWorld?: boolean;\n}\n\n/** An external endpoint must also identify the outside system that calls it. */\nexport interface ExternalEndpointOptions extends EndpointOptions {\n /** The outside system (`'twilio'`) — graph identity, not display text. */\n calledBy: string;\n /** What that caller is; picks its graph shape. Defaults to `'saas'`. */\n callerKind?: ExternalSystemKind;\n}\n"]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
/** Nominal backing keeps raw string literals out of contract declarations. */
|
|
3
|
+
declare enum ApiTypeValue {
|
|
4
|
+
SVC_TO_SVC = "svc-to-svc",
|
|
5
|
+
EXTERNAL_CUSTOMER = "external-customer",
|
|
6
|
+
MCP = "mcp"
|
|
7
|
+
}
|
|
8
|
+
/** Short, statically importable decorator arguments. */
|
|
9
|
+
export declare const SVC_TO_SVC = ApiTypeValue.SVC_TO_SVC;
|
|
10
|
+
export declare const EXTERNAL_CUSTOMER = ApiTypeValue.EXTERNAL_CUSTOMER;
|
|
11
|
+
export declare const MCP = ApiTypeValue.MCP;
|
|
12
|
+
/** WHICH generated documents a contract feeds. One value per document. */
|
|
13
|
+
export type ApiTypeKind = typeof SVC_TO_SVC | typeof EXTERNAL_CUSTOMER | typeof MCP;
|
|
14
|
+
/** Metadata key for the contract-level declaration, parallel to {@link METADATA_KEYS}. */
|
|
15
|
+
export declare const API_TYPE_METADATA_KEY = "webpieces:api-type";
|
|
16
|
+
/** The fail-closed default: a contract that says nothing feeds only the internal document. */
|
|
17
|
+
export declare const DEFAULT_API_TYPES: readonly ApiTypeKind[];
|
|
18
|
+
/**
|
|
19
|
+
* WHICH generated documents this CONTRACT feeds.
|
|
20
|
+
*
|
|
21
|
+
* ```typescript
|
|
22
|
+
* @ApiPath('/stores')
|
|
23
|
+
* @ApiType(SVC_TO_SVC, EXTERNAL_CUSTOMER) // private + customer documents
|
|
24
|
+
* export abstract class StoreApi { ... }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* | value | document |
|
|
28
|
+
* |---|---|
|
|
29
|
+
* | `SVC_TO_SVC` | `full-private-openapi.json` |
|
|
30
|
+
* | `EXTERNAL_CUSTOMER` | `public-openapi.json` |
|
|
31
|
+
* | `MCP` | `mcp-openapi.json` |
|
|
32
|
+
*
|
|
33
|
+
* A document is WRITTEN when at least one contract declares its type, and it contains the contracts
|
|
34
|
+
* that declared it and no others. No contract declaring `MCP` therefore means no `mcp-openapi.json`
|
|
35
|
+
* at all — there is no separate emptiness rule to keep in step with this one.
|
|
36
|
+
*
|
|
37
|
+
* ## Absent means `SVC_TO_SVC` only, and the level is why that is affordable
|
|
38
|
+
*
|
|
39
|
+
* `.claude/rules/no-backwards-compat.md` shim shape #5 rejects "a widening that is an ABSENCE rather
|
|
40
|
+
* than a token": a default that publishes to customers would mean you reach them having typed
|
|
41
|
+
* nothing, so the safe state requires an edit and the widest grant is free. Naming the type inverts
|
|
42
|
+
* that — `grep -rn EXTERNAL_CUSTOMER` is the entire customer-facing surface on one screen.
|
|
43
|
+
*
|
|
44
|
+
* It is a CLASS-level declaration because that costs one token per contract rather than one per
|
|
45
|
+
* method. A per-method audience list was the earlier design and was rejected on exactly that
|
|
46
|
+
* ergonomic ground; the per-METHOD case that remains — a new endpoint on an already-published API —
|
|
47
|
+
* is served by `{ hidden: true }` in `EndpointOptions`, which subtracts one method from the customer
|
|
48
|
+
* document and leaves it in the other two. The two are orthogonal: this one selects FILES, that one
|
|
49
|
+
* subtracts a METHOD from one file.
|
|
50
|
+
*
|
|
51
|
+
* ## `MCP` and `@WpMcpTool` are ONE decision
|
|
52
|
+
*
|
|
53
|
+
* `MCP` on a contract with no `@WpMcpTool` method is an error, and a `@WpMcpTool` method on a
|
|
54
|
+
* contract that does not declare `MCP` is an error. Both directions are asserted by
|
|
55
|
+
* {@link assertApiTypeMatchesMcpTools}; without that, membership is declared in two places and they
|
|
56
|
+
* can disagree, which is the defect this whole documentation epic exists to remove.
|
|
57
|
+
*/
|
|
58
|
+
export declare function ApiType(first: ApiTypeKind, ...rest: readonly ApiTypeKind[]): ClassDecorator;
|
|
59
|
+
/** The documents this contract feeds — its declaration, else {@link DEFAULT_API_TYPES}. */
|
|
60
|
+
export declare function getApiTypes(apiClass: Function): readonly ApiTypeKind[];
|
|
61
|
+
/**
|
|
62
|
+
* MCP membership and `@WpMcpTool` must AGREE, in both directions.
|
|
63
|
+
*
|
|
64
|
+
* A wiring-time assert rather than a type, because the two declarations sit on different decorators
|
|
65
|
+
* at different levels and TypeScript cannot relate them. It is the sibling of
|
|
66
|
+
* `assertEveryEndpointHasAuthMode`, and exists for the same reason.
|
|
67
|
+
*/
|
|
68
|
+
export declare function assertApiTypeMatchesMcpTools(apiClass: Function): void;
|
|
69
|
+
/** Reads the endpoints map so a caller can see which methods exist without importing decorators.ts. */
|
|
70
|
+
export declare function getApiTypeEndpointNames(apiClass: Function): readonly string[];
|
|
71
|
+
export {};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_API_TYPES = exports.API_TYPE_METADATA_KEY = exports.MCP = exports.EXTERNAL_CUSTOMER = exports.SVC_TO_SVC = void 0;
|
|
4
|
+
exports.ApiType = ApiType;
|
|
5
|
+
exports.getApiTypes = getApiTypes;
|
|
6
|
+
exports.assertApiTypeMatchesMcpTools = assertApiTypeMatchesMcpTools;
|
|
7
|
+
exports.getApiTypeEndpointNames = getApiTypeEndpointNames;
|
|
8
|
+
require("reflect-metadata");
|
|
9
|
+
const decorators_1 = require("./decorators");
|
|
10
|
+
const McpMetadata_1 = require("../mcp/McpMetadata");
|
|
11
|
+
/** Nominal backing keeps raw string literals out of contract declarations. */
|
|
12
|
+
var ApiTypeValue;
|
|
13
|
+
(function (ApiTypeValue) {
|
|
14
|
+
ApiTypeValue["SVC_TO_SVC"] = "svc-to-svc";
|
|
15
|
+
ApiTypeValue["EXTERNAL_CUSTOMER"] = "external-customer";
|
|
16
|
+
ApiTypeValue["MCP"] = "mcp";
|
|
17
|
+
})(ApiTypeValue || (ApiTypeValue = {}));
|
|
18
|
+
/** Short, statically importable decorator arguments. */
|
|
19
|
+
exports.SVC_TO_SVC = ApiTypeValue.SVC_TO_SVC;
|
|
20
|
+
exports.EXTERNAL_CUSTOMER = ApiTypeValue.EXTERNAL_CUSTOMER;
|
|
21
|
+
exports.MCP = ApiTypeValue.MCP;
|
|
22
|
+
/** Metadata key for the contract-level declaration, parallel to {@link METADATA_KEYS}. */
|
|
23
|
+
exports.API_TYPE_METADATA_KEY = 'webpieces:api-type';
|
|
24
|
+
/** The fail-closed default: a contract that says nothing feeds only the internal document. */
|
|
25
|
+
exports.DEFAULT_API_TYPES = [exports.SVC_TO_SVC];
|
|
26
|
+
/**
|
|
27
|
+
* WHICH generated documents this CONTRACT feeds.
|
|
28
|
+
*
|
|
29
|
+
* ```typescript
|
|
30
|
+
* @ApiPath('/stores')
|
|
31
|
+
* @ApiType(SVC_TO_SVC, EXTERNAL_CUSTOMER) // private + customer documents
|
|
32
|
+
* export abstract class StoreApi { ... }
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* | value | document |
|
|
36
|
+
* |---|---|
|
|
37
|
+
* | `SVC_TO_SVC` | `full-private-openapi.json` |
|
|
38
|
+
* | `EXTERNAL_CUSTOMER` | `public-openapi.json` |
|
|
39
|
+
* | `MCP` | `mcp-openapi.json` |
|
|
40
|
+
*
|
|
41
|
+
* A document is WRITTEN when at least one contract declares its type, and it contains the contracts
|
|
42
|
+
* that declared it and no others. No contract declaring `MCP` therefore means no `mcp-openapi.json`
|
|
43
|
+
* at all — there is no separate emptiness rule to keep in step with this one.
|
|
44
|
+
*
|
|
45
|
+
* ## Absent means `SVC_TO_SVC` only, and the level is why that is affordable
|
|
46
|
+
*
|
|
47
|
+
* `.claude/rules/no-backwards-compat.md` shim shape #5 rejects "a widening that is an ABSENCE rather
|
|
48
|
+
* than a token": a default that publishes to customers would mean you reach them having typed
|
|
49
|
+
* nothing, so the safe state requires an edit and the widest grant is free. Naming the type inverts
|
|
50
|
+
* that — `grep -rn EXTERNAL_CUSTOMER` is the entire customer-facing surface on one screen.
|
|
51
|
+
*
|
|
52
|
+
* It is a CLASS-level declaration because that costs one token per contract rather than one per
|
|
53
|
+
* method. A per-method audience list was the earlier design and was rejected on exactly that
|
|
54
|
+
* ergonomic ground; the per-METHOD case that remains — a new endpoint on an already-published API —
|
|
55
|
+
* is served by `{ hidden: true }` in `EndpointOptions`, which subtracts one method from the customer
|
|
56
|
+
* document and leaves it in the other two. The two are orthogonal: this one selects FILES, that one
|
|
57
|
+
* subtracts a METHOD from one file.
|
|
58
|
+
*
|
|
59
|
+
* ## `MCP` and `@WpMcpTool` are ONE decision
|
|
60
|
+
*
|
|
61
|
+
* `MCP` on a contract with no `@WpMcpTool` method is an error, and a `@WpMcpTool` method on a
|
|
62
|
+
* contract that does not declare `MCP` is an error. Both directions are asserted by
|
|
63
|
+
* {@link assertApiTypeMatchesMcpTools}; without that, membership is declared in two places and they
|
|
64
|
+
* can disagree, which is the defect this whole documentation epic exists to remove.
|
|
65
|
+
*/
|
|
66
|
+
// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope
|
|
67
|
+
function ApiType(first, ...rest) {
|
|
68
|
+
const types = [first, ...rest];
|
|
69
|
+
return (target) => {
|
|
70
|
+
Reflect.defineMetadata(exports.API_TYPE_METADATA_KEY, types, target);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** The documents this contract feeds — its declaration, else {@link DEFAULT_API_TYPES}. */
|
|
74
|
+
// webpieces-disable no-function-outside-class -- metadata reader paired with the decorator
|
|
75
|
+
function getApiTypes(apiClass) {
|
|
76
|
+
const declared = Reflect.getMetadata(exports.API_TYPE_METADATA_KEY, apiClass);
|
|
77
|
+
return declared ?? exports.DEFAULT_API_TYPES;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* MCP membership and `@WpMcpTool` must AGREE, in both directions.
|
|
81
|
+
*
|
|
82
|
+
* A wiring-time assert rather than a type, because the two declarations sit on different decorators
|
|
83
|
+
* at different levels and TypeScript cannot relate them. It is the sibling of
|
|
84
|
+
* `assertEveryEndpointHasAuthMode`, and exists for the same reason.
|
|
85
|
+
*/
|
|
86
|
+
// webpieces-disable no-function-outside-class -- wiring-time assert, sibling of assertEveryEndpointHasAuthMode
|
|
87
|
+
function assertApiTypeMatchesMcpTools(apiClass) {
|
|
88
|
+
const declaresMcp = getApiTypes(apiClass).includes(exports.MCP);
|
|
89
|
+
const tools = (0, McpMetadata_1.getWpMcpTools)(apiClass);
|
|
90
|
+
if (declaresMcp && tools.length === 0) {
|
|
91
|
+
throw new Error(`${apiClass.name} declares @ApiType(..., MCP) but no method carries @WpMcpTool. ` +
|
|
92
|
+
'Add @WpMcpTool({name, description, openWorldHint}) to the methods agents may ' +
|
|
93
|
+
'call, or drop MCP from the @ApiType list.');
|
|
94
|
+
}
|
|
95
|
+
if (!declaresMcp && tools.length > 0) {
|
|
96
|
+
const named = tools.map((tool) => tool.methodName).join(', ');
|
|
97
|
+
throw new Error(`${apiClass.name} has @WpMcpTool on ${named} but does not declare @ApiType(..., MCP). ` +
|
|
98
|
+
'Add MCP to the @ApiType list — membership has ONE spelling, so a tool on a ' +
|
|
99
|
+
'contract nobody published to agents is a contradiction, not a hint.');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Reads the endpoints map so a caller can see which methods exist without importing decorators.ts. */
|
|
103
|
+
// webpieces-disable no-function-outside-class -- metadata reader, sibling of getApiTypes
|
|
104
|
+
function getApiTypeEndpointNames(apiClass) {
|
|
105
|
+
const endpoints = Reflect.getMetadata(decorators_1.METADATA_KEYS.ENDPOINTS, apiClass) ?? {};
|
|
106
|
+
return Object.keys(endpoints);
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=api-type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-type.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/api-type.ts"],"names":[],"mappings":";;;AAkEA,0BAKC;AAID,kCAMC;AAUD,oEAkBC;AAID,0DAIC;AArHD,4BAA0B;AAC1B,6CAA6C;AAC7C,oDAAsE;AAEtE,8EAA8E;AAC9E,IAAK,YAIJ;AAJD,WAAK,YAAY;IACb,yCAAyB,CAAA;IACzB,uDAAuC,CAAA;IACvC,2BAAW,CAAA;AACf,CAAC,EAJI,YAAY,KAAZ,YAAY,QAIhB;AAED,wDAAwD;AAC3C,QAAA,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;AACrC,QAAA,iBAAiB,GAAG,YAAY,CAAC,iBAAiB,CAAC;AACnD,QAAA,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC;AAKpC,0FAA0F;AAC7E,QAAA,qBAAqB,GAAG,oBAAoB,CAAC;AAE1D,8FAA8F;AACjF,QAAA,iBAAiB,GAA2B,CAAC,kBAAU,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,2GAA2G;AAC3G,SAAgB,OAAO,CAAC,KAAkB,EAAE,GAAG,IAA4B;IACvE,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;IAC/B,OAAO,CAAC,MAAgB,EAAE,EAAE;QACxB,OAAO,CAAC,cAAc,CAAC,6BAAqB,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC,CAAC;AACN,CAAC;AAED,2FAA2F;AAC3F,2FAA2F;AAC3F,SAAgB,WAAW,CAAC,QAAkB;IAC1C,MAAM,QAAQ,GAA8B,OAAO,CAAC,WAAW,CAC3D,6BAAqB,EACrB,QAAQ,CACX,CAAC;IACF,OAAO,QAAQ,IAAI,yBAAiB,CAAC;AACzC,CAAC;AAED;;;;;;GAMG;AACH,+GAA+G;AAC/G,SAAgB,4BAA4B,CAAC,QAAkB;IAC3D,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,WAAG,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,IAAA,2BAAa,EAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CACX,GAAG,QAAQ,CAAC,IAAI,iEAAiE;YAC7E,+EAA+E;YAC/E,2CAA2C,CAClD,CAAC;IACN,CAAC;IACD,IAAI,CAAC,WAAW,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,MAAM,IAAI,KAAK,CACX,GAAG,QAAQ,CAAC,IAAI,sBAAsB,KAAK,4CAA4C;YACnF,6EAA6E;YAC7E,qEAAqE,CAC5E,CAAC;IACN,CAAC;AACL,CAAC;AAED,uGAAuG;AACvG,yFAAyF;AACzF,SAAgB,uBAAuB,CAAC,QAAkB;IACtD,MAAM,SAAS,GACX,OAAO,CAAC,WAAW,CAAC,0BAAa,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;IACjE,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC","sourcesContent":["import 'reflect-metadata';\nimport { METADATA_KEYS } from './decorators';\nimport { getWpMcpTools, WpMcpToolMetadata } from '../mcp/McpMetadata';\n\n/** Nominal backing keeps raw string literals out of contract declarations. */\nenum ApiTypeValue {\n SVC_TO_SVC = 'svc-to-svc',\n EXTERNAL_CUSTOMER = 'external-customer',\n MCP = 'mcp',\n}\n\n/** Short, statically importable decorator arguments. */\nexport const SVC_TO_SVC = ApiTypeValue.SVC_TO_SVC;\nexport const EXTERNAL_CUSTOMER = ApiTypeValue.EXTERNAL_CUSTOMER;\nexport const MCP = ApiTypeValue.MCP;\n\n/** WHICH generated documents a contract feeds. One value per document. */\nexport type ApiTypeKind = typeof SVC_TO_SVC | typeof EXTERNAL_CUSTOMER | typeof MCP;\n\n/** Metadata key for the contract-level declaration, parallel to {@link METADATA_KEYS}. */\nexport const API_TYPE_METADATA_KEY = 'webpieces:api-type';\n\n/** The fail-closed default: a contract that says nothing feeds only the internal document. */\nexport const DEFAULT_API_TYPES: readonly ApiTypeKind[] = [SVC_TO_SVC];\n\n/**\n * WHICH generated documents this CONTRACT feeds.\n *\n * ```typescript\n * @ApiPath('/stores')\n * @ApiType(SVC_TO_SVC, EXTERNAL_CUSTOMER) // private + customer documents\n * export abstract class StoreApi { ... }\n * ```\n *\n * | value | document |\n * |---|---|\n * | `SVC_TO_SVC` | `full-private-openapi.json` |\n * | `EXTERNAL_CUSTOMER` | `public-openapi.json` |\n * | `MCP` | `mcp-openapi.json` |\n *\n * A document is WRITTEN when at least one contract declares its type, and it contains the contracts\n * that declared it and no others. No contract declaring `MCP` therefore means no `mcp-openapi.json`\n * at all — there is no separate emptiness rule to keep in step with this one.\n *\n * ## Absent means `SVC_TO_SVC` only, and the level is why that is affordable\n *\n * `.claude/rules/no-backwards-compat.md` shim shape #5 rejects \"a widening that is an ABSENCE rather\n * than a token\": a default that publishes to customers would mean you reach them having typed\n * nothing, so the safe state requires an edit and the widest grant is free. Naming the type inverts\n * that — `grep -rn EXTERNAL_CUSTOMER` is the entire customer-facing surface on one screen.\n *\n * It is a CLASS-level declaration because that costs one token per contract rather than one per\n * method. A per-method audience list was the earlier design and was rejected on exactly that\n * ergonomic ground; the per-METHOD case that remains — a new endpoint on an already-published API —\n * is served by `{ hidden: true }` in `EndpointOptions`, which subtracts one method from the customer\n * document and leaves it in the other two. The two are orthogonal: this one selects FILES, that one\n * subtracts a METHOD from one file.\n *\n * ## `MCP` and `@WpMcpTool` are ONE decision\n *\n * `MCP` on a contract with no `@WpMcpTool` method is an error, and a `@WpMcpTool` method on a\n * contract that does not declare `MCP` is an error. Both directions are asserted by\n * {@link assertApiTypeMatchesMcpTools}; without that, membership is declared in two places and they\n * can disagree, which is the defect this whole documentation epic exists to remove.\n */\n// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope\nexport function ApiType(first: ApiTypeKind, ...rest: readonly ApiTypeKind[]): ClassDecorator {\n const types = [first, ...rest];\n return (target: Function) => {\n Reflect.defineMetadata(API_TYPE_METADATA_KEY, types, target);\n };\n}\n\n/** The documents this contract feeds — its declaration, else {@link DEFAULT_API_TYPES}. */\n// webpieces-disable no-function-outside-class -- metadata reader paired with the decorator\nexport function getApiTypes(apiClass: Function): readonly ApiTypeKind[] {\n const declared: ApiTypeKind[] | undefined = Reflect.getMetadata(\n API_TYPE_METADATA_KEY,\n apiClass,\n );\n return declared ?? DEFAULT_API_TYPES;\n}\n\n/**\n * MCP membership and `@WpMcpTool` must AGREE, in both directions.\n *\n * A wiring-time assert rather than a type, because the two declarations sit on different decorators\n * at different levels and TypeScript cannot relate them. It is the sibling of\n * `assertEveryEndpointHasAuthMode`, and exists for the same reason.\n */\n// webpieces-disable no-function-outside-class -- wiring-time assert, sibling of assertEveryEndpointHasAuthMode\nexport function assertApiTypeMatchesMcpTools(apiClass: Function): void {\n const declaresMcp = getApiTypes(apiClass).includes(MCP);\n const tools = getWpMcpTools(apiClass);\n if (declaresMcp && tools.length === 0) {\n throw new Error(\n `${apiClass.name} declares @ApiType(..., MCP) but no method carries @WpMcpTool. ` +\n 'Add @WpMcpTool({name, description, openWorldHint}) to the methods agents may ' +\n 'call, or drop MCP from the @ApiType list.',\n );\n }\n if (!declaresMcp && tools.length > 0) {\n const named = tools.map((tool: WpMcpToolMetadata) => tool.methodName).join(', ');\n throw new Error(\n `${apiClass.name} has @WpMcpTool on ${named} but does not declare @ApiType(..., MCP). ` +\n 'Add MCP to the @ApiType list — membership has ONE spelling, so a tool on a ' +\n 'contract nobody published to agents is a contradiction, not a hint.',\n );\n }\n}\n\n/** Reads the endpoints map so a caller can see which methods exist without importing decorators.ts. */\n// webpieces-disable no-function-outside-class -- metadata reader, sibling of getApiTypes\nexport function getApiTypeEndpointNames(apiClass: Function): readonly string[] {\n const endpoints: Record<string, string> =\n Reflect.getMetadata(METADATA_KEYS.ENDPOINTS, apiClass) ?? {};\n return Object.keys(endpoints);\n}\n"]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
/**
|
|
3
|
+
* The three facts about a NUMBER that TypeScript cannot state, plus the type alias that states the
|
|
4
|
+
* first one without a decorator at all.
|
|
5
|
+
*
|
|
6
|
+
* ## Why any of this exists
|
|
7
|
+
*
|
|
8
|
+
* TypeScript has ONE numeric type. `limit: number` cannot say whether `1.5` is legal, and a
|
|
9
|
+
* published schema that says `type: number` where the server means `integer` is wrong in a way no
|
|
10
|
+
* test catches — the wrong value simply arrives one day. A bound is worse still: `minimum` and
|
|
11
|
+
* `maximum` are policy, and policy has nowhere at all to live in a TypeScript type.
|
|
12
|
+
*
|
|
13
|
+
* ## `Integer` is the PREFERRED spelling, and `@WpInt()` is the other accepted one
|
|
14
|
+
*
|
|
15
|
+
* ```typescript
|
|
16
|
+
* limit?: Integer; // PREFERRED — it COMPOSES: Integer[], Record<string, Integer>
|
|
17
|
+
* @WpInt() limit?: number; // also accepted
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* `Integer` is preferred because it composes: a decorator on `counts?: number[]` is ambiguous about
|
|
21
|
+
* whether it describes the ARRAY or its ITEMS, which is the exact ambiguity that made the deleted
|
|
22
|
+
* `WpDtoFieldOptions.arrayItems` argument unusable, while `Integer[]` and `Record<string, Integer>`
|
|
23
|
+
* are not ambiguous about anything. `@WpInt()` stays for the field whose declared type you do not
|
|
24
|
+
* want to change, and because a decorator needs a class to hang on where a type alias does not.
|
|
25
|
+
*
|
|
26
|
+
* Two spellings of one thing is normally a shim this repo rejects (`.claude/rules/no-backwards-compat.md`
|
|
27
|
+
* shape #1). This pair is a deliberate exception, authorized by Dean in design review on 2026-09-22
|
|
28
|
+
* and recorded in issue #981 and in `packages/docs/api-doc-model/responsibilities.md`. It is NOT
|
|
29
|
+
* justified by an existing release — nothing has ever shipped `@WpInt` — the reason is ergonomic.
|
|
30
|
+
*
|
|
31
|
+
* ## They are read by the COMPILER, and the metadata is a by-product
|
|
32
|
+
*
|
|
33
|
+
* `@webpieces/api-doc-model` reads these off the SOURCE with the TypeScript compiler, because a
|
|
34
|
+
* field's type is erased at runtime and reflection can therefore never see the shapes a partner-grade
|
|
35
|
+
* document is made of. The metadata written below is what makes them ordinary decorators rather than
|
|
36
|
+
* markers the runtime cannot see at all, and it is deliberately the same shape for all three: a map
|
|
37
|
+
* from property name to the declared value.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* INTEGER-ness, expressed in the type. `Integer` is `number` at runtime and everywhere TypeScript
|
|
41
|
+
* looks — it is a DECLARATION for the document generator, which reads the written syntax rather than
|
|
42
|
+
* the checker's answer, precisely so this alias survives to be read.
|
|
43
|
+
*/
|
|
44
|
+
export type Integer = number;
|
|
45
|
+
/** Metadata keys for the numeric field declarations, parallel to `METADATA_KEYS` in `decorators.ts`. */
|
|
46
|
+
export declare const NUMERIC_METADATA_KEYS: {
|
|
47
|
+
/** property name -> true, for every `@WpInt()` field. */
|
|
48
|
+
INT: string;
|
|
49
|
+
/** property name -> the declared minimum. */
|
|
50
|
+
MIN: string;
|
|
51
|
+
/** property name -> the declared maximum. */
|
|
52
|
+
MAX: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* This numeric field holds an INTEGER. Prefer writing the type as {@link Integer}, which composes.
|
|
56
|
+
*/
|
|
57
|
+
export declare function WpInt(): PropertyDecorator;
|
|
58
|
+
/**
|
|
59
|
+
* The smallest value this field may hold. Policy, not type — on a non-numeric field it is a BUILD
|
|
60
|
+
* FAILURE from the document generator rather than a silently dropped constraint, because dropping it
|
|
61
|
+
* would publish a contract weaker than the one its author wrote down.
|
|
62
|
+
*/
|
|
63
|
+
export declare function WpMin(value: number): PropertyDecorator;
|
|
64
|
+
/** The largest value this field may hold. See {@link WpMin}. */
|
|
65
|
+
export declare function WpMax(value: number): PropertyDecorator;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NUMERIC_METADATA_KEYS = void 0;
|
|
4
|
+
exports.WpInt = WpInt;
|
|
5
|
+
exports.WpMin = WpMin;
|
|
6
|
+
exports.WpMax = WpMax;
|
|
7
|
+
require("reflect-metadata");
|
|
8
|
+
/** Metadata keys for the numeric field declarations, parallel to `METADATA_KEYS` in `decorators.ts`. */
|
|
9
|
+
exports.NUMERIC_METADATA_KEYS = {
|
|
10
|
+
/** property name -> true, for every `@WpInt()` field. */
|
|
11
|
+
INT: 'webpieces:field-int',
|
|
12
|
+
/** property name -> the declared minimum. */
|
|
13
|
+
MIN: 'webpieces:field-min',
|
|
14
|
+
/** property name -> the declared maximum. */
|
|
15
|
+
MAX: 'webpieces:field-max',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* One metadata write, shared by all three decorators, so they cannot drift in shape.
|
|
19
|
+
*
|
|
20
|
+
* `value` is `number | boolean` because that is the whole of what these three declare: a bound, or
|
|
21
|
+
* the fact of being an integer.
|
|
22
|
+
*/
|
|
23
|
+
// webpieces-disable no-function-outside-class -- decorator support; decorators are inherently module-scope
|
|
24
|
+
function record(key, target, propertyKey, value) {
|
|
25
|
+
const owner = typeof target === 'function' ? target : target.constructor;
|
|
26
|
+
// webpieces-disable no-any-unknown -- reflect-metadata hands back whatever was stored; the values are ours and are narrowed by the signature above
|
|
27
|
+
const existing = Reflect.getMetadata(key, owner) || {};
|
|
28
|
+
existing[String(propertyKey)] = value;
|
|
29
|
+
Reflect.defineMetadata(key, existing, owner);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* This numeric field holds an INTEGER. Prefer writing the type as {@link Integer}, which composes.
|
|
33
|
+
*/
|
|
34
|
+
// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope
|
|
35
|
+
function WpInt() {
|
|
36
|
+
return (target, propertyKey) => {
|
|
37
|
+
record(exports.NUMERIC_METADATA_KEYS.INT, target, propertyKey, true);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The smallest value this field may hold. Policy, not type — on a non-numeric field it is a BUILD
|
|
42
|
+
* FAILURE from the document generator rather than a silently dropped constraint, because dropping it
|
|
43
|
+
* would publish a contract weaker than the one its author wrote down.
|
|
44
|
+
*/
|
|
45
|
+
// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope
|
|
46
|
+
function WpMin(value) {
|
|
47
|
+
return (target, propertyKey) => {
|
|
48
|
+
record(exports.NUMERIC_METADATA_KEYS.MIN, target, propertyKey, value);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** The largest value this field may hold. See {@link WpMin}. */
|
|
52
|
+
// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope
|
|
53
|
+
function WpMax(value) {
|
|
54
|
+
return (target, propertyKey) => {
|
|
55
|
+
record(exports.NUMERIC_METADATA_KEYS.MAX, target, propertyKey, value);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=numeric-field-decorators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"numeric-field-decorators.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/numeric-field-decorators.ts"],"names":[],"mappings":";;;AAiFA,sBAIC;AAQD,sBAIC;AAID,sBAIC;AAzGD,4BAA0B;AA+C1B,wGAAwG;AAC3F,QAAA,qBAAqB,GAAG;IACjC,yDAAyD;IACzD,GAAG,EAAE,qBAAqB;IAC1B,6CAA6C;IAC7C,GAAG,EAAE,qBAAqB;IAC1B,6CAA6C;IAC7C,GAAG,EAAE,qBAAqB;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,2GAA2G;AAC3G,SAAS,MAAM,CACX,GAAW,EACX,MAAc,EACd,WAA4B,EAC5B,KAAuB;IAEvB,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;IACzE,mJAAmJ;IACnJ,MAAM,QAAQ,GAA4B,OAAO,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;IAChF,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,KAAK,CAAC;IACtC,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,2GAA2G;AAC3G,SAAgB,KAAK;IACjB,OAAO,CAAC,MAAc,EAAE,WAA4B,EAAE,EAAE;QACpD,MAAM,CAAC,6BAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;IACjE,CAAC,CAAC;AACN,CAAC;AAED;;;;GAIG;AACH,2GAA2G;AAC3G,SAAgB,KAAK,CAAC,KAAa;IAC/B,OAAO,CAAC,MAAc,EAAE,WAA4B,EAAE,EAAE;QACpD,MAAM,CAAC,6BAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC;AACN,CAAC;AAED,gEAAgE;AAChE,2GAA2G;AAC3G,SAAgB,KAAK,CAAC,KAAa;IAC/B,OAAO,CAAC,MAAc,EAAE,WAA4B,EAAE,EAAE;QACpD,MAAM,CAAC,6BAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC;AACN,CAAC","sourcesContent":["import 'reflect-metadata';\n\n/**\n * The three facts about a NUMBER that TypeScript cannot state, plus the type alias that states the\n * first one without a decorator at all.\n *\n * ## Why any of this exists\n *\n * TypeScript has ONE numeric type. `limit: number` cannot say whether `1.5` is legal, and a\n * published schema that says `type: number` where the server means `integer` is wrong in a way no\n * test catches — the wrong value simply arrives one day. A bound is worse still: `minimum` and\n * `maximum` are policy, and policy has nowhere at all to live in a TypeScript type.\n *\n * ## `Integer` is the PREFERRED spelling, and `@WpInt()` is the other accepted one\n *\n * ```typescript\n * limit?: Integer; // PREFERRED — it COMPOSES: Integer[], Record<string, Integer>\n * @WpInt() limit?: number; // also accepted\n * ```\n *\n * `Integer` is preferred because it composes: a decorator on `counts?: number[]` is ambiguous about\n * whether it describes the ARRAY or its ITEMS, which is the exact ambiguity that made the deleted\n * `WpDtoFieldOptions.arrayItems` argument unusable, while `Integer[]` and `Record<string, Integer>`\n * are not ambiguous about anything. `@WpInt()` stays for the field whose declared type you do not\n * want to change, and because a decorator needs a class to hang on where a type alias does not.\n *\n * Two spellings of one thing is normally a shim this repo rejects (`.claude/rules/no-backwards-compat.md`\n * shape #1). This pair is a deliberate exception, authorized by Dean in design review on 2026-09-22\n * and recorded in issue #981 and in `packages/docs/api-doc-model/responsibilities.md`. It is NOT\n * justified by an existing release — nothing has ever shipped `@WpInt` — the reason is ergonomic.\n *\n * ## They are read by the COMPILER, and the metadata is a by-product\n *\n * `@webpieces/api-doc-model` reads these off the SOURCE with the TypeScript compiler, because a\n * field's type is erased at runtime and reflection can therefore never see the shapes a partner-grade\n * document is made of. The metadata written below is what makes them ordinary decorators rather than\n * markers the runtime cannot see at all, and it is deliberately the same shape for all three: a map\n * from property name to the declared value.\n */\n\n/**\n * INTEGER-ness, expressed in the type. `Integer` is `number` at runtime and everywhere TypeScript\n * looks — it is a DECLARATION for the document generator, which reads the written syntax rather than\n * the checker's answer, precisely so this alias survives to be read.\n */\nexport type Integer = number;\n\n/** Metadata keys for the numeric field declarations, parallel to `METADATA_KEYS` in `decorators.ts`. */\nexport const NUMERIC_METADATA_KEYS = {\n /** property name -> true, for every `@WpInt()` field. */\n INT: 'webpieces:field-int',\n /** property name -> the declared minimum. */\n MIN: 'webpieces:field-min',\n /** property name -> the declared maximum. */\n MAX: 'webpieces:field-max',\n};\n\n/**\n * One metadata write, shared by all three decorators, so they cannot drift in shape.\n *\n * `value` is `number | boolean` because that is the whole of what these three declare: a bound, or\n * the fact of being an integer.\n */\n// webpieces-disable no-function-outside-class -- decorator support; decorators are inherently module-scope\nfunction record(\n key: string,\n target: object,\n propertyKey: string | symbol,\n value: number | boolean,\n): void {\n const owner = typeof target === 'function' ? target : target.constructor;\n // webpieces-disable no-any-unknown -- reflect-metadata hands back whatever was stored; the values are ours and are narrowed by the signature above\n const existing: Record<string, unknown> = Reflect.getMetadata(key, owner) || {};\n existing[String(propertyKey)] = value;\n Reflect.defineMetadata(key, existing, owner);\n}\n\n/**\n * This numeric field holds an INTEGER. Prefer writing the type as {@link Integer}, which composes.\n */\n// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope\nexport function WpInt(): PropertyDecorator {\n return (target: object, propertyKey: string | symbol) => {\n record(NUMERIC_METADATA_KEYS.INT, target, propertyKey, true);\n };\n}\n\n/**\n * The smallest value this field may hold. Policy, not type — on a non-numeric field it is a BUILD\n * FAILURE from the document generator rather than a silently dropped constraint, because dropping it\n * would publish a contract weaker than the one its author wrote down.\n */\n// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope\nexport function WpMin(value: number): PropertyDecorator {\n return (target: object, propertyKey: string | symbol) => {\n record(NUMERIC_METADATA_KEYS.MIN, target, propertyKey, value);\n };\n}\n\n/** The largest value this field may hold. See {@link WpMin}. */\n// webpieces-disable no-function-outside-class -- decorator factory; decorators are inherently module-scope\nexport function WpMax(value: number): PropertyDecorator {\n return (target: object, propertyKey: string | symbol) => {\n record(NUMERIC_METADATA_KEYS.MAX, target, propertyKey, value);\n };\n}\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export { LogManager } from './logging/LogManager';
|
|
|
19
19
|
export { LogChunker, LogChunkerImpl, LogChunkInfo, MAX_GCP_LOG_BYTES, GCP_LOG_BUDGET_BYTES, } from './logging/LogChunker';
|
|
20
20
|
export { ApiPath, Endpoint, WpAuthPublic, WpAuthJwt, rolesRequired, MISSING_AUTH_DECORATOR_FIX, WpAuthOidc, WpAuthSharedSecret, WpAuthWebhook, WpAuthApiKey, WpAuthLocalOnly, MaskLog, getApiPath, getEndpoints, getEndpointHttpMethod, getEndpointOptions, getEndpointOperation, getEndpointKind, getEndpointKinds, getMaskSpec, isFormPost, isRawBody, isApiPath, getAuthMeta, getAuthMode, assertEveryEndpointHasAuthMode, assertEveryExternalEndpointDeclaresCaller, assertEveryWebhookEndpointRetainsRawBody, validateNoConflictingDecorators, METADATA_KEYS, } from './http/decorators';
|
|
21
21
|
export { PathParam, QueryParam, getHttpParameterDeclarations, } from './http/http-parameter-decorators';
|
|
22
|
+
export { WpInt, WpMin, WpMax, NUMERIC_METADATA_KEYS } from './http/numeric-field-decorators';
|
|
23
|
+
export type { Integer } from './http/numeric-field-decorators';
|
|
24
|
+
export { ApiType, SVC_TO_SVC, EXTERNAL_CUSTOMER, MCP, API_TYPE_METADATA_KEY, DEFAULT_API_TYPES, getApiTypes, getApiTypeEndpointNames, assertApiTypeMatchesMcpTools, } from './http/api-type';
|
|
25
|
+
export type { ApiTypeKind } from './http/api-type';
|
|
22
26
|
export { WpInternal, WpIpcEndpoint, isInternalApi, getIpcApiId, getIpcEndpoints, getIpcEndpointKind, getIpcMaskSpec, assertInternalApi, assertNotInternalApi, IPC_METADATA_KEYS, } from './ipc/IpcDecorators';
|
|
23
27
|
export type { IpcApiType, IpcEndpointKind, IpcEndpointOptions } from './ipc/IpcDecorators';
|
|
24
28
|
export { RouteMetadata } from './http/RouteMetadata';
|
|
@@ -76,7 +80,7 @@ export { LogApiCallImpl } from './http/LogApiCall';
|
|
|
76
80
|
export { MaskSpec } from './http/LogFieldMask';
|
|
77
81
|
export type { MaskMode } from './http/LogFieldMask';
|
|
78
82
|
export { ApiCallInfo } from './http/ApiCallInfo';
|
|
79
|
-
export type {
|
|
83
|
+
export type { ApiCallDirection, ApiResult } from './http/ApiCallInfo';
|
|
80
84
|
export { ApiCallLogName, ApiCallLogNameImpl, LOG_API_CALL_LOGGER_NAME, } from './http/ApiCallLogName';
|
|
81
85
|
export { ApiMethodInfo } from './http/ApiMethodInfo';
|
|
82
86
|
export type { ApiSide } from './http/ApiMethodInfo';
|
package/src/index.js
CHANGED
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
* @packageDocumentation
|
|
9
9
|
*/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.
|
|
12
|
-
exports.
|
|
13
|
-
exports.
|
|
14
|
-
exports.
|
|
11
|
+
exports.WpMax = exports.WpMin = exports.WpInt = exports.getHttpParameterDeclarations = exports.QueryParam = exports.PathParam = exports.METADATA_KEYS = exports.validateNoConflictingDecorators = exports.assertEveryWebhookEndpointRetainsRawBody = exports.assertEveryExternalEndpointDeclaresCaller = exports.assertEveryEndpointHasAuthMode = exports.getAuthMode = exports.getAuthMeta = exports.isApiPath = exports.isRawBody = exports.isFormPost = exports.getMaskSpec = exports.getEndpointKinds = exports.getEndpointKind = exports.getEndpointOperation = exports.getEndpointOptions = exports.getEndpointHttpMethod = exports.getEndpoints = exports.getApiPath = exports.MaskLog = exports.WpAuthLocalOnly = exports.WpAuthApiKey = exports.WpAuthWebhook = exports.WpAuthSharedSecret = exports.WpAuthOidc = exports.MISSING_AUTH_DECORATOR_FIX = exports.rolesRequired = exports.WpAuthJwt = exports.WpAuthPublic = exports.Endpoint = exports.ApiPath = exports.GCP_LOG_BUDGET_BYTES = exports.MAX_GCP_LOG_BYTES = exports.LogChunkInfo = exports.LogChunkerImpl = exports.LogChunker = exports.LogManager = exports.ConsoleLoggerFactory = exports.ConsoleLogger = exports.DESIGN_METADATA_KEYS = exports.isDocumentDesign = exports.DocumentDesign = exports.ContextTuple = exports.ContextKey = exports.toError = void 0;
|
|
12
|
+
exports.WpMcpJwtAuthMetadata = exports.WpMcpAuthJwt = exports.mcpHintsForOperation = exports.getWpMcpTools = exports.WpMcpToolMetadata = exports.WpMcpToolHints = exports.WpMcpTool = exports.WRITE = exports.WRITE_IDEMPOTENT = exports.READ = exports.EXTERNAL = exports.CRON = exports.CLOUDTASKS = exports.RPC = exports.POST = exports.GET = exports.getStreamingEndpoint = exports.WpStream = exports.StreamWriter = exports.StreamTransportError = exports.StreamEventValidator = exports.StreamingEndpointMetadata = exports.StreamEnvelope = exports.StreamCorrelation = exports.HttpParameterDeclaration = exports.HttpParameterBinding = exports.HttpContractMapper = exports.BoundHttpRequest = exports.RouteMetadataFactory = exports.RouteMetadata = exports.IPC_METADATA_KEYS = exports.assertNotInternalApi = exports.assertInternalApi = exports.getIpcMaskSpec = exports.getIpcEndpointKind = exports.getIpcEndpoints = exports.getIpcApiId = exports.isInternalApi = exports.WpIpcEndpoint = exports.WpInternal = exports.assertApiTypeMatchesMcpTools = exports.getApiTypeEndpointNames = exports.getApiTypes = exports.DEFAULT_API_TYPES = exports.API_TYPE_METADATA_KEY = exports.MCP = exports.EXTERNAL_CUSTOMER = exports.SVC_TO_SVC = exports.ApiType = exports.NUMERIC_METADATA_KEYS = void 0;
|
|
13
|
+
exports.HttpResponseStatus = exports.HttpHeader = exports.RuntimeLocality = exports.ServiceInfo = exports.ApiCallTimeoutError = exports.CallContext = exports.CallDeadline = exports.CallRegistry = exports.ClientRegistry = exports.HeaderRegistry = exports.DateTimeUtil = exports.TimeUtil = exports.DateUtil = exports.InstantUtil = exports.NetworkRejectClassifier = exports.NO_REG_CODE = exports.WRONG_COMPANY = exports.WRONG_DOMAIN = exports.EMAIL_NOT_CONFIRMED = exports.NOT_APPROVED = exports.WRONG_LOGIN = exports.WRONG_LOGIN_TYPE = exports.ENTITY_NOT_FOUND = exports.SECRETS = exports.Secrets = exports.getEndpointCaller = exports.isExternalSystemKind = exports.ExternalCaller = exports.DEFAULT_CALLER_KIND = exports.EXTERNAL_SYSTEM_KINDS = exports.getQueueName = exports.assertPubSubConventions = exports.assertApiKind = exports.getApiKind = exports.ENDPOINT_KINDS_BY_API_KIND = exports.Queue = exports.PubSub = exports.Rpc = exports.AuthMeta = exports.DtoSchemaBuilder = exports.DtoValidationFailure = exports.ApiJsonSchema = exports.WpResponseDto = exports.WpDtoFieldMetadata = exports.WpDtoMapFieldOptions = exports.WpMcpHeader = exports.WpDtoFieldOptions = exports.WpDtoField = exports.WpDto = exports.getWpMcpAuthJwt = void 0;
|
|
14
|
+
exports.ApiUnsupportedMediaTypeError = exports.ApiPreconditionFailedError = exports.ApiUnprocessableError = exports.ApiConflictError = exports.ApiEndpointNotFoundError = exports.ApiConnectionError = exports.ApiDependencyBackoffError = exports.ApiUnauthorizedError = exports.ApiBadRequestError = exports.ApiEndUserError = exports.ApiRequestTimeoutError = exports.ApiForbiddenError = exports.ApiRateLimitedError = exports.ApiImplementationError = exports.ApiDependencyTimeoutError = exports.ApiUnavailableError = exports.ApiBadGatewayError = exports.ApiDependencyError = exports.ApiNotFoundError = exports.ApiError = exports.FilterChain = exports.Filter = exports.SerializedError = exports.SerializedMap = exports.RecordSerializer = exports.getDoNotRecordFields = exports.DoNotRecord = exports.RecordedTestCase = exports.RecordedError = exports.RecordedEndpoint = exports.RecorderKeys = exports.ApiMethodInfo = exports.LOG_API_CALL_LOGGER_NAME = exports.ApiCallLogNameImpl = exports.ApiCallLogName = exports.ApiCallInfo = exports.MaskSpec = exports.LogApiCallImpl = exports.ContextMgr = exports.DestinationTrust = exports.WebpiecesCoreHeaders = exports.templateDeriver = exports.WEBPIECES_DEFAULT_FAILURE_CLASSIFIER = exports.WebpiecesDefaultFailureClassifier = exports.KeyedFailureClassifier = exports.ReceivedApiErrorRule = exports.SurfaceEndUserStatus = exports.WEBPIECES_DEFAULT_ERROR_TRANSLATOR = exports.WebpiecesDefaultErrorTranslator = exports.HttpResponseDto = void 0;
|
|
15
|
+
exports.ApiErrorHttpStatus = exports.ApiErrorBoundary = exports.ApiErrorPayload = exports.ApiErrorCodec = exports.ApiCodedError = exports.ApiNotImplementedError = void 0;
|
|
15
16
|
var errorUtils_1 = require("./lib/errorUtils");
|
|
16
17
|
Object.defineProperty(exports, "toError", { enumerable: true, get: function () { return errorUtils_1.toError; } });
|
|
17
18
|
var ContextKey_1 = require("./ContextKey");
|
|
@@ -79,6 +80,21 @@ var http_parameter_decorators_1 = require("./http/http-parameter-decorators");
|
|
|
79
80
|
Object.defineProperty(exports, "PathParam", { enumerable: true, get: function () { return http_parameter_decorators_1.PathParam; } });
|
|
80
81
|
Object.defineProperty(exports, "QueryParam", { enumerable: true, get: function () { return http_parameter_decorators_1.QueryParam; } });
|
|
81
82
|
Object.defineProperty(exports, "getHttpParameterDeclarations", { enumerable: true, get: function () { return http_parameter_decorators_1.getHttpParameterDeclarations; } });
|
|
83
|
+
var numeric_field_decorators_1 = require("./http/numeric-field-decorators");
|
|
84
|
+
Object.defineProperty(exports, "WpInt", { enumerable: true, get: function () { return numeric_field_decorators_1.WpInt; } });
|
|
85
|
+
Object.defineProperty(exports, "WpMin", { enumerable: true, get: function () { return numeric_field_decorators_1.WpMin; } });
|
|
86
|
+
Object.defineProperty(exports, "WpMax", { enumerable: true, get: function () { return numeric_field_decorators_1.WpMax; } });
|
|
87
|
+
Object.defineProperty(exports, "NUMERIC_METADATA_KEYS", { enumerable: true, get: function () { return numeric_field_decorators_1.NUMERIC_METADATA_KEYS; } });
|
|
88
|
+
var api_type_1 = require("./http/api-type");
|
|
89
|
+
Object.defineProperty(exports, "ApiType", { enumerable: true, get: function () { return api_type_1.ApiType; } });
|
|
90
|
+
Object.defineProperty(exports, "SVC_TO_SVC", { enumerable: true, get: function () { return api_type_1.SVC_TO_SVC; } });
|
|
91
|
+
Object.defineProperty(exports, "EXTERNAL_CUSTOMER", { enumerable: true, get: function () { return api_type_1.EXTERNAL_CUSTOMER; } });
|
|
92
|
+
Object.defineProperty(exports, "MCP", { enumerable: true, get: function () { return api_type_1.MCP; } });
|
|
93
|
+
Object.defineProperty(exports, "API_TYPE_METADATA_KEY", { enumerable: true, get: function () { return api_type_1.API_TYPE_METADATA_KEY; } });
|
|
94
|
+
Object.defineProperty(exports, "DEFAULT_API_TYPES", { enumerable: true, get: function () { return api_type_1.DEFAULT_API_TYPES; } });
|
|
95
|
+
Object.defineProperty(exports, "getApiTypes", { enumerable: true, get: function () { return api_type_1.getApiTypes; } });
|
|
96
|
+
Object.defineProperty(exports, "getApiTypeEndpointNames", { enumerable: true, get: function () { return api_type_1.getApiTypeEndpointNames; } });
|
|
97
|
+
Object.defineProperty(exports, "assertApiTypeMatchesMcpTools", { enumerable: true, get: function () { return api_type_1.assertApiTypeMatchesMcpTools; } });
|
|
82
98
|
var IpcDecorators_1 = require("./ipc/IpcDecorators");
|
|
83
99
|
Object.defineProperty(exports, "WpInternal", { enumerable: true, get: function () { return IpcDecorators_1.WpInternal; } });
|
|
84
100
|
Object.defineProperty(exports, "WpIpcEndpoint", { enumerable: true, get: function () { return IpcDecorators_1.WpIpcEndpoint; } });
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/core-util/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @webpieces/core-util\n *\n * Utility functions for WebPieces applications.\n * This package works in both browser and Node.js environments.\n *\n * @packageDocumentation\n */\n\nexport { toError } from './lib/errorUtils';\nexport { ContextKey } from './ContextKey';\nexport type {\n AnyContextKey,\n AnyTrustedContextKey,\n AnyUntrustedContextKey,\n Trust,\n} from './ContextKey';\nexport { ContextTuple } from './ContextTuple';\n\n// @DocumentDesign — DI-design-root marker. Applies to ANY project kind (server\n// controllers AND library impl classes), so it lives here (browser + Node) rather\n// than in a server-only routing package.\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './DocumentDesign';\n\n// Logging (merged from former @webpieces/wp-logging).\n// Pluggable logging interface + a browser-safe console default; apps plug in\n// bunyan/winston/pino/etc. via LogManager.setFactory(...). Browser + Node.\nexport type { Logger, LogLevel } from './logging/Logger';\nexport type { LoggerFactory } from './logging/LoggerFactory';\nexport { ConsoleLogger } from './logging/ConsoleLogger';\nexport { ConsoleLoggerFactory } from './logging/ConsoleLoggerFactory';\nexport { LogManager } from './logging/LogManager';\nexport {\n LogChunker,\n LogChunkerImpl,\n LogChunkInfo,\n MAX_GCP_LOG_BYTES,\n GCP_LOG_BUDGET_BYTES,\n} from './logging/LogChunker';\n\n// HTTP API contract (merged from former @webpieces/http-api).\n// Shared HTTP API definition consumed by both client and server: REST\n// decorators, the API error taxonomy, datetime DTOs, platform-header\n// registry/readers, ValidateImplementation, and the test-case recorder\n// contract. Pure definitions — express-free, browser + Node safe.\n\n// API definition decorators\nexport {\n ApiPath,\n Endpoint,\n // Auth mode decorators (clean service-to-service + user JWT model)\n WpAuthPublic,\n WpAuthJwt,\n rolesRequired,\n MISSING_AUTH_DECORATOR_FIX,\n WpAuthOidc,\n WpAuthSharedSecret,\n WpAuthWebhook,\n WpAuthApiKey,\n WpAuthLocalOnly,\n MaskLog,\n getApiPath,\n getEndpoints,\n getEndpointHttpMethod,\n getEndpointOptions,\n getEndpointOperation,\n getEndpointKind,\n getEndpointKinds,\n getMaskSpec,\n isFormPost,\n isRawBody,\n isApiPath,\n getAuthMeta,\n getAuthMode,\n assertEveryEndpointHasAuthMode,\n assertEveryExternalEndpointDeclaresCaller,\n assertEveryWebhookEndpointRetainsRawBody,\n validateNoConflictingDecorators,\n METADATA_KEYS,\n} from './http/decorators';\nexport {\n PathParam,\n QueryParam,\n getHttpParameterDeclarations,\n} from './http/http-parameter-decorators';\nexport {\n WpInternal,\n WpIpcEndpoint,\n isInternalApi,\n getIpcApiId,\n getIpcEndpoints,\n getIpcEndpointKind,\n getIpcMaskSpec,\n assertInternalApi,\n assertNotInternalApi,\n IPC_METADATA_KEYS,\n} from './ipc/IpcDecorators';\nexport type { IpcApiType, IpcEndpointKind, IpcEndpointOptions } from './ipc/IpcDecorators';\n// The runtime representation of ONE route (split out of decorators.ts for file size only).\nexport { RouteMetadata } from './http/RouteMetadata';\nexport { RouteMetadataFactory } from './http/RouteMetadataFactory';\nexport {\n BoundHttpRequest,\n HttpContractMapper,\n HttpParameterBinding,\n HttpParameterDeclaration,\n} from './http/HttpContract';\nexport {\n StreamCorrelation,\n StreamEnvelope,\n StreamingEndpointMetadata,\n StreamEventValidator,\n StreamTransportError,\n StreamWriter,\n WpStream,\n getStreamingEndpoint,\n} from './http/StreamingContract';\nexport type {\n RequestStream,\n ResponseStream,\n StreamEnvelopeKind,\n StreamFailureOptions,\n} from './http/StreamingContract';\nexport type {\n EndpointResponseType,\n HttpMethod,\n HttpParameterSource,\n HttpParameterValueType,\n} from './http/HttpContract';\nexport { GET, POST } from './http/HttpContract';\nexport type {\n EndpointKind,\n EndpointOperation,\n EndpointOptions,\n ExternalEndpointOptions,\n} from './http/decorators';\nexport {\n RPC,\n CLOUDTASKS,\n CRON,\n EXTERNAL,\n READ,\n WRITE_IDEMPOTENT,\n WRITE,\n} from './http/decorators';\nexport {\n WpMcpTool,\n WpMcpToolHints,\n WpMcpToolMetadata,\n getWpMcpTools,\n mcpHintsForOperation,\n} from './mcp/McpMetadata';\nexport type { WpMcpMethodDecorator, WpMcpToolOptions } from './mcp/McpMetadata';\nexport { WpMcpAuthJwt, WpMcpJwtAuthMetadata, getWpMcpAuthJwt } from './mcp/McpAuthMetadata';\nexport {\n WpDto,\n WpDtoField,\n WpDtoFieldOptions,\n WpMcpHeader,\n WpDtoMapFieldOptions,\n WpDtoFieldMetadata,\n WpResponseDto,\n ApiJsonSchema,\n DtoValidationFailure,\n DtoSchemaBuilder,\n} from './mcp/DtoSchema';\nexport type { DtoClass, DtoElementType, DtoValue } from './mcp/DtoSchema';\n// The TYPE layer of the auth surface — likewise split out of decorators.ts for file size only.\nexport { AuthMeta } from './http/auth-mode';\nexport type {\n AuthMode,\n ApiKeyCredential,\n ApiKeyCredentials,\n JwtRoles,\n JwtRequirement,\n} from './http/auth-mode';\n// API kind (RPC vs PubSub/Cloud Tasks) + queue naming. Split out of decorators.ts for file size only;\n// one-way dependency api-kind -> decorators, and the barrel keeps the surface identical.\nexport {\n Rpc,\n PubSub,\n Queue,\n ENDPOINT_KINDS_BY_API_KIND,\n getApiKind,\n assertApiKind,\n assertPubSubConventions,\n getQueueName,\n} from './http/api-kind';\nexport type { ApiKind } from './http/api-kind';\n// WHO calls an `external` endpoint — the caller declaration\n// @Endpoint(POST, ..., WRITE, EXTERNAL, { calledBy })\n// requires, and the reader for it.\nexport {\n EXTERNAL_SYSTEM_KINDS,\n DEFAULT_CALLER_KIND,\n ExternalCaller,\n isExternalSystemKind,\n getEndpointCaller,\n} from './http/external-caller';\nexport type { ExternalSystemKind } from './http/external-caller';\n// Client-side shared-secret store (the value THIS service sends per @WpAuthSharedSecret key).\nexport { Secrets, SECRETS } from './http/Secrets';\n\n// Type validators\nexport { ValidateImplementation } from './http/validators';\n\n// Authentication subtype constants.\nexport {\n ENTITY_NOT_FOUND,\n WRONG_LOGIN_TYPE,\n WRONG_LOGIN,\n NOT_APPROVED,\n EMAIL_NOT_CONFIRMED,\n WRONG_DOMAIN,\n WRONG_COMPANY,\n NO_REG_CODE,\n} from './errors';\n\nexport { NetworkRejectClassifier } from './http/networkReject';\n\n// Date/Time DTOs and Utilities (inspired by Java Time / JSR-310)\nexport {\n InstantDto,\n DateDto,\n TimeDto,\n DateTimeDto,\n InstantUtil,\n DateUtil,\n TimeUtil,\n DateTimeUtil,\n} from './http/datetime';\n\n// Context keys + registry (the global magic-context header system)\nexport { HeaderRegistry } from './http/HeaderRegistry';\nexport { ClientRegistry } from './http/ClientRegistry';\nexport { CallRegistry } from './http/CallRegistry';\nexport { CallDeadline } from './http/CallDeadline';\nexport { CallContext } from './http/CallStrategy';\nexport type { Attempt, CallStrategy } from './http/CallStrategy';\nexport { ApiCallTimeoutError } from './http/ApiCallTimeoutError';\nexport type { ServiceUrlDeriver } from './http/ClientRegistry';\n\n// \"What service am I\" — set once at startup, read by the logging backends and by\n// RequestContextHeaders (to stamp requestIdSource on ids this service mints).\nexport { ServiceInfo } from './http/ServiceInfo';\n// \"Where am I running\" — declared once at startup (setupRuntime, from RuntimeSetupOptions.locality).\n// The ONE input to @WpAuthLocalOnly enforcement. Undeclared reads as DEPLOYED (fail safe).\nexport { RuntimeLocality } from './http/RuntimeLocality';\nexport type { Locality } from './http/RuntimeLocality';\n// The ENTIRE HTTP response as pure data — the ONE form both transports (express, fetch) are\n// normalised into, so an ErrorTranslator implementation is written once and serves both.\nexport { HttpHeader, HttpResponseStatus, HttpResponseDto } from './http/HttpResponseDto';\n// Pluggable, bidirectional error translation (app exception <-> the WHOLE response). Set on\n// ClientRegistry at startup; consulted before the built-in webpieces mapping on BOTH sides.\nexport type { ErrorTranslator } from './http/ErrorTranslator';\n// THE webpieces default translator — always installed, and what an app's own translator delegates to\n// in order to decline an error. ONE class, both halves, node and browser alike.\nexport {\n WebpiecesDefaultErrorTranslator,\n WEBPIECES_DEFAULT_ERROR_TRANSLATOR,\n} from './http/WebpiecesDefaultErrorTranslator';\n// WHICH KIND OF CALLER drove this request (gui / llm / public-api), and the per-request end-user\n// status derived from it — the replacement for the deleted per-router EndUserStatus.\nexport { SurfaceEndUserStatus } from './http/Surface';\nexport type { Surface } from './http/Surface';\n// The ONE rule for an error RECEIVED from another process, shared verbatim by HTTP and IPC.\nexport { ReceivedApiErrorRule } from './errors/ReceivedApiErrorRule';\n// Pluggable per-client failure classification (is a thrown API-call error a real failure or an\n// expected non-failure?). Registered on ClientRegistry at startup; consulted by LogApiCall.\nexport type { FailureClassifier } from './http/FailureClassifier';\nexport { KeyedFailureClassifier } from './http/FailureClassifier';\nexport {\n WebpiecesDefaultFailureClassifier,\n WEBPIECES_DEFAULT_FAILURE_CLASSIFIER,\n} from './http/WebpiecesDefaultFailureClassifier';\nexport { templateDeriver } from './http/templateDeriver';\nexport { WebpiecesCoreHeaders } from './http/WebpiecesCoreHeaders';\nexport { ContextReader } from './http/ContextReader';\nexport { ContextWriter, ContextStore } from './http/ContextWriter';\n\n// The OUTBOUND half of the trust model: whether a TRUSTED context key may ride to the endpoint being\n// called. Built ONLY from the destination endpoint's AuthMode — see the class doc.\nexport { DestinationTrust } from './http/DestinationTrust';\n\n// BROWSER-ONLY outbound-header propagation (app-held store + registry -> outbound HTTP headers).\n// Only @webpieces/http-client-browser may name it; the server reads RequestContext directly via\n// RequestContextHeaders in the Node-only @webpieces/core-context.\nexport { ContextMgr } from './http/ContextMgr';\n\n// API-call logging helper (uses LogManager above). NOT a singleton: construct one per environment\n// with that environment's ApiCallContext — `new LogApiCallImpl(new RequestContextApiCallContext())`\n// on node, `new LogApiCallImpl(new BrowserApiCallContext())` in a browser.\nexport { LogApiCallImpl } from './http/LogApiCall';\n\n// Opt-in field masking for the LogApiCall log path — declare per-api sensitive fields so secrets\n// (OAuth refresh tokens, id-token JWTs) are masked in the logs while the real value stays on the wire.\nexport { MaskSpec } from './http/LogFieldMask';\nexport type { MaskMode } from './http/LogFieldMask';\n\n// The structured `api` tag + the context-writer seam LogApiCall stamps through. The Node\n// RequestContext-backed impl lives in @webpieces/core-context, the browser one in\n// @webpieces/http-client-browser; each is CONSTRUCTED by its package, never installed globally.\nexport { ApiCallInfo } from './http/ApiCallInfo';\nexport type { ApiType, ApiResult } from './http/ApiCallInfo';\n// Console-render bridge: turns LogApiCall's [LogApiCall] bracket into [API.{side}.{phase}] locally.\nexport {\n ApiCallLogName,\n ApiCallLogNameImpl,\n LOG_API_CALL_LOGGER_NAME,\n} from './http/ApiCallLogName';\nexport { ApiMethodInfo } from './http/ApiMethodInfo';\nexport type { ApiSide } from './http/ApiMethodInfo';\nexport type { ApiCallContext } from './http/ApiCallContext';\n\n// Test-case recording contract (impl lives in http-server; hooks in http-client)\nexport { TestCaseRecorder, RecorderKeys } from './http/recorder/TestCaseRecorder';\nexport {\n RecordedEndpoint,\n RecordedError,\n RecordedTestCase,\n} from './http/recorder/RecordedEndpoint';\nexport { DoNotRecord, getDoNotRecordFields } from './http/recorder/DoNotRecord';\nexport { RecordSerializer, SerializedMap, SerializedError } from './http/recorder/RecordSerializer';\n\n// ---------------------------------------------------------------------------------------------\n// Filter-chain primitives, shared by BOTH chains: the inbound server chain\n// (`Filter<MethodMeta, WpResponse<unknown>>`, @webpieces/http-routing) and the outbound client\n// chain (`Filter<ClientRequest, Response>`, @webpieces/http-client-core). Declared once, here, in\n// the package both depend on — see the class doc for why a second pair would be a shim.\nexport { Filter } from './filters/Filter';\nexport type { Service } from './filters/Filter';\nexport { FilterChain } from './filters/FilterChain';\n\nexport {\n ApiError,\n ApiNotFoundError,\n ApiDependencyError,\n ApiBadGatewayError,\n ApiUnavailableError,\n ApiDependencyTimeoutError,\n ApiImplementationError,\n ApiRateLimitedError,\n ApiForbiddenError,\n ApiRequestTimeoutError,\n ApiEndUserError,\n ApiBadRequestError,\n ApiUnauthorizedError,\n ApiDependencyBackoffError,\n ApiConnectionError,\n ApiEndpointNotFoundError,\n ApiConflictError,\n ApiUnprocessableError,\n ApiPreconditionFailedError,\n ApiUnsupportedMediaTypeError,\n ApiNotImplementedError,\n ApiCodedError,\n ApiErrorCodec,\n ApiErrorPayload,\n ApiErrorBoundary,\n} from './errors';\nexport type { ApiErrorKind, ApiStatusCode, EdgeHttpStatus } from './errors';\nexport { ApiErrorHttpStatus } from './http/ApiErrorHttpStatus';\nexport type { PublishedKind, PublishedApiError } from './http/ApiErrorHttpStatus';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/core-util/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @webpieces/core-util\n *\n * Utility functions for WebPieces applications.\n * This package works in both browser and Node.js environments.\n *\n * @packageDocumentation\n */\n\nexport { toError } from './lib/errorUtils';\nexport { ContextKey } from './ContextKey';\nexport type {\n AnyContextKey,\n AnyTrustedContextKey,\n AnyUntrustedContextKey,\n Trust,\n} from './ContextKey';\nexport { ContextTuple } from './ContextTuple';\n\n// @DocumentDesign — DI-design-root marker. Applies to ANY project kind (server\n// controllers AND library impl classes), so it lives here (browser + Node) rather\n// than in a server-only routing package.\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './DocumentDesign';\n\n// Logging (merged from former @webpieces/wp-logging).\n// Pluggable logging interface + a browser-safe console default; apps plug in\n// bunyan/winston/pino/etc. via LogManager.setFactory(...). Browser + Node.\nexport type { Logger, LogLevel } from './logging/Logger';\nexport type { LoggerFactory } from './logging/LoggerFactory';\nexport { ConsoleLogger } from './logging/ConsoleLogger';\nexport { ConsoleLoggerFactory } from './logging/ConsoleLoggerFactory';\nexport { LogManager } from './logging/LogManager';\nexport {\n LogChunker,\n LogChunkerImpl,\n LogChunkInfo,\n MAX_GCP_LOG_BYTES,\n GCP_LOG_BUDGET_BYTES,\n} from './logging/LogChunker';\n\n// HTTP API contract (merged from former @webpieces/http-api).\n// Shared HTTP API definition consumed by both client and server: REST\n// decorators, the API error taxonomy, datetime DTOs, platform-header\n// registry/readers, ValidateImplementation, and the test-case recorder\n// contract. Pure definitions — express-free, browser + Node safe.\n\n// API definition decorators\nexport {\n ApiPath,\n Endpoint,\n // Auth mode decorators (clean service-to-service + user JWT model)\n WpAuthPublic,\n WpAuthJwt,\n rolesRequired,\n MISSING_AUTH_DECORATOR_FIX,\n WpAuthOidc,\n WpAuthSharedSecret,\n WpAuthWebhook,\n WpAuthApiKey,\n WpAuthLocalOnly,\n MaskLog,\n getApiPath,\n getEndpoints,\n getEndpointHttpMethod,\n getEndpointOptions,\n getEndpointOperation,\n getEndpointKind,\n getEndpointKinds,\n getMaskSpec,\n isFormPost,\n isRawBody,\n isApiPath,\n getAuthMeta,\n getAuthMode,\n assertEveryEndpointHasAuthMode,\n assertEveryExternalEndpointDeclaresCaller,\n assertEveryWebhookEndpointRetainsRawBody,\n validateNoConflictingDecorators,\n METADATA_KEYS,\n} from './http/decorators';\nexport {\n PathParam,\n QueryParam,\n getHttpParameterDeclarations,\n} from './http/http-parameter-decorators';\nexport { WpInt, WpMin, WpMax, NUMERIC_METADATA_KEYS } from './http/numeric-field-decorators';\nexport type { Integer } from './http/numeric-field-decorators';\nexport {\n ApiType,\n SVC_TO_SVC,\n EXTERNAL_CUSTOMER,\n MCP,\n API_TYPE_METADATA_KEY,\n DEFAULT_API_TYPES,\n getApiTypes,\n getApiTypeEndpointNames,\n assertApiTypeMatchesMcpTools,\n} from './http/api-type';\nexport type { ApiTypeKind } from './http/api-type';\nexport {\n WpInternal,\n WpIpcEndpoint,\n isInternalApi,\n getIpcApiId,\n getIpcEndpoints,\n getIpcEndpointKind,\n getIpcMaskSpec,\n assertInternalApi,\n assertNotInternalApi,\n IPC_METADATA_KEYS,\n} from './ipc/IpcDecorators';\nexport type { IpcApiType, IpcEndpointKind, IpcEndpointOptions } from './ipc/IpcDecorators';\n// The runtime representation of ONE route (split out of decorators.ts for file size only).\nexport { RouteMetadata } from './http/RouteMetadata';\nexport { RouteMetadataFactory } from './http/RouteMetadataFactory';\nexport {\n BoundHttpRequest,\n HttpContractMapper,\n HttpParameterBinding,\n HttpParameterDeclaration,\n} from './http/HttpContract';\nexport {\n StreamCorrelation,\n StreamEnvelope,\n StreamingEndpointMetadata,\n StreamEventValidator,\n StreamTransportError,\n StreamWriter,\n WpStream,\n getStreamingEndpoint,\n} from './http/StreamingContract';\nexport type {\n RequestStream,\n ResponseStream,\n StreamEnvelopeKind,\n StreamFailureOptions,\n} from './http/StreamingContract';\nexport type {\n EndpointResponseType,\n HttpMethod,\n HttpParameterSource,\n HttpParameterValueType,\n} from './http/HttpContract';\nexport { GET, POST } from './http/HttpContract';\nexport type {\n EndpointKind,\n EndpointOperation,\n EndpointOptions,\n ExternalEndpointOptions,\n} from './http/decorators';\nexport {\n RPC,\n CLOUDTASKS,\n CRON,\n EXTERNAL,\n READ,\n WRITE_IDEMPOTENT,\n WRITE,\n} from './http/decorators';\nexport {\n WpMcpTool,\n WpMcpToolHints,\n WpMcpToolMetadata,\n getWpMcpTools,\n mcpHintsForOperation,\n} from './mcp/McpMetadata';\nexport type { WpMcpMethodDecorator, WpMcpToolOptions } from './mcp/McpMetadata';\nexport { WpMcpAuthJwt, WpMcpJwtAuthMetadata, getWpMcpAuthJwt } from './mcp/McpAuthMetadata';\nexport {\n WpDto,\n WpDtoField,\n WpDtoFieldOptions,\n WpMcpHeader,\n WpDtoMapFieldOptions,\n WpDtoFieldMetadata,\n WpResponseDto,\n ApiJsonSchema,\n DtoValidationFailure,\n DtoSchemaBuilder,\n} from './mcp/DtoSchema';\nexport type { DtoClass, DtoElementType, DtoValue } from './mcp/DtoSchema';\n// The TYPE layer of the auth surface — likewise split out of decorators.ts for file size only.\nexport { AuthMeta } from './http/auth-mode';\nexport type {\n AuthMode,\n ApiKeyCredential,\n ApiKeyCredentials,\n JwtRoles,\n JwtRequirement,\n} from './http/auth-mode';\n// API kind (RPC vs PubSub/Cloud Tasks) + queue naming. Split out of decorators.ts for file size only;\n// one-way dependency api-kind -> decorators, and the barrel keeps the surface identical.\nexport {\n Rpc,\n PubSub,\n Queue,\n ENDPOINT_KINDS_BY_API_KIND,\n getApiKind,\n assertApiKind,\n assertPubSubConventions,\n getQueueName,\n} from './http/api-kind';\nexport type { ApiKind } from './http/api-kind';\n// WHO calls an `external` endpoint — the caller declaration\n// @Endpoint(POST, ..., WRITE, EXTERNAL, { calledBy })\n// requires, and the reader for it.\nexport {\n EXTERNAL_SYSTEM_KINDS,\n DEFAULT_CALLER_KIND,\n ExternalCaller,\n isExternalSystemKind,\n getEndpointCaller,\n} from './http/external-caller';\nexport type { ExternalSystemKind } from './http/external-caller';\n// Client-side shared-secret store (the value THIS service sends per @WpAuthSharedSecret key).\nexport { Secrets, SECRETS } from './http/Secrets';\n\n// Type validators\nexport { ValidateImplementation } from './http/validators';\n\n// Authentication subtype constants.\nexport {\n ENTITY_NOT_FOUND,\n WRONG_LOGIN_TYPE,\n WRONG_LOGIN,\n NOT_APPROVED,\n EMAIL_NOT_CONFIRMED,\n WRONG_DOMAIN,\n WRONG_COMPANY,\n NO_REG_CODE,\n} from './errors';\n\nexport { NetworkRejectClassifier } from './http/networkReject';\n\n// Date/Time DTOs and Utilities (inspired by Java Time / JSR-310)\nexport {\n InstantDto,\n DateDto,\n TimeDto,\n DateTimeDto,\n InstantUtil,\n DateUtil,\n TimeUtil,\n DateTimeUtil,\n} from './http/datetime';\n\n// Context keys + registry (the global magic-context header system)\nexport { HeaderRegistry } from './http/HeaderRegistry';\nexport { ClientRegistry } from './http/ClientRegistry';\nexport { CallRegistry } from './http/CallRegistry';\nexport { CallDeadline } from './http/CallDeadline';\nexport { CallContext } from './http/CallStrategy';\nexport type { Attempt, CallStrategy } from './http/CallStrategy';\nexport { ApiCallTimeoutError } from './http/ApiCallTimeoutError';\nexport type { ServiceUrlDeriver } from './http/ClientRegistry';\n\n// \"What service am I\" — set once at startup, read by the logging backends and by\n// RequestContextHeaders (to stamp requestIdSource on ids this service mints).\nexport { ServiceInfo } from './http/ServiceInfo';\n// \"Where am I running\" — declared once at startup (setupRuntime, from RuntimeSetupOptions.locality).\n// The ONE input to @WpAuthLocalOnly enforcement. Undeclared reads as DEPLOYED (fail safe).\nexport { RuntimeLocality } from './http/RuntimeLocality';\nexport type { Locality } from './http/RuntimeLocality';\n// The ENTIRE HTTP response as pure data — the ONE form both transports (express, fetch) are\n// normalised into, so an ErrorTranslator implementation is written once and serves both.\nexport { HttpHeader, HttpResponseStatus, HttpResponseDto } from './http/HttpResponseDto';\n// Pluggable, bidirectional error translation (app exception <-> the WHOLE response). Set on\n// ClientRegistry at startup; consulted before the built-in webpieces mapping on BOTH sides.\nexport type { ErrorTranslator } from './http/ErrorTranslator';\n// THE webpieces default translator — always installed, and what an app's own translator delegates to\n// in order to decline an error. ONE class, both halves, node and browser alike.\nexport {\n WebpiecesDefaultErrorTranslator,\n WEBPIECES_DEFAULT_ERROR_TRANSLATOR,\n} from './http/WebpiecesDefaultErrorTranslator';\n// WHICH KIND OF CALLER drove this request (gui / llm / public-api), and the per-request end-user\n// status derived from it — the replacement for the deleted per-router EndUserStatus.\nexport { SurfaceEndUserStatus } from './http/Surface';\nexport type { Surface } from './http/Surface';\n// The ONE rule for an error RECEIVED from another process, shared verbatim by HTTP and IPC.\nexport { ReceivedApiErrorRule } from './errors/ReceivedApiErrorRule';\n// Pluggable per-client failure classification (is a thrown API-call error a real failure or an\n// expected non-failure?). Registered on ClientRegistry at startup; consulted by LogApiCall.\nexport type { FailureClassifier } from './http/FailureClassifier';\nexport { KeyedFailureClassifier } from './http/FailureClassifier';\nexport {\n WebpiecesDefaultFailureClassifier,\n WEBPIECES_DEFAULT_FAILURE_CLASSIFIER,\n} from './http/WebpiecesDefaultFailureClassifier';\nexport { templateDeriver } from './http/templateDeriver';\nexport { WebpiecesCoreHeaders } from './http/WebpiecesCoreHeaders';\nexport { ContextReader } from './http/ContextReader';\nexport { ContextWriter, ContextStore } from './http/ContextWriter';\n\n// The OUTBOUND half of the trust model: whether a TRUSTED context key may ride to the endpoint being\n// called. Built ONLY from the destination endpoint's AuthMode — see the class doc.\nexport { DestinationTrust } from './http/DestinationTrust';\n\n// BROWSER-ONLY outbound-header propagation (app-held store + registry -> outbound HTTP headers).\n// Only @webpieces/http-client-browser may name it; the server reads RequestContext directly via\n// RequestContextHeaders in the Node-only @webpieces/core-context.\nexport { ContextMgr } from './http/ContextMgr';\n\n// API-call logging helper (uses LogManager above). NOT a singleton: construct one per environment\n// with that environment's ApiCallContext — `new LogApiCallImpl(new RequestContextApiCallContext())`\n// on node, `new LogApiCallImpl(new BrowserApiCallContext())` in a browser.\nexport { LogApiCallImpl } from './http/LogApiCall';\n\n// Opt-in field masking for the LogApiCall log path — declare per-api sensitive fields so secrets\n// (OAuth refresh tokens, id-token JWTs) are masked in the logs while the real value stays on the wire.\nexport { MaskSpec } from './http/LogFieldMask';\nexport type { MaskMode } from './http/LogFieldMask';\n\n// The structured `api` tag + the context-writer seam LogApiCall stamps through. The Node\n// RequestContext-backed impl lives in @webpieces/core-context, the browser one in\n// @webpieces/http-client-browser; each is CONSTRUCTED by its package, never installed globally.\nexport { ApiCallInfo } from './http/ApiCallInfo';\nexport type { ApiCallDirection, ApiResult } from './http/ApiCallInfo';\n// Console-render bridge: turns LogApiCall's [LogApiCall] bracket into [API.{side}.{phase}] locally.\nexport {\n ApiCallLogName,\n ApiCallLogNameImpl,\n LOG_API_CALL_LOGGER_NAME,\n} from './http/ApiCallLogName';\nexport { ApiMethodInfo } from './http/ApiMethodInfo';\nexport type { ApiSide } from './http/ApiMethodInfo';\nexport type { ApiCallContext } from './http/ApiCallContext';\n\n// Test-case recording contract (impl lives in http-server; hooks in http-client)\nexport { TestCaseRecorder, RecorderKeys } from './http/recorder/TestCaseRecorder';\nexport {\n RecordedEndpoint,\n RecordedError,\n RecordedTestCase,\n} from './http/recorder/RecordedEndpoint';\nexport { DoNotRecord, getDoNotRecordFields } from './http/recorder/DoNotRecord';\nexport { RecordSerializer, SerializedMap, SerializedError } from './http/recorder/RecordSerializer';\n\n// ---------------------------------------------------------------------------------------------\n// Filter-chain primitives, shared by BOTH chains: the inbound server chain\n// (`Filter<MethodMeta, WpResponse<unknown>>`, @webpieces/http-routing) and the outbound client\n// chain (`Filter<ClientRequest, Response>`, @webpieces/http-client-core). Declared once, here, in\n// the package both depend on — see the class doc for why a second pair would be a shim.\nexport { Filter } from './filters/Filter';\nexport type { Service } from './filters/Filter';\nexport { FilterChain } from './filters/FilterChain';\n\nexport {\n ApiError,\n ApiNotFoundError,\n ApiDependencyError,\n ApiBadGatewayError,\n ApiUnavailableError,\n ApiDependencyTimeoutError,\n ApiImplementationError,\n ApiRateLimitedError,\n ApiForbiddenError,\n ApiRequestTimeoutError,\n ApiEndUserError,\n ApiBadRequestError,\n ApiUnauthorizedError,\n ApiDependencyBackoffError,\n ApiConnectionError,\n ApiEndpointNotFoundError,\n ApiConflictError,\n ApiUnprocessableError,\n ApiPreconditionFailedError,\n ApiUnsupportedMediaTypeError,\n ApiNotImplementedError,\n ApiCodedError,\n ApiErrorCodec,\n ApiErrorPayload,\n ApiErrorBoundary,\n} from './errors';\nexport type { ApiErrorKind, ApiStatusCode, EdgeHttpStatus } from './errors';\nexport { ApiErrorHttpStatus } from './http/ApiErrorHttpStatus';\nexport type { PublishedKind, PublishedApiError } from './http/ApiErrorHttpStatus';\n"]}
|