stitchkit 0.80.1 → 0.82.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/CHANGELOG.md +6552 -0
- package/README.md +4 -0
- package/dist/agent-runtime/provider-failure.d.ts.map +1 -1
- package/dist/agent-runtime-coding-tools.js +1 -1
- package/dist/agent-runtime-harness.js +7 -5
- package/dist/agent-runtime.js +15 -19
- package/dist/application/notification-outbox.d.ts +80 -0
- package/dist/application/notification-outbox.d.ts.map +1 -0
- package/dist/application/process-lifecycle.d.ts +166 -0
- package/dist/application/process-lifecycle.d.ts.map +1 -0
- package/dist/application/state-store.d.ts +18 -0
- package/dist/application/state-store.d.ts.map +1 -0
- package/dist/application.d.ts +3 -0
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +568 -11
- package/dist/browser/http.d.ts +14 -0
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/resumable.d.ts +6 -0
- package/dist/browser/resumable.d.ts.map +1 -1
- package/dist/cli.js +9 -7
- package/dist/contract/define.d.ts +27 -4
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/errors-factory.d.ts +22 -3
- package/dist/contract/errors-factory.d.ts.map +1 -1
- package/dist/contract/index.d.ts +2 -2
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +1 -1
- package/dist/geo/index.d.ts +4 -0
- package/dist/geo/index.d.ts.map +1 -0
- package/dist/geo/maxmind.d.ts +4 -0
- package/dist/geo/maxmind.d.ts.map +1 -0
- package/dist/geo/resolver.d.ts +9 -0
- package/dist/geo/resolver.d.ts.map +1 -0
- package/dist/geo/types.d.ts +59 -0
- package/dist/geo/types.d.ts.map +1 -0
- package/dist/geo.d.ts +3 -0
- package/dist/geo.d.ts.map +1 -0
- package/dist/geo.js +245 -0
- package/dist/{index-9s6z8vgf.js → index-1dd82z59.js} +1 -1
- package/dist/{index-vwp69871.js → index-27487ay5.js} +4 -4
- package/dist/{index-7ag81v2f.js → index-27gm3d6g.js} +10 -321
- package/dist/{index-y01f4223.js → index-2bxcmqkb.js} +127 -43
- package/dist/{index-dxesg10d.js → index-3ds42w1w.js} +3 -3
- package/dist/index-3xwxfj4z.js +334 -0
- package/dist/{index-egaabxkz.js → index-5z8tezpx.js} +2 -2
- package/dist/{index-fxz0v7vg.js → index-7evdsyez.js} +1 -83
- package/dist/{index-xcetq6j3.js → index-90d7h2cr.js} +32 -13
- package/dist/{index-t0z5p5w6.js → index-apn8repm.js} +1 -1
- package/dist/{index-758zx2ha.js → index-dggwnnjv.js} +2 -2
- package/dist/{index-dwf1f2ap.js → index-f9mb610r.js} +1 -62
- package/dist/{index-5mtc969c.js → index-fwbkp2jn.js} +1 -1
- package/dist/index-p13mwz16.js +16 -0
- package/dist/{index-m9kzax52.js → index-p18f59zy.js} +21 -5
- package/dist/{index-hb5pf3s4.js → index-qmgs7y68.js} +1 -1
- package/dist/{index-2rwwmr7v.js → index-s4ckmrac.js} +1 -1
- package/dist/{index-h4pj6fta.js → index-s8cnx02s.js} +8 -5
- package/dist/{index-k9ay6v6d.js → index-vchzar7e.js} +74 -23
- package/dist/index-vsbzgd7b.js +84 -0
- package/dist/{index-dxjjv399.js → index-xbppf54a.js} +95 -15
- package/dist/index-y91ry9h2.js +4 -0
- package/dist/index-zcgf3gqf.js +83 -0
- package/dist/index.js +17 -13
- package/dist/internal/error-message.d.ts +3 -0
- package/dist/internal/error-message.d.ts.map +1 -0
- package/dist/internal/media-type.d.ts +8 -0
- package/dist/internal/media-type.d.ts.map +1 -0
- package/dist/internal/route-pattern.d.ts +21 -0
- package/dist/internal/route-pattern.d.ts.map +1 -1
- package/dist/internal/upgrade-plan.d.ts +18 -0
- package/dist/internal/upgrade-plan.d.ts.map +1 -0
- package/dist/node.js +9 -6
- package/dist/observability/audit.d.ts +28 -1
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/bounded-logger.d.ts +20 -0
- package/dist/observability/bounded-logger.d.ts.map +1 -0
- package/dist/observability/context.d.ts +12 -3
- package/dist/observability/context.d.ts.map +1 -1
- package/dist/observability/index.d.ts +3 -2
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +138 -8
- package/dist/observability/sanitize.d.ts +17 -0
- package/dist/observability/sanitize.d.ts.map +1 -1
- package/dist/primitives.js +1 -1
- package/dist/react/query-client.d.ts +33 -0
- package/dist/react/query-client.d.ts.map +1 -0
- package/dist/react.d.ts +1 -0
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +83 -1
- package/dist/realtime/registry.d.ts +93 -0
- package/dist/realtime/registry.d.ts.map +1 -0
- package/dist/release/header.d.ts +9 -0
- package/dist/release/header.d.ts.map +1 -0
- package/dist/release/marker.d.ts +39 -0
- package/dist/release/marker.d.ts.map +1 -0
- package/dist/release/socket.d.ts +57 -0
- package/dist/release/socket.d.ts.map +1 -0
- package/dist/release/watcher.d.ts +66 -0
- package/dist/release/watcher.d.ts.map +1 -0
- package/dist/release.d.ts +15 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +196 -0
- package/dist/remote.js +12 -7
- package/dist/server/context.d.ts +2 -1
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/error-hook.d.ts +17 -16
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/file-state-store.d.ts +23 -0
- package/dist/server/file-state-store.d.ts.map +1 -0
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +469 -11
- package/dist/server/middleware/cookies.d.ts +33 -1
- package/dist/server/middleware/cookies.d.ts.map +1 -1
- package/dist/server/middleware/cors.d.ts +16 -1
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/release-signal.d.ts +35 -0
- package/dist/server/release-signal.d.ts.map +1 -0
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/types.d.ts +26 -2
- package/dist/server/types.d.ts.map +1 -1
- package/dist/testing/surface-manifest.d.ts.map +1 -1
- package/dist/testing.js +7 -4
- package/dist/tool-invoker.js +8 -6
- package/dist/tools/download-core.d.ts.map +1 -1
- package/dist/tools/remote.d.ts.map +1 -1
- package/dist/tools/view-file.d.ts.map +1 -1
- package/dist/tools.js +20 -16
- package/dist/tracking/attribution.d.ts +51 -0
- package/dist/tracking/attribution.d.ts.map +1 -0
- package/dist/tracking/beacon.d.ts +14 -0
- package/dist/tracking/beacon.d.ts.map +1 -0
- package/dist/tracking/clicks.d.ts +46 -0
- package/dist/tracking/clicks.d.ts.map +1 -0
- package/dist/tracking/client.d.ts +121 -0
- package/dist/tracking/client.d.ts.map +1 -0
- package/dist/tracking/contract.d.ts +57 -0
- package/dist/tracking/contract.d.ts.map +1 -0
- package/dist/tracking/delivery.d.ts +24 -0
- package/dist/tracking/delivery.d.ts.map +1 -0
- package/dist/tracking/host.d.ts +43 -0
- package/dist/tracking/host.d.ts.map +1 -0
- package/dist/tracking/once-per-page.d.ts +17 -0
- package/dist/tracking/once-per-page.d.ts.map +1 -0
- package/dist/tracking/outbox-storage-indexeddb.d.ts +12 -0
- package/dist/tracking/outbox-storage-indexeddb.d.ts.map +1 -0
- package/dist/tracking/outbox-storage-memory.d.ts +12 -0
- package/dist/tracking/outbox-storage-memory.d.ts.map +1 -0
- package/dist/tracking/outbox.d.ts +98 -0
- package/dist/tracking/outbox.d.ts.map +1 -0
- package/dist/tracking/schemas.d.ts +183 -0
- package/dist/tracking/schemas.d.ts.map +1 -0
- package/dist/tracking/scroll.d.ts +22 -0
- package/dist/tracking/scroll.d.ts.map +1 -0
- package/dist/tracking/sequence-reserve.d.ts +34 -0
- package/dist/tracking/sequence-reserve.d.ts.map +1 -0
- package/dist/tracking/server/active-interval.d.ts +26 -0
- package/dist/tracking/server/active-interval.d.ts.map +1 -0
- package/dist/tracking/server/bot.d.ts +9 -0
- package/dist/tracking/server/bot.d.ts.map +1 -0
- package/dist/tracking/server/disposition.d.ts +55 -0
- package/dist/tracking/server/disposition.d.ts.map +1 -0
- package/dist/tracking/server/hash.d.ts +13 -0
- package/dist/tracking/server/hash.d.ts.map +1 -0
- package/dist/tracking/server/presence.d.ts +27 -0
- package/dist/tracking/server/presence.d.ts.map +1 -0
- package/dist/tracking/server/visit-lease.d.ts +92 -0
- package/dist/tracking/server/visit-lease.d.ts.map +1 -0
- package/dist/tracking/visible-time.d.ts +38 -0
- package/dist/tracking/visible-time.d.ts.map +1 -0
- package/dist/tracking-server.d.ts +15 -0
- package/dist/tracking-server.d.ts.map +1 -0
- package/dist/tracking-server.js +173 -0
- package/dist/tracking.d.ts +24 -0
- package/dist/tracking.d.ts.map +1 -0
- package/dist/tracking.js +1091 -0
- package/dist/upgrade-cli.d.ts +27 -0
- package/dist/upgrade-cli.d.ts.map +1 -0
- package/dist/upgrade-cli.js +177 -0
- package/llms-full.txt +1001 -29
- package/llms.txt +4 -0
- package/package.json +30 -5
|
@@ -5,88 +5,6 @@ import {
|
|
|
5
5
|
isRecord
|
|
6
6
|
} from "./index-77fekveh.js";
|
|
7
7
|
|
|
8
|
-
// src/internal/random-hex.ts
|
|
9
|
-
function randomHex(bytes) {
|
|
10
|
-
const arr = new Uint8Array(bytes);
|
|
11
|
-
crypto.getRandomValues(arr);
|
|
12
|
-
let hex = "";
|
|
13
|
-
for (const byte of arr)
|
|
14
|
-
hex += byte.toString(16).padStart(2, "0");
|
|
15
|
-
return hex;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// src/observability/trace.ts
|
|
19
|
-
var TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(.*)$/i;
|
|
20
|
-
function createTraceContext() {
|
|
21
|
-
return { traceId: randomHex(16), spanId: randomHex(8) };
|
|
22
|
-
}
|
|
23
|
-
function parseTraceparent(header) {
|
|
24
|
-
if (!header)
|
|
25
|
-
return null;
|
|
26
|
-
const match = TRACEPARENT_RE.exec(header.trim());
|
|
27
|
-
if (!match?.[1] || !match[2] || !match[3] || !match[4] || match[5] === undefined)
|
|
28
|
-
return null;
|
|
29
|
-
const version = match[1].toLowerCase();
|
|
30
|
-
if (version === "ff")
|
|
31
|
-
return null;
|
|
32
|
-
const suffix = match[5];
|
|
33
|
-
if (version === "00" ? suffix !== "" : suffix !== "" && !/^(?:-[0-9a-f]{2,})+$/i.test(suffix)) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
const traceId = match[2].toLowerCase();
|
|
37
|
-
const parentSpanId = match[3].toLowerCase();
|
|
38
|
-
const traceFlags = match[4].toLowerCase();
|
|
39
|
-
if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
|
|
40
|
-
return null;
|
|
41
|
-
return { traceId, spanId: randomHex(8), parentSpanId, traceFlags };
|
|
42
|
-
}
|
|
43
|
-
function formatTraceparent(ctx) {
|
|
44
|
-
return `00-${ctx.traceId}-${ctx.spanId}-${ctx.traceFlags ?? "01"}`;
|
|
45
|
-
}
|
|
46
|
-
function resolveTraceContext(req) {
|
|
47
|
-
return parseTraceparent(req.headers.get("traceparent")) ?? createTraceContext();
|
|
48
|
-
}
|
|
49
|
-
function childSpan(parent) {
|
|
50
|
-
return {
|
|
51
|
-
traceId: parent.traceId,
|
|
52
|
-
spanId: randomHex(8),
|
|
53
|
-
parentSpanId: parent.spanId,
|
|
54
|
-
...parent.tracestate !== undefined && { tracestate: parent.tracestate },
|
|
55
|
-
...parent.baggage !== undefined && { baggage: parent.baggage },
|
|
56
|
-
...parent.traceFlags !== undefined && { traceFlags: parent.traceFlags }
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
var encoder = new TextEncoder;
|
|
60
|
-
function boundedPropagationValue(value, maxBytes, maxMembers) {
|
|
61
|
-
if (typeof value !== "string")
|
|
62
|
-
return;
|
|
63
|
-
const trimmed = value.trim();
|
|
64
|
-
if (!trimmed || encoder.encode(trimmed).byteLength > maxBytes)
|
|
65
|
-
return;
|
|
66
|
-
for (const character of trimmed) {
|
|
67
|
-
const code = character.charCodeAt(0);
|
|
68
|
-
if (code <= 31 || code === 127)
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const members = trimmed.split(",");
|
|
72
|
-
if (members.length > maxMembers || members.some((member) => !member.trim())) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
return trimmed;
|
|
76
|
-
}
|
|
77
|
-
function resolvePropagationContext(metadata, fallback) {
|
|
78
|
-
const traceparent = metadata?.traceparent;
|
|
79
|
-
const parsed = typeof traceparent === "string" ? parseTraceparent(traceparent) : null;
|
|
80
|
-
const trace = traceparent === undefined ? fallback ?? createTraceContext() : parsed ?? createTraceContext();
|
|
81
|
-
const tracestate = parsed ? boundedPropagationValue(metadata?.tracestate, 512, 32) : undefined;
|
|
82
|
-
const baggage = boundedPropagationValue(metadata?.baggage, 8192, 180);
|
|
83
|
-
return {
|
|
84
|
-
...trace,
|
|
85
|
-
...tracestate !== undefined && { tracestate },
|
|
86
|
-
...baggage !== undefined && { baggage }
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
|
|
90
8
|
// src/internal/errors.ts
|
|
91
9
|
import { z } from "zod";
|
|
92
10
|
function issuePath(path) {
|
|
@@ -191,4 +109,4 @@ function validateDeclaredOutput(schema, data, onStripped) {
|
|
|
191
109
|
return validateHandlerOutput(schema, data, onStripped);
|
|
192
110
|
}
|
|
193
111
|
|
|
194
|
-
export {
|
|
112
|
+
export { formatZodError, zodIssues, errorCode, recordedErrorMessage, normalizeError, validateDeclaredOutput };
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
contextContributionDelta,
|
|
3
3
|
mergeContextContribution,
|
|
4
4
|
prepareContextContribution
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-p18f59zy.js";
|
|
6
6
|
import {
|
|
7
7
|
base64UrlToBytes,
|
|
8
8
|
bytesToBase64Url
|
|
9
|
-
} from "./index-
|
|
9
|
+
} from "./index-2bxcmqkb.js";
|
|
10
10
|
import {
|
|
11
11
|
forbidden,
|
|
12
12
|
unauthorized
|
|
@@ -20,23 +20,32 @@ import {
|
|
|
20
20
|
} from "./index-77fekveh.js";
|
|
21
21
|
|
|
22
22
|
// src/server/middleware/cookies.ts
|
|
23
|
-
function
|
|
23
|
+
function parseCookieHeader(header) {
|
|
24
24
|
if (!header)
|
|
25
|
-
return
|
|
26
|
-
const
|
|
25
|
+
return [];
|
|
26
|
+
const pairs = [];
|
|
27
27
|
for (const pair of header.split(";")) {
|
|
28
28
|
const eq = pair.indexOf("=");
|
|
29
29
|
if (eq === -1)
|
|
30
30
|
continue;
|
|
31
31
|
const key = pair.slice(0, eq).trim();
|
|
32
|
-
if (!key
|
|
32
|
+
if (!key)
|
|
33
33
|
continue;
|
|
34
34
|
const raw = pair.slice(eq + 1).trim();
|
|
35
|
+
let value = raw;
|
|
35
36
|
try {
|
|
36
|
-
|
|
37
|
-
} catch {
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
value = decodeURIComponent(raw);
|
|
38
|
+
} catch {}
|
|
39
|
+
pairs.push([key, value]);
|
|
40
|
+
}
|
|
41
|
+
return pairs;
|
|
42
|
+
}
|
|
43
|
+
function parseCookies(header) {
|
|
44
|
+
const cookies = {};
|
|
45
|
+
for (const [key, value] of parseCookieHeader(header)) {
|
|
46
|
+
if (isUnsafeKey(key))
|
|
47
|
+
continue;
|
|
48
|
+
cookies[key] = value;
|
|
40
49
|
}
|
|
41
50
|
return cookies;
|
|
42
51
|
}
|
|
@@ -57,11 +66,21 @@ function serializeCookie(name, value, opts = {}) {
|
|
|
57
66
|
return cookie;
|
|
58
67
|
}
|
|
59
68
|
function defineCookie(config) {
|
|
60
|
-
const { name, ...options } = config;
|
|
69
|
+
const { name, duplicates = "last", ...options } = config;
|
|
70
|
+
const getAll = (req) => parseCookieHeader(req.headers.get("cookie")).flatMap(([key, value]) => key === name ? [value] : []);
|
|
61
71
|
return {
|
|
62
72
|
get(req) {
|
|
63
|
-
|
|
73
|
+
const values = getAll(req);
|
|
74
|
+
if (values.length === 0)
|
|
75
|
+
return;
|
|
76
|
+
if (duplicates === "first")
|
|
77
|
+
return values[0];
|
|
78
|
+
if (duplicates === "reject") {
|
|
79
|
+
return new Set(values).size === 1 ? values[0] : undefined;
|
|
80
|
+
}
|
|
81
|
+
return values[values.length - 1];
|
|
64
82
|
},
|
|
83
|
+
getAll,
|
|
65
84
|
set(value) {
|
|
66
85
|
return serializeCookie(name, value, options);
|
|
67
86
|
},
|
|
@@ -304,4 +323,4 @@ async function verifyPkce(verifier, challenge) {
|
|
|
304
323
|
return derived === challenge;
|
|
305
324
|
}
|
|
306
325
|
|
|
307
|
-
export { parseCookies, serializeCookie, defineCookie, verifyJwt, signJwt, extractToken, createAuthHook, composeAuthHooks, createBearerResolver, deriveCodeChallenge, verifyPkce };
|
|
326
|
+
export { parseCookieHeader, parseCookies, serializeCookie, defineCookie, verifyJwt, signJwt, extractToken, createAuthHook, composeAuthHooks, createBearerResolver, deriveCodeChallenge, verifyPkce };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getRequestContext,
|
|
3
3
|
runWithRequestContext
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-vsbzgd7b.js";
|
|
5
5
|
import {
|
|
6
6
|
objectShapeKeys
|
|
7
7
|
} from "./index-mgtxfe6b.js";
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
formatZodError,
|
|
13
13
|
normalizeError,
|
|
14
14
|
validateDeclaredOutput
|
|
15
|
-
} from "./index-
|
|
15
|
+
} from "./index-7evdsyez.js";
|
|
16
16
|
import {
|
|
17
17
|
AppError,
|
|
18
18
|
STITCH_ERROR_STATUS,
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
resolveTraceContext
|
|
3
|
-
} from "./index-fxz0v7vg.js";
|
|
4
1
|
import {
|
|
5
2
|
isUnsafeKey
|
|
6
3
|
} from "./index-kzfs85xp.js";
|
|
@@ -177,62 +174,4 @@ function isPublicIp(value) {
|
|
|
177
174
|
return true;
|
|
178
175
|
}
|
|
179
176
|
|
|
180
|
-
|
|
181
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
182
|
-
var storage;
|
|
183
|
-
var requestStorage = () => {
|
|
184
|
-
storage ??= new AsyncLocalStorage;
|
|
185
|
-
return storage;
|
|
186
|
-
};
|
|
187
|
-
function runWithRequestContext(ctx, fn) {
|
|
188
|
-
return requestStorage().run(ctx, fn);
|
|
189
|
-
}
|
|
190
|
-
function getRequestContext() {
|
|
191
|
-
return requestStorage().getStore();
|
|
192
|
-
}
|
|
193
|
-
function getTraceId() {
|
|
194
|
-
return requestStorage().getStore()?.trace.traceId;
|
|
195
|
-
}
|
|
196
|
-
function getUserId() {
|
|
197
|
-
return requestStorage().getStore()?.userId;
|
|
198
|
-
}
|
|
199
|
-
function setRequestUser(userId) {
|
|
200
|
-
const ctx = requestStorage().getStore();
|
|
201
|
-
if (ctx)
|
|
202
|
-
ctx.userId = userId;
|
|
203
|
-
}
|
|
204
|
-
function setRequestEndpoint(serviceName, action) {
|
|
205
|
-
const ctx = requestStorage().getStore();
|
|
206
|
-
if (ctx) {
|
|
207
|
-
ctx.serviceName = serviceName;
|
|
208
|
-
ctx.action = action;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
function setRequestDimensions(dimensions) {
|
|
212
|
-
const ctx = requestStorage().getStore();
|
|
213
|
-
if (ctx)
|
|
214
|
-
ctx.dimensions = { ...ctx.dimensions, ...dimensions };
|
|
215
|
-
}
|
|
216
|
-
function setRequestError(error) {
|
|
217
|
-
const ctx = requestStorage().getStore();
|
|
218
|
-
if (ctx)
|
|
219
|
-
ctx.error = error;
|
|
220
|
-
}
|
|
221
|
-
function wrapInRequestContext(handler, options = {}) {
|
|
222
|
-
return (req, server) => {
|
|
223
|
-
const ctx = {
|
|
224
|
-
trace: resolveTraceContext(req),
|
|
225
|
-
source: "http",
|
|
226
|
-
method: req.method,
|
|
227
|
-
path: new URL(req.url, "http://localhost").pathname,
|
|
228
|
-
startedAt: process.hrtime.bigint(),
|
|
229
|
-
...getClientInfo(req, {
|
|
230
|
-
trustProxy: options.trustProxy,
|
|
231
|
-
socketIp: resolveSocketIp(req, server)
|
|
232
|
-
})
|
|
233
|
-
};
|
|
234
|
-
return runWithRequestContext(ctx, () => handler(req, server));
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export { generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams, isPublicIp, runWithRequestContext, getRequestContext, getTraceId, getUserId, setRequestUser, setRequestEndpoint, setRequestDimensions, setRequestError, wrapInRequestContext };
|
|
177
|
+
export { generateTraceId, resolveTraceId, resolveSocketIp, extractIp, getClientInfo, parseQueryParams, isPublicIp };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isRecord
|
|
3
|
+
} from "./index-77fekveh.js";
|
|
4
|
+
|
|
5
|
+
// src/internal/error-message.ts
|
|
6
|
+
function messageOf(value) {
|
|
7
|
+
if (value instanceof Error)
|
|
8
|
+
return value.message;
|
|
9
|
+
if (typeof value === "string")
|
|
10
|
+
return value;
|
|
11
|
+
if (isRecord(value) && typeof value.message === "string")
|
|
12
|
+
return value.message;
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { messageOf };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
mergeMeta
|
|
3
|
-
|
|
2
|
+
mergeMeta,
|
|
3
|
+
resolveRouteParamsSchema
|
|
4
|
+
} from "./index-2bxcmqkb.js";
|
|
4
5
|
import {
|
|
5
6
|
isUnsafeKey
|
|
6
7
|
} from "./index-kzfs85xp.js";
|
|
@@ -92,7 +93,7 @@ function bindContract(contract, handlers) {
|
|
|
92
93
|
toolName: "toolName" in endpoint ? endpoint.toolName : undefined,
|
|
93
94
|
expose: endpoint.rawResponse || endpoint.rawBody || endpoint.responseMeta || "stream" in endpoint && endpoint.stream ? HTTP_ONLY : endpoint.expose,
|
|
94
95
|
scope: endpoint.scope ?? groupScope,
|
|
95
|
-
paramsSchema: endpoint.params,
|
|
96
|
+
paramsSchema: resolveRouteParamsSchema(endpoint.path, endpoint.params),
|
|
96
97
|
inputSchema: endpoint.input,
|
|
97
98
|
outputSchema: endpoint.output,
|
|
98
99
|
stream: "stream" in endpoint ? endpoint.stream : undefined,
|
|
@@ -106,6 +107,7 @@ function bindContract(contract, handlers) {
|
|
|
106
107
|
meta: mergeMeta(contract.meta.meta, endpoint.meta),
|
|
107
108
|
rawResponse: endpoint.rawResponse,
|
|
108
109
|
rawBody: endpoint.rawBody,
|
|
110
|
+
safelistedBody: endpoint.safelistedBody,
|
|
109
111
|
responseMeta: endpoint.responseMeta,
|
|
110
112
|
contentType: "contentType" in endpoint ? endpoint.contentType : undefined,
|
|
111
113
|
handler: streamingHandler ? (ctx) => streamingHandler.execute(ctx, ctx.files ?? {}) : (ctx) => {
|
|
@@ -196,7 +198,7 @@ function createImplementRegistry() {
|
|
|
196
198
|
|
|
197
199
|
// src/server/middleware/cors.ts
|
|
198
200
|
var DEFAULT_CORS_ALLOW_HEADERS = "Content-Type, Authorization, X-Trace-Id, traceparent, tracestate";
|
|
199
|
-
var DEFAULT_CORS_EXPOSE_HEADERS = "Content-Disposition, Content-Length, Content-Range, Accept-Ranges, ETag, Last-Modified, X-Request-Id";
|
|
201
|
+
var DEFAULT_CORS_EXPOSE_HEADERS = "Content-Disposition, Content-Length, Content-Range, Accept-Ranges, ETag, Last-Modified, X-Request-Id, X-Build-Id";
|
|
200
202
|
function assertCorsConfig(config) {
|
|
201
203
|
if (config.credentials && (config.origin === undefined || config.origin === "*")) {
|
|
202
204
|
throw new Error("[stitchkit] cors: `credentials: true` cannot be combined with a wildcard origin. " + "Set `origin` to an explicit string or list.");
|
|
@@ -222,6 +224,15 @@ function resolveOrigin(config, requestOrigin) {
|
|
|
222
224
|
}
|
|
223
225
|
return config.origin;
|
|
224
226
|
}
|
|
227
|
+
function isOriginAllowed(config, requestOrigin) {
|
|
228
|
+
if (!config || config.origin === undefined || config.origin === "*")
|
|
229
|
+
return false;
|
|
230
|
+
if (!requestOrigin || requestOrigin === "null")
|
|
231
|
+
return false;
|
|
232
|
+
const lower = requestOrigin.toLowerCase();
|
|
233
|
+
const allowed = Array.isArray(config.origin) ? config.origin : [config.origin];
|
|
234
|
+
return allowed.some((origin) => origin.toLowerCase() === lower);
|
|
235
|
+
}
|
|
225
236
|
function corsHeaders(config, requestOrigin) {
|
|
226
237
|
const allowOrigin = resolveOrigin(config, requestOrigin);
|
|
227
238
|
const headers = {
|
|
@@ -250,6 +261,11 @@ function corsPreflightResponse(config, req) {
|
|
|
250
261
|
});
|
|
251
262
|
}
|
|
252
263
|
|
|
264
|
+
// src/internal/media-type.ts
|
|
265
|
+
function mediaTypeEssence(contentType) {
|
|
266
|
+
return (contentType ?? "").split(";", 1)[0]?.trim().toLowerCase() ?? "";
|
|
267
|
+
}
|
|
268
|
+
|
|
253
269
|
// src/server/process-signal-common.ts
|
|
254
270
|
var DEFAULT_PROCESS_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
255
271
|
var defaultSignalSource = {
|
|
@@ -373,4 +389,4 @@ function mergeContextContribution(ctx, value, scope) {
|
|
|
373
389
|
Object.assign(ctx, prepareContextContribution(value, scope));
|
|
374
390
|
}
|
|
375
391
|
|
|
376
|
-
export { defineMultipartStream, createMultipartStream, contractOnlyService, implement, createImplement, createScopedImplement, createScopedImplementRegistry, implementRegistry, createImplementRegistry, DEFAULT_CORS_ALLOW_HEADERS, DEFAULT_CORS_EXPOSE_HEADERS, assertCorsConfig, corsHeaders, corsPreflightResponse, DEFAULT_PROCESS_SIGNALS, defaultSignalSource, reportSignalError, guardSignalCallback, RUNTIME_CONTEXT_RESERVED_KEYS, contextContributionDelta, prepareContextContribution, mergeContextContribution };
|
|
392
|
+
export { mediaTypeEssence, defineMultipartStream, createMultipartStream, contractOnlyService, implement, createImplement, createScopedImplement, createScopedImplementRegistry, implementRegistry, createImplementRegistry, DEFAULT_CORS_ALLOW_HEADERS, DEFAULT_CORS_EXPOSE_HEADERS, assertCorsConfig, isOriginAllowed, corsHeaders, corsPreflightResponse, DEFAULT_PROCESS_SIGNALS, defaultSignalSource, reportSignalError, guardSignalCallback, RUNTIME_CONTEXT_RESERVED_KEYS, contextContributionDelta, prepareContextContribution, mergeContextContribution };
|
|
@@ -8,15 +8,18 @@ var BackoffPolicySchema = z.object({
|
|
|
8
8
|
}).strict().readonly().refine((policy) => policy.maxDelayMs >= policy.minDelayMs, {
|
|
9
9
|
message: "maxDelayMs must be at least minDelayMs"
|
|
10
10
|
});
|
|
11
|
+
function backoffDelay(policy, attempt, random = Math.random) {
|
|
12
|
+
const exponential = Math.min(policy.maxDelayMs, policy.minDelayMs * 2 ** Math.max(0, attempt - 1));
|
|
13
|
+
const spread = exponential * policy.jitter * random();
|
|
14
|
+
return Math.max(1, Math.round(exponential - spread));
|
|
15
|
+
}
|
|
11
16
|
function createBackoff(policy, random = Math.random) {
|
|
12
|
-
const
|
|
17
|
+
const parsed = BackoffPolicySchema.parse(policy);
|
|
13
18
|
let attempt = 0;
|
|
14
19
|
return {
|
|
15
20
|
next() {
|
|
16
|
-
const exponential = Math.min(maxDelayMs, minDelayMs * 2 ** attempt);
|
|
17
21
|
attempt += 1;
|
|
18
|
-
|
|
19
|
-
return Math.max(1, Math.round(exponential - spread));
|
|
22
|
+
return backoffDelay(parsed, attempt, random);
|
|
20
23
|
},
|
|
21
24
|
reset() {
|
|
22
25
|
attempt = 0;
|
|
@@ -84,4 +87,4 @@ async function* resumableIterator(config) {
|
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
export { BackoffPolicySchema, createBackoff, resumableIterator };
|
|
90
|
+
export { BackoffPolicySchema, backoffDelay, createBackoff, resumableIterator };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RELEASE_HEADER
|
|
3
|
+
} from "./index-y91ry9h2.js";
|
|
1
4
|
import {
|
|
2
5
|
ShutdownOptionsSchema,
|
|
3
6
|
isStreamCancellation,
|
|
@@ -7,7 +10,7 @@ import {
|
|
|
7
10
|
import {
|
|
8
11
|
createValidatedRealtimeSocket,
|
|
9
12
|
isModuleNotFound
|
|
10
|
-
} from "./index-
|
|
13
|
+
} from "./index-apn8repm.js";
|
|
11
14
|
import {
|
|
12
15
|
DEFAULT_PROCESS_SIGNALS,
|
|
13
16
|
RUNTIME_CONTEXT_RESERVED_KEYS,
|
|
@@ -16,35 +19,42 @@ import {
|
|
|
16
19
|
corsPreflightResponse,
|
|
17
20
|
defaultSignalSource,
|
|
18
21
|
guardSignalCallback,
|
|
22
|
+
isOriginAllowed,
|
|
23
|
+
mediaTypeEssence,
|
|
19
24
|
reportSignalError
|
|
20
|
-
} from "./index-
|
|
25
|
+
} from "./index-p18f59zy.js";
|
|
21
26
|
import {
|
|
22
|
-
extractIp,
|
|
23
|
-
getClientInfo,
|
|
24
27
|
getRequestContext,
|
|
25
|
-
parseQueryParams,
|
|
26
|
-
resolveSocketIp,
|
|
27
|
-
resolveTraceId,
|
|
28
28
|
runWithRequestContext,
|
|
29
29
|
setRequestEndpoint,
|
|
30
30
|
setRequestError
|
|
31
|
-
} from "./index-
|
|
31
|
+
} from "./index-vsbzgd7b.js";
|
|
32
|
+
import {
|
|
33
|
+
extractIp,
|
|
34
|
+
getClientInfo,
|
|
35
|
+
parseQueryParams,
|
|
36
|
+
resolveSocketIp,
|
|
37
|
+
resolveTraceId
|
|
38
|
+
} from "./index-f9mb610r.js";
|
|
32
39
|
import {
|
|
33
40
|
errorCode,
|
|
34
41
|
normalizeError,
|
|
35
42
|
recordedErrorMessage,
|
|
36
|
-
resolveTraceContext,
|
|
37
43
|
validateDeclaredOutput
|
|
38
|
-
} from "./index-
|
|
44
|
+
} from "./index-7evdsyez.js";
|
|
39
45
|
import {
|
|
40
46
|
DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
|
|
41
47
|
joinRoutePath,
|
|
42
48
|
parseTrailingWildcard
|
|
43
|
-
} from "./index-
|
|
49
|
+
} from "./index-2bxcmqkb.js";
|
|
44
50
|
import {
|
|
45
51
|
AppError,
|
|
46
|
-
badRequest
|
|
52
|
+
badRequest,
|
|
53
|
+
forbidden
|
|
47
54
|
} from "./index-0w9abg87.js";
|
|
55
|
+
import {
|
|
56
|
+
resolveTraceContext
|
|
57
|
+
} from "./index-zcgf3gqf.js";
|
|
48
58
|
import {
|
|
49
59
|
isUnsafeKey,
|
|
50
60
|
safeJsonParse
|
|
@@ -829,11 +839,23 @@ async function readRequestText(req, maxBytes) {
|
|
|
829
839
|
}
|
|
830
840
|
|
|
831
841
|
// src/server/context.ts
|
|
832
|
-
function parseJsonBody(req, text) {
|
|
842
|
+
function parseJsonBody(req, text, method, cors) {
|
|
833
843
|
if (text.trim() === "")
|
|
834
844
|
return {};
|
|
835
|
-
|
|
836
|
-
|
|
845
|
+
const essence = mediaTypeEssence(req.headers.get("content-type"));
|
|
846
|
+
if (essence !== "application/json") {
|
|
847
|
+
if (!method.safelistedBody || essence !== "text/plain") {
|
|
848
|
+
badRequest("Request body must be application/json");
|
|
849
|
+
}
|
|
850
|
+
const origin = req.headers.get("origin");
|
|
851
|
+
if (!cors || cors.origin === undefined || cors.origin === "*") {
|
|
852
|
+
forbidden("A text/plain body requires an explicit cors.origin allow-list on the server");
|
|
853
|
+
}
|
|
854
|
+
if (!origin)
|
|
855
|
+
forbidden("A text/plain body requires an Origin header");
|
|
856
|
+
if (!isOriginAllowed(cors, origin)) {
|
|
857
|
+
forbidden("A text/plain body is accepted only from an allowed origin");
|
|
858
|
+
}
|
|
837
859
|
}
|
|
838
860
|
try {
|
|
839
861
|
return safeJsonParse(text);
|
|
@@ -865,7 +887,7 @@ function parsePathParamsInto(ctx, method) {
|
|
|
865
887
|
ctx.params = method.paramsSchema.parse(ctx.params);
|
|
866
888
|
}
|
|
867
889
|
}
|
|
868
|
-
async function parseRequestPayloadInto(ctx, req, url, method, maxJsonBodyBytes) {
|
|
890
|
+
async function parseRequestPayloadInto(ctx, req, url, method, maxJsonBodyBytes, cors) {
|
|
869
891
|
if (method.multipart) {
|
|
870
892
|
const multipart = await parseMultipart(req, method.multipart, method.inputSchema, method.multipartReceivers);
|
|
871
893
|
ctx.input = multipart.fields;
|
|
@@ -876,12 +898,11 @@ async function parseRequestPayloadInto(ctx, req, url, method, maxJsonBodyBytes)
|
|
|
876
898
|
if (req.method === "GET") {
|
|
877
899
|
ctx.input = method.inputSchema.parse(parseQueryParams(url));
|
|
878
900
|
} else if (req.method === "DELETE") {
|
|
879
|
-
|
|
880
|
-
if (ct?.includes("application/json")) {
|
|
901
|
+
if (mediaTypeEssence(req.headers.get("content-type")) === "application/json") {
|
|
881
902
|
const text = await readRequestText(req, method.maxJsonBodyBytes ?? maxJsonBodyBytes);
|
|
882
903
|
if (method.rawBody)
|
|
883
904
|
ctx.rawBody = text;
|
|
884
|
-
ctx.input = method.inputSchema.parse(parseJsonBody(req, text));
|
|
905
|
+
ctx.input = method.inputSchema.parse(parseJsonBody(req, text, method, cors));
|
|
885
906
|
} else {
|
|
886
907
|
ctx.input = method.inputSchema.parse(parseQueryParams(url));
|
|
887
908
|
}
|
|
@@ -889,7 +910,7 @@ async function parseRequestPayloadInto(ctx, req, url, method, maxJsonBodyBytes)
|
|
|
889
910
|
const text = await readRequestText(req, method.maxJsonBodyBytes ?? maxJsonBodyBytes);
|
|
890
911
|
if (method.rawBody)
|
|
891
912
|
ctx.rawBody = text;
|
|
892
|
-
ctx.input = method.inputSchema.parse(parseJsonBody(req, text));
|
|
913
|
+
ctx.input = method.inputSchema.parse(parseJsonBody(req, text, method, cors));
|
|
893
914
|
}
|
|
894
915
|
}
|
|
895
916
|
return;
|
|
@@ -1331,16 +1352,29 @@ function matchSegments(patternSegments, requestSegments) {
|
|
|
1331
1352
|
if (actual === undefined)
|
|
1332
1353
|
return null;
|
|
1333
1354
|
if (pattern.startsWith(":")) {
|
|
1334
|
-
|
|
1355
|
+
const decoded = decodeSegment(actual);
|
|
1356
|
+
if (decoded === null)
|
|
1357
|
+
return null;
|
|
1358
|
+
params[pattern.slice(1)] = decoded;
|
|
1335
1359
|
} else if (pattern !== actual) {
|
|
1336
1360
|
return null;
|
|
1337
1361
|
}
|
|
1338
1362
|
}
|
|
1339
1363
|
if (wildcardName) {
|
|
1340
|
-
|
|
1364
|
+
const decoded = requestSegments.slice(prefixLength).map(decodeSegment);
|
|
1365
|
+
if (decoded.some((segment) => segment === null))
|
|
1366
|
+
return null;
|
|
1367
|
+
params[wildcardName] = decoded.join("/");
|
|
1341
1368
|
}
|
|
1342
1369
|
return params;
|
|
1343
1370
|
}
|
|
1371
|
+
function decodeSegment(segment) {
|
|
1372
|
+
try {
|
|
1373
|
+
return decodeURIComponent(segment);
|
|
1374
|
+
} catch {
|
|
1375
|
+
return null;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1344
1378
|
function segmentRank(segment) {
|
|
1345
1379
|
if (segment?.startsWith("*"))
|
|
1346
1380
|
return 2;
|
|
@@ -1473,6 +1507,17 @@ function matchRawRoute(rawRoutes, httpMethod, pathname) {
|
|
|
1473
1507
|
}
|
|
1474
1508
|
function validateRawRoutes(rawRoutes) {
|
|
1475
1509
|
const routes = rawRoutes ?? [];
|
|
1510
|
+
for (const route of routes) {
|
|
1511
|
+
if (route.serviceName !== undefined && route.serviceName.trim().length === 0) {
|
|
1512
|
+
throw new Error(`Raw route ${route.method} ${route.path} has an empty serviceName`);
|
|
1513
|
+
}
|
|
1514
|
+
if (route.action !== undefined && route.action.trim().length === 0) {
|
|
1515
|
+
throw new Error(`Raw route ${route.method} ${route.path} has an empty action`);
|
|
1516
|
+
}
|
|
1517
|
+
if (route.action !== undefined && route.serviceName === undefined) {
|
|
1518
|
+
throw new Error(`Raw route ${route.method} ${route.path} declares action without serviceName`);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1476
1521
|
const shapes = routes.map((route) => rawRouteShape(route.path));
|
|
1477
1522
|
const conflicts = [];
|
|
1478
1523
|
for (const [laterIndex, later] of routes.entries()) {
|
|
@@ -1720,6 +1765,9 @@ function createHandler(config) {
|
|
|
1720
1765
|
if (config.rawRoutes) {
|
|
1721
1766
|
const rawMatch = matchRawRoute(config.rawRoutes, req.method, url.pathname);
|
|
1722
1767
|
if (rawMatch) {
|
|
1768
|
+
if (rawMatch.route.serviceName !== undefined) {
|
|
1769
|
+
setRequestEndpoint(rawMatch.route.serviceName, rawMatch.route.action);
|
|
1770
|
+
}
|
|
1723
1771
|
try {
|
|
1724
1772
|
const res = await rawMatch.route.handler(req, {
|
|
1725
1773
|
params: rawMatch.params,
|
|
@@ -1756,7 +1804,7 @@ function createHandler(config) {
|
|
|
1756
1804
|
if (groupHooks?.authorize) {
|
|
1757
1805
|
await groupHooks.authorize(ctx, method);
|
|
1758
1806
|
}
|
|
1759
|
-
multipartLifecycle = await parseRequestPayloadInto(ctx, req, url, method, config.maxJsonBodyBytes);
|
|
1807
|
+
multipartLifecycle = await parseRequestPayloadInto(ctx, req, url, method, config.maxJsonBodyBytes, cors);
|
|
1760
1808
|
if (hooks?.beforeHandle) {
|
|
1761
1809
|
await hooks.beforeHandle(ctx, method);
|
|
1762
1810
|
}
|
|
@@ -1851,6 +1899,9 @@ function createHandler(config) {
|
|
|
1851
1899
|
const response = await dispatch(req, url, traceId2, server, clientIp, startedAt);
|
|
1852
1900
|
try {
|
|
1853
1901
|
response.headers.set("x-request-id", traceId2);
|
|
1902
|
+
const buildId = config.release?.current();
|
|
1903
|
+
if (buildId)
|
|
1904
|
+
response.headers.set(RELEASE_HEADER, buildId);
|
|
1854
1905
|
} catch {}
|
|
1855
1906
|
return response;
|
|
1856
1907
|
};
|