@webpieces/core-util 0.4.880 → 0.4.882
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/errors/ApiCallSite.d.ts +58 -0
- package/src/errors/ApiCallSite.js +96 -0
- package/src/errors/ApiCallSite.js.map +1 -0
- package/src/errors/ApiError.d.ts +9 -0
- package/src/errors/ApiError.js.map +1 -1
- package/src/errors/ReportableApiFailure.d.ts +43 -0
- package/src/errors/ReportableApiFailure.js +75 -0
- package/src/errors/ReportableApiFailure.js.map +1 -0
- package/src/errors/index.d.ts +3 -0
- package/src/errors/index.js +6 -1
- package/src/errors/index.js.map +1 -1
- package/src/http/WebpiecesDefaultErrorTranslator.d.ts +3 -0
- package/src/http/WebpiecesDefaultErrorTranslator.js +10 -0
- package/src/http/WebpiecesDefaultErrorTranslator.js.map +1 -1
- package/src/http/WebpiecesDefaultFailureClassifier.d.ts +3 -2
- package/src/http/WebpiecesDefaultFailureClassifier.js +6 -3
- package/src/http/WebpiecesDefaultFailureClassifier.js.map +1 -1
- package/src/http/api-type.js +2 -2
- package/src/http/api-type.js.map +1 -1
- package/src/index.d.ts +8 -2
- package/src/index.js +20 -1
- package/src/index.js.map +1 -1
- package/src/mcp/McpCompileAssertions.js +14 -4
- package/src/mcp/McpCompileAssertions.js.map +1 -1
- package/src/mcp/McpMetadata.d.ts +25 -13
- package/src/mcp/McpMetadata.js +31 -14
- package/src/mcp/McpMetadata.js.map +1 -1
- package/src/mcp/McpToolCatalogFile.d.ts +14 -2
- package/src/mcp/McpToolCatalogFile.js +24 -3
- package/src/mcp/McpToolCatalogFile.js.map +1 -1
- package/src/oauth/OAuthAuthorizationErrorRedirect.d.ts +37 -0
- package/src/oauth/OAuthAuthorizationErrorRedirect.js +61 -0
- package/src/oauth/OAuthAuthorizationErrorRedirect.js.map +1 -0
- package/src/oauth/OAuthBearerChallenge.d.ts +31 -0
- package/src/oauth/OAuthBearerChallenge.js +52 -0
- package/src/oauth/OAuthBearerChallenge.js.map +1 -0
- package/src/oauth/OAuthErrorCode.d.ts +69 -0
- package/src/oauth/OAuthErrorCode.js +89 -0
- package/src/oauth/OAuthErrorCode.js.map +1 -0
- package/src/oauth/OAuthErrorResponse.d.ts +34 -0
- package/src/oauth/OAuthErrorResponse.js +74 -0
- package/src/oauth/OAuthErrorResponse.js.map +1 -0
- package/src/oauth/OAuthProtocolError.d.ts +61 -0
- package/src/oauth/OAuthProtocolError.js +83 -0
- package/src/oauth/OAuthProtocolError.js.map +1 -0
- package/src/oauth/OAuthProtocolErrorCompileAssertions.d.ts +10 -0
- package/src/oauth/OAuthProtocolErrorCompileAssertions.js +39 -0
- package/src/oauth/OAuthProtocolErrorCompileAssertions.js.map +1 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WEBPIECES_DEFAULT_FAILURE_CLASSIFIER = exports.WebpiecesDefaultFailureClassifier = void 0;
|
|
4
4
|
const ApiError_1 = require("../errors/ApiError");
|
|
5
|
+
const OAuthProtocolError_1 = require("../oauth/OAuthProtocolError");
|
|
5
6
|
/**
|
|
6
7
|
* The webpieces built-in {@link FailureClassifier} — the terminal tier, used when no app default and
|
|
7
8
|
* no per-apiClass classifier claims an error. It is the SINGLE SOURCE OF TRUTH for the historical
|
|
@@ -18,8 +19,9 @@ const ApiError_1 = require("../errors/ApiError");
|
|
|
18
19
|
* - ApiBadRequestError (400), ApiUnauthorizedError (401), ApiForbiddenError (403),
|
|
19
20
|
* ApiNotFoundError (404), ApiConflictError (409), ApiPreconditionFailedError (412),
|
|
20
21
|
* ApiUnsupportedMediaTypeError (415), ApiUnprocessableError (422), and an ApiCodedError whose
|
|
21
|
-
* `isCallerError()` is true (below 500, except 408/429)
|
|
22
|
-
*
|
|
22
|
+
* `isCallerError()` is true (below 500, except 408/429), and an OAuthProtocolError below 500 (a
|
|
23
|
+
* refused grant or token is the OAuth protocol working, #1176) → the server is fine, the caller
|
|
24
|
+
* erred → NON-failure.
|
|
23
25
|
* SERVER — something may actually be WRONG, so SURFACE it (failure):
|
|
24
26
|
* - ApiRequestTimeoutError (408): a 4xx, but the client may NEVER have seen the response — deliberately
|
|
25
27
|
* absent below, so it counts as a failure. Implementation/dependency failures, ApiNotImplementedError
|
|
@@ -54,7 +56,8 @@ class WebpiecesDefaultFailureClassifier {
|
|
|
54
56
|
error instanceof ApiError_1.ApiUnprocessableError ||
|
|
55
57
|
error instanceof ApiError_1.ApiPreconditionFailedError ||
|
|
56
58
|
error instanceof ApiError_1.ApiUnsupportedMediaTypeError ||
|
|
57
|
-
(error instanceof ApiError_1.ApiCodedError && error.isCallerError())
|
|
59
|
+
(error instanceof ApiError_1.ApiCodedError && error.isCallerError()) ||
|
|
60
|
+
(error instanceof OAuthProtocolError_1.OAuthProtocolError && error.isCallerError());
|
|
58
61
|
return !healthyRejection;
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebpiecesDefaultFailureClassifier.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/WebpiecesDefaultFailureClassifier.ts"],"names":[],"mappings":";;;AAAA,iDAW4B;
|
|
1
|
+
{"version":3,"file":"WebpiecesDefaultFailureClassifier.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/WebpiecesDefaultFailureClassifier.ts"],"names":[],"mappings":";;;AAAA,iDAW4B;AAC5B,oEAAiE;AAIjE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAa,iCAAiC;IAC1C;;;;;OAKG;IACH,SAAS,CAAC,KAAY,EAAE,UAAyB;QAC7C,gEAAgE;QAChE,IAAI,KAAK,YAAY,0BAAe,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,8EAA8E;QAC9E,IAAI,UAAU,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,sFAAsF;QACtF,oGAAoG;QACpG,MAAM,gBAAgB,GAClB,KAAK,YAAY,6BAAkB;YACnC,KAAK,YAAY,+BAAoB;YACrC,KAAK,YAAY,4BAAiB;YAClC,KAAK,YAAY,2BAAgB;YACjC,KAAK,YAAY,2BAAgB;YACjC,KAAK,YAAY,gCAAqB;YACtC,KAAK,YAAY,qCAA0B;YAC3C,KAAK,YAAY,uCAA4B;YAC7C,CAAC,KAAK,YAAY,wBAAa,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACzD,CAAC,KAAK,YAAY,uCAAkB,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,gBAAgB,CAAC;IAC7B,CAAC;CACJ;AA/BD,8EA+BC;AAED,oFAAoF;AACvE,QAAA,oCAAoC,GAAG,IAAI,iCAAiC,EAAE,CAAC","sourcesContent":["import {\n ApiBadRequestError,\n ApiUnauthorizedError,\n ApiForbiddenError,\n ApiNotFoundError,\n ApiEndUserError,\n ApiConflictError,\n ApiUnprocessableError,\n ApiPreconditionFailedError,\n ApiUnsupportedMediaTypeError,\n ApiCodedError,\n} from '../errors/ApiError';\nimport { OAuthProtocolError } from '../oauth/OAuthProtocolError';\nimport { ApiMethodInfo } from './ApiMethodInfo';\nimport { FailureClassifier } from './FailureClassifier';\n\n/**\n * The webpieces built-in {@link FailureClassifier} — the terminal tier, used when no app default and\n * no per-apiClass classifier claims an error. It is the SINGLE SOURCE OF TRUTH for the historical\n * `LogApiCall.isUserError` behavior (which now delegates here), so the classification lives in one\n * place.\n *\n * The question is \"are things WORKING?\", NOT \"was it an HTTP 4xx vs 5xx\" — the two differ (see 408).\n * Classification is by portable Error TYPE, never by transport: this runs over in-process calls,\n * pubsub/queue handlers, and HTTP through one code path and only ever sees a thrown Error. The API\n * classes are portable error types that travel with the throw anywhere, so matching the TYPE works\n * with or without any HTTP in the picture.\n *\n * SERVER — a healthy server correctly rejecting a CLIENT'S mistake is metrics NOISE, not a failure:\n * - ApiBadRequestError (400), ApiUnauthorizedError (401), ApiForbiddenError (403),\n * ApiNotFoundError (404), ApiConflictError (409), ApiPreconditionFailedError (412),\n * ApiUnsupportedMediaTypeError (415), ApiUnprocessableError (422), and an ApiCodedError whose\n * `isCallerError()` is true (below 500, except 408/429), and an OAuthProtocolError below 500 (a\n * refused grant or token is the OAuth protocol working, #1176) → the server is fine, the caller\n * erred → NON-failure.\n * SERVER — something may actually be WRONG, so SURFACE it (failure):\n * - ApiRequestTimeoutError (408): a 4xx, but the client may NEVER have seen the response — deliberately\n * absent below, so it counts as a failure. Implementation/dependency failures, ApiNotImplementedError\n * (501), an ApiCodedError of 500+ (or 408/429), and non-API errors are failures.\n *\n * ApiEndUserError (266): ALWAYS a non-failure, server OR client — an expected \"user made a mistake\".\n * CLIENT: receiving ANY error except 266 means the outbound call FAILED → failure.\n */\nexport class WebpiecesDefaultFailureClassifier implements FailureClassifier {\n /**\n * Terminal tier — NEVER returns undefined (a definitive verdict is required so classification\n * always resolves to a boolean).\n *\n * @returns true = failure, false = expected/non-failure\n */\n isFailure(error: Error, methodInfo: ApiMethodInfo): boolean {\n // 266 is the one error that is never a failure, on either side.\n if (error instanceof ApiEndUserError) {\n return false;\n }\n // A client that RECEIVED any error (except the 266 above) made a failed call.\n if (methodInfo.side !== 'server') {\n return true;\n }\n // SERVER: only a healthy rejection of the caller's mistake is a non-failure. Note 408\n // (ApiRequestTimeoutError) is intentionally NOT here — the client may never have seen the response.\n const healthyRejection =\n error instanceof ApiBadRequestError ||\n error instanceof ApiUnauthorizedError ||\n error instanceof ApiForbiddenError ||\n error instanceof ApiNotFoundError ||\n error instanceof ApiConflictError ||\n error instanceof ApiUnprocessableError ||\n error instanceof ApiPreconditionFailedError ||\n error instanceof ApiUnsupportedMediaTypeError ||\n (error instanceof ApiCodedError && error.isCallerError()) ||\n (error instanceof OAuthProtocolError && error.isCallerError());\n return !healthyRejection;\n }\n}\n\n/** Process-wide built-in instance — stateless, so one shared instance is enough. */\nexport const WEBPIECES_DEFAULT_FAILURE_CLASSIFIER = new WebpiecesDefaultFailureClassifier();\n"]}
|
package/src/http/api-type.js
CHANGED
|
@@ -102,8 +102,8 @@ function assertApiTypeMatchesMcpTools(apiClass) {
|
|
|
102
102
|
'every method is permanently outside MCP does not feed the MCP document.');
|
|
103
103
|
}
|
|
104
104
|
throw new Error(`${apiClass.name} declares @ApiType(..., MCP) but no method carries @WpMcpTool. ` +
|
|
105
|
-
"Add @WpMcpTool('<stable_tool_name>') to the methods
|
|
106
|
-
'from the @ApiType list.');
|
|
105
|
+
"Add @WpMcpTool('<stable_tool_name>', '<Human-readable title>') to the methods " +
|
|
106
|
+
'agents may call, or drop MCP from the @ApiType list.');
|
|
107
107
|
}
|
|
108
108
|
if (!declaresMcp && tools.length > 0) {
|
|
109
109
|
const named = tools.map((tool) => tool.methodName).join(', ');
|
package/src/http/api-type.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-type.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/api-type.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { METADATA_KEYS } from './decorators';\nimport {\n InvalidEndpointForMcpMetadata,\n getInvalidEndpointsForMcp,\n getWpMcpTools,\n WpMcpToolMetadata,\n} 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 * `@InvalidEndpointForMcp` sits OUTSIDE that biconditional: a method declared permanently unusable\n * as a tool is neither required to carry `@WpMcpTool` nor permitted to. A contract on which EVERY\n * endpoint is so declared must not declare `MCP` at all, and that too is asserted there.\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 const excluded = getInvalidEndpointsForMcp(apiClass);\n assertNoToolIsAlsoExcluded(apiClass, tools, excluded);\n if (declaresMcp && tools.length === 0) {\n // The all-excluded case gets its own sentence because its cure is the opposite one: there is\n // nothing to add, and the contract should stop declaring MCP.\n if (excluded.length > 0 && excluded.length === getApiTypeEndpointNames(apiClass).length) {\n throw new Error(\n `${apiClass.name} declares @ApiType(..., MCP) but EVERY endpoint on it is ` +\n '@InvalidEndpointForMcp. Drop MCP from the @ApiType list — a contract whose ' +\n 'every method is permanently outside MCP does not feed the MCP document.',\n );\n }\n throw new Error(\n `${apiClass.name} declares @ApiType(..., MCP) but no method carries @WpMcpTool. ` +\n \"Add @WpMcpTool('<stable_tool_name>') to the methods agents may call, or drop MCP \" +\n '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/**\n * `@WpMcpTool` and `@InvalidEndpointForMcp` on ONE method is a contradiction, not a precedence rule.\n *\n * Resolving it either way would make the pair a second spelling of a decision that already has one —\n * shim shape #1 in `.claude/rules/no-backwards-compat.md` — and whichever way it resolved, half the\n * readers of that method would be wrong about what it does.\n */\n// webpieces-disable no-function-outside-class -- private assert of assertApiTypeMatchesMcpTools, beside it\nfunction assertNoToolIsAlsoExcluded(\n apiClass: Function,\n tools: readonly WpMcpToolMetadata[],\n excluded: readonly InvalidEndpointForMcpMetadata[],\n): void {\n const excludedNames = new Set(\n excluded.map((one: InvalidEndpointForMcpMetadata) => one.methodName),\n );\n const both = tools\n .filter((tool: WpMcpToolMetadata) => excludedNames.has(tool.methodName))\n .map((tool: WpMcpToolMetadata) => tool.methodName);\n if (both.length === 0) return;\n throw new Error(\n `${apiClass.name} carries BOTH @WpMcpTool and @InvalidEndpointForMcp on ${both.join(', ')}. ` +\n 'They contradict each other — one publishes the method to agents and the other declares ' +\n 'it permanently unusable as a tool. Delete whichever one is wrong.',\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"]}
|
|
1
|
+
{"version":3,"file":"api-type.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/http/api-type.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { METADATA_KEYS } from './decorators';\nimport {\n InvalidEndpointForMcpMetadata,\n getInvalidEndpointsForMcp,\n getWpMcpTools,\n WpMcpToolMetadata,\n} 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 * `@InvalidEndpointForMcp` sits OUTSIDE that biconditional: a method declared permanently unusable\n * as a tool is neither required to carry `@WpMcpTool` nor permitted to. A contract on which EVERY\n * endpoint is so declared must not declare `MCP` at all, and that too is asserted there.\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 const excluded = getInvalidEndpointsForMcp(apiClass);\n assertNoToolIsAlsoExcluded(apiClass, tools, excluded);\n if (declaresMcp && tools.length === 0) {\n // The all-excluded case gets its own sentence because its cure is the opposite one: there is\n // nothing to add, and the contract should stop declaring MCP.\n if (excluded.length > 0 && excluded.length === getApiTypeEndpointNames(apiClass).length) {\n throw new Error(\n `${apiClass.name} declares @ApiType(..., MCP) but EVERY endpoint on it is ` +\n '@InvalidEndpointForMcp. Drop MCP from the @ApiType list — a contract whose ' +\n 'every method is permanently outside MCP does not feed the MCP document.',\n );\n }\n throw new Error(\n `${apiClass.name} declares @ApiType(..., MCP) but no method carries @WpMcpTool. ` +\n \"Add @WpMcpTool('<stable_tool_name>', '<Human-readable title>') to the methods \" +\n 'agents may 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/**\n * `@WpMcpTool` and `@InvalidEndpointForMcp` on ONE method is a contradiction, not a precedence rule.\n *\n * Resolving it either way would make the pair a second spelling of a decision that already has one —\n * shim shape #1 in `.claude/rules/no-backwards-compat.md` — and whichever way it resolved, half the\n * readers of that method would be wrong about what it does.\n */\n// webpieces-disable no-function-outside-class -- private assert of assertApiTypeMatchesMcpTools, beside it\nfunction assertNoToolIsAlsoExcluded(\n apiClass: Function,\n tools: readonly WpMcpToolMetadata[],\n excluded: readonly InvalidEndpointForMcpMetadata[],\n): void {\n const excludedNames = new Set(\n excluded.map((one: InvalidEndpointForMcpMetadata) => one.methodName),\n );\n const both = tools\n .filter((tool: WpMcpToolMetadata) => excludedNames.has(tool.methodName))\n .map((tool: WpMcpToolMetadata) => tool.methodName);\n if (both.length === 0) return;\n throw new Error(\n `${apiClass.name} carries BOTH @WpMcpTool and @InvalidEndpointForMcp on ${both.join(', ')}. ` +\n 'They contradict each other — one publishes the method to agents and the other declares ' +\n 'it permanently unusable as a tool. Delete whichever one is wrong.',\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"]}
|
package/src/index.d.ts
CHANGED
|
@@ -98,7 +98,13 @@ export { RecordSerializer, SerializedMap, SerializedError } from './http/recorde
|
|
|
98
98
|
export { Filter } from './filters/Filter';
|
|
99
99
|
export type { Service } from './filters/Filter';
|
|
100
100
|
export { FilterChain } from './filters/FilterChain';
|
|
101
|
-
export { ApiError, ApiNotFoundError, ApiDependencyError, ApiBadGatewayError, ApiUnavailableError, ApiDependencyTimeoutError, ApiImplementationError, ApiRateLimitedError, ApiForbiddenError, ApiRequestTimeoutError, ApiEndUserError, ApiBadRequestError, ApiUnauthorizedError, ApiDependencyBackoffError, ApiConnectionError, ApiEndpointNotFoundError, ApiConflictError, ApiUnprocessableError, ApiPreconditionFailedError, ApiUnsupportedMediaTypeError, ApiNotImplementedError, ApiCodedError, ApiClientTooOldError, ApiEndUserNotFoundError, ApiEndUserForbiddenError, ApiEndUserBadRequestError, EndUserErrorCode, EndUserErrorRegistry, ClientRole, ApiErrorCodec, ApiErrorPayload, ApiErrorBoundary, } from './errors';
|
|
102
|
-
export type { ApiErrorKind, ApiStatusCode, EdgeHttpStatus, EndUserErrorFactory, } from './errors';
|
|
101
|
+
export { ApiError, ApiNotFoundError, ApiDependencyError, ApiBadGatewayError, ApiUnavailableError, ApiDependencyTimeoutError, ApiImplementationError, ApiRateLimitedError, ApiForbiddenError, ApiRequestTimeoutError, ApiEndUserError, ApiBadRequestError, ApiUnauthorizedError, ApiDependencyBackoffError, ApiConnectionError, ApiEndpointNotFoundError, ApiConflictError, ApiUnprocessableError, ApiPreconditionFailedError, ApiUnsupportedMediaTypeError, ApiNotImplementedError, ApiCodedError, ApiClientTooOldError, ApiEndUserNotFoundError, ApiEndUserForbiddenError, ApiEndUserBadRequestError, EndUserErrorCode, EndUserErrorRegistry, ClientRole, ApiErrorCodec, ApiErrorPayload, ApiErrorBoundary, ApiCallSite, ReportableApiFailure, RpcCallFailed, } from './errors';
|
|
102
|
+
export type { ApiErrorKind, ApiStatusCode, EdgeHttpStatus, EndUserErrorFactory, CallSiteBoundary, } from './errors';
|
|
103
103
|
export { ApiErrorHttpStatus } from './http/ApiErrorHttpStatus';
|
|
104
|
+
export { OAuthErrorCode, OAuthErrorStatus, OAuthText } from './oauth/OAuthErrorCode';
|
|
105
|
+
export type { OAuthHttpStatus, InvalidClientStatus, OAuthFixedStatusErrorCode, BearerErrorCode, AuthorizationEndpointErrorCode, } from './oauth/OAuthErrorCode';
|
|
106
|
+
export { OAuthProtocolError, OAuthErrorExtras } from './oauth/OAuthProtocolError';
|
|
107
|
+
export { OAuthBearerChallenge } from './oauth/OAuthBearerChallenge';
|
|
108
|
+
export { OAuthErrorBody, OAuthErrorResponse } from './oauth/OAuthErrorResponse';
|
|
109
|
+
export { OAuthAuthorizationErrorRedirect } from './oauth/OAuthAuthorizationErrorRedirect';
|
|
104
110
|
export type { PublishedKind, PublishedApiError } from './http/ApiErrorHttpStatus';
|
package/src/index.js
CHANGED
|
@@ -12,7 +12,7 @@ exports.MCP = exports.EXTERNAL_CUSTOMER = exports.SVC_TO_SVC = exports.ApiType =
|
|
|
12
12
|
exports.InvalidEndpointForMcp = exports.WRITE = exports.WRITE_IDEMPOTENT = exports.READ = exports.EXTERNAL = exports.CRON = exports.CLOUDTASKS = exports.RPC = exports.POST = exports.GET = exports.registerStreamingSchemas = exports.getStreamingEndpoint = exports.WpStream = exports.StreamDirection = exports.StreamWriter = exports.StreamTransportError = exports.StreamEventValidator = exports.StreamingEndpointMetadata = exports.StreamEnvelope = exports.StreamCorrelation = exports.HttpParameterDeclaration = exports.HttpParameterBinding = exports.HttpContractMapper = exports.BoundHttpRequest = exports.StreamDisconnectedError = exports.StreamProtocolError = exports.StreamErrorControl = exports.registerStreamingCatalog = exports.StreamingSchemaCatalog = exports.getAuthorization = exports.WpAuthorization = exports.AuthorizationDeclaration = exports.AuthorizationType = 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 = void 0;
|
|
13
13
|
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.apiKey = exports.webhook = exports.sharedSecret = exports.oidc = exports.jwt = exports.AuthDeclaration = exports.AuthMeta = exports.GenerateOutputTarget = exports.GenerateOutputLookup = exports.GenerateLayoutProblem = exports.GeneratedApiDocsLayout = exports.McpToolDefinition = exports.McpToolCatalogError = exports.McpToolCatalogFile = exports.ObjectSchemaBuilder = exports.DtoValidationFailure = exports.ApiJsonSchemaValidator = exports.ApiJsonSchemaDiscriminator = exports.ApiJsonSchema = exports.mcpHintsForOperation = exports.getWpMcpTools = exports.getInvalidEndpointsForMcp = exports.WpMcpToolMetadata = exports.WpMcpToolHints = exports.WpMcpTool = exports.InvalidEndpointForMcpMetadata = void 0;
|
|
14
14
|
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 = 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 = void 0;
|
|
15
|
-
exports.ApiErrorHttpStatus = exports.ApiErrorBoundary = exports.ApiErrorPayload = exports.ApiErrorCodec = exports.ClientRole = exports.EndUserErrorRegistry = exports.EndUserErrorCode = exports.ApiEndUserBadRequestError = exports.ApiEndUserForbiddenError = exports.ApiEndUserNotFoundError = exports.ApiClientTooOldError = exports.ApiCodedError = exports.ApiNotImplementedError = 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 = void 0;
|
|
15
|
+
exports.OAuthAuthorizationErrorRedirect = exports.OAuthErrorResponse = exports.OAuthErrorBody = exports.OAuthBearerChallenge = exports.OAuthErrorExtras = exports.OAuthProtocolError = exports.OAuthText = exports.OAuthErrorStatus = exports.OAuthErrorCode = exports.ApiErrorHttpStatus = exports.RpcCallFailed = exports.ReportableApiFailure = exports.ApiCallSite = exports.ApiErrorBoundary = exports.ApiErrorPayload = exports.ApiErrorCodec = exports.ClientRole = exports.EndUserErrorRegistry = exports.EndUserErrorCode = exports.ApiEndUserBadRequestError = exports.ApiEndUserForbiddenError = exports.ApiEndUserNotFoundError = exports.ApiClientTooOldError = exports.ApiCodedError = exports.ApiNotImplementedError = 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 = void 0;
|
|
16
16
|
var errorUtils_1 = require("./lib/errorUtils");
|
|
17
17
|
Object.defineProperty(exports, "toError", { enumerable: true, get: function () { return errorUtils_1.toError; } });
|
|
18
18
|
var ContextKey_1 = require("./ContextKey");
|
|
@@ -354,6 +354,25 @@ Object.defineProperty(exports, "ClientRole", { enumerable: true, get: function (
|
|
|
354
354
|
Object.defineProperty(exports, "ApiErrorCodec", { enumerable: true, get: function () { return errors_2.ApiErrorCodec; } });
|
|
355
355
|
Object.defineProperty(exports, "ApiErrorPayload", { enumerable: true, get: function () { return errors_2.ApiErrorPayload; } });
|
|
356
356
|
Object.defineProperty(exports, "ApiErrorBoundary", { enumerable: true, get: function () { return errors_2.ApiErrorBoundary; } });
|
|
357
|
+
Object.defineProperty(exports, "ApiCallSite", { enumerable: true, get: function () { return errors_2.ApiCallSite; } });
|
|
358
|
+
Object.defineProperty(exports, "ReportableApiFailure", { enumerable: true, get: function () { return errors_2.ReportableApiFailure; } });
|
|
359
|
+
Object.defineProperty(exports, "RpcCallFailed", { enumerable: true, get: function () { return errors_2.RpcCallFailed; } });
|
|
357
360
|
var ApiErrorHttpStatus_1 = require("./http/ApiErrorHttpStatus");
|
|
358
361
|
Object.defineProperty(exports, "ApiErrorHttpStatus", { enumerable: true, get: function () { return ApiErrorHttpStatus_1.ApiErrorHttpStatus; } });
|
|
362
|
+
// RFC 6749 / 6750 / 7591 OAuth refusals for app-hosted OAuth endpoints (#1176): the typed error,
|
|
363
|
+
// its one renderer, the Bearer challenge builder and the authorization-endpoint error redirect.
|
|
364
|
+
var OAuthErrorCode_1 = require("./oauth/OAuthErrorCode");
|
|
365
|
+
Object.defineProperty(exports, "OAuthErrorCode", { enumerable: true, get: function () { return OAuthErrorCode_1.OAuthErrorCode; } });
|
|
366
|
+
Object.defineProperty(exports, "OAuthErrorStatus", { enumerable: true, get: function () { return OAuthErrorCode_1.OAuthErrorStatus; } });
|
|
367
|
+
Object.defineProperty(exports, "OAuthText", { enumerable: true, get: function () { return OAuthErrorCode_1.OAuthText; } });
|
|
368
|
+
var OAuthProtocolError_1 = require("./oauth/OAuthProtocolError");
|
|
369
|
+
Object.defineProperty(exports, "OAuthProtocolError", { enumerable: true, get: function () { return OAuthProtocolError_1.OAuthProtocolError; } });
|
|
370
|
+
Object.defineProperty(exports, "OAuthErrorExtras", { enumerable: true, get: function () { return OAuthProtocolError_1.OAuthErrorExtras; } });
|
|
371
|
+
var OAuthBearerChallenge_1 = require("./oauth/OAuthBearerChallenge");
|
|
372
|
+
Object.defineProperty(exports, "OAuthBearerChallenge", { enumerable: true, get: function () { return OAuthBearerChallenge_1.OAuthBearerChallenge; } });
|
|
373
|
+
var OAuthErrorResponse_1 = require("./oauth/OAuthErrorResponse");
|
|
374
|
+
Object.defineProperty(exports, "OAuthErrorBody", { enumerable: true, get: function () { return OAuthErrorResponse_1.OAuthErrorBody; } });
|
|
375
|
+
Object.defineProperty(exports, "OAuthErrorResponse", { enumerable: true, get: function () { return OAuthErrorResponse_1.OAuthErrorResponse; } });
|
|
376
|
+
var OAuthAuthorizationErrorRedirect_1 = require("./oauth/OAuthAuthorizationErrorRedirect");
|
|
377
|
+
Object.defineProperty(exports, "OAuthAuthorizationErrorRedirect", { enumerable: true, get: function () { return OAuthAuthorizationErrorRedirect_1.OAuthAuthorizationErrorRedirect; } });
|
|
359
378
|
//# sourceMappingURL=index.js.map
|
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 WpAuth,\n MISSING_AUTH_DECORATOR_FIX,\n WpLocalOnly,\n isLocalOnly,\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 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 { AuthorizationType, AuthorizationDeclaration, WpAuthorization, getAuthorization } from './http/authorization';\nexport type { AuthorizationRequirement } from './http/authorization';\nexport { StreamingSchemaCatalog, registerStreamingCatalog } from './http/StreamingSchemaCatalog';\nexport {\n StreamErrorControl,\n StreamProtocolError,\n StreamDisconnectedError,\n} from './http/StreamErrorControl';\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 StreamDirection,\n WpStream,\n getStreamingEndpoint,\n registerStreamingSchemas,\n} from './http/StreamingContract';\nexport type { RequestStream, ResponseStream, StreamEnvelopeKind } 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 { RPC, CLOUDTASKS, CRON, EXTERNAL, READ, WRITE_IDEMPOTENT, WRITE } from './http/decorators';\nexport {\n InvalidEndpointForMcp,\n InvalidEndpointForMcpMetadata,\n WpMcpTool,\n WpMcpToolHints,\n WpMcpToolMetadata,\n getInvalidEndpointsForMcp,\n getWpMcpTools,\n mcpHintsForOperation,\n} from './mcp/McpMetadata';\nexport type { WpMcpMethodDecorator } from './mcp/McpMetadata';\nexport {\n ApiJsonSchema,\n ApiJsonSchemaDiscriminator,\n ApiJsonSchemaValidator,\n DtoValidationFailure,\n ObjectSchemaBuilder,\n} from './mcp/DtoSchema';\nexport type { ApiJsonSchemaType, DtoValue } from './mcp/DtoSchema';\nexport {\n McpToolCatalogFile,\n McpToolCatalogError,\n McpToolDefinition,\n} from './mcp/McpToolCatalogFile';\nexport {\n GeneratedApiDocsLayout,\n GenerateLayoutProblem,\n GenerateOutputLookup,\n GenerateOutputTarget,\n} from './mcp/GeneratedApiDocsLayout';\nexport type {\n LayoutDependsOn,\n LayoutDependsOnObject,\n LayoutTarget,\n LayoutTargets,\n} from './mcp/GeneratedApiDocsLayout';\n// The TYPE layer of the auth surface — likewise split out of decorators.ts for file size only.\nexport { AuthMeta, AuthDeclaration, jwt, oidc, sharedSecret, webhook, apiKey } from './http/auth-mode';\nexport type {\n AuthMode,\n ApiKeyCredential,\n ApiKeyCredentials,\n AuthMethod,\n AuthMethods,\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 sharedSecret(...) 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 @WpLocalOnly 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 ApiClientTooOldError,\n ApiEndUserNotFoundError,\n ApiEndUserForbiddenError,\n ApiEndUserBadRequestError,\n EndUserErrorCode,\n EndUserErrorRegistry,\n ClientRole,\n ApiErrorCodec,\n ApiErrorPayload,\n ApiErrorBoundary,\n} from './errors';\nexport type {\n ApiErrorKind,\n ApiStatusCode,\n EdgeHttpStatus,\n EndUserErrorFactory,\n} 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 WpAuth,\n MISSING_AUTH_DECORATOR_FIX,\n WpLocalOnly,\n isLocalOnly,\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 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 { AuthorizationType, AuthorizationDeclaration, WpAuthorization, getAuthorization } from './http/authorization';\nexport type { AuthorizationRequirement } from './http/authorization';\nexport { StreamingSchemaCatalog, registerStreamingCatalog } from './http/StreamingSchemaCatalog';\nexport {\n StreamErrorControl,\n StreamProtocolError,\n StreamDisconnectedError,\n} from './http/StreamErrorControl';\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 StreamDirection,\n WpStream,\n getStreamingEndpoint,\n registerStreamingSchemas,\n} from './http/StreamingContract';\nexport type { RequestStream, ResponseStream, StreamEnvelopeKind } 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 { RPC, CLOUDTASKS, CRON, EXTERNAL, READ, WRITE_IDEMPOTENT, WRITE } from './http/decorators';\nexport {\n InvalidEndpointForMcp,\n InvalidEndpointForMcpMetadata,\n WpMcpTool,\n WpMcpToolHints,\n WpMcpToolMetadata,\n getInvalidEndpointsForMcp,\n getWpMcpTools,\n mcpHintsForOperation,\n} from './mcp/McpMetadata';\nexport type { WpMcpMethodDecorator } from './mcp/McpMetadata';\nexport {\n ApiJsonSchema,\n ApiJsonSchemaDiscriminator,\n ApiJsonSchemaValidator,\n DtoValidationFailure,\n ObjectSchemaBuilder,\n} from './mcp/DtoSchema';\nexport type { ApiJsonSchemaType, DtoValue } from './mcp/DtoSchema';\nexport {\n McpToolCatalogFile,\n McpToolCatalogError,\n McpToolDefinition,\n} from './mcp/McpToolCatalogFile';\nexport {\n GeneratedApiDocsLayout,\n GenerateLayoutProblem,\n GenerateOutputLookup,\n GenerateOutputTarget,\n} from './mcp/GeneratedApiDocsLayout';\nexport type {\n LayoutDependsOn,\n LayoutDependsOnObject,\n LayoutTarget,\n LayoutTargets,\n} from './mcp/GeneratedApiDocsLayout';\n// The TYPE layer of the auth surface — likewise split out of decorators.ts for file size only.\nexport { AuthMeta, AuthDeclaration, jwt, oidc, sharedSecret, webhook, apiKey } from './http/auth-mode';\nexport type {\n AuthMode,\n ApiKeyCredential,\n ApiKeyCredentials,\n AuthMethod,\n AuthMethods,\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 sharedSecret(...) 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 @WpLocalOnly 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 ApiClientTooOldError,\n ApiEndUserNotFoundError,\n ApiEndUserForbiddenError,\n ApiEndUserBadRequestError,\n EndUserErrorCode,\n EndUserErrorRegistry,\n ClientRole,\n ApiErrorCodec,\n ApiErrorPayload,\n ApiErrorBoundary,\n ApiCallSite,\n ReportableApiFailure,\n RpcCallFailed,\n} from './errors';\nexport type {\n ApiErrorKind,\n ApiStatusCode,\n EdgeHttpStatus,\n EndUserErrorFactory,\n CallSiteBoundary,\n} from './errors';\nexport { ApiErrorHttpStatus } from './http/ApiErrorHttpStatus';\n\n// RFC 6749 / 6750 / 7591 OAuth refusals for app-hosted OAuth endpoints (#1176): the typed error,\n// its one renderer, the Bearer challenge builder and the authorization-endpoint error redirect.\nexport { OAuthErrorCode, OAuthErrorStatus, OAuthText } from './oauth/OAuthErrorCode';\nexport type {\n OAuthHttpStatus,\n InvalidClientStatus,\n OAuthFixedStatusErrorCode,\n BearerErrorCode,\n AuthorizationEndpointErrorCode,\n} from './oauth/OAuthErrorCode';\nexport { OAuthProtocolError, OAuthErrorExtras } from './oauth/OAuthProtocolError';\nexport { OAuthBearerChallenge } from './oauth/OAuthBearerChallenge';\nexport { OAuthErrorBody, OAuthErrorResponse } from './oauth/OAuthErrorResponse';\nexport { OAuthAuthorizationErrorRedirect } from './oauth/OAuthAuthorizationErrorRedirect';\nexport type { PublishedKind, PublishedApiError } from './http/ApiErrorHttpStatus';\n"]}
|
|
@@ -9,10 +9,14 @@ const McpMetadata_1 = require("./McpMetadata");
|
|
|
9
9
|
* with TS2578 the moment one of these starts compiling.
|
|
10
10
|
*/
|
|
11
11
|
class InvalidMcpContract {
|
|
12
|
-
// @ts-expect-error @WpMcpTool takes the stable protocol NAME, not an options object
|
|
12
|
+
// @ts-expect-error @WpMcpTool takes the stable protocol NAME and a TITLE, not an options object
|
|
13
13
|
options(_request) {
|
|
14
14
|
throw new Error('contract only');
|
|
15
15
|
}
|
|
16
|
+
// @ts-expect-error the title is REQUIRED (#1180) — the one-argument spelling is gone, not optional
|
|
17
|
+
untitled(_request) {
|
|
18
|
+
throw new Error('contract only');
|
|
19
|
+
}
|
|
16
20
|
// @ts-expect-error side-effect claims belong on @Endpoint.operation, never @WpMcpTool
|
|
17
21
|
hints(_request) {
|
|
18
22
|
throw new Error('contract only');
|
|
@@ -25,7 +29,13 @@ tslib_1.__decorate([
|
|
|
25
29
|
tslib_1.__metadata("design:returntype", Promise)
|
|
26
30
|
], InvalidMcpContract.prototype, "options", null);
|
|
27
31
|
tslib_1.__decorate([
|
|
28
|
-
(0, McpMetadata_1.WpMcpTool)('
|
|
32
|
+
(0, McpMetadata_1.WpMcpTool)('missing_title'),
|
|
33
|
+
tslib_1.__metadata("design:type", Function),
|
|
34
|
+
tslib_1.__metadata("design:paramtypes", [Object]),
|
|
35
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
36
|
+
], InvalidMcpContract.prototype, "untitled", null);
|
|
37
|
+
tslib_1.__decorate([
|
|
38
|
+
(0, McpMetadata_1.WpMcpTool)('invalid', 'Invalid tool', true),
|
|
29
39
|
tslib_1.__metadata("design:type", Function),
|
|
30
40
|
tslib_1.__metadata("design:paramtypes", [Object]),
|
|
31
41
|
tslib_1.__metadata("design:returntype", Promise)
|
|
@@ -41,13 +51,13 @@ class InvalidMcpArities {
|
|
|
41
51
|
}
|
|
42
52
|
}
|
|
43
53
|
tslib_1.__decorate([
|
|
44
|
-
(0, McpMetadata_1.WpMcpTool)('zero-arity'),
|
|
54
|
+
(0, McpMetadata_1.WpMcpTool)('zero-arity', 'Zero arity'),
|
|
45
55
|
tslib_1.__metadata("design:type", Function),
|
|
46
56
|
tslib_1.__metadata("design:paramtypes", []),
|
|
47
57
|
tslib_1.__metadata("design:returntype", Promise)
|
|
48
58
|
], InvalidMcpArities.prototype, "zero", null);
|
|
49
59
|
tslib_1.__decorate([
|
|
50
|
-
(0, McpMetadata_1.WpMcpTool)('multi-arity'),
|
|
60
|
+
(0, McpMetadata_1.WpMcpTool)('multi-arity', 'Multi arity'),
|
|
51
61
|
tslib_1.__metadata("design:type", Function),
|
|
52
62
|
tslib_1.__metadata("design:paramtypes", [Object, Object]),
|
|
53
63
|
tslib_1.__metadata("design:returntype", Promise)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpCompileAssertions.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/mcp/McpCompileAssertions.ts"],"names":[],"mappings":";;;AAAA,+CAA0C;AAE1C;;;;;GAKG;AACH,MAAe,kBAAkB;IAC7B,
|
|
1
|
+
{"version":3,"file":"McpCompileAssertions.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/mcp/McpCompileAssertions.ts"],"names":[],"mappings":";;;AAAA,+CAA0C;AAE1C;;;;;GAKG;AACH,MAAe,kBAAkB;IAC7B,gGAAgG;IAEhG,OAAO,CAAC,QAAgB;QACpB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;IAED,mGAAmG;IAEnG,QAAQ,CAAC,QAAgB;QACrB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;IAED,sFAAsF;IAEtF,KAAK,CAAC,QAAgB;QAClB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;CACJ;AAfG;IADC,IAAA,uBAAS,EAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;;;;iDAG9B;AAID;IADC,IAAA,uBAAS,EAAC,eAAe,CAAC;;;;kDAG1B;AAID;IADC,IAAA,uBAAS,EAAC,SAAS,EAAE,cAAc,EAAE,IAAI,CAAC;;;;+CAG1C;AAGL,MAAe,iBAAiB;IAC5B,6DAA6D;IAE7D,IAAI;QACA,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;IAED,6DAA6D;IAE7D,KAAK,CAAC,MAAc,EAAE,OAAe;QACjC,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;CACJ;AATG;IADC,IAAA,uBAAS,EAAC,YAAY,EAAE,YAAY,CAAC;;;;6CAGrC;AAID;IADC,IAAA,uBAAS,EAAC,aAAa,EAAE,aAAa,CAAC;;;;8CAGvC;AAGL,KAAK,kBAAkB,CAAC;AACxB,KAAK,iBAAiB,CAAC","sourcesContent":["import { WpMcpTool } from './McpMetadata';\n\n/**\n * Compile-time pins for `@WpMcpTool`. These live in a COMPILED file rather than a `.spec.ts` because\n * vitest strips types with esbuild and `tsconfig.lib.json` excludes specs, so a `@ts-expect-error` in\n * a spec is inert (`.claude/rules/no-backwards-compat.md` shim shape #4). Here, tsc fails the build\n * with TS2578 the moment one of these starts compiling.\n */\nabstract class InvalidMcpContract {\n // @ts-expect-error @WpMcpTool takes the stable protocol NAME and a TITLE, not an options object\n @WpMcpTool({ name: 'invalid' })\n options(_request: object): Promise<object> {\n throw new Error('contract only');\n }\n\n // @ts-expect-error the title is REQUIRED (#1180) — the one-argument spelling is gone, not optional\n @WpMcpTool('missing_title')\n untitled(_request: object): Promise<object> {\n throw new Error('contract only');\n }\n\n // @ts-expect-error side-effect claims belong on @Endpoint.operation, never @WpMcpTool\n @WpMcpTool('invalid', 'Invalid tool', true)\n hints(_request: object): Promise<object> {\n throw new Error('contract only');\n }\n}\n\nabstract class InvalidMcpArities {\n // @ts-expect-error MCP tools require exactly one request DTO\n @WpMcpTool('zero-arity', 'Zero arity')\n zero(): Promise<object> {\n throw new Error('contract only');\n }\n\n // @ts-expect-error MCP tools require exactly one request DTO\n @WpMcpTool('multi-arity', 'Multi arity')\n multi(_first: object, _second: object): Promise<object> {\n throw new Error('contract only');\n }\n}\n\nvoid InvalidMcpContract;\nvoid InvalidMcpArities;\n"]}
|
package/src/mcp/McpMetadata.d.ts
CHANGED
|
@@ -17,33 +17,45 @@ export type WpMcpMethodDecorator = <TMethod extends AsyncObjectMethod>(target: o
|
|
|
17
17
|
export declare class WpMcpToolMetadata {
|
|
18
18
|
readonly methodName: string;
|
|
19
19
|
readonly name: string;
|
|
20
|
-
|
|
20
|
+
/** The human-readable display name; `tools/list` publishes it as `title` AND `annotations.title`. */
|
|
21
|
+
readonly title: string;
|
|
22
|
+
constructor(methodName: string, name: string,
|
|
23
|
+
/** The human-readable display name; `tools/list` publishes it as `title` AND `annotations.title`. */
|
|
24
|
+
title: string);
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
23
27
|
* Explicitly publishes an existing `@Endpoint(POST, path, WRITE, RPC)` method as an MCP tool, under
|
|
24
|
-
* the STABLE protocol name given here.
|
|
28
|
+
* the STABLE protocol name and the human-readable TITLE given here.
|
|
25
29
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
30
|
+
* ```typescript
|
|
31
|
+
* @WpMcpTool('learner_get_passages', 'Get your passages')
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* Those two are the whole argument list — the only facts about a tool the source cannot otherwise
|
|
35
|
+
* state:
|
|
29
36
|
*
|
|
30
37
|
* | fact | where it comes from |
|
|
31
38
|
* |---|---|
|
|
39
|
+
* | `name` | this decorator — the stable protocol identity, independent of the method name because renaming a method must not break a saved agent workflow |
|
|
40
|
+
* | `title` | this decorator — the display name clients and the Claude Connectors Directory show; published as BOTH `Tool.title` and `annotations.title` |
|
|
32
41
|
* | `description` | the method's JSDoc body, or its `@mcp` tag — the same words the partner reads |
|
|
33
42
|
* | `readOnlyHint` / `destructiveHint` / `idempotentHint` | `@Endpoint`'s `operation`, via {@link mcpHintsForOperation} |
|
|
34
43
|
* | `openWorldHint` | `@Endpoint`'s `openWorld` option |
|
|
35
44
|
* | `inputSchema` / `outputSchema` | the declared request and response types |
|
|
36
45
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
46
|
+
* ## Why the title is REQUIRED and never derived (#1180)
|
|
47
|
+
*
|
|
48
|
+
* The Connectors Directory flags every tool without `annotations.title`. An optional title gets
|
|
49
|
+
* skipped and the miss surfaces only at directory-submission time, so it is a compile-time
|
|
50
|
+
* requirement and an empty or whitespace one throws at decoration time. It is never computed from
|
|
51
|
+
* the name: `learner_get_passages` → "Learner get passages" is exactly the mechanical listing text
|
|
52
|
+
* reviewers push back on, and the area prefix means nothing to an end user.
|
|
40
53
|
*
|
|
41
|
-
* Until #984
|
|
42
|
-
* paragraph drift the first time somebody edits one,
|
|
43
|
-
*
|
|
44
|
-
* held one field, so it is a plain string and `WpMcpToolOptions` is deleted with it.
|
|
54
|
+
* Until #984 the decorator also took a `description`, duplicating the JSDoc. Two authored copies of
|
|
55
|
+
* one paragraph drift the first time somebody edits one, so it is gone; the title is a short NAME,
|
|
56
|
+
* not a second copy of the description.
|
|
45
57
|
*/
|
|
46
|
-
export declare function WpMcpTool(name: string): WpMcpMethodDecorator;
|
|
58
|
+
export declare function WpMcpTool(name: string, title: string): WpMcpMethodDecorator;
|
|
47
59
|
/** Runtime metadata for one endpoint declared PERMANENTLY outside MCP. */
|
|
48
60
|
export declare class InvalidEndpointForMcpMetadata {
|
|
49
61
|
readonly methodName: string;
|
package/src/mcp/McpMetadata.js
CHANGED
|
@@ -27,45 +27,62 @@ exports.WpMcpToolHints = WpMcpToolHints;
|
|
|
27
27
|
class WpMcpToolMetadata {
|
|
28
28
|
methodName;
|
|
29
29
|
name;
|
|
30
|
-
|
|
30
|
+
title;
|
|
31
|
+
constructor(methodName, name,
|
|
32
|
+
/** The human-readable display name; `tools/list` publishes it as `title` AND `annotations.title`. */
|
|
33
|
+
title) {
|
|
31
34
|
this.methodName = methodName;
|
|
32
35
|
this.name = name;
|
|
36
|
+
this.title = title;
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
39
|
exports.WpMcpToolMetadata = WpMcpToolMetadata;
|
|
36
40
|
/**
|
|
37
41
|
* Explicitly publishes an existing `@Endpoint(POST, path, WRITE, RPC)` method as an MCP tool, under
|
|
38
|
-
* the STABLE protocol name given here.
|
|
42
|
+
* the STABLE protocol name and the human-readable TITLE given here.
|
|
39
43
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
44
|
+
* ```typescript
|
|
45
|
+
* @WpMcpTool('learner_get_passages', 'Get your passages')
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* Those two are the whole argument list — the only facts about a tool the source cannot otherwise
|
|
49
|
+
* state:
|
|
43
50
|
*
|
|
44
51
|
* | fact | where it comes from |
|
|
45
52
|
* |---|---|
|
|
53
|
+
* | `name` | this decorator — the stable protocol identity, independent of the method name because renaming a method must not break a saved agent workflow |
|
|
54
|
+
* | `title` | this decorator — the display name clients and the Claude Connectors Directory show; published as BOTH `Tool.title` and `annotations.title` |
|
|
46
55
|
* | `description` | the method's JSDoc body, or its `@mcp` tag — the same words the partner reads |
|
|
47
56
|
* | `readOnlyHint` / `destructiveHint` / `idempotentHint` | `@Endpoint`'s `operation`, via {@link mcpHintsForOperation} |
|
|
48
57
|
* | `openWorldHint` | `@Endpoint`'s `openWorld` option |
|
|
49
58
|
* | `inputSchema` / `outputSchema` | the declared request and response types |
|
|
50
59
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
60
|
+
* ## Why the title is REQUIRED and never derived (#1180)
|
|
61
|
+
*
|
|
62
|
+
* The Connectors Directory flags every tool without `annotations.title`. An optional title gets
|
|
63
|
+
* skipped and the miss surfaces only at directory-submission time, so it is a compile-time
|
|
64
|
+
* requirement and an empty or whitespace one throws at decoration time. It is never computed from
|
|
65
|
+
* the name: `learner_get_passages` → "Learner get passages" is exactly the mechanical listing text
|
|
66
|
+
* reviewers push back on, and the area prefix means nothing to an end user.
|
|
54
67
|
*
|
|
55
|
-
* Until #984
|
|
56
|
-
* paragraph drift the first time somebody edits one,
|
|
57
|
-
*
|
|
58
|
-
* held one field, so it is a plain string and `WpMcpToolOptions` is deleted with it.
|
|
68
|
+
* Until #984 the decorator also took a `description`, duplicating the JSDoc. Two authored copies of
|
|
69
|
+
* one paragraph drift the first time somebody edits one, so it is gone; the title is a short NAME,
|
|
70
|
+
* not a second copy of the description.
|
|
59
71
|
*/
|
|
60
72
|
// webpieces-disable no-function-outside-class -- decorator factories are inherently module-scope
|
|
61
|
-
function WpMcpTool(name) {
|
|
73
|
+
function WpMcpTool(name, title) {
|
|
62
74
|
if (name.trim() === '')
|
|
63
75
|
throw new Error('@WpMcpTool requires a non-empty stable name.');
|
|
76
|
+
if (title.trim() === '') {
|
|
77
|
+
throw new Error(`@WpMcpTool('${name}', ...) requires a non-empty human-readable title, e.g. ` +
|
|
78
|
+
"@WpMcpTool('learner_get_passages', 'Get your passages'). tools/list publishes it as " +
|
|
79
|
+
'title and annotations.title, and the Claude Connectors Directory flags a tool without one.');
|
|
80
|
+
}
|
|
64
81
|
return (target, propertyKey, _descriptor) => {
|
|
65
82
|
const apiClass = target.constructor;
|
|
66
83
|
const tools = Reflect.getMetadata(decorators_1.METADATA_KEYS.MCP_TOOLS, apiClass) ?? {};
|
|
67
84
|
const methodName = String(propertyKey);
|
|
68
|
-
tools[methodName] = new WpMcpToolMetadata(methodName, name);
|
|
85
|
+
tools[methodName] = new WpMcpToolMetadata(methodName, name, title);
|
|
69
86
|
Reflect.defineMetadata(decorators_1.METADATA_KEYS.MCP_TOOLS, tools, apiClass);
|
|
70
87
|
};
|
|
71
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpMetadata.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/mcp/McpMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { METADATA_KEYS } from '../http/decorators';\nimport { EndpointOperation, READ, WRITE_IDEMPOTENT, WRITE } from '../http/HttpEndpointOptions';\n\n/** The immutable hints MCP clients use when deciding whether and how to call a tool. */\nexport class WpMcpToolHints {\n constructor(\n public readonly readOnlyHint: boolean,\n public readonly destructiveHint: boolean,\n public readonly idempotentHint: boolean,\n public readonly openWorldHint: boolean,\n ) {}\n}\n\ntype AsyncObjectMethod = (...args: never[]) => Promise<object>;\ntype ExactOneParameter<TMethod extends AsyncObjectMethod> = Parameters<TMethod>['length'] extends 1\n ? object\n : never;\ntype ExactOneMethodDescriptor<TMethod extends AsyncObjectMethod> =\n TypedPropertyDescriptor<TMethod> & ExactOneParameter<TMethod>;\n\n/** Method decorator restricted to one request DTO and one async response DTO. */\nexport type WpMcpMethodDecorator = <TMethod extends AsyncObjectMethod>(\n target: object,\n propertyKey: string | symbol,\n descriptor: ExactOneMethodDescriptor<TMethod>,\n) => void;\n\n/** Runtime metadata for one explicitly exposed endpoint. */\nexport class WpMcpToolMetadata {\n constructor(\n public readonly methodName: string,\n public readonly name: string,\n ) {}\n}\n\n/**\n * Explicitly publishes an existing `@Endpoint(POST, path, WRITE, RPC)` method as an MCP tool, under\n * the STABLE protocol name given here.\n *\n * The name is the whole argument, and deliberately the only one. It is independent of the method\n * name because renaming a method must not break a saved agent workflow, and nothing else about a\n * tool is unsayable in the source:\n *\n * | fact | where it comes from |\n * |---|---|\n * | `description` | the method's JSDoc body, or its `@mcp` tag — the same words the partner reads |\n * | `readOnlyHint` / `destructiveHint` / `idempotentHint` | `@Endpoint`'s `operation`, via {@link mcpHintsForOperation} |\n * | `openWorldHint` | `@Endpoint`'s `openWorld` option |\n * | `inputSchema` / `outputSchema` | the declared request and response types |\n *\n * ```typescript\n * @WpMcpTool('search_stores')\n * ```\n *\n * Until #984 it also took a `description`, duplicating the JSDoc. Two authored copies of one\n * paragraph drift the first time somebody edits one, and nothing catches it — the partner reads the\n * OpenAPI text and the agent reads the decorator text. With `description` gone the options object\n * held one field, so it is a plain string and `WpMcpToolOptions` is deleted with it.\n */\n// webpieces-disable no-function-outside-class -- decorator factories are inherently module-scope\nexport function WpMcpTool(name: string): WpMcpMethodDecorator {\n if (name.trim() === '') throw new Error('@WpMcpTool requires a non-empty stable name.');\n return <TMethod extends AsyncObjectMethod>(\n target: object,\n propertyKey: string | symbol,\n _descriptor: ExactOneMethodDescriptor<TMethod>,\n ): void => {\n const apiClass = target.constructor;\n const tools: Record<string, WpMcpToolMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_TOOLS, apiClass) ?? {};\n const methodName = String(propertyKey);\n tools[methodName] = new WpMcpToolMetadata(methodName, name);\n Reflect.defineMetadata(METADATA_KEYS.MCP_TOOLS, tools, apiClass);\n };\n}\n\n/** Runtime metadata for one endpoint declared PERMANENTLY outside MCP. */\nexport class InvalidEndpointForMcpMetadata {\n constructor(\n public readonly methodName: string,\n /** WHY it can never be a tool. Non-empty, enforced at decoration time. */\n public readonly reason: string,\n ) {}\n}\n\n/**\n * Declares that this endpoint is PERMANENTLY outside MCP, and says why.\n *\n * ## It is not a suppression, and that distinction is the whole feature\n *\n * `// webpieces-disable api-rules-for-mcp -- <reason>` says \"stop complaining\". This says \"this is\n * structurally impossible, forever\", and the two have different futures: a suppression is something\n * somebody should eventually come back to, and this is something nobody should. Both measured cases\n * are types that are CORRECT and must not be \"fixed\" —\n *\n * - a webhook TRANSPORT envelope, whose `data` is owned by each event's own published contract;\n * typing it here would fork that ownership and make adding an event type a change to the\n * transport contract rather than a registration, and\n * - a freeform-SQL escape hatch, whose result columns depend on the model-authored `SELECT`.\n *\n * The second one is worth stating rather than burying: it is the most obviously useful tool in that\n * repo, and it is excluded by a type that is right.\n *\n * ## Absence already says \"not a tool YET\"\n *\n * A method with no `@WpMcpTool` is simply not published. This decorator is the NEVER, and the reason\n * is what makes `grep -rn InvalidEndpointForMcp` a list of permanent exclusions with their arguments\n * rather than a list of names. `api-rules-for-mcp` restates that list on every run, so an exclusion\n * stays visible instead of being announced once and forgotten.\n *\n * ## It contradicts `@WpMcpTool`\n *\n * Both on one method is an ERROR, asserted by {@link assertApiTypeMatchesMcpTools}. \"Publish this as\n * a tool\" and \"this can never be a tool\" are two spellings of one decision, which is exactly the\n * defect `.claude/rules/no-backwards-compat.md` shim shape #1 rejects.\n *\n * ```typescript\n * @InvalidEndpointForMcp('a transport envelope body is opaque by design; the published partner ' +\n * 'contract for each event type owns its shape')\n * ```\n */\n// webpieces-disable no-function-outside-class -- decorator factories are inherently module-scope\nexport function InvalidEndpointForMcp(reason: string): MethodDecorator {\n if (reason.trim() === '') {\n throw new Error(\n '@InvalidEndpointForMcp requires a non-empty reason. The reason IS the declaration — ' +\n 'without it this is a suppression with a longer name.',\n );\n }\n return (target: object, propertyKey: string | symbol): void => {\n const apiClass = target.constructor;\n const excluded: Record<string, InvalidEndpointForMcpMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_INVALID, apiClass) ?? {};\n const methodName = String(propertyKey);\n excluded[methodName] = new InvalidEndpointForMcpMetadata(methodName, reason);\n Reflect.defineMetadata(METADATA_KEYS.MCP_INVALID, excluded, apiClass);\n };\n}\n\n/** Every method declared permanently outside MCP by {@link InvalidEndpointForMcp}. */\n// webpieces-disable no-function-outside-class -- metadata reader paired with the decorator\nexport function getInvalidEndpointsForMcp(apiClass: Function): InvalidEndpointForMcpMetadata[] {\n const excluded: Record<string, InvalidEndpointForMcpMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_INVALID, apiClass) ?? {};\n return Object.values(excluded);\n}\n\n/** The one mapping from endpoint side effects to MCP advisory annotations. */\n// webpieces-disable no-function-outside-class -- pure metadata mapping shared by MCP registration\nexport function mcpHintsForOperation(\n operation: EndpointOperation,\n openWorldHint: boolean,\n): WpMcpToolHints {\n switch (operation) {\n case READ:\n return new WpMcpToolHints(true, false, true, openWorldHint);\n case WRITE_IDEMPOTENT:\n return new WpMcpToolHints(false, true, true, openWorldHint);\n case WRITE:\n return new WpMcpToolHints(false, true, false, openWorldHint);\n }\n}\n\n/** Returns only methods explicitly opted in through {@link WpMcpTool}. */\n// webpieces-disable no-function-outside-class -- metadata reader paired with the decorator\nexport function getWpMcpTools(apiClass: Function): WpMcpToolMetadata[] {\n const tools: Record<string, WpMcpToolMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_TOOLS, apiClass) ?? {};\n return Object.values(tools);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"McpMetadata.js","sourceRoot":"","sources":["../../../../../../packages/core/core-util/src/mcp/McpMetadata.ts"],"names":[],"mappings":"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","sourcesContent":["import 'reflect-metadata';\nimport { METADATA_KEYS } from '../http/decorators';\nimport { EndpointOperation, READ, WRITE_IDEMPOTENT, WRITE } from '../http/HttpEndpointOptions';\n\n/** The immutable hints MCP clients use when deciding whether and how to call a tool. */\nexport class WpMcpToolHints {\n constructor(\n public readonly readOnlyHint: boolean,\n public readonly destructiveHint: boolean,\n public readonly idempotentHint: boolean,\n public readonly openWorldHint: boolean,\n ) {}\n}\n\ntype AsyncObjectMethod = (...args: never[]) => Promise<object>;\ntype ExactOneParameter<TMethod extends AsyncObjectMethod> = Parameters<TMethod>['length'] extends 1\n ? object\n : never;\ntype ExactOneMethodDescriptor<TMethod extends AsyncObjectMethod> =\n TypedPropertyDescriptor<TMethod> & ExactOneParameter<TMethod>;\n\n/** Method decorator restricted to one request DTO and one async response DTO. */\nexport type WpMcpMethodDecorator = <TMethod extends AsyncObjectMethod>(\n target: object,\n propertyKey: string | symbol,\n descriptor: ExactOneMethodDescriptor<TMethod>,\n) => void;\n\n/** Runtime metadata for one explicitly exposed endpoint. */\nexport class WpMcpToolMetadata {\n constructor(\n public readonly methodName: string,\n public readonly name: string,\n /** The human-readable display name; `tools/list` publishes it as `title` AND `annotations.title`. */\n public readonly title: string,\n ) {}\n}\n\n/**\n * Explicitly publishes an existing `@Endpoint(POST, path, WRITE, RPC)` method as an MCP tool, under\n * the STABLE protocol name and the human-readable TITLE given here.\n *\n * ```typescript\n * @WpMcpTool('learner_get_passages', 'Get your passages')\n * ```\n *\n * Those two are the whole argument list — the only facts about a tool the source cannot otherwise\n * state:\n *\n * | fact | where it comes from |\n * |---|---|\n * | `name` | this decorator — the stable protocol identity, independent of the method name because renaming a method must not break a saved agent workflow |\n * | `title` | this decorator — the display name clients and the Claude Connectors Directory show; published as BOTH `Tool.title` and `annotations.title` |\n * | `description` | the method's JSDoc body, or its `@mcp` tag — the same words the partner reads |\n * | `readOnlyHint` / `destructiveHint` / `idempotentHint` | `@Endpoint`'s `operation`, via {@link mcpHintsForOperation} |\n * | `openWorldHint` | `@Endpoint`'s `openWorld` option |\n * | `inputSchema` / `outputSchema` | the declared request and response types |\n *\n * ## Why the title is REQUIRED and never derived (#1180)\n *\n * The Connectors Directory flags every tool without `annotations.title`. An optional title gets\n * skipped and the miss surfaces only at directory-submission time, so it is a compile-time\n * requirement and an empty or whitespace one throws at decoration time. It is never computed from\n * the name: `learner_get_passages` → \"Learner get passages\" is exactly the mechanical listing text\n * reviewers push back on, and the area prefix means nothing to an end user.\n *\n * Until #984 the decorator also took a `description`, duplicating the JSDoc. Two authored copies of\n * one paragraph drift the first time somebody edits one, so it is gone; the title is a short NAME,\n * not a second copy of the description.\n */\n// webpieces-disable no-function-outside-class -- decorator factories are inherently module-scope\nexport function WpMcpTool(name: string, title: string): WpMcpMethodDecorator {\n if (name.trim() === '') throw new Error('@WpMcpTool requires a non-empty stable name.');\n if (title.trim() === '') {\n throw new Error(\n `@WpMcpTool('${name}', ...) requires a non-empty human-readable title, e.g. ` +\n \"@WpMcpTool('learner_get_passages', 'Get your passages'). tools/list publishes it as \" +\n 'title and annotations.title, and the Claude Connectors Directory flags a tool without one.',\n );\n }\n return <TMethod extends AsyncObjectMethod>(\n target: object,\n propertyKey: string | symbol,\n _descriptor: ExactOneMethodDescriptor<TMethod>,\n ): void => {\n const apiClass = target.constructor;\n const tools: Record<string, WpMcpToolMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_TOOLS, apiClass) ?? {};\n const methodName = String(propertyKey);\n tools[methodName] = new WpMcpToolMetadata(methodName, name, title);\n Reflect.defineMetadata(METADATA_KEYS.MCP_TOOLS, tools, apiClass);\n };\n}\n\n/** Runtime metadata for one endpoint declared PERMANENTLY outside MCP. */\nexport class InvalidEndpointForMcpMetadata {\n constructor(\n public readonly methodName: string,\n /** WHY it can never be a tool. Non-empty, enforced at decoration time. */\n public readonly reason: string,\n ) {}\n}\n\n/**\n * Declares that this endpoint is PERMANENTLY outside MCP, and says why.\n *\n * ## It is not a suppression, and that distinction is the whole feature\n *\n * `// webpieces-disable api-rules-for-mcp -- <reason>` says \"stop complaining\". This says \"this is\n * structurally impossible, forever\", and the two have different futures: a suppression is something\n * somebody should eventually come back to, and this is something nobody should. Both measured cases\n * are types that are CORRECT and must not be \"fixed\" —\n *\n * - a webhook TRANSPORT envelope, whose `data` is owned by each event's own published contract;\n * typing it here would fork that ownership and make adding an event type a change to the\n * transport contract rather than a registration, and\n * - a freeform-SQL escape hatch, whose result columns depend on the model-authored `SELECT`.\n *\n * The second one is worth stating rather than burying: it is the most obviously useful tool in that\n * repo, and it is excluded by a type that is right.\n *\n * ## Absence already says \"not a tool YET\"\n *\n * A method with no `@WpMcpTool` is simply not published. This decorator is the NEVER, and the reason\n * is what makes `grep -rn InvalidEndpointForMcp` a list of permanent exclusions with their arguments\n * rather than a list of names. `api-rules-for-mcp` restates that list on every run, so an exclusion\n * stays visible instead of being announced once and forgotten.\n *\n * ## It contradicts `@WpMcpTool`\n *\n * Both on one method is an ERROR, asserted by {@link assertApiTypeMatchesMcpTools}. \"Publish this as\n * a tool\" and \"this can never be a tool\" are two spellings of one decision, which is exactly the\n * defect `.claude/rules/no-backwards-compat.md` shim shape #1 rejects.\n *\n * ```typescript\n * @InvalidEndpointForMcp('a transport envelope body is opaque by design; the published partner ' +\n * 'contract for each event type owns its shape')\n * ```\n */\n// webpieces-disable no-function-outside-class -- decorator factories are inherently module-scope\nexport function InvalidEndpointForMcp(reason: string): MethodDecorator {\n if (reason.trim() === '') {\n throw new Error(\n '@InvalidEndpointForMcp requires a non-empty reason. The reason IS the declaration — ' +\n 'without it this is a suppression with a longer name.',\n );\n }\n return (target: object, propertyKey: string | symbol): void => {\n const apiClass = target.constructor;\n const excluded: Record<string, InvalidEndpointForMcpMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_INVALID, apiClass) ?? {};\n const methodName = String(propertyKey);\n excluded[methodName] = new InvalidEndpointForMcpMetadata(methodName, reason);\n Reflect.defineMetadata(METADATA_KEYS.MCP_INVALID, excluded, apiClass);\n };\n}\n\n/** Every method declared permanently outside MCP by {@link InvalidEndpointForMcp}. */\n// webpieces-disable no-function-outside-class -- metadata reader paired with the decorator\nexport function getInvalidEndpointsForMcp(apiClass: Function): InvalidEndpointForMcpMetadata[] {\n const excluded: Record<string, InvalidEndpointForMcpMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_INVALID, apiClass) ?? {};\n return Object.values(excluded);\n}\n\n/** The one mapping from endpoint side effects to MCP advisory annotations. */\n// webpieces-disable no-function-outside-class -- pure metadata mapping shared by MCP registration\nexport function mcpHintsForOperation(\n operation: EndpointOperation,\n openWorldHint: boolean,\n): WpMcpToolHints {\n switch (operation) {\n case READ:\n return new WpMcpToolHints(true, false, true, openWorldHint);\n case WRITE_IDEMPOTENT:\n return new WpMcpToolHints(false, true, true, openWorldHint);\n case WRITE:\n return new WpMcpToolHints(false, true, false, openWorldHint);\n }\n}\n\n/** Returns only methods explicitly opted in through {@link WpMcpTool}. */\n// webpieces-disable no-function-outside-class -- metadata reader paired with the decorator\nexport function getWpMcpTools(apiClass: Function): WpMcpToolMetadata[] {\n const tools: Record<string, WpMcpToolMetadata> =\n Reflect.getMetadata(METADATA_KEYS.MCP_TOOLS, apiClass) ?? {};\n return Object.values(tools);\n}\n"]}
|