stitchkit 0.67.0 → 0.68.1
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/agent-runtime/admission-lanes.d.ts +1 -1
- package/dist/agent-runtime/compaction.d.ts +2 -2
- package/dist/agent-runtime/events.d.ts +1 -1
- package/dist/agent-runtime/history.d.ts +1 -1
- package/dist/agent-runtime/history.d.ts.map +1 -1
- package/dist/agent-runtime/injection.d.ts +1 -1
- package/dist/agent-runtime/managed-tools.d.ts +3 -3
- package/dist/agent-runtime/models.d.ts +1 -1
- package/dist/agent-runtime/observability.d.ts +1 -1
- package/dist/agent-runtime/prompt.d.ts +1 -1
- package/dist/agent-runtime/prompt.d.ts.map +1 -1
- package/dist/agent-runtime/protocol.d.ts +19 -1
- package/dist/agent-runtime/protocol.d.ts.map +1 -1
- package/dist/agent-runtime/run-execution.d.ts +5 -5
- package/dist/agent-runtime/run-execution.d.ts.map +1 -1
- package/dist/agent-runtime/runtime-internals.d.ts +1 -1
- package/dist/agent-runtime/runtime-result.d.ts +1 -1
- package/dist/agent-runtime/runtime.d.ts +14 -12
- package/dist/agent-runtime/runtime.d.ts.map +1 -1
- package/dist/agent-runtime/store-driver.d.ts +2 -2
- package/dist/agent-runtime/store.d.ts +2 -2
- package/dist/agent-runtime/terminal-commit.d.ts +2 -2
- package/dist/agent-runtime/terminal-status.d.ts +1 -1
- package/dist/agent-runtime-openrouter.d.ts +1 -1
- package/dist/agent-runtime.d.ts +15 -15
- package/dist/agent-runtime.d.ts.map +1 -1
- package/dist/agent-runtime.js +90 -30
- package/dist/application/admission.d.ts +131 -0
- package/dist/application/admission.d.ts.map +1 -0
- package/dist/application/channel.d.ts +106 -0
- package/dist/application/channel.d.ts.map +1 -0
- package/dist/application/events.d.ts +2 -2
- package/dist/application/grammy.d.ts +2 -2
- package/dist/application/graph.d.ts +1 -1
- package/dist/application/health.d.ts +1 -1
- package/dist/application/kernel.d.ts +3 -3
- package/dist/application/latest-sink.d.ts.map +1 -1
- package/dist/application/opentelemetry.d.ts +3 -3
- package/dist/application/resource.d.ts +1 -1
- package/dist/application/schedule.d.ts +1 -1
- package/dist/application/server-resource.d.ts +7 -9
- package/dist/application/server-resource.d.ts.map +1 -1
- package/dist/application-grammy.d.ts +1 -1
- package/dist/application-grammy.js +1 -1
- package/dist/application-opentelemetry.d.ts +1 -1
- package/dist/application-opentelemetry.js +1 -1
- package/dist/application.d.ts +11 -9
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +393 -24
- package/dist/browser/client-multipart.d.ts +1 -1
- package/dist/browser/client-url.d.ts +2 -2
- package/dist/browser/client.d.ts +4 -5
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/contract-stream.d.ts +5 -0
- package/dist/browser/contract-stream.d.ts.map +1 -0
- package/dist/browser/http.d.ts +9 -6
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/socket-io.d.ts +12 -31
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/browser/stream.d.ts +5 -2
- package/dist/browser/stream.d.ts.map +1 -1
- package/dist/browser/transport.d.ts +3 -0
- package/dist/browser/transport.d.ts.map +1 -0
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +7 -7
- package/dist/contract/define.d.ts +34 -2
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/errors-factory.d.ts +1 -1
- package/dist/contract/errors.d.ts +4 -0
- package/dist/contract/errors.d.ts.map +1 -1
- package/dist/contract/factory.d.ts +1 -1
- package/dist/contract/index.d.ts +7 -6
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +5 -1
- package/dist/contract/stream.d.ts +19 -0
- package/dist/contract/stream.d.ts.map +1 -0
- package/dist/files/boundary.d.ts +1 -1
- package/dist/files.d.ts +2 -2
- package/dist/{index-xxye8j3k.js → index-0w9abg87.js} +4 -0
- package/dist/{index-svqhcrrj.js → index-2ve29dzn.js} +159 -13
- package/dist/index-69m2278y.js +115 -0
- package/dist/{index-physbf4z.js → index-6wzr93cg.js} +1 -1
- package/dist/index-7etq650s.js +75 -0
- package/dist/index-9ky9hhg3.js +484 -0
- package/dist/{index-413xk7ga.js → index-cq9q73nf.js} +50 -1
- package/dist/{index-1pgeyyee.js → index-cszjsxy5.js} +25 -88
- package/dist/{index-wrhf06ak.js → index-cz32amcb.js} +8 -8
- package/dist/{index-6taryy00.js → index-dafax5md.js} +1 -1
- package/dist/index-g2j2m6vv.js +63 -0
- package/dist/{index-8mxadm34.js → index-nck3yx3y.js} +1102 -22
- package/dist/{index-y91zd0ch.js → index-pr0qsmjy.js} +3 -2
- package/dist/index-v5bayx1z.js +138 -0
- package/dist/{index-mfw1pec7.js → index-wqyrvhzz.js} +3 -3
- package/dist/{index-x8v8b7rc.js → index-zpyj7hsv.js} +330 -58
- package/dist/index.d.ts +10 -10
- package/dist/index.js +274 -109
- package/dist/internal/bounded-lines.d.ts +4 -0
- package/dist/internal/bounded-lines.d.ts.map +1 -0
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/observability-sink.d.ts +1 -1
- package/dist/node.d.ts +11 -10
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +11 -8
- package/dist/observability/audit.d.ts +5 -5
- package/dist/observability/context.d.ts +2 -2
- package/dist/observability/event.d.ts +2 -2
- package/dist/observability/index.d.ts +6 -6
- package/dist/observability/index.js +6 -7
- package/dist/react/entity-cache.d.ts +26 -1
- package/dist/react/entity-cache.d.ts.map +1 -1
- package/dist/react.d.ts +3 -3
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +136 -38
- package/dist/realtime/contract.d.ts +1 -1
- package/dist/realtime/index.d.ts +4 -4
- package/dist/realtime/rejection.d.ts +1 -1
- package/dist/realtime/request.d.ts +1 -1
- package/dist/realtime/socket.d.ts +2 -2
- package/dist/remote.d.ts +1 -1
- package/dist/remote.js +5 -6
- package/dist/server/bun.d.ts +3 -3
- package/dist/server/context-contribution.d.ts +1 -1
- package/dist/server/context.d.ts +4 -4
- package/dist/server/contract-stream.d.ts +5 -0
- package/dist/server/contract-stream.d.ts.map +1 -0
- package/dist/server/create.d.ts +1 -1
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +3 -3
- package/dist/server/file.d.ts +1 -1
- package/dist/server/implement.d.ts +2 -2
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +31 -30
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +44 -286
- package/dist/server/lifecycle.d.ts +1 -1
- package/dist/server/logging.d.ts +1 -1
- package/dist/server/middleware/auth.d.ts +2 -2
- package/dist/server/multipart.d.ts +2 -2
- package/dist/server/node.d.ts +2 -2
- package/dist/server/openapi.d.ts +1 -1
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/process-signal-common.d.ts +1 -1
- package/dist/server/process-signals.d.ts +1 -1
- package/dist/server/realtime.d.ts +4 -4
- package/dist/server/response-metadata.d.ts +1 -1
- package/dist/server/router.d.ts +1 -1
- package/dist/server/shutdown.d.ts +1 -1
- package/dist/server/socket-io-node.d.ts +3 -3
- package/dist/server/socket-io.d.ts +6 -6
- package/dist/server/stream.d.ts +3 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/server/streaming-route.d.ts +4 -2
- package/dist/server/streaming-route.d.ts.map +1 -1
- package/dist/server/types.d.ts +18 -8
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/unix-client-body.d.ts +4 -0
- package/dist/server/unix-client-body.d.ts.map +1 -0
- package/dist/server/unix-client-bun.d.ts +13 -0
- package/dist/server/unix-client-bun.d.ts.map +1 -0
- package/dist/server/unix-client-error.d.ts +9 -0
- package/dist/server/unix-client-error.d.ts.map +1 -0
- package/dist/server/unix-client.d.ts +25 -0
- package/dist/server/unix-client.d.ts.map +1 -0
- package/dist/testing/agent-store-conformance.d.ts +1 -1
- package/dist/testing/managed-resource-conformance-contract.d.ts +1 -1
- package/dist/testing/managed-resource-conformance-driver.d.ts +2 -2
- package/dist/testing/managed-resource-conformance-scenarios.d.ts +2 -2
- package/dist/testing/managed-resource-conformance.d.ts +2 -2
- package/dist/testing/surface-conformance.d.ts +3 -3
- package/dist/testing/surface-manifest.d.ts +5 -5
- package/dist/testing.d.ts +8 -8
- package/dist/testing.js +6 -5
- package/dist/tool-invoker.d.ts +9 -0
- package/dist/tool-invoker.d.ts.map +1 -0
- package/dist/tool-invoker.js +16 -0
- package/dist/tools/agent.d.ts +4 -4
- package/dist/tools/async-operation.d.ts +3 -3
- package/dist/tools/cli-command.d.ts +3 -3
- package/dist/tools/cli-format.d.ts +1 -1
- package/dist/tools/cli-policy.d.ts +1 -1
- package/dist/tools/cli-wait.d.ts +1 -1
- package/dist/tools/cli.d.ts +7 -7
- package/dist/tools/define-download-tool.d.ts +4 -4
- package/dist/tools/define-upload-tool.d.ts +3 -3
- package/dist/tools/define-view-file-tool.d.ts +3 -3
- package/dist/tools/define-wait-tool.d.ts +2 -2
- package/dist/tools/download-core.d.ts +2 -2
- package/dist/tools/execute.d.ts +2 -2
- package/dist/tools/flatten-join.d.ts +1 -1
- package/dist/tools/internal/surface-projector.d.ts +3 -3
- package/dist/tools/invoker.d.ts +4 -4
- package/dist/tools/lifecycle.d.ts +1 -1
- package/dist/tools/list-names.d.ts +2 -2
- package/dist/tools/managed-file-error.d.ts +1 -1
- package/dist/tools/manifest.d.ts +3 -3
- package/dist/tools/mcp-handler.d.ts +4 -4
- package/dist/tools/mcp-prepare.d.ts +8 -8
- package/dist/tools/mcp-round-policy.d.ts +1 -1
- package/dist/tools/mcp-round.d.ts +3 -3
- package/dist/tools/mcp-stdio-signals.d.ts +2 -2
- package/dist/tools/mcp-stdio.d.ts +3 -3
- package/dist/tools/mcp.d.ts +7 -7
- package/dist/tools/mount-download.d.ts +1 -1
- package/dist/tools/mount-upload.d.ts +1 -1
- package/dist/tools/mount.d.ts +5 -5
- package/dist/tools/native-definition.d.ts +2 -2
- package/dist/tools/native-mcp.d.ts +3 -3
- package/dist/tools/oauth-metadata.d.ts +1 -1
- package/dist/tools/oauth-provider.d.ts +1 -1
- package/dist/tools/presentation.d.ts +1 -1
- package/dist/tools/remote.d.ts +3 -3
- package/dist/tools/runtime-tool.d.ts +2 -2
- package/dist/tools/surface.d.ts +5 -5
- package/dist/tools/tool-logger.d.ts +1 -1
- package/dist/tools/toolkit.d.ts +7 -7
- package/dist/tools/transports.d.ts +2 -2
- package/dist/tools/upload-core.d.ts +1 -1
- package/dist/tools/view-file.d.ts +1 -1
- package/dist/tools.d.ts +42 -42
- package/dist/tools.js +27 -72
- package/llms-full.txt +506 -35
- package/package.json +8 -4
- package/dist/index-48ffdxgk.js +0 -6
- package/dist/index-pzyt11ch.js +0 -127
- package/dist/index-tvwcrx2d.js +0 -224
- package/dist/index-wd8g8z6e.js +0 -206
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stitchkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.68.1",
|
|
4
4
|
"description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
"types": "./dist/tools.d.ts",
|
|
57
57
|
"import": "./dist/tools.js"
|
|
58
58
|
},
|
|
59
|
+
"./tools/invoker": {
|
|
60
|
+
"types": "./dist/tool-invoker.d.ts",
|
|
61
|
+
"import": "./dist/tool-invoker.js"
|
|
62
|
+
},
|
|
59
63
|
"./cli": {
|
|
60
64
|
"types": "./dist/cli.d.ts",
|
|
61
65
|
"import": "./dist/cli.js"
|
|
@@ -119,9 +123,9 @@
|
|
|
119
123
|
"scripts": {
|
|
120
124
|
"check": "bun x tsc --noEmit",
|
|
121
125
|
"build:browser": "bun build src/index.ts src/react.ts src/contract/index.ts src/declaration.ts --outdir dist --target node --packages external --splitting --root src",
|
|
122
|
-
"build:server": "bun build src/server/index.ts src/node.ts src/tools.ts src/cli.ts src/remote.ts src/files.ts src/testing.ts src/observability/index.ts src/agent-runtime.ts src/agent-runtime-openrouter.ts src/application.ts src/application-grammy.ts src/application-opentelemetry.ts --outdir dist --target node --packages external --splitting --root src",
|
|
123
|
-
"build:js": "bun run build:browser && bun run build:server",
|
|
124
|
-
"build:types": "bun x tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
126
|
+
"build:server": "bun build src/server/index.ts src/node.ts src/tools.ts src/tool-invoker.ts src/cli.ts src/remote.ts src/files.ts src/testing.ts src/observability/index.ts src/agent-runtime.ts src/agent-runtime-openrouter.ts src/application.ts src/application-grammy.ts src/application-opentelemetry.ts --outdir dist --target node --packages external --splitting --root src",
|
|
127
|
+
"build:js": "bun run build:browser && bun run build:server && bun scripts/preserve-webpack-ignore.mjs",
|
|
128
|
+
"build:types": "bun x tsc -p tsconfig.build.json --emitDeclarationOnly && bun scripts/rewrite-declaration-specifiers.mjs",
|
|
125
129
|
"build": "rm -rf dist && bun run build:js && bun run build:types && bun scripts/check-browser-clean.mjs && bun scripts/check-env-live.mjs && bun scripts/check-public-types.mjs",
|
|
126
130
|
"dev": "bun run build:js -- --watch",
|
|
127
131
|
"prepack": "cp ../../README.md ./README.md && bun ../../scripts/gen-llms.ts && bun run build",
|
package/dist/index-48ffdxgk.js
DELETED
package/dist/index-pzyt11ch.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
// src/observability/trace.ts
|
|
2
|
-
var TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(.*)$/i;
|
|
3
|
-
function randomHex(bytes) {
|
|
4
|
-
const arr = new Uint8Array(bytes);
|
|
5
|
-
crypto.getRandomValues(arr);
|
|
6
|
-
let hex = "";
|
|
7
|
-
for (const byte of arr)
|
|
8
|
-
hex += byte.toString(16).padStart(2, "0");
|
|
9
|
-
return hex;
|
|
10
|
-
}
|
|
11
|
-
function createTraceContext() {
|
|
12
|
-
return { traceId: randomHex(16), spanId: randomHex(8) };
|
|
13
|
-
}
|
|
14
|
-
function parseTraceparent(header) {
|
|
15
|
-
if (!header)
|
|
16
|
-
return null;
|
|
17
|
-
const match = TRACEPARENT_RE.exec(header.trim());
|
|
18
|
-
if (!match?.[1] || !match[2] || !match[3] || !match[4] || match[5] === undefined)
|
|
19
|
-
return null;
|
|
20
|
-
const version = match[1].toLowerCase();
|
|
21
|
-
if (version === "ff")
|
|
22
|
-
return null;
|
|
23
|
-
const suffix = match[5];
|
|
24
|
-
if (version === "00" ? suffix !== "" : suffix !== "" && !/^(?:-[0-9a-f]{2,})+$/i.test(suffix)) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
const traceId = match[2].toLowerCase();
|
|
28
|
-
const parentSpanId = match[3].toLowerCase();
|
|
29
|
-
const traceFlags = match[4].toLowerCase();
|
|
30
|
-
if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
|
|
31
|
-
return null;
|
|
32
|
-
return { traceId, spanId: randomHex(8), parentSpanId, traceFlags };
|
|
33
|
-
}
|
|
34
|
-
function formatTraceparent(ctx) {
|
|
35
|
-
return `00-${ctx.traceId}-${ctx.spanId}-${ctx.traceFlags ?? "01"}`;
|
|
36
|
-
}
|
|
37
|
-
function resolveTraceContext(req) {
|
|
38
|
-
return parseTraceparent(req.headers.get("traceparent")) ?? createTraceContext();
|
|
39
|
-
}
|
|
40
|
-
function childSpan(parent) {
|
|
41
|
-
return {
|
|
42
|
-
traceId: parent.traceId,
|
|
43
|
-
spanId: randomHex(8),
|
|
44
|
-
parentSpanId: parent.spanId,
|
|
45
|
-
...parent.tracestate !== undefined && { tracestate: parent.tracestate },
|
|
46
|
-
...parent.baggage !== undefined && { baggage: parent.baggage },
|
|
47
|
-
...parent.traceFlags !== undefined && { traceFlags: parent.traceFlags }
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
var encoder = new TextEncoder;
|
|
51
|
-
function boundedPropagationValue(value, maxBytes, maxMembers) {
|
|
52
|
-
if (typeof value !== "string")
|
|
53
|
-
return;
|
|
54
|
-
const trimmed = value.trim();
|
|
55
|
-
if (!trimmed || encoder.encode(trimmed).byteLength > maxBytes)
|
|
56
|
-
return;
|
|
57
|
-
for (const character of trimmed) {
|
|
58
|
-
const code = character.charCodeAt(0);
|
|
59
|
-
if (code <= 31 || code === 127)
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const members = trimmed.split(",");
|
|
63
|
-
if (members.length > maxMembers || members.some((member) => !member.trim())) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
return trimmed;
|
|
67
|
-
}
|
|
68
|
-
function resolvePropagationContext(metadata, fallback) {
|
|
69
|
-
const traceparent = metadata?.traceparent;
|
|
70
|
-
const parsed = typeof traceparent === "string" ? parseTraceparent(traceparent) : null;
|
|
71
|
-
const trace = traceparent === undefined ? fallback ?? createTraceContext() : parsed ?? createTraceContext();
|
|
72
|
-
const tracestate = parsed ? boundedPropagationValue(metadata?.tracestate, 512, 32) : undefined;
|
|
73
|
-
const baggage = boundedPropagationValue(metadata?.baggage, 8192, 180);
|
|
74
|
-
return {
|
|
75
|
-
...trace,
|
|
76
|
-
...tracestate !== undefined && { tracestate },
|
|
77
|
-
...baggage !== undefined && { baggage }
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// src/internal/route-pattern.ts
|
|
82
|
-
var PARAM_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
83
|
-
function joinRoutePath(...parts) {
|
|
84
|
-
const joined = parts.filter((part) => Boolean(part)).map((part) => part.replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
|
|
85
|
-
return `/${joined}`;
|
|
86
|
-
}
|
|
87
|
-
function parseTrailingWildcard(path) {
|
|
88
|
-
const segments = path.split("/").filter(Boolean);
|
|
89
|
-
const paramNames = new Set;
|
|
90
|
-
let wildcard = null;
|
|
91
|
-
for (const [segmentIndex, segment] of segments.entries()) {
|
|
92
|
-
if (segment.startsWith(":")) {
|
|
93
|
-
const name2 = segment.slice(1);
|
|
94
|
-
if (!PARAM_IDENTIFIER.test(name2)) {
|
|
95
|
-
throw new Error(`Invalid route parameter name "${name2}" in path "${path}"`);
|
|
96
|
-
}
|
|
97
|
-
if (paramNames.has(name2)) {
|
|
98
|
-
throw new Error(`Duplicate route parameter name "${name2}" in path "${path}"`);
|
|
99
|
-
}
|
|
100
|
-
paramNames.add(name2);
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (!segment.startsWith("*")) {
|
|
104
|
-
if (segment.includes("*")) {
|
|
105
|
-
throw new Error(`Wildcard must occupy its own segment in path "${path}"`);
|
|
106
|
-
}
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
const name = segment.slice(1);
|
|
110
|
-
if (!PARAM_IDENTIFIER.test(name)) {
|
|
111
|
-
throw new Error(`Trailing wildcard in path "${path}" must be named, for example "/*filePath"`);
|
|
112
|
-
}
|
|
113
|
-
if (segmentIndex !== segments.length - 1) {
|
|
114
|
-
throw new Error(`Wildcard "*${name}" must be the final segment in path "${path}"`);
|
|
115
|
-
}
|
|
116
|
-
if (wildcard) {
|
|
117
|
-
throw new Error(`Path "${path}" contains more than one wildcard`);
|
|
118
|
-
}
|
|
119
|
-
if (paramNames.has(name)) {
|
|
120
|
-
throw new Error(`Duplicate route parameter name "${name}" in path "${path}"`);
|
|
121
|
-
}
|
|
122
|
-
wildcard = { name, segmentIndex };
|
|
123
|
-
}
|
|
124
|
-
return wildcard;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export { joinRoutePath, parseTrailingWildcard, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, resolvePropagationContext };
|
package/dist/index-tvwcrx2d.js
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
isUnsafeKey
|
|
3
|
-
} from "./index-wd8g8z6e.js";
|
|
4
|
-
import {
|
|
5
|
-
resolveTraceContext
|
|
6
|
-
} from "./index-pzyt11ch.js";
|
|
7
|
-
import {
|
|
8
|
-
isRecord
|
|
9
|
-
} from "./index-smpbdg6k.js";
|
|
10
|
-
import {
|
|
11
|
-
AppError
|
|
12
|
-
} from "./index-xxye8j3k.js";
|
|
13
|
-
|
|
14
|
-
// src/internal/errors.ts
|
|
15
|
-
import { z } from "zod";
|
|
16
|
-
function issuePath(path) {
|
|
17
|
-
return path.length > 0 ? path.map(String).join(".") : "(root)";
|
|
18
|
-
}
|
|
19
|
-
function formatZodError(error) {
|
|
20
|
-
const issues = error.issues.slice(0, 5);
|
|
21
|
-
const lines = issues.map((issue) => `${issuePath(issue.path)}: ${issue.message}`);
|
|
22
|
-
const suffix = error.issues.length > 5 ? `
|
|
23
|
-
...and ${error.issues.length - 5} more issues` : "";
|
|
24
|
-
return lines.join(`
|
|
25
|
-
`) + suffix;
|
|
26
|
-
}
|
|
27
|
-
function zodIssues(error) {
|
|
28
|
-
return error.issues.map((issue) => ({
|
|
29
|
-
path: issuePath(issue.path),
|
|
30
|
-
code: issue.code,
|
|
31
|
-
message: issue.message
|
|
32
|
-
}));
|
|
33
|
-
}
|
|
34
|
-
var MAX_DETAIL_ISSUES = 20;
|
|
35
|
-
function errorCode(err) {
|
|
36
|
-
if (AppError.is(err))
|
|
37
|
-
return err.code;
|
|
38
|
-
if (err instanceof z.ZodError)
|
|
39
|
-
return "VALIDATION_ERROR";
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
function recordedErrorMessage(code, envelopeMessage, thrown) {
|
|
43
|
-
if ((code === "INTERNAL_SERVER_ERROR" || code === "REALTIME_CONTRACT_VIOLATION") && thrown !== undefined) {
|
|
44
|
-
if (thrown instanceof Error)
|
|
45
|
-
return thrown.message;
|
|
46
|
-
if (typeof thrown === "string")
|
|
47
|
-
return thrown;
|
|
48
|
-
}
|
|
49
|
-
return envelopeMessage;
|
|
50
|
-
}
|
|
51
|
-
function normalizeError(err) {
|
|
52
|
-
if (AppError.is(err)) {
|
|
53
|
-
if (err.code === "REALTIME_CONTRACT_VIOLATION") {
|
|
54
|
-
return new AppError("REALTIME_CONTRACT_VIOLATION", "Realtime contract violation", 500);
|
|
55
|
-
}
|
|
56
|
-
return err;
|
|
57
|
-
}
|
|
58
|
-
if (err instanceof z.ZodError) {
|
|
59
|
-
return new AppError("VALIDATION_ERROR", formatZodError(err), 400, {
|
|
60
|
-
issues: zodIssues(err).slice(0, MAX_DETAIL_ISSUES)
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
console.error("[stitchkit] unhandled error:", err);
|
|
64
|
-
return new AppError("INTERNAL_SERVER_ERROR", "Internal server error", 500);
|
|
65
|
-
}
|
|
66
|
-
function strippedPaths(before, after, prefix) {
|
|
67
|
-
if (Array.isArray(before)) {
|
|
68
|
-
if (!Array.isArray(after))
|
|
69
|
-
return [];
|
|
70
|
-
return before.flatMap((item, i) => strippedPaths(item, after[i], `${prefix}[${i}]`));
|
|
71
|
-
}
|
|
72
|
-
if (!isRecord(before) || !isRecord(after))
|
|
73
|
-
return [];
|
|
74
|
-
const paths = [];
|
|
75
|
-
for (const [key, value] of Object.entries(before)) {
|
|
76
|
-
const path = prefix ? `${prefix}.${key}` : key;
|
|
77
|
-
if (!(key in after)) {
|
|
78
|
-
paths.push(path);
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
paths.push(...strippedPaths(value, after[key], path));
|
|
82
|
-
}
|
|
83
|
-
return paths;
|
|
84
|
-
}
|
|
85
|
-
function validateHandlerOutput(schema, data, onStripped) {
|
|
86
|
-
const parsed = schema.safeParse(data);
|
|
87
|
-
if (parsed.success) {
|
|
88
|
-
if (onStripped) {
|
|
89
|
-
const paths = strippedPaths(data, parsed.data, "");
|
|
90
|
-
if (paths.length > 0)
|
|
91
|
-
onStripped(paths);
|
|
92
|
-
}
|
|
93
|
-
return { ok: true, data: parsed.data };
|
|
94
|
-
}
|
|
95
|
-
return {
|
|
96
|
-
ok: false,
|
|
97
|
-
message: `Handler output does not match the contract: ${formatZodError(parsed.error)}`
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function validateDeclaredOutput(schema, data, onStripped) {
|
|
101
|
-
if (!schema) {
|
|
102
|
-
if (data === undefined || data === null)
|
|
103
|
-
return { ok: true, data };
|
|
104
|
-
return {
|
|
105
|
-
ok: false,
|
|
106
|
-
message: "Handler returned data but the contract declares no output"
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
if (data === undefined) {
|
|
110
|
-
return {
|
|
111
|
-
ok: false,
|
|
112
|
-
message: "Handler returned undefined but the contract declares an output"
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
return validateHandlerOutput(schema, data, onStripped);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// src/server/request.ts
|
|
119
|
-
function generateTraceId() {
|
|
120
|
-
return `${Date.now().toString(36)}-${crypto.randomUUID().slice(0, 8)}`;
|
|
121
|
-
}
|
|
122
|
-
function resolveTraceId(req) {
|
|
123
|
-
const header = req.headers.get("x-request-id") ?? req.headers.get("x-trace-id");
|
|
124
|
-
const trimmed = header?.trim();
|
|
125
|
-
if (trimmed && trimmed.length <= 128 && /^[\w.-]+$/.test(trimmed)) {
|
|
126
|
-
return trimmed;
|
|
127
|
-
}
|
|
128
|
-
return generateTraceId();
|
|
129
|
-
}
|
|
130
|
-
function resolveSocketIp(req, server) {
|
|
131
|
-
if (typeof server === "object" && server !== null && "requestIP" in server && typeof server.requestIP === "function") {
|
|
132
|
-
const addr = server.requestIP(req);
|
|
133
|
-
if (isRecord(addr) && typeof addr.address === "string" && addr.address) {
|
|
134
|
-
return addr.address;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if ("ip" in req && typeof req.ip === "string" && req.ip)
|
|
138
|
-
return req.ip;
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
function extractIp(req, options = {}) {
|
|
142
|
-
if (options.trustProxy) {
|
|
143
|
-
const forwarded = req.headers.get("x-forwarded-for");
|
|
144
|
-
if (forwarded)
|
|
145
|
-
return (forwarded.split(",")[0] ?? "").trim().replace(/^::ffff:/, "");
|
|
146
|
-
const realIp = req.headers.get("x-real-ip");
|
|
147
|
-
if (realIp)
|
|
148
|
-
return realIp.trim().replace(/^::ffff:/, "");
|
|
149
|
-
}
|
|
150
|
-
return (options.socketIp ?? "").replace(/^::ffff:/, "");
|
|
151
|
-
}
|
|
152
|
-
function getClientInfo(req, options = {}) {
|
|
153
|
-
return {
|
|
154
|
-
ipAddress: extractIp(req, options) || undefined,
|
|
155
|
-
userAgent: req.headers.get("user-agent") ?? undefined
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function parseQueryParams(url) {
|
|
159
|
-
const query = {};
|
|
160
|
-
for (const key of new Set(url.searchParams.keys())) {
|
|
161
|
-
if (isUnsafeKey(key))
|
|
162
|
-
continue;
|
|
163
|
-
const values = url.searchParams.getAll(key);
|
|
164
|
-
const [first] = values;
|
|
165
|
-
query[key] = values.length === 1 && first !== undefined ? first : values;
|
|
166
|
-
}
|
|
167
|
-
return query;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// src/observability/context.ts
|
|
171
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
172
|
-
var storage = new AsyncLocalStorage;
|
|
173
|
-
function runWithRequestContext(ctx, fn) {
|
|
174
|
-
return storage.run(ctx, fn);
|
|
175
|
-
}
|
|
176
|
-
function getRequestContext() {
|
|
177
|
-
return storage.getStore();
|
|
178
|
-
}
|
|
179
|
-
function getTraceId() {
|
|
180
|
-
return storage.getStore()?.trace.traceId;
|
|
181
|
-
}
|
|
182
|
-
function getUserId() {
|
|
183
|
-
return storage.getStore()?.userId;
|
|
184
|
-
}
|
|
185
|
-
function setRequestUser(userId) {
|
|
186
|
-
const ctx = storage.getStore();
|
|
187
|
-
if (ctx)
|
|
188
|
-
ctx.userId = userId;
|
|
189
|
-
}
|
|
190
|
-
function setRequestEndpoint(serviceName, action) {
|
|
191
|
-
const ctx = storage.getStore();
|
|
192
|
-
if (ctx) {
|
|
193
|
-
ctx.serviceName = serviceName;
|
|
194
|
-
ctx.action = action;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
function setRequestDimensions(dimensions) {
|
|
198
|
-
const ctx = storage.getStore();
|
|
199
|
-
if (ctx)
|
|
200
|
-
ctx.dimensions = { ...ctx.dimensions, ...dimensions };
|
|
201
|
-
}
|
|
202
|
-
function setRequestError(error) {
|
|
203
|
-
const ctx = storage.getStore();
|
|
204
|
-
if (ctx)
|
|
205
|
-
ctx.error = error;
|
|
206
|
-
}
|
|
207
|
-
function wrapInRequestContext(handler, options = {}) {
|
|
208
|
-
return (req, server) => {
|
|
209
|
-
const ctx = {
|
|
210
|
-
trace: resolveTraceContext(req),
|
|
211
|
-
source: "http",
|
|
212
|
-
method: req.method,
|
|
213
|
-
path: new URL(req.url, "http://localhost").pathname,
|
|
214
|
-
startedAt: process.hrtime.bigint(),
|
|
215
|
-
...getClientInfo(req, {
|
|
216
|
-
trustProxy: options.trustProxy,
|
|
217
|
-
socketIp: resolveSocketIp(req, server)
|
|
218
|
-
})
|
|
219
|
-
};
|
|
220
|
-
return runWithRequestContext(ctx, () => handler(req, server));
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export { formatZodError, zodIssues, errorCode, recordedErrorMessage, normalizeError, validateDeclaredOutput, generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams, runWithRequestContext, getRequestContext, getTraceId, getUserId, setRequestUser, setRequestEndpoint, setRequestDimensions, setRequestError, wrapInRequestContext };
|
package/dist/index-wd8g8z6e.js
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseTrailingWildcard
|
|
3
|
-
} from "./index-pzyt11ch.js";
|
|
4
|
-
|
|
5
|
-
// src/contract/define.ts
|
|
6
|
-
import { z } from "zod";
|
|
7
|
-
|
|
8
|
-
// src/internal/safe-json.ts
|
|
9
|
-
function isUnsafeKey(key) {
|
|
10
|
-
return key === "__proto__";
|
|
11
|
-
}
|
|
12
|
-
function safeJsonParse(text) {
|
|
13
|
-
return JSON.parse(text, (key, value) => isUnsafeKey(key) ? undefined : value);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// src/contract/define.ts
|
|
17
|
-
function defineContract(meta, endpoints) {
|
|
18
|
-
const toolTransports = new Map;
|
|
19
|
-
for (const [key, ep] of Object.entries(endpoints)) {
|
|
20
|
-
const wildcard = parseTrailingWildcard(ep.path);
|
|
21
|
-
if (wildcard) {
|
|
22
|
-
if (!ep.params) {
|
|
23
|
-
throw new Error(`Contract "${meta.prefix}": endpoint "${key}" wildcard "${wildcard.name}" requires a params schema field`);
|
|
24
|
-
}
|
|
25
|
-
const paramsJson = z.toJSONSchema(ep.params, { io: "input" });
|
|
26
|
-
if (!paramsJson.properties || !(wildcard.name in paramsJson.properties)) {
|
|
27
|
-
throw new Error(`Contract "${meta.prefix}": endpoint "${key}" params schema is missing wildcard field "${wildcard.name}"`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
if (ep.desc.trim() === "") {
|
|
31
|
-
throw new Error(`Contract "${meta.prefix}": endpoint "${key}" has an empty desc`);
|
|
32
|
-
}
|
|
33
|
-
if (ep.maxJsonBodyBytes !== undefined && (!Number.isSafeInteger(ep.maxJsonBodyBytes) || ep.maxJsonBodyBytes <= 0)) {
|
|
34
|
-
throw new Error(`Contract "${meta.prefix}": endpoint "${key}" maxJsonBodyBytes must be a positive safe integer, received ${ep.maxJsonBodyBytes}`);
|
|
35
|
-
}
|
|
36
|
-
if (ep.multipart)
|
|
37
|
-
assertMultipartEndpoint(meta.prefix, key, ep);
|
|
38
|
-
if (ep.rawResponse)
|
|
39
|
-
assertRawEndpoint(meta.prefix, key, ep);
|
|
40
|
-
if (ep.method === "HEAD")
|
|
41
|
-
assertHeadEndpoint(meta.prefix, key, ep);
|
|
42
|
-
if (ep.rawBody)
|
|
43
|
-
assertRawBodyEndpoint(meta.prefix, key, ep);
|
|
44
|
-
if ("responseMeta" in ep)
|
|
45
|
-
assertResponseMetaEndpoint(meta.prefix, key, ep);
|
|
46
|
-
if (!("toolName" in ep) || !ep.toolName)
|
|
47
|
-
continue;
|
|
48
|
-
const transports = new Set(ep.expose ? ep.expose.filter((t) => t !== "HTTP") : ["MCP", "AGENT"]);
|
|
49
|
-
if (transports.size === 0) {
|
|
50
|
-
throw new Error(`Contract "${meta.prefix}": endpoint "${key}" sets toolName "${ep.toolName}" but is not exposed on any tool transport (MCP / AGENT)`);
|
|
51
|
-
}
|
|
52
|
-
const existing = toolTransports.get(ep.toolName);
|
|
53
|
-
if (existing) {
|
|
54
|
-
for (const t of transports) {
|
|
55
|
-
if (existing.transports.has(t)) {
|
|
56
|
-
throw new Error(`Contract "${meta.prefix}": duplicate toolName "${ep.toolName}" on transport "${t}" (endpoints: "${existing.key}" and "${key}")`);
|
|
57
|
-
}
|
|
58
|
-
existing.transports.add(t);
|
|
59
|
-
}
|
|
60
|
-
} else {
|
|
61
|
-
toolTransports.set(ep.toolName, { key, transports });
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return { meta, endpoints };
|
|
65
|
-
}
|
|
66
|
-
function assertPositiveLimit(where, name, value) {
|
|
67
|
-
if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {
|
|
68
|
-
throw new Error(`${where} ${name} must be a positive safe integer, received ${value}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function assertMultipartEndpoint(prefix, key, ep) {
|
|
72
|
-
const where = `Contract "${prefix}": multipart endpoint "${key}"`;
|
|
73
|
-
if (ep.method !== "POST" && ep.method !== "PUT" && ep.method !== "PATCH") {
|
|
74
|
-
throw new Error(`${where} must use POST, PUT or PATCH`);
|
|
75
|
-
}
|
|
76
|
-
const multipart = ep.multipart;
|
|
77
|
-
if (!multipart || typeof multipart !== "object") {
|
|
78
|
-
throw new Error(`${where} must declare a multipart descriptor`);
|
|
79
|
-
}
|
|
80
|
-
assertPositiveLimit(where, "maxRequestBytes", multipart.maxRequestBytes);
|
|
81
|
-
assertPositiveLimit(where, "maxFieldBytes", multipart.maxFieldBytes);
|
|
82
|
-
const entries = Object.entries(multipart.files);
|
|
83
|
-
if (entries.length === 0)
|
|
84
|
-
throw new Error(`${where} must declare at least one file field`);
|
|
85
|
-
for (const [field, policy] of entries) {
|
|
86
|
-
if (!field || isUnsafeKey(field))
|
|
87
|
-
throw new Error(`${where} has an invalid file field name`);
|
|
88
|
-
assertPositiveLimit(`${where} field "${field}"`, "maxBytes", policy.maxBytes);
|
|
89
|
-
assertPositiveLimit(`${where} field "${field}"`, "maxFiles", policy.maxFiles);
|
|
90
|
-
if (policy.multiple !== true && policy.maxFiles !== undefined) {
|
|
91
|
-
throw new Error(`${where} field "${field}" may set maxFiles only with multiple: true`);
|
|
92
|
-
}
|
|
93
|
-
if (policy.contentTypes) {
|
|
94
|
-
if (policy.contentTypes.length === 0) {
|
|
95
|
-
throw new Error(`${where} field "${field}" contentTypes cannot be empty`);
|
|
96
|
-
}
|
|
97
|
-
for (const contentType of policy.contentTypes) {
|
|
98
|
-
if (!/^[a-z0-9!#$&^_.+-]+\/(?:[a-z0-9!#$&^_.+-]+|\*)$/i.test(contentType)) {
|
|
99
|
-
throw new Error(`${where} field "${field}" has invalid content type policy "${contentType}"`);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
function assertRawEndpoint(prefix, key, ep) {
|
|
106
|
-
const where = `Contract "${prefix}": raw endpoint "${key}"`;
|
|
107
|
-
if (ep.output)
|
|
108
|
-
throw new Error(`${where} cannot declare an output schema`);
|
|
109
|
-
if ("toolName" in ep && ep.toolName)
|
|
110
|
-
throw new Error(`${where} cannot set a toolName`);
|
|
111
|
-
if ("ui" in ep && ep.ui)
|
|
112
|
-
throw new Error(`${where} cannot set MCP ui metadata`);
|
|
113
|
-
if ("annotations" in ep && ep.annotations) {
|
|
114
|
-
throw new Error(`${where} cannot set MCP annotations`);
|
|
115
|
-
}
|
|
116
|
-
const nonHttp = (ep.expose ?? []).filter((t) => t !== "HTTP");
|
|
117
|
-
if (nonHttp.length > 0) {
|
|
118
|
-
throw new Error(`${where} is HTTP-only — remove ${nonHttp.join(", ")} from expose`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
function assertHeadEndpoint(prefix, key, ep) {
|
|
122
|
-
const where = `Contract "${prefix}": HEAD endpoint "${key}"`;
|
|
123
|
-
if (!ep.rawResponse)
|
|
124
|
-
throw new Error(`${where} must declare rawResponse: true`);
|
|
125
|
-
if (ep.input)
|
|
126
|
-
throw new Error(`${where} cannot declare an input schema`);
|
|
127
|
-
if (ep.multipart)
|
|
128
|
-
throw new Error(`${where} cannot be multipart`);
|
|
129
|
-
if (ep.rawBody)
|
|
130
|
-
throw new Error(`${where} cannot retain a raw body`);
|
|
131
|
-
}
|
|
132
|
-
function assertRawBodyEndpoint(prefix, key, ep) {
|
|
133
|
-
const where = `Contract "${prefix}": rawBody endpoint "${key}"`;
|
|
134
|
-
if (!ep.input)
|
|
135
|
-
throw new Error(`${where} must declare an input schema`);
|
|
136
|
-
if (ep.multipart)
|
|
137
|
-
throw new Error(`${where} cannot be multipart`);
|
|
138
|
-
if (ep.method !== "POST" && ep.method !== "PUT" && ep.method !== "PATCH") {
|
|
139
|
-
throw new Error(`${where} must use POST, PUT or PATCH`);
|
|
140
|
-
}
|
|
141
|
-
if ("toolName" in ep && ep.toolName)
|
|
142
|
-
throw new Error(`${where} cannot set a toolName`);
|
|
143
|
-
if ("ui" in ep && ep.ui)
|
|
144
|
-
throw new Error(`${where} cannot set MCP ui metadata`);
|
|
145
|
-
if ("annotations" in ep && ep.annotations) {
|
|
146
|
-
throw new Error(`${where} cannot set MCP annotations`);
|
|
147
|
-
}
|
|
148
|
-
const nonHttp = (ep.expose ?? []).filter((transport) => transport !== "HTTP");
|
|
149
|
-
if (nonHttp.length > 0) {
|
|
150
|
-
throw new Error(`${where} is HTTP-only — remove ${nonHttp.join(", ")} from expose`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
function assertResponseMetaEndpoint(prefix, key, ep) {
|
|
154
|
-
const where = `Contract "${prefix}": responseMeta endpoint "${key}"`;
|
|
155
|
-
if (!ep.responseMeta || typeof ep.responseMeta !== "object") {
|
|
156
|
-
throw new Error(`${where} must declare responseMeta as an object`);
|
|
157
|
-
}
|
|
158
|
-
const status = ep.responseMeta.status;
|
|
159
|
-
if (status !== undefined && (!Number.isSafeInteger(status) || status < 200 || status > 299)) {
|
|
160
|
-
throw new Error(`${where} status must be a successful 2xx integer, received ${status}`);
|
|
161
|
-
}
|
|
162
|
-
if (ep.output && (status === 204 || status === 205)) {
|
|
163
|
-
throw new Error(`${where} cannot combine output with bodyless status ${status}`);
|
|
164
|
-
}
|
|
165
|
-
if (ep.rawResponse)
|
|
166
|
-
throw new Error(`${where} cannot also be a rawResponse endpoint`);
|
|
167
|
-
if ("toolName" in ep && ep.toolName)
|
|
168
|
-
throw new Error(`${where} cannot set a toolName`);
|
|
169
|
-
if ("ui" in ep && ep.ui)
|
|
170
|
-
throw new Error(`${where} cannot set MCP ui metadata`);
|
|
171
|
-
if ("annotations" in ep && ep.annotations) {
|
|
172
|
-
throw new Error(`${where} cannot set MCP annotations`);
|
|
173
|
-
}
|
|
174
|
-
const nonHttp = (ep.expose ?? []).filter((transport) => transport !== "HTTP");
|
|
175
|
-
if (nonHttp.length > 0) {
|
|
176
|
-
throw new Error(`${where} is HTTP-only — remove ${nonHttp.join(", ")} from expose`);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
function mergeMeta(contractMeta, endpointMeta) {
|
|
180
|
-
if (!contractMeta)
|
|
181
|
-
return endpointMeta;
|
|
182
|
-
if (!endpointMeta)
|
|
183
|
-
return { ...contractMeta };
|
|
184
|
-
return { ...contractMeta, ...endpointMeta };
|
|
185
|
-
}
|
|
186
|
-
// src/contract/errors-factory.ts
|
|
187
|
-
import { z as z2 } from "zod";
|
|
188
|
-
// src/contract/pagination.ts
|
|
189
|
-
import { z as z3 } from "zod";
|
|
190
|
-
|
|
191
|
-
// src/internal/base64url.ts
|
|
192
|
-
function bytesToBase64Url(bytes) {
|
|
193
|
-
let binary = "";
|
|
194
|
-
for (const byte of bytes)
|
|
195
|
-
binary += String.fromCharCode(byte);
|
|
196
|
-
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
197
|
-
}
|
|
198
|
-
function base64UrlToBytes(segment) {
|
|
199
|
-
if (!/^[A-Za-z0-9_-]*$/.test(segment) || segment.length % 4 === 1) {
|
|
200
|
-
throw new Error("invalid base64url segment");
|
|
201
|
-
}
|
|
202
|
-
const b64 = segment.replace(/-/g, "+").replace(/_/g, "/");
|
|
203
|
-
const padded = b64.padEnd(Math.ceil(b64.length / 4) * 4, "=");
|
|
204
|
-
return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
|
|
205
|
-
}
|
|
206
|
-
export { isUnsafeKey, safeJsonParse, defineContract, mergeMeta, bytesToBase64Url, base64UrlToBytes };
|