stitchkit 0.2.0 → 0.4.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/README.md +11 -10
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/http.d.ts +5 -0
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/socket-io.d.ts +17 -0
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/cli.d.ts +23 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +21 -0
- package/dist/contract/define.d.ts +35 -2
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +2 -1
- package/dist/index-0ed3bx43.js +33 -0
- package/dist/index-0ma1eqv4.js +1007 -0
- package/dist/index-1cf8jkhf.js +219 -0
- package/dist/index-37x76zdn.js +4 -0
- package/dist/{index-v2z2v3mq.js → index-3qmtdfpa.js} +304 -62
- package/dist/index-48ffdxgk.js +6 -0
- package/dist/{index-5sxnvwb1.js → index-78q1qm7v.js} +6 -3
- package/dist/{index-kckky6zw.js → index-afzt3nmx.js} +1 -1
- package/dist/{index-n7bmdwmz.js → index-d4rwrjbc.js} +8 -4
- package/dist/index-kzfs85xp.js +9 -0
- package/dist/index-mwmpw6j1.js +60 -0
- package/dist/{index-a35v22fh.js → index-vhdvv00d.js} +13 -5
- package/dist/index-x3fcszf8.js +8 -0
- package/dist/index.js +17 -4
- package/dist/internal/errors.d.ts +13 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/http-input.d.ts +13 -0
- package/dist/internal/http-input.d.ts.map +1 -0
- package/dist/internal/safe-json.d.ts +19 -0
- package/dist/internal/safe-json.d.ts.map +1 -0
- package/dist/internal/secure-fetch.d.ts +27 -0
- package/dist/internal/secure-fetch.d.ts.map +1 -0
- package/dist/internal/within-dir.d.ts +7 -0
- package/dist/internal/within-dir.d.ts.map +1 -0
- package/dist/node.d.ts +10 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +41 -7
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/context.d.ts +9 -1
- package/dist/observability/context.d.ts.map +1 -1
- package/dist/observability/event.d.ts +4 -0
- package/dist/observability/event.d.ts.map +1 -1
- package/dist/observability/index.js +38 -15
- package/dist/observability/sanitize.d.ts.map +1 -1
- package/dist/react.js +2 -0
- package/dist/server/context.d.ts +3 -2
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/event-bus.d.ts +10 -1
- package/dist/server/event-bus.d.ts.map +1 -1
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +6 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +203 -193
- package/dist/server/logger.d.ts +5 -4
- package/dist/server/logger.d.ts.map +1 -1
- package/dist/server/middleware/auth.d.ts +41 -1
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/middleware/cookies.d.ts.map +1 -1
- package/dist/server/middleware/cors.d.ts +7 -0
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/middleware/pkce.d.ts +17 -0
- package/dist/server/middleware/pkce.d.ts.map +1 -0
- package/dist/server/multipart.d.ts +2 -1
- package/dist/server/multipart.d.ts.map +1 -1
- package/dist/server/node.d.ts +9 -0
- package/dist/server/node.d.ts.map +1 -1
- package/dist/server/openapi.d.ts +52 -0
- package/dist/server/openapi.d.ts.map +1 -0
- package/dist/server/rate-limit.d.ts +7 -2
- package/dist/server/rate-limit.d.ts.map +1 -1
- package/dist/server/request.d.ts +27 -4
- package/dist/server/request.d.ts.map +1 -1
- package/dist/server/router.d.ts +4 -2
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/socket-io.d.ts +60 -15
- package/dist/server/socket-io.d.ts.map +1 -1
- package/dist/server/stream.d.ts +3 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/server/types.d.ts +17 -1
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/websocket.d.ts +73 -0
- package/dist/server/websocket.d.ts.map +1 -0
- package/dist/tools/cli-args.d.ts +68 -0
- package/dist/tools/cli-args.d.ts.map +1 -0
- package/dist/tools/cli-format.d.ts +39 -0
- package/dist/tools/cli-format.d.ts.map +1 -0
- package/dist/tools/cli-wait.d.ts +45 -0
- package/dist/tools/cli-wait.d.ts.map +1 -0
- package/dist/tools/cli.d.ts +77 -0
- package/dist/tools/cli.d.ts.map +1 -0
- package/dist/tools/coerce.d.ts +8 -4
- package/dist/tools/coerce.d.ts.map +1 -1
- package/dist/tools/execute.d.ts +1 -1
- package/dist/tools/execute.d.ts.map +1 -1
- package/dist/tools/json-schema.d.ts +29 -4
- package/dist/tools/json-schema.d.ts.map +1 -1
- package/dist/tools/manifest.d.ts +4 -0
- package/dist/tools/manifest.d.ts.map +1 -1
- package/dist/tools/mcp-app.d.ts +59 -0
- package/dist/tools/mcp-app.d.ts.map +1 -0
- package/dist/tools/mcp-handler.d.ts +18 -0
- package/dist/tools/mcp-handler.d.ts.map +1 -1
- package/dist/tools/mcp.d.ts +9 -0
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mount-download.d.ts +30 -0
- package/dist/tools/mount-download.d.ts.map +1 -0
- package/dist/tools/mount-upload.d.ts +19 -0
- package/dist/tools/mount-upload.d.ts.map +1 -0
- package/dist/tools/mount-wait.d.ts +36 -0
- package/dist/tools/mount-wait.d.ts.map +1 -0
- package/dist/tools/mount.d.ts +8 -4
- package/dist/tools/mount.d.ts.map +1 -1
- package/dist/tools/native-result.d.ts +17 -0
- package/dist/tools/native-result.d.ts.map +1 -0
- package/dist/tools/oauth-metadata.d.ts +28 -0
- package/dist/tools/oauth-metadata.d.ts.map +1 -0
- package/dist/tools/oauth-provider.d.ts +85 -0
- package/dist/tools/oauth-provider.d.ts.map +1 -0
- package/dist/tools/remote.d.ts +2 -2
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/toolkit.d.ts +51 -0
- package/dist/tools/toolkit.d.ts.map +1 -0
- package/dist/tools/view-file.d.ts +12 -0
- package/dist/tools/view-file.d.ts.map +1 -1
- package/dist/tools/wait-core.d.ts +33 -0
- package/dist/tools/wait-core.d.ts.map +1 -0
- package/dist/tools.d.ts +13 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +637 -424
- package/package.json +22 -9
- package/dist/index-ke4mx4ea.js +0 -38
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isUnsafeKey
|
|
3
|
+
} from "./index-kzfs85xp.js";
|
|
4
|
+
import {
|
|
5
|
+
isRecord
|
|
6
|
+
} from "./index-809wc1tt.js";
|
|
7
|
+
|
|
8
|
+
// src/server/request.ts
|
|
9
|
+
function generateTraceId() {
|
|
10
|
+
return `${Date.now().toString(36)}-${crypto.randomUUID().slice(0, 8)}`;
|
|
11
|
+
}
|
|
12
|
+
function resolveTraceId(req) {
|
|
13
|
+
const header = req.headers.get("x-request-id") ?? req.headers.get("x-trace-id");
|
|
14
|
+
const trimmed = header?.trim();
|
|
15
|
+
if (trimmed && trimmed.length <= 128 && /^[\w.-]+$/.test(trimmed)) {
|
|
16
|
+
return trimmed;
|
|
17
|
+
}
|
|
18
|
+
return generateTraceId();
|
|
19
|
+
}
|
|
20
|
+
function resolveSocketIp(req, server) {
|
|
21
|
+
if (typeof server === "object" && server !== null && "requestIP" in server && typeof server.requestIP === "function") {
|
|
22
|
+
const addr = server.requestIP(req);
|
|
23
|
+
if (isRecord(addr) && typeof addr.address === "string" && addr.address) {
|
|
24
|
+
return addr.address;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if ("ip" in req && typeof req.ip === "string" && req.ip)
|
|
28
|
+
return req.ip;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
function extractIp(req, options = {}) {
|
|
32
|
+
if (options.trustProxy) {
|
|
33
|
+
const forwarded = req.headers.get("x-forwarded-for");
|
|
34
|
+
if (forwarded)
|
|
35
|
+
return (forwarded.split(",")[0] ?? "").trim().replace(/^::ffff:/, "");
|
|
36
|
+
const realIp = req.headers.get("x-real-ip");
|
|
37
|
+
if (realIp)
|
|
38
|
+
return realIp.trim().replace(/^::ffff:/, "");
|
|
39
|
+
}
|
|
40
|
+
return (options.socketIp ?? "").replace(/^::ffff:/, "");
|
|
41
|
+
}
|
|
42
|
+
function getClientInfo(req, options = {}) {
|
|
43
|
+
return {
|
|
44
|
+
ipAddress: extractIp(req, options) || undefined,
|
|
45
|
+
userAgent: req.headers.get("user-agent") ?? undefined
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function parseQueryParams(url) {
|
|
49
|
+
const query = {};
|
|
50
|
+
for (const key of new Set(url.searchParams.keys())) {
|
|
51
|
+
if (isUnsafeKey(key))
|
|
52
|
+
continue;
|
|
53
|
+
const values = url.searchParams.getAll(key);
|
|
54
|
+
const [first] = values;
|
|
55
|
+
query[key] = values.length === 1 && first !== undefined ? first : values;
|
|
56
|
+
}
|
|
57
|
+
return query;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AppError
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-afzt3nmx.js";
|
|
4
4
|
|
|
5
5
|
// src/internal/errors.ts
|
|
6
6
|
import { z } from "zod";
|
|
@@ -21,9 +21,17 @@ function normalizeError(err) {
|
|
|
21
21
|
if (err instanceof z.ZodError) {
|
|
22
22
|
return new AppError("VALIDATION_ERROR", formatZodError(err), 400);
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
console.error("[stitchkit] unhandled error:", err);
|
|
25
|
+
return new AppError("INTERNAL_SERVER_ERROR", "Internal server error", 500);
|
|
26
|
+
}
|
|
27
|
+
function validateHandlerOutput(schema, data) {
|
|
28
|
+
const parsed = schema.safeParse(data);
|
|
29
|
+
if (parsed.success)
|
|
30
|
+
return { ok: true, data: parsed.data };
|
|
31
|
+
return {
|
|
32
|
+
ok: false,
|
|
33
|
+
message: `Handler output does not match the contract: ${formatZodError(parsed.error)}`
|
|
34
|
+
};
|
|
27
35
|
}
|
|
28
36
|
|
|
29
|
-
export { formatZodError, normalizeError };
|
|
37
|
+
export { formatZodError, normalizeError, validateHandlerOutput };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// src/internal/within-dir.ts
|
|
2
|
+
import { sep } from "node:path";
|
|
3
|
+
function isWithinDir(root, target) {
|
|
4
|
+
const base = root.endsWith(sep) ? root.slice(0, -sep.length) : root;
|
|
5
|
+
return target === root || target === base || target.startsWith(base + sep);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export { isWithinDir };
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,12 @@ import {
|
|
|
3
3
|
createClient,
|
|
4
4
|
createClients,
|
|
5
5
|
createHttpClient
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-78q1qm7v.js";
|
|
7
7
|
import {
|
|
8
8
|
parseSSE
|
|
9
|
-
} from "./index-
|
|
10
|
-
import"./index-
|
|
9
|
+
} from "./index-d4rwrjbc.js";
|
|
10
|
+
import"./index-48ffdxgk.js";
|
|
11
|
+
import"./index-vhdvv00d.js";
|
|
11
12
|
import {
|
|
12
13
|
ALL_TRANSPORTS,
|
|
13
14
|
AppError,
|
|
@@ -20,9 +21,18 @@ import {
|
|
|
20
21
|
paginatedSchema,
|
|
21
22
|
rateLimited,
|
|
22
23
|
unauthorized
|
|
23
|
-
} from "./index-
|
|
24
|
+
} from "./index-afzt3nmx.js";
|
|
25
|
+
import"./index-809wc1tt.js";
|
|
26
|
+
import"./index-37x76zdn.js";
|
|
24
27
|
// src/browser/socket-io.ts
|
|
25
28
|
import { io } from "socket.io-client";
|
|
29
|
+
function toIoAuth(auth) {
|
|
30
|
+
if (typeof auth !== "function")
|
|
31
|
+
return auth;
|
|
32
|
+
return (cb) => {
|
|
33
|
+
Promise.resolve().then(auth).then(cb, () => cb({}));
|
|
34
|
+
};
|
|
35
|
+
}
|
|
26
36
|
function createSocketIOClient(config) {
|
|
27
37
|
let socket = null;
|
|
28
38
|
const connectionListeners = new Set;
|
|
@@ -41,6 +51,9 @@ function createSocketIOClient(config) {
|
|
|
41
51
|
socket = io(config.url, {
|
|
42
52
|
path: config.path ?? "/socket.io/",
|
|
43
53
|
withCredentials: config.withCredentials ?? true,
|
|
54
|
+
auth: toIoAuth(config.auth),
|
|
55
|
+
...config.query && { query: config.query },
|
|
56
|
+
...config.extraHeaders && { extraHeaders: config.extraHeaders },
|
|
44
57
|
transports: config.transports ?? ["websocket", "polling"],
|
|
45
58
|
autoConnect: false,
|
|
46
59
|
reconnection: true,
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
1
|
+
import { type ZodType, z } from 'zod';
|
|
2
2
|
import { AppError } from '../contract';
|
|
3
3
|
export declare function formatZodError(error: z.ZodError): string;
|
|
4
4
|
export declare function normalizeError(err: unknown): AppError;
|
|
5
|
+
/**
|
|
6
|
+
* Validate a handler's return value against the contract `output` schema. A
|
|
7
|
+
* mismatch is a **server** fault (the handler broke its own contract) — shared
|
|
8
|
+
* by the HTTP and tool transports so both report it identically.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateHandlerOutput(schema: ZodType, data: unknown): {
|
|
11
|
+
ok: true;
|
|
12
|
+
data: unknown;
|
|
13
|
+
} | {
|
|
14
|
+
ok: false;
|
|
15
|
+
message: string;
|
|
16
|
+
};
|
|
5
17
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,wBAAgB,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,MAAM,CASxD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAYrD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,GACZ;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAO9D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a method's input travels over HTTP — the single source of truth for the
|
|
3
|
+
* convention shared by the typed client (what it SENDS) and the OpenAPI
|
|
4
|
+
* generator (what it DOCUMENTS), so the two cannot drift. GET and DELETE carry
|
|
5
|
+
* their input as query parameters; the body verbs (POST / PUT / PATCH) carry it
|
|
6
|
+
* as a request body.
|
|
7
|
+
*
|
|
8
|
+
* The server runtime is a tolerant superset of this: it additionally accepts a
|
|
9
|
+
* DELETE *body* when the request carries an `application/json` content-type. The
|
|
10
|
+
* canonical form a client uses and the spec documents is the query form.
|
|
11
|
+
*/
|
|
12
|
+
export declare function inputIsQuery(method: string): boolean;
|
|
13
|
+
//# sourceMappingURL=http-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-input.d.ts","sourceRoot":"","sources":["../../src/internal/http-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEpD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prototype-pollution defence for untrusted input. Assigning a `__proto__` key
|
|
3
|
+
* onto a plain object (`obj[key] = value`, a JSON reviver, a merge) invokes the
|
|
4
|
+
* `__proto__` setter and rewires the prototype chain — the single real
|
|
5
|
+
* pollution vector at an assignment boundary. `constructor` / `prototype` as
|
|
6
|
+
* plain own keys are inert (they shadow, they do not poison), so they are NOT
|
|
7
|
+
* stripped — dropping them would silently corrupt legitimate data fields.
|
|
8
|
+
*
|
|
9
|
+
* Every boundary that ingests client-controlled keys (JSON bodies, query
|
|
10
|
+
* strings, cookies, multipart fields, tool arguments) routes through here.
|
|
11
|
+
*/
|
|
12
|
+
/** True for a key that must never be copied onto a plain object from untrusted input. */
|
|
13
|
+
export declare function isUnsafeKey(key: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* `JSON.parse` that strips the `__proto__` key from the result. Throws on
|
|
16
|
+
* invalid JSON, exactly like `JSON.parse` — callers handle that as a 400.
|
|
17
|
+
*/
|
|
18
|
+
export declare function safeJsonParse(text: string): unknown;
|
|
19
|
+
//# sourceMappingURL=safe-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safe-json.d.ts","sourceRoot":"","sources":["../../src/internal/safe-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** True for a loopback / private / link-local / ULA / CGNAT IP literal. */
|
|
2
|
+
export declare function isPrivateIp(ip: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Refuse a URL that is not `http(s)`, has no host, or whose host is — or
|
|
5
|
+
* resolves to — a private/internal address. Called on the initial URL and on
|
|
6
|
+
* every redirect hop, so a public host cannot `302` to an internal address or
|
|
7
|
+
* to a `file:` / `gopher:` / `data:` scheme.
|
|
8
|
+
*/
|
|
9
|
+
export declare function assertPublicUrl(url: URL): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Fetch a URL with the SSRF guard enforced on the initial URL and on every
|
|
12
|
+
* redirect hop — a public host can otherwise `302` to an internal address or a
|
|
13
|
+
* non-http(s) scheme.
|
|
14
|
+
*
|
|
15
|
+
* Note: the DNS resolution here and the resolution `fetch` performs are
|
|
16
|
+
* separate, so a hostile resolver retains a narrow rebinding window. The
|
|
17
|
+
* per-hop re-check is the larger and fully-closed hole; a static private DNS
|
|
18
|
+
* record is rejected outright.
|
|
19
|
+
*/
|
|
20
|
+
export declare function fetchGuarded(start: URL, allowPrivate: boolean): Promise<Response>;
|
|
21
|
+
/**
|
|
22
|
+
* Read a response body into a buffer, aborting (and returning `null`) if it
|
|
23
|
+
* exceeds `max` bytes — the size cap that keeps a hostile or unbounded stream
|
|
24
|
+
* from OOM-ing the process. A missing body yields an empty buffer.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readCapped(res: Response, max: number): Promise<Buffer | null>;
|
|
27
|
+
//# sourceMappingURL=secure-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-fetch.d.ts","sourceRoot":"","sources":["../../src/internal/secure-fetch.ts"],"names":[],"mappings":"AA8CA,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAkC/C;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CA0B7D;AAED;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAavF;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBnF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when `target` (an already-`resolve`d absolute path) stays inside `root`.
|
|
3
|
+
* Blocks `..`, absolute and otherwise-escaping paths — the shared containment
|
|
4
|
+
* check behind `staticRoute` and `view_file`'s local-file branch.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isWithinDir(root: string, target: string): boolean;
|
|
7
|
+
//# sourceMappingURL=within-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"within-dir.d.ts","sourceRoot":"","sources":["../../src/internal/within-dir.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAQjE"}
|
package/dist/node.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `stitchkit/node` — the Node entrypoint. Everything a Node app needs without
|
|
3
|
+
* touching the Bun-named `createServer`: the Fetch-clean `createHandler`, the
|
|
4
|
+
* srvx-backed `serveNode`, `implement`, the error helpers and (lazily-loaded,
|
|
5
|
+
* Node-safe) `createSocketIOServer`.
|
|
6
|
+
*/
|
|
7
|
+
export { AppError, appError, badRequest, conflict, forbidden, notFound, rateLimited, unauthorized, } from './contract';
|
|
1
8
|
export { createHandler } from './server/create';
|
|
9
|
+
export { createImplement, implement } from './server/implement';
|
|
2
10
|
export { type NodeServerConfig, type NodeServerHandle, serveNode } from './server/node';
|
|
3
|
-
export type
|
|
11
|
+
export { createSocketIOServer, type SocketIOServerConfig, type SocketIOServerHandle, } from './server/socket-io';
|
|
12
|
+
export type { HandlerConfig, RawRoute, RawRouteContext, ServiceDef, } from './server/types';
|
|
4
13
|
//# sourceMappingURL=node.d.ts.map
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACxF,YAAY,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EACL,oBAAoB,EACpB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,aAAa,EACb,QAAQ,EACR,eAAe,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC"}
|
package/dist/node.js
CHANGED
|
@@ -1,16 +1,39 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createHandler
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
createHandler,
|
|
3
|
+
createImplement,
|
|
4
|
+
createSocketIOServer,
|
|
5
|
+
implement
|
|
6
|
+
} from "./index-3qmtdfpa.js";
|
|
7
|
+
import"./index-x3fcszf8.js";
|
|
8
|
+
import"./index-vhdvv00d.js";
|
|
9
|
+
import {
|
|
10
|
+
AppError,
|
|
11
|
+
appError,
|
|
12
|
+
badRequest,
|
|
13
|
+
conflict,
|
|
14
|
+
forbidden,
|
|
15
|
+
notFound,
|
|
16
|
+
rateLimited,
|
|
17
|
+
unauthorized
|
|
18
|
+
} from "./index-afzt3nmx.js";
|
|
19
|
+
import"./index-mwmpw6j1.js";
|
|
20
|
+
import"./index-kzfs85xp.js";
|
|
21
|
+
import"./index-809wc1tt.js";
|
|
22
|
+
import"./index-37x76zdn.js";
|
|
7
23
|
// src/server/node.ts
|
|
8
24
|
import { serve } from "srvx";
|
|
9
25
|
async function serveNode(config) {
|
|
10
|
-
const { port = 3000, hostname, ...handlerConfig } = config;
|
|
26
|
+
const { port = 3000, hostname, socket, ...handlerConfig } = config;
|
|
11
27
|
const handler = createHandler(handlerConfig);
|
|
12
28
|
const server = serve({ port, hostname, fetch: handler });
|
|
13
29
|
await server.ready();
|
|
30
|
+
if (socket) {
|
|
31
|
+
const nodeServer = server.node?.server;
|
|
32
|
+
if (!nodeServer || !("maxRequestsPerSocket" in nodeServer)) {
|
|
33
|
+
throw new Error("[stitchkit] serveNode: expected a node:http.Server for Socket.IO (none / http2).");
|
|
34
|
+
}
|
|
35
|
+
socket.attach(nodeServer);
|
|
36
|
+
}
|
|
14
37
|
const listenUrl = server.url ?? `http://${hostname ?? "localhost"}:${port}`;
|
|
15
38
|
const resolvedPort = Number(new URL(listenUrl).port) || port;
|
|
16
39
|
const resolvedHost = hostname ?? "localhost";
|
|
@@ -21,6 +44,17 @@ async function serveNode(config) {
|
|
|
21
44
|
};
|
|
22
45
|
}
|
|
23
46
|
export {
|
|
47
|
+
unauthorized,
|
|
24
48
|
serveNode,
|
|
25
|
-
|
|
49
|
+
rateLimited,
|
|
50
|
+
notFound,
|
|
51
|
+
implement,
|
|
52
|
+
forbidden,
|
|
53
|
+
createSocketIOServer,
|
|
54
|
+
createImplement,
|
|
55
|
+
createHandler,
|
|
56
|
+
conflict,
|
|
57
|
+
badRequest,
|
|
58
|
+
appError,
|
|
59
|
+
AppError
|
|
26
60
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;AAGhF,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iFAAiF;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,KACpD,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB;AAmBD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;AAGhF,oCAAoC;AACpC,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iFAAiF;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,qEAAqE;AACrE,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,IAAI,EAAE,CAAC,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,KACpD,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD;;;OAGG;IACH,QAAQ,EAAE,aAAa,CAAC;CACzB;AAmBD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CA+F9D"}
|
|
@@ -46,6 +46,14 @@ export declare function setRequestError(error: {
|
|
|
46
46
|
code?: string;
|
|
47
47
|
message?: string;
|
|
48
48
|
}): void;
|
|
49
|
+
/** Options for `wrapInRequestContext`. */
|
|
50
|
+
export interface WrapRequestContextOptions {
|
|
51
|
+
/**
|
|
52
|
+
* Trust `x-forwarded-for` for the client IP — enable only behind a proxy
|
|
53
|
+
* that rewrites it. Default `false`: the real socket peer IP is used.
|
|
54
|
+
*/
|
|
55
|
+
trustProxy?: boolean;
|
|
56
|
+
}
|
|
49
57
|
/**
|
|
50
58
|
* Wrap a fetch handler so it runs inside a fresh `RequestContext` — trace ids
|
|
51
59
|
* (the inbound `traceparent` continued, or freshly minted), timing and client
|
|
@@ -56,5 +64,5 @@ export declare function setRequestError(error: {
|
|
|
56
64
|
* logs share one id), pass `traceId: getTraceId` to `createServer` /
|
|
57
65
|
* `createHandler`.
|
|
58
66
|
*/
|
|
59
|
-
export declare function wrapInRequestContext<S>(handler: (req: Request, server: S) => Promise<Response
|
|
67
|
+
export declare function wrapInRequestContext<S>(handler: (req: Request, server: S) => Promise<Response>, options?: WrapRequestContextOptions): (req: Request, server: S) => Promise<Response>;
|
|
60
68
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/observability/context.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAEjE,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,KAAK,EAAE,YAAY,CAAC;IACpB,4CAA4C;IAC5C,MAAM,EAAE,eAAe,CAAC;IACxB,iBAAiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAID,yDAAyD;AACzD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE5E;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED,mEAAmE;AACnE,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAE/C;AAED,qDAAqD;AACrD,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAGhF;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/observability/context.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAEjE,oDAAoD;AACpD,MAAM,WAAW,cAAc;IAC7B,sCAAsC;IACtC,KAAK,EAAE,YAAY,CAAC;IACpB,4CAA4C;IAC5C,MAAM,EAAE,eAAe,CAAC;IACxB,iBAAiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAID,yDAAyD;AACzD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE5E;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED,mEAAmE;AACnE,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAE/C;AAED,qDAAqD;AACrD,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAGhF;AAED,0CAA0C;AAC1C,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,EACvD,OAAO,GAAE,yBAA8B,GACtC,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAiBhD"}
|
|
@@ -39,6 +39,10 @@ export interface RequestEvent {
|
|
|
39
39
|
responseBytes: number;
|
|
40
40
|
/** Resolved user id, when authenticated. */
|
|
41
41
|
userId?: string;
|
|
42
|
+
/** How the caller authenticated, when the app records it on the context. */
|
|
43
|
+
authMethod?: string;
|
|
44
|
+
/** Client id the call was made under (e.g. an OAuth client), when recorded. */
|
|
45
|
+
clientId?: string;
|
|
42
46
|
/** Client IP. */
|
|
43
47
|
ipAddress?: string;
|
|
44
48
|
/** Client user-agent. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/observability/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,MAAM,EAAE,eAAe,CAAC;IACxB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,mDAAmD;IACnD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,EAAE,IAAI,CAAC;CACjB"}
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/observability/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,MAAM,EAAE,eAAe,CAAC;IACxB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,mDAAmD;IACnD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,EAAE,IAAI,CAAC;CACjB"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getClientInfo,
|
|
3
|
+
resolveSocketIp
|
|
4
|
+
} from "../index-mwmpw6j1.js";
|
|
5
|
+
import {
|
|
6
|
+
isUnsafeKey
|
|
7
|
+
} from "../index-kzfs85xp.js";
|
|
1
8
|
import {
|
|
2
9
|
isRecord
|
|
3
10
|
} from "../index-809wc1tt.js";
|
|
4
|
-
import
|
|
5
|
-
getClientInfo
|
|
6
|
-
} from "../index-ke4mx4ea.js";
|
|
11
|
+
import"../index-37x76zdn.js";
|
|
7
12
|
|
|
8
13
|
// src/observability/context.ts
|
|
9
14
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -27,11 +32,11 @@ function parseTraceparent(header) {
|
|
|
27
32
|
const match = TRACEPARENT_RE.exec(header.trim());
|
|
28
33
|
if (!match?.[1] || !match[2])
|
|
29
34
|
return null;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
};
|
|
35
|
+
const traceId = match[1].toLowerCase();
|
|
36
|
+
const parentSpanId = match[2].toLowerCase();
|
|
37
|
+
if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
|
|
38
|
+
return null;
|
|
39
|
+
return { traceId, spanId: randomHex(8), parentSpanId };
|
|
35
40
|
}
|
|
36
41
|
function formatTraceparent(ctx) {
|
|
37
42
|
return `00-${ctx.traceId}-${ctx.spanId}-01`;
|
|
@@ -71,15 +76,18 @@ function setRequestError(error) {
|
|
|
71
76
|
if (ctx)
|
|
72
77
|
ctx.error = error;
|
|
73
78
|
}
|
|
74
|
-
function wrapInRequestContext(handler) {
|
|
79
|
+
function wrapInRequestContext(handler, options = {}) {
|
|
75
80
|
return (req, server) => {
|
|
76
81
|
const ctx = {
|
|
77
82
|
trace: resolveTraceContext(req),
|
|
78
83
|
source: "http",
|
|
79
84
|
method: req.method,
|
|
80
|
-
path: new URL(req.url).pathname,
|
|
85
|
+
path: new URL(req.url, "http://localhost").pathname,
|
|
81
86
|
startedAt: process.hrtime.bigint(),
|
|
82
|
-
...getClientInfo(req
|
|
87
|
+
...getClientInfo(req, {
|
|
88
|
+
trustProxy: options.trustProxy,
|
|
89
|
+
socketIp: resolveSocketIp(req, server)
|
|
90
|
+
})
|
|
83
91
|
};
|
|
84
92
|
return runWithRequestContext(ctx, () => handler(req, server));
|
|
85
93
|
};
|
|
@@ -93,6 +101,7 @@ var MASK = "[redacted]";
|
|
|
93
101
|
function redact(value, options = {}) {
|
|
94
102
|
const sensitive = options.sensitiveKeys ?? DEFAULT_SENSITIVE_KEYS;
|
|
95
103
|
const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
104
|
+
const ancestors = new Set;
|
|
96
105
|
const walk = (input, depth) => {
|
|
97
106
|
if (depth > maxDepth)
|
|
98
107
|
return "[max depth]";
|
|
@@ -111,13 +120,24 @@ function redact(value, options = {}) {
|
|
|
111
120
|
return { _type: "formdata", keys: [...input.keys()] };
|
|
112
121
|
}
|
|
113
122
|
if (Array.isArray(input)) {
|
|
114
|
-
|
|
123
|
+
if (ancestors.has(input))
|
|
124
|
+
return "[circular]";
|
|
125
|
+
ancestors.add(input);
|
|
126
|
+
const result = input.map((item) => walk(item, depth + 1));
|
|
127
|
+
ancestors.delete(input);
|
|
128
|
+
return result;
|
|
115
129
|
}
|
|
116
130
|
if (isRecord(input)) {
|
|
131
|
+
if (ancestors.has(input))
|
|
132
|
+
return "[circular]";
|
|
133
|
+
ancestors.add(input);
|
|
117
134
|
const out = {};
|
|
118
135
|
for (const [key, val] of Object.entries(input)) {
|
|
136
|
+
if (isUnsafeKey(key))
|
|
137
|
+
continue;
|
|
119
138
|
out[key] = sensitive.test(key) ? MASK : walk(val, depth + 1);
|
|
120
139
|
}
|
|
140
|
+
ancestors.delete(input);
|
|
121
141
|
return out;
|
|
122
142
|
}
|
|
123
143
|
return String(input);
|
|
@@ -126,11 +146,12 @@ function redact(value, options = {}) {
|
|
|
126
146
|
}
|
|
127
147
|
function truncatePreview(value, maxBytes = DEFAULT_MAX_BYTES) {
|
|
128
148
|
const json = JSON.stringify(value);
|
|
129
|
-
|
|
149
|
+
const bytes = Buffer.byteLength(json, "utf8");
|
|
150
|
+
if (bytes <= maxBytes)
|
|
130
151
|
return value;
|
|
131
152
|
return {
|
|
132
153
|
_truncated: true,
|
|
133
|
-
_originalBytes:
|
|
154
|
+
_originalBytes: bytes,
|
|
134
155
|
preview: `${json.slice(0, maxBytes)}…`
|
|
135
156
|
};
|
|
136
157
|
}
|
|
@@ -147,7 +168,7 @@ function measureSize(value) {
|
|
|
147
168
|
if (Array.isArray(value)) {
|
|
148
169
|
return { resultSize: value.length, responseBytes };
|
|
149
170
|
}
|
|
150
|
-
if (
|
|
171
|
+
if (isRecord(value) && Array.isArray(value.items) && "nextCursor" in value) {
|
|
151
172
|
return { resultSize: value.items.length, responseBytes };
|
|
152
173
|
}
|
|
153
174
|
return { resultSize: null, responseBytes };
|
|
@@ -237,6 +258,8 @@ function createAuditHook(config) {
|
|
|
237
258
|
resultSize: measure.resultSize,
|
|
238
259
|
responseBytes: measure.responseBytes,
|
|
239
260
|
userId: readString(context.userId),
|
|
261
|
+
authMethod: readString(context.authMethod),
|
|
262
|
+
clientId: readString(context.clientId),
|
|
240
263
|
ipAddress: readString(context.ipAddress),
|
|
241
264
|
userAgent: readString(context.userAgent),
|
|
242
265
|
startedAt: new Date(Date.now() - durationMs)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/observability/sanitize.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/observability/sanitize.ts"],"names":[],"mappings":"AAOA,8EAA8E;AAC9E,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mCAAmC;AACnC,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,8BAA8B;IAC9B,aAAa,EAAE,MAAM,CAAC;CACvB;AASD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,GAAE,eAAoB,GAAG,SAAS,CAoD/E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,SAAoB,GAAG,SAAS,CASzF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,eAAoB,GAC5B,SAAS,GAAG,IAAI,CAGlB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAcvD"}
|
package/dist/react.js
CHANGED
package/dist/server/context.d.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* endpoint schemas and gathers request metadata (trace id, client info).
|
|
4
4
|
*/
|
|
5
5
|
import { type RuntimeContext } from '../contract';
|
|
6
|
+
import { type ClientIpOptions } from './request';
|
|
6
7
|
import type { MethodDef } from './types';
|
|
7
|
-
export declare function buildContext(req: Request, url: URL, method: MethodDef, pathParams: Record<string, string>, traceId: string): Promise<RuntimeContext>;
|
|
8
|
-
export declare function buildErrorContext(req: Request, url: URL, traceId: string): RuntimeContext;
|
|
8
|
+
export declare function buildContext(req: Request, url: URL, method: MethodDef, pathParams: Record<string, string>, traceId: string, clientIp: ClientIpOptions): Promise<RuntimeContext>;
|
|
9
|
+
export declare function buildErrorContext(req: Request, url: URL, traceId: string, clientIp: ClientIpOptions): RuntimeContext;
|
|
9
10
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAG9D,OAAO,EAAE,KAAK,eAAe,EAAmC,MAAM,WAAW,CAAC;AAClF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAmCzC,wBAAsB,YAAY,CAChC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CA2CzB;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,GACxB,cAAc,CAWhB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/server/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/server/create.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAEV,eAAe,EACf,aAAa,EAGd,MAAM,SAAS,CAAC;AAEjB,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAwMxF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,uBAsBnD"}
|
|
@@ -19,6 +19,15 @@ export interface EventBus<M extends Record<string, unknown> = DefaultEventMap> {
|
|
|
19
19
|
off<K extends keyof M & string>(event: K, handler: EventHandler<M[K]>): void;
|
|
20
20
|
clear(): void;
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
/** Options for `createEventBus`. */
|
|
23
|
+
export interface EventBusOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Called when a listener throws or rejects. A bus listener's failure must
|
|
26
|
+
* never break the bus, so it is caught — but without this hook it is also
|
|
27
|
+
* invisible. Wire it to a logger to surface listener bugs.
|
|
28
|
+
*/
|
|
29
|
+
onListenerError?: (error: unknown, event: string) => void;
|
|
30
|
+
}
|
|
31
|
+
export declare function createEventBus<M extends Record<string, unknown> = DefaultEventMap>(options?: EventBusOptions): EventBus<M>;
|
|
23
32
|
export {};
|
|
24
33
|
//# sourceMappingURL=event-bus.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/server/event-bus.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnE,sEAAsE;AACtE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe;IAC3E,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7D,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IAClF,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IACpF,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7E,KAAK,IAAI,IAAI,CAAC;CACf;AAYD,wBAAgB,cAAc,
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/server/event-bus.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnE,sEAAsE;AACtE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,QAAQ,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe;IAC3E,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7D,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IAClF,IAAI,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC;IACpF,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7E,KAAK,IAAI,IAAI,CAAC;CACf;AAYD,oCAAoC;AACpC,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,EAChF,OAAO,GAAE,eAAoB,GAC5B,QAAQ,CAAC,CAAC,CAAC,CA0Db"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../src/server/implement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../src/server/implement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,KAAK,EAAE,QAAQ,EAAa,UAAU,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,IAAI,SAAS,cAAc,GAAG,cAAc,EAC5C,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,UAAU,CAsC3E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAS,cAAc,MACjD,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC3C,UAAU,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAChC,UAAU,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,KAC1B,UAAU,CACd"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3,15 +3,18 @@ export { cacheHeaders, createCache } from './cache';
|
|
|
3
3
|
export { createHandler, createServer } from './create';
|
|
4
4
|
export { createEventBus, type EventBus } from './event-bus';
|
|
5
5
|
export { createImplement, implement } from './implement';
|
|
6
|
-
export { type AuthHook, type AuthHookConfig, type AuthRule, type BearerResolverConfig, createAuthHook, createBearerResolver, extractToken, type JwtPayload, verifyJwt, } from './middleware/auth';
|
|
6
|
+
export { type AuthHook, type AuthHookConfig, type AuthRule, type BearerResolverConfig, createAuthHook, createBearerResolver, extractToken, type JwtPayload, type SignJwtOptions, signJwt, verifyJwt, } from './middleware/auth';
|
|
7
7
|
export { type CookieDef, type CookieOptions, defineCookie, parseCookies, serializeCookie, } from './middleware/cookies';
|
|
8
8
|
export { type CorsConfig, corsHeaders, corsPreflightResponse, } from './middleware/cors';
|
|
9
|
+
export { deriveCodeChallenge, type PkceMethod, verifyPkce } from './middleware/pkce';
|
|
9
10
|
export { parseMultipart } from './multipart';
|
|
11
|
+
export { generateOpenApiDocument, type OpenApiConfig, type OpenApiDocument, type OpenApiInfo, type OpenApiServer, openApiRoute, } from './openapi';
|
|
10
12
|
export { createRateLimiter, type RateLimitConfig } from './rate-limit';
|
|
11
|
-
export { extractIp, generateTraceId, getClientInfo, resolveTraceId, } from './request';
|
|
13
|
+
export { type ClientIpOptions, extractIp, generateTraceId, getClientInfo, resolveSocketIp, resolveTraceId, } from './request';
|
|
12
14
|
export { staticRoute } from './router';
|
|
13
15
|
export type { SocketIOServerConfig, SocketIOServerHandle } from './socket-io';
|
|
14
|
-
export { createSocketIOServer } from './socket-io';
|
|
16
|
+
export { createSocketIOServer, socketIoLane } from './socket-io';
|
|
15
17
|
export { type ParseSSEOptions, parseSSE, streamSSE } from './stream';
|
|
16
18
|
export type { BunServer, BunServerConfig, HandlerConfig, Handlers, LifecycleHooks, MethodDef, RawRoute, RawRouteContext, RouteGroup, ServerPassthrough, ServiceDef, StitchLogger, } from './types';
|
|
19
|
+
export { type ComposedLane, composeWebSocketHandlers, type WebSocketComposeConfig, type WebSocketLane, webSocketLane, } from './websocket';
|
|
17
20
|
//# sourceMappingURL=index.d.ts.map
|