stitchkit 0.26.0 → 0.28.0
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/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/http.d.ts +7 -1
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/contract/define.d.ts +60 -3
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/index.js +1 -1
- package/dist/{index-bkccbx64.js → index-17jpjnhd.js} +196 -44
- package/dist/{index-q5w3cvvp.js → index-4whcb3c3.js} +3 -1
- package/dist/{index-dzx781tm.js → index-9g9d6r1h.js} +40 -4
- package/dist/{index-tje0q6gp.js → index-czmqks7r.js} +6 -1
- package/dist/{index-p6fge9a5.js → index-jvescqgr.js} +1 -1
- package/dist/{index-h4y2wg3n.js → index-pmftwk2a.js} +18 -0
- package/dist/index.js +20 -8
- package/dist/node.d.ts +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +7 -7
- package/dist/observability/context.d.ts +8 -4
- package/dist/observability/context.d.ts.map +1 -1
- package/dist/observability/index.js +6 -8
- package/dist/server/create.d.ts +2 -2
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +3 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +19 -7
- package/dist/server/logger.d.ts +36 -4
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/logging.d.ts +20 -0
- package/dist/server/logging.d.ts.map +1 -0
- package/dist/server/middleware/cors.d.ts +25 -0
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/node.d.ts +2 -2
- package/dist/server/node.d.ts.map +1 -1
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/router.d.ts +27 -0
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/types.d.ts +116 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/tools/list-names.d.ts +2 -1
- package/dist/tools/list-names.d.ts.map +1 -1
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/tool-logger.d.ts +7 -0
- package/dist/tools/tool-logger.d.ts.map +1 -1
- package/dist/tools.js +29 -14
- package/llms-full.txt +234 -14
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/dist/index-khwedj16.js +0 -40
- /package/dist/{index-0d0rb85d.js → index-zza375qp.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/browser/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI/F,OAAO,EAEL,KAAK,UAAU,IAAI,WAAW,EAG/B,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/browser/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI/F,OAAO,EAEL,KAAK,UAAU,IAAI,WAAW,EAG/B,MAAM,QAAQ,CAAC;AAsFhB,kFAAkF;AAClF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC1D,OAAO,GACP;KAAG,CAAC,IAAI,CAAC,GAAG,MAAM;CAAE,CAAC;AAEzB;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK;IAC5D,UAAU,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,CAAC;IAClE,eAAe,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,KAAK,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EAE9B,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAChC,cAAc,EAAE,YAAY,GAAG,WAAW,EAC1C,cAAc,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,GACvC,gBAAgB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAepC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC,EAC1E,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;CAAE,CAKzF"}
|
package/dist/browser/http.d.ts
CHANGED
|
@@ -65,7 +65,13 @@ type ParamArrayValue = Array<string | number>;
|
|
|
65
65
|
export interface RequestOptions {
|
|
66
66
|
params?: Record<string, ParamValue | ParamArrayValue>;
|
|
67
67
|
timeout?: number;
|
|
68
|
-
|
|
68
|
+
/**
|
|
69
|
+
* How to read the body. `'response'` hands back the untouched `Response` —
|
|
70
|
+
* what a `raw` endpoint answers with, and strictly more than `'blob'`: the
|
|
71
|
+
* caller still gets `.blob()` / `.body`, plus the headers where
|
|
72
|
+
* `Content-Disposition` (the download filename) lives.
|
|
73
|
+
*/
|
|
74
|
+
responseType?: 'json' | 'blob' | 'response';
|
|
69
75
|
}
|
|
70
76
|
/** The HTTP transport adapter `createClient` builds typed methods on. */
|
|
71
77
|
export interface HttpClient {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/browser/http.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEvB,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;AAEzD,qBAAa,QAAS,SAAQ,KAAK;aAEf,IAAI,EAAE,MAAM;aACZ,MAAM,EAAE,MAAM;aACd,OAAO,CAAC,EAAE,OAAO;aAEjB,IAAI,CAAC,EAAE,MAAM;gBAJb,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,MAAU,EAClB,OAAO,CAAC,EAAE,OAAO,YAAA,EACjC,OAAO,CAAC,EAAE,MAAM,EACA,IAAI,CAAC,EAAE,MAAM,YAAA;IAM/B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ;CAG7C;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAU9E;AAED,MAAM,MAAM,cAAc,GACtB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEtD,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC;;;;;OAKG;IACH,KAAK,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACvE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,aAAa,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9D;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AACxD,KAAK,eAAe,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;AAE9C,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,eAAe,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/browser/http.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
emitResult,
|
|
5
5
|
parseCliArgs,
|
|
6
6
|
pollUntilDone
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-4whcb3c3.js";
|
|
8
8
|
import"./index-0ed3bx43.js";
|
|
9
|
-
import"./index-
|
|
9
|
+
import"./index-zza375qp.js";
|
|
10
10
|
import"./index-c7nyw0yt.js";
|
|
11
11
|
export {
|
|
12
12
|
pollUntilDone,
|
|
@@ -93,6 +93,7 @@ export interface EndpointToolAnnotations {
|
|
|
93
93
|
interface HttpOnlyEndpointDef extends EndpointDefBase {
|
|
94
94
|
expose: readonly ['HTTP'];
|
|
95
95
|
toolName?: never;
|
|
96
|
+
rawResponse?: never;
|
|
96
97
|
}
|
|
97
98
|
interface ToolEndpointDef extends EndpointDefBase {
|
|
98
99
|
toolName?: string;
|
|
@@ -101,8 +102,55 @@ interface ToolEndpointDef extends EndpointDefBase {
|
|
|
101
102
|
ui?: EndpointUiMeta;
|
|
102
103
|
/** MCP behavioural hints (read-only / destructive / title) for hosts. */
|
|
103
104
|
annotations?: EndpointToolAnnotations;
|
|
105
|
+
rawResponse?: never;
|
|
104
106
|
}
|
|
105
|
-
|
|
107
|
+
/**
|
|
108
|
+
* An endpoint whose handler returns the **`Response` itself** instead of data —
|
|
109
|
+
* a file download, a PDF, an SSE stream, a redirect. → ADR 0038.
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* pdf: {
|
|
113
|
+
* method: 'GET', path: '/:id/pdf', desc: 'Download the offer as a PDF',
|
|
114
|
+
* params: z.object({ id: z.uuid() }),
|
|
115
|
+
* rawResponse: true, contentType: 'application/pdf',
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* Only the **response** is raw — hence the name, and the difference from
|
|
120
|
+
* `rawRoutes`, which sit outside the contract entirely. Here the request half is
|
|
121
|
+
* unchanged: `params` / `input` / `multipart` parse and validate exactly as
|
|
122
|
+
* elsewhere, and `beforeHandle` runs, so the auth gate applies with no guard in
|
|
123
|
+
* the handler. What is handed over is the response, so there is no `output` to
|
|
124
|
+
* validate, nothing to serialize into a tool result, and the endpoint is
|
|
125
|
+
* **HTTP-only**: never an MCP tool, an agent tool or a CLI command.
|
|
126
|
+
* `afterHandle` is skipped (it transforms data; there is none).
|
|
127
|
+
*/
|
|
128
|
+
interface RawResponseEndpointDef extends EndpointDefBase {
|
|
129
|
+
/**
|
|
130
|
+
* Marks the response as raw. Must be the literal `true` — it is the
|
|
131
|
+
* discriminant of the union, so `rawResponse: false` is not a way to say
|
|
132
|
+
* "normal".
|
|
133
|
+
*/
|
|
134
|
+
rawResponse: true;
|
|
135
|
+
/**
|
|
136
|
+
* The `Content-Type` this endpoint answers with, for documentation only —
|
|
137
|
+
* the handler still sets the real header (`serveFile` detects it from the
|
|
138
|
+
* path). Drives the OpenAPI response media type; without it the endpoint
|
|
139
|
+
* documents as `application/octet-stream`.
|
|
140
|
+
*/
|
|
141
|
+
contentType?: string;
|
|
142
|
+
/** There is no output schema — the handler owns the whole response. */
|
|
143
|
+
output?: never;
|
|
144
|
+
/** Never a tool, so a tool name would be dead metadata. */
|
|
145
|
+
toolName?: never;
|
|
146
|
+
/** MCP-only decoration; a raw endpoint never reaches MCP. */
|
|
147
|
+
ui?: never;
|
|
148
|
+
/** MCP-only decoration; a raw endpoint never reaches MCP. */
|
|
149
|
+
annotations?: never;
|
|
150
|
+
/** Redundant but allowed, so `expose: ['HTTP']` survives a migration. */
|
|
151
|
+
expose?: readonly ['HTTP'];
|
|
152
|
+
}
|
|
153
|
+
export type EndpointDef = HttpOnlyEndpointDef | ToolEndpointDef | RawResponseEndpointDef;
|
|
106
154
|
export interface ContractMeta<TScope extends string = string> {
|
|
107
155
|
prefix: string;
|
|
108
156
|
scope?: TScope;
|
|
@@ -110,7 +158,9 @@ export interface ContractMeta<TScope extends string = string> {
|
|
|
110
158
|
* Contract-wide default for every endpoint's opaque `meta` (→ ADR 0021).
|
|
111
159
|
* Endpoints **shallow-merge** over it, key by key — so a contract-wide
|
|
112
160
|
* `{ public: true }` survives an endpoint that adds `{ rateTier: 2 }`. One
|
|
113
|
-
* level only
|
|
161
|
+
* level only, no deep merge. An explicit `key: undefined` on the endpoint is
|
|
162
|
+
* the opt-out: it shadows the contract's value, so `meta?.key` readers see
|
|
163
|
+
* nothing — test values, not key membership. → ADR 0036.
|
|
114
164
|
*
|
|
115
165
|
* `expose` deliberately has no equivalent — see ADR 0036 for why, and pin
|
|
116
166
|
* `listToolNames` in a snapshot to catch an endpoint that forgot it.
|
|
@@ -211,7 +261,14 @@ type MultipartArgs<E> = E extends {
|
|
|
211
261
|
[P in K]: MultipartFile;
|
|
212
262
|
} : unknown;
|
|
213
263
|
type EndpointArgs<E> = InferInput<Prop<E, 'params'>> & InferInput<Prop<E, 'input'>> & MultipartArgs<E>;
|
|
214
|
-
|
|
264
|
+
/**
|
|
265
|
+
* What the typed client resolves to. A `raw` endpoint hands back the untouched
|
|
266
|
+
* `Response` — its body is bytes, and the headers carry what the caller needs
|
|
267
|
+
* (`Content-Disposition`, `Content-Range`, `ETag`). → ADR 0038.
|
|
268
|
+
*/
|
|
269
|
+
type EndpointOutput<E> = E extends {
|
|
270
|
+
rawResponse: true;
|
|
271
|
+
} ? Response : Prop<E, 'output'> extends ZodType<infer O> ? O : undefined;
|
|
215
272
|
export type EndpointFn<E> = [keyof EndpointArgs<E>] extends [never] ? () => Promise<EndpointOutput<E>> : (args: EndpointArgs<E>) => Promise<EndpointOutput<E>>;
|
|
216
273
|
export type TypedClient<C extends Record<string, EndpointDef>> = {
|
|
217
274
|
[K in keyof C]: EndpointFn<C[K]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/contract/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAEtC,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE,eAAO,MAAM,cAAc,0CAA2C,CAAC;AACvE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE/E,UAAU,eAAe;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,WAAW,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,UAAU,CAAC,EAAE,SAAS,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;CAC3C;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gFAAgF;IAChF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,UAAU,mBAAoB,SAAQ,eAAe;IACnD,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1B,QAAQ,CAAC,EAAE,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/contract/define.ts"],"names":[],"mappings":"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"}
|
package/dist/contract/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
assertCorsConfig,
|
|
3
3
|
corsHeaders,
|
|
4
4
|
corsPreflightResponse
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-czmqks7r.js";
|
|
6
6
|
import {
|
|
7
7
|
AppError,
|
|
8
8
|
badRequest,
|
|
@@ -11,17 +11,19 @@ import {
|
|
|
11
11
|
mergeMeta,
|
|
12
12
|
normalizeError,
|
|
13
13
|
validateHandlerOutput
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-zza375qp.js";
|
|
15
15
|
import {
|
|
16
16
|
extractIp,
|
|
17
17
|
getClientInfo,
|
|
18
|
+
getRequestContext,
|
|
18
19
|
parseQueryParams,
|
|
19
20
|
resolveSocketIp,
|
|
20
21
|
resolveTraceId,
|
|
21
22
|
setRequestEndpoint
|
|
22
|
-
} from "./index-
|
|
23
|
+
} from "./index-9g9d6r1h.js";
|
|
23
24
|
import {
|
|
24
25
|
__require,
|
|
26
|
+
isRecord,
|
|
25
27
|
isUnsafeKey,
|
|
26
28
|
safeJsonParse,
|
|
27
29
|
typedEntries
|
|
@@ -213,6 +215,26 @@ function validateRoutes(routeMap) {
|
|
|
213
215
|
}
|
|
214
216
|
}
|
|
215
217
|
}
|
|
218
|
+
function findShadowedRoutes(routeMap, rawRoutes) {
|
|
219
|
+
if (!rawRoutes || rawRoutes.length === 0)
|
|
220
|
+
return [];
|
|
221
|
+
const shadowed = [];
|
|
222
|
+
for (const [httpMethod, entries] of routeMap) {
|
|
223
|
+
for (const entry of entries) {
|
|
224
|
+
const probe = `/${entry.segments.map((s) => s.startsWith(":") ? "__param__" : s).join("/")}`;
|
|
225
|
+
const match = matchRawRoute(rawRoutes, httpMethod, probe);
|
|
226
|
+
if (!match)
|
|
227
|
+
continue;
|
|
228
|
+
shadowed.push({
|
|
229
|
+
pattern: `${httpMethod} ${entry.pattern}`,
|
|
230
|
+
endpoint: `${entry.method.serviceName}.${entry.method.key}`,
|
|
231
|
+
rawRoute: `${match.route.method} ${match.route.path}`,
|
|
232
|
+
scope: entry.method.scope
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return shadowed;
|
|
237
|
+
}
|
|
216
238
|
function matchRawRoute(rawRoutes, httpMethod, pathname) {
|
|
217
239
|
for (const route of rawRoutes) {
|
|
218
240
|
if (route.method !== "ALL" && route.method !== httpMethod)
|
|
@@ -406,7 +428,7 @@ function levelForStatus(status) {
|
|
|
406
428
|
return "info";
|
|
407
429
|
}
|
|
408
430
|
function buildLogFields(method, path, status, durationMs, traceId, errorCode2) {
|
|
409
|
-
return { traceId, method, path, status, durationMs,
|
|
431
|
+
return { traceId, method, path, status, durationMs, errorCode: errorCode2 };
|
|
410
432
|
}
|
|
411
433
|
function formatMs(ms) {
|
|
412
434
|
if (ms >= 1000)
|
|
@@ -450,16 +472,25 @@ function logIncoming(req, pathname, traceId, ipAddress) {
|
|
|
450
472
|
}
|
|
451
473
|
return log;
|
|
452
474
|
}
|
|
453
|
-
function
|
|
475
|
+
function structuredLine(own, extra) {
|
|
476
|
+
try {
|
|
477
|
+
return JSON.stringify({ ...extra, ...own });
|
|
478
|
+
} catch {
|
|
479
|
+
return JSON.stringify(own);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function logOutgoing(entry) {
|
|
483
|
+
const { req, pathname, status, log, ipAddress, errorCode: errorCode2, durationMs, extra } = entry;
|
|
454
484
|
const ms = elapsedMs(log.startTime);
|
|
455
485
|
if (isProd) {
|
|
456
|
-
|
|
486
|
+
const own = {
|
|
457
487
|
ts: new Date().toISOString(),
|
|
458
488
|
level: levelForStatus(status),
|
|
459
489
|
msg: `${req.method} ${pathname} ${status}`,
|
|
460
|
-
...buildLogFields(req.method, pathname, status,
|
|
490
|
+
...buildLogFields(req.method, pathname, status, durationMs, log.traceId, errorCode2),
|
|
461
491
|
ip: ipAddress
|
|
462
|
-
}
|
|
492
|
+
};
|
|
493
|
+
console.log(structuredLine(own, extra));
|
|
463
494
|
return;
|
|
464
495
|
}
|
|
465
496
|
const mc = METHOD_COLOR[req.method] ?? c.dim;
|
|
@@ -467,42 +498,126 @@ function logOutgoing(req, pathname, status, log, ipAddress, errorCode2) {
|
|
|
467
498
|
console.log(`${c.gray}[${timestamp()}]${c.reset} ${mc}${req.method}${c.reset} ${c.dim}${log.traceId}${c.reset} ${c.cyan}←${c.reset} ${safePath(pathname)} ${statusColor(status)}${status}${c.reset}${code} ${durationColor(ms)}${formatMs(ms)}${c.reset} ${ipLabel(ipAddress ?? "")}`);
|
|
468
499
|
}
|
|
469
500
|
|
|
501
|
+
// src/server/logging.ts
|
|
502
|
+
var LOGGER_METHODS = ["info", "warn", "error", "debug"];
|
|
503
|
+
function isBareLogger(value) {
|
|
504
|
+
if (value.logger !== undefined || value.skip !== undefined || value.enrich !== undefined) {
|
|
505
|
+
return false;
|
|
506
|
+
}
|
|
507
|
+
return LOGGER_METHODS.every((method) => typeof value[method] === "function");
|
|
508
|
+
}
|
|
509
|
+
function resolveLoggingConfig(logging) {
|
|
510
|
+
if (logging === false)
|
|
511
|
+
return null;
|
|
512
|
+
if (logging === true)
|
|
513
|
+
return {};
|
|
514
|
+
if (isRecord(logging) && isBareLogger(logging)) {
|
|
515
|
+
throw new Error("[stitchkit] `logging` no longer takes a StitchLogger directly — nest it: " + "`logging: { logger: myLogger }`.");
|
|
516
|
+
}
|
|
517
|
+
return logging;
|
|
518
|
+
}
|
|
519
|
+
function shouldSkipLog(config, req, url) {
|
|
520
|
+
if (!config.skip)
|
|
521
|
+
return false;
|
|
522
|
+
try {
|
|
523
|
+
return config.skip(req, url);
|
|
524
|
+
} catch {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function collectExtraLogFields(config, req, url, outcome) {
|
|
529
|
+
const fields = {};
|
|
530
|
+
const ctx = getRequestContext();
|
|
531
|
+
if (ctx) {
|
|
532
|
+
if (ctx.userId)
|
|
533
|
+
fields.userId = ctx.userId;
|
|
534
|
+
if (ctx.serviceName)
|
|
535
|
+
fields.serviceName = ctx.serviceName;
|
|
536
|
+
if (ctx.action)
|
|
537
|
+
fields.action = ctx.action;
|
|
538
|
+
if (ctx.dimensions)
|
|
539
|
+
fields.dimensions = ctx.dimensions;
|
|
540
|
+
}
|
|
541
|
+
if (config.enrich) {
|
|
542
|
+
try {
|
|
543
|
+
const extra = config.enrich(req, url, outcome);
|
|
544
|
+
if (extra)
|
|
545
|
+
Object.assign(fields, extra);
|
|
546
|
+
} catch {}
|
|
547
|
+
}
|
|
548
|
+
return fields;
|
|
549
|
+
}
|
|
550
|
+
|
|
470
551
|
// src/server/create.ts
|
|
471
552
|
function createHandler(config) {
|
|
472
553
|
const { cors, hooks, logging = false, trustProxy = false } = config;
|
|
473
554
|
if (cors)
|
|
474
555
|
assertCorsConfig(cors);
|
|
475
|
-
const
|
|
476
|
-
const
|
|
477
|
-
const
|
|
556
|
+
const logConfig = resolveLoggingConfig(logging);
|
|
557
|
+
const customLogger = logConfig?.logger ?? null;
|
|
558
|
+
const useDefaultLog = logConfig !== null && !logConfig.logger;
|
|
559
|
+
const customTraceId = config.traceId;
|
|
478
560
|
const routeMap = buildRouteMap(normalizeGroups(config));
|
|
479
561
|
validateRoutes(routeMap);
|
|
562
|
+
for (const shadow of findShadowedRoutes(routeMap, config.rawRoutes)) {
|
|
563
|
+
const gate = shadow.scope && shadow.scope !== "public" ? ` (scope "${shadow.scope}")` : "";
|
|
564
|
+
const line = `[stitchkit] raw route ${shadow.rawRoute} shadows contract route ${shadow.pattern}` + ` → ${shadow.endpoint}${gate} will never run, and its hooks never apply`;
|
|
565
|
+
if (customLogger)
|
|
566
|
+
customLogger.warn(line);
|
|
567
|
+
else
|
|
568
|
+
console.warn(line);
|
|
569
|
+
}
|
|
480
570
|
async function dispatch(req, url, traceId, server, clientIp) {
|
|
481
|
-
const shouldLogRequest =
|
|
571
|
+
const shouldLogRequest = logConfig !== null && shouldLog(url.pathname, req.method) && !shouldSkipLog(logConfig, req, url);
|
|
482
572
|
const ipAddress = extractIp(req, clientIp) || undefined;
|
|
483
573
|
let reqLog;
|
|
484
574
|
if (shouldLogRequest && useDefaultLog) {
|
|
485
575
|
reqLog = logIncoming(req, url.pathname, traceId, ipAddress);
|
|
486
576
|
}
|
|
487
577
|
if (shouldLogRequest && customLogger) {
|
|
488
|
-
customLogger.debug(`${req.method} ${url.pathname}`, {
|
|
489
|
-
traceId,
|
|
490
|
-
method: req.method,
|
|
491
|
-
path: url.pathname,
|
|
492
|
-
ip: ipAddress
|
|
493
|
-
});
|
|
494
578
|
reqLog = { traceId, startTime: performance.now() };
|
|
579
|
+
try {
|
|
580
|
+
customLogger.debug(`${req.method} ${url.pathname}`, {
|
|
581
|
+
traceId,
|
|
582
|
+
method: req.method,
|
|
583
|
+
path: url.pathname,
|
|
584
|
+
ip: ipAddress
|
|
585
|
+
});
|
|
586
|
+
} catch {}
|
|
495
587
|
}
|
|
588
|
+
let logged = false;
|
|
496
589
|
const logDone = (status, errorCode2) => {
|
|
497
|
-
if (!reqLog)
|
|
590
|
+
if (!reqLog || logged || !logConfig)
|
|
498
591
|
return;
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
if (customLogger) {
|
|
592
|
+
logged = true;
|
|
593
|
+
try {
|
|
502
594
|
const durationMs = Math.round(elapsedMs(reqLog.startTime));
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
595
|
+
const extra = collectExtraLogFields(logConfig, req, url, {
|
|
596
|
+
status,
|
|
597
|
+
durationMs,
|
|
598
|
+
errorCode: errorCode2
|
|
599
|
+
});
|
|
600
|
+
if (useDefaultLog) {
|
|
601
|
+
logOutgoing({
|
|
602
|
+
req,
|
|
603
|
+
pathname: url.pathname,
|
|
604
|
+
status,
|
|
605
|
+
log: reqLog,
|
|
606
|
+
ipAddress,
|
|
607
|
+
errorCode: errorCode2,
|
|
608
|
+
durationMs,
|
|
609
|
+
extra
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
if (customLogger) {
|
|
613
|
+
const level = levelForStatus(status);
|
|
614
|
+
customLogger[level](`${req.method} ${url.pathname} ${status}${errorCode2 ? ` ${errorCode2}` : ""} ${durationMs}ms`, {
|
|
615
|
+
...extra,
|
|
616
|
+
...buildLogFields(req.method, url.pathname, status, durationMs, reqLog.traceId, errorCode2),
|
|
617
|
+
ip: ipAddress
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
} catch {}
|
|
506
621
|
};
|
|
507
622
|
const respondError = async (err, errCtx, endpoint) => {
|
|
508
623
|
if (hooks?.onError) {
|
|
@@ -520,9 +635,7 @@ function createHandler(config) {
|
|
|
520
635
|
return json(appErr.toJSON(), appErr.status, cors, req);
|
|
521
636
|
};
|
|
522
637
|
if (cors && req.method === "OPTIONS") {
|
|
523
|
-
|
|
524
|
-
logDone(204);
|
|
525
|
-
return res;
|
|
638
|
+
return corsPreflightResponse(cors, req);
|
|
526
639
|
}
|
|
527
640
|
if (hooks?.onRequest) {
|
|
528
641
|
const earlyResponse = await hooks.onRequest(req);
|
|
@@ -571,6 +684,14 @@ function createHandler(config) {
|
|
|
571
684
|
await groupHooks.beforeHandle(ctx, method);
|
|
572
685
|
}
|
|
573
686
|
let result = await method.handler(ctx);
|
|
687
|
+
if (method.rawResponse) {
|
|
688
|
+
if (!(result instanceof Response)) {
|
|
689
|
+
throw new AppError("INTERNAL_SERVER_ERROR", `Raw endpoint ${method.serviceName}.${method.key} must return a Response`, 500);
|
|
690
|
+
}
|
|
691
|
+
const rawRes = applyCors(result, cors, req);
|
|
692
|
+
logDone(rawRes.status);
|
|
693
|
+
return rawRes;
|
|
694
|
+
}
|
|
574
695
|
if (groupHooks?.afterHandle) {
|
|
575
696
|
const transformed = await groupHooks.afterHandle(ctx, result, method);
|
|
576
697
|
if (transformed !== undefined)
|
|
@@ -581,13 +702,18 @@ function createHandler(config) {
|
|
|
581
702
|
if (transformed !== undefined)
|
|
582
703
|
result = transformed;
|
|
583
704
|
}
|
|
705
|
+
if (result instanceof Response) {
|
|
706
|
+
throw new AppError("INTERNAL_SERVER_ERROR", `${method.serviceName}.${method.key} produced a Response on the data path — only a \`rawResponse: true\` endpoint may return one (an afterHandle hook must return data)`, 500);
|
|
707
|
+
}
|
|
584
708
|
if (method.outputSchema) {
|
|
585
709
|
const checked = validateHandlerOutput(method.outputSchema, result, config.warnOnOutputStrip ? (paths) => {
|
|
586
710
|
const line = `[stitchkit] output strip ${method.serviceName}.${method.key}: ${paths.join(", ")}`;
|
|
587
|
-
|
|
588
|
-
customLogger
|
|
589
|
-
|
|
590
|
-
|
|
711
|
+
try {
|
|
712
|
+
if (customLogger)
|
|
713
|
+
customLogger.warn(line);
|
|
714
|
+
else
|
|
715
|
+
console.warn(line);
|
|
716
|
+
} catch {}
|
|
591
717
|
} : undefined);
|
|
592
718
|
if (!checked.ok) {
|
|
593
719
|
throw new AppError("INTERNAL_SERVER_ERROR", checked.message, 500);
|
|
@@ -595,18 +721,20 @@ function createHandler(config) {
|
|
|
595
721
|
result = checked.data;
|
|
596
722
|
}
|
|
597
723
|
if (result === undefined || result === null) {
|
|
724
|
+
const empty = new Response(null, { status: 204, headers: corsHeaders2(cors, req) });
|
|
598
725
|
logDone(204);
|
|
599
|
-
return
|
|
726
|
+
return empty;
|
|
600
727
|
}
|
|
728
|
+
const body = json(result, 200, cors, req);
|
|
601
729
|
logDone(200);
|
|
602
|
-
return
|
|
730
|
+
return body;
|
|
603
731
|
} catch (err) {
|
|
604
732
|
return respondError(err, ctx, method);
|
|
605
733
|
}
|
|
606
734
|
}
|
|
607
735
|
return async (req, server) => {
|
|
608
736
|
const url = new URL(req.url, "http://localhost");
|
|
609
|
-
const traceId =
|
|
737
|
+
const traceId = customTraceId?.(req) ?? resolveTraceId(req);
|
|
610
738
|
const clientIp = {
|
|
611
739
|
trustProxy,
|
|
612
740
|
socketIp: resolveSocketIp(req, server)
|
|
@@ -620,7 +748,8 @@ function createHandler(config) {
|
|
|
620
748
|
}
|
|
621
749
|
function createServer(config) {
|
|
622
750
|
const { routes, websocket, development, bun: bunExtra, port = 3000, hostname } = config;
|
|
623
|
-
const
|
|
751
|
+
const handler = createHandler(config);
|
|
752
|
+
const fetch = config.wrapFetch ? config.wrapFetch(handler) : handler;
|
|
624
753
|
return websocket ? Bun.serve({
|
|
625
754
|
...bunExtra,
|
|
626
755
|
...routes && { routes },
|
|
@@ -663,20 +792,41 @@ function applyCors(res, cors, req) {
|
|
|
663
792
|
const extra = corsHeaders2(cors, req);
|
|
664
793
|
if (Object.keys(extra).length === 0)
|
|
665
794
|
return res;
|
|
666
|
-
|
|
667
|
-
|
|
795
|
+
try {
|
|
796
|
+
for (const [key, value] of Object.entries(extra))
|
|
797
|
+
setCorsHeader(res.headers, key, value);
|
|
798
|
+
return res;
|
|
799
|
+
} catch {
|
|
800
|
+
const headers = new Headers(res.headers);
|
|
801
|
+
for (const [key, value] of Object.entries(extra))
|
|
802
|
+
setCorsHeader(headers, key, value);
|
|
803
|
+
return new Response(res.body, {
|
|
804
|
+
status: res.status,
|
|
805
|
+
statusText: res.statusText,
|
|
806
|
+
headers
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
function setCorsHeader(headers, key, value) {
|
|
811
|
+
if (key !== "Vary") {
|
|
668
812
|
headers.set(key, value);
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
const existing = headers.get("Vary");
|
|
816
|
+
if (existing === null || existing.trim() === "") {
|
|
817
|
+
headers.set("Vary", value);
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
const present = existing.split(",").some((field) => field.trim().toLowerCase() === "origin");
|
|
821
|
+
if (!present)
|
|
822
|
+
headers.set("Vary", `${existing}, ${value}`);
|
|
674
823
|
}
|
|
675
824
|
function json(data, status, cors, req) {
|
|
676
825
|
return Response.json(data, { status, headers: corsHeaders2(cors, req) });
|
|
677
826
|
}
|
|
678
827
|
|
|
679
828
|
// src/server/implement.ts
|
|
829
|
+
var HTTP_ONLY = Object.freeze(["HTTP"]);
|
|
680
830
|
function implement(contract, handlers) {
|
|
681
831
|
const methods = {};
|
|
682
832
|
const groupScope = contract.meta.scope ?? "public";
|
|
@@ -689,7 +839,7 @@ function implement(contract, handlers) {
|
|
|
689
839
|
serviceName: contract.meta.prefix,
|
|
690
840
|
key: String(key),
|
|
691
841
|
toolName: "toolName" in endpoint ? endpoint.toolName : undefined,
|
|
692
|
-
expose: endpoint.expose,
|
|
842
|
+
expose: endpoint.rawResponse ? HTTP_ONLY : endpoint.expose,
|
|
693
843
|
scope: endpoint.scope ?? groupScope,
|
|
694
844
|
paramsSchema: endpoint.params,
|
|
695
845
|
inputSchema: endpoint.input,
|
|
@@ -700,6 +850,8 @@ function implement(contract, handlers) {
|
|
|
700
850
|
ui: "ui" in endpoint ? endpoint.ui : undefined,
|
|
701
851
|
annotations: "annotations" in endpoint ? endpoint.annotations : undefined,
|
|
702
852
|
meta: mergeMeta(contract.meta.meta, endpoint.meta),
|
|
853
|
+
rawResponse: endpoint.rawResponse,
|
|
854
|
+
contentType: "contentType" in endpoint ? endpoint.contentType : undefined,
|
|
703
855
|
handler: (ctx) => typedHandler(ctx)
|
|
704
856
|
};
|
|
705
857
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
isWithinDir,
|
|
8
8
|
normalizeError,
|
|
9
9
|
validateHandlerOutput
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-zza375qp.js";
|
|
11
11
|
import {
|
|
12
12
|
isRecord,
|
|
13
13
|
isUnsafeKey,
|
|
@@ -515,6 +515,8 @@ function collectTools(service, transport, config = {}) {
|
|
|
515
515
|
}
|
|
516
516
|
if (method.multipart)
|
|
517
517
|
continue;
|
|
518
|
+
if (method.rawResponse)
|
|
519
|
+
continue;
|
|
518
520
|
const name = method.toolName ?? toToolName(service.name, methodName);
|
|
519
521
|
if (assertNames && transport !== "CLI") {
|
|
520
522
|
if (!method.toolName && !hasUsableChars(service.name)) {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
resolveTraceContext
|
|
3
|
-
} from "./index-khwedj16.js";
|
|
4
1
|
import {
|
|
5
2
|
isRecord,
|
|
6
3
|
isUnsafeKey
|
|
@@ -58,6 +55,45 @@ function parseQueryParams(url) {
|
|
|
58
55
|
return query;
|
|
59
56
|
}
|
|
60
57
|
|
|
58
|
+
// src/observability/trace.ts
|
|
59
|
+
var TRACEPARENT_RE = /^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/i;
|
|
60
|
+
function randomHex(bytes) {
|
|
61
|
+
const arr = new Uint8Array(bytes);
|
|
62
|
+
crypto.getRandomValues(arr);
|
|
63
|
+
let hex = "";
|
|
64
|
+
for (const byte of arr)
|
|
65
|
+
hex += byte.toString(16).padStart(2, "0");
|
|
66
|
+
return hex;
|
|
67
|
+
}
|
|
68
|
+
function createTraceContext() {
|
|
69
|
+
return { traceId: randomHex(16), spanId: randomHex(8) };
|
|
70
|
+
}
|
|
71
|
+
function parseTraceparent(header) {
|
|
72
|
+
if (!header)
|
|
73
|
+
return null;
|
|
74
|
+
const match = TRACEPARENT_RE.exec(header.trim());
|
|
75
|
+
if (!match?.[1] || !match[2])
|
|
76
|
+
return null;
|
|
77
|
+
const traceId = match[1].toLowerCase();
|
|
78
|
+
const parentSpanId = match[2].toLowerCase();
|
|
79
|
+
if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
|
|
80
|
+
return null;
|
|
81
|
+
return { traceId, spanId: randomHex(8), parentSpanId };
|
|
82
|
+
}
|
|
83
|
+
function formatTraceparent(ctx) {
|
|
84
|
+
return `00-${ctx.traceId}-${ctx.spanId}-01`;
|
|
85
|
+
}
|
|
86
|
+
function resolveTraceContext(req) {
|
|
87
|
+
return parseTraceparent(req.headers.get("traceparent")) ?? createTraceContext();
|
|
88
|
+
}
|
|
89
|
+
function childSpan(parent) {
|
|
90
|
+
return {
|
|
91
|
+
traceId: parent.traceId,
|
|
92
|
+
spanId: randomHex(8),
|
|
93
|
+
parentSpanId: parent.spanId
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
61
97
|
// src/observability/context.ts
|
|
62
98
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
63
99
|
var storage = new AsyncLocalStorage;
|
|
@@ -112,4 +148,4 @@ function wrapInRequestContext(handler, options = {}) {
|
|
|
112
148
|
};
|
|
113
149
|
}
|
|
114
150
|
|
|
115
|
-
export { generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams, runWithRequestContext, getRequestContext, getTraceId, getUserId, setRequestUser, setRequestEndpoint, setRequestDimensions, setRequestError, wrapInRequestContext };
|
|
151
|
+
export { generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, runWithRequestContext, getRequestContext, getTraceId, getUserId, setRequestUser, setRequestEndpoint, setRequestDimensions, setRequestError, wrapInRequestContext };
|