stitchkit 0.45.0 → 0.47.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 +5 -4
- package/dist/browser/cancellation.d.ts +14 -0
- package/dist/browser/cancellation.d.ts.map +1 -0
- package/dist/browser/client-multipart.d.ts +3 -1
- package/dist/browser/client-multipart.d.ts.map +1 -1
- package/dist/browser/client.d.ts +1 -0
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/http.d.ts +1 -0
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/browser/socket-io.d.ts +3 -1
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/cli.js +3 -4
- package/dist/contract/define.d.ts +59 -15
- package/dist/contract/define.d.ts.map +1 -1
- package/dist/contract/errors.d.ts +1 -0
- package/dist/contract/errors.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 -2
- package/dist/{index-w0mec79h.js → index-44xysy8r.js} +697 -301
- package/dist/{index-r6czv7yt.js → index-45dz4m51.js} +50 -3
- package/dist/index-8ekq6res.js +181 -0
- package/dist/{index-yh0p5ddn.js → index-ee621cmy.js} +39 -19
- package/dist/{index-mvjyq9h9.js → index-kp8xamqp.js} +309 -144
- package/dist/{index-36f1xkdb.js → index-nrytvb30.js} +5 -4
- package/dist/{index-6jypn22c.js → index-r1qp4rve.js} +9 -1
- package/dist/{index-s4qsmgwe.js → index-tss6bk5c.js} +4 -1
- package/dist/index-yxpe3phd.js +63 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +315 -134
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/secure-fetch.d.ts +23 -3
- package/dist/internal/secure-fetch.d.ts.map +1 -1
- package/dist/internal/typed.d.ts +7 -0
- package/dist/internal/typed.d.ts.map +1 -1
- package/dist/internal/within-dir.d.ts +6 -0
- package/dist/internal/within-dir.d.ts.map +1 -1
- package/dist/logger.d.ts +8 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/node.js +3 -4
- package/dist/observability/audit.d.ts +22 -3
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/event.d.ts +7 -0
- package/dist/observability/event.d.ts.map +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +130 -134
- package/dist/observability/sanitize.d.ts +8 -1
- package/dist/observability/sanitize.d.ts.map +1 -1
- package/dist/observability/trace.d.ts +3 -1
- package/dist/observability/trace.d.ts.map +1 -1
- package/dist/react/cache-bridge.d.ts +4 -0
- package/dist/react/cache-bridge.d.ts.map +1 -1
- package/dist/react.js +46 -5
- package/dist/realtime/contract.d.ts +4 -1
- package/dist/realtime/contract.d.ts.map +1 -1
- package/dist/realtime/rejection.d.ts +10 -0
- package/dist/realtime/rejection.d.ts.map +1 -0
- package/dist/realtime/socket.d.ts +14 -1
- package/dist/realtime/socket.d.ts.map +1 -1
- package/dist/server/cache.d.ts +5 -1
- package/dist/server/cache.d.ts.map +1 -1
- package/dist/server/context.d.ts +8 -5
- 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 +1 -0
- package/dist/server/error-hook.d.ts.map +1 -1
- package/dist/server/file.d.ts +6 -0
- package/dist/server/file.d.ts.map +1 -1
- package/dist/server/implement.d.ts +33 -2
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -6
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +133 -14
- package/dist/server/middleware/auth.d.ts +7 -4
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/middleware/cors.d.ts.map +1 -1
- package/dist/server/multipart.d.ts +13 -18
- package/dist/server/multipart.d.ts.map +1 -1
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/realtime.d.ts +2 -0
- package/dist/server/realtime.d.ts.map +1 -1
- package/dist/server/router.d.ts +0 -8
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/stream.d.ts.map +1 -1
- package/dist/server/types.d.ts +50 -22
- package/dist/server/types.d.ts.map +1 -1
- package/dist/tools/cli-args.d.ts +11 -3
- package/dist/tools/cli-args.d.ts.map +1 -1
- package/dist/tools/cli.d.ts +5 -0
- package/dist/tools/cli.d.ts.map +1 -1
- package/dist/tools/coerce.d.ts.map +1 -1
- package/dist/tools/json-schema.d.ts.map +1 -1
- package/dist/tools/mcp-handler.d.ts +4 -3
- package/dist/tools/mcp-handler.d.ts.map +1 -1
- package/dist/tools/mcp-prepare.d.ts +95 -0
- package/dist/tools/mcp-prepare.d.ts.map +1 -0
- package/dist/tools/mcp-round.d.ts +4 -0
- package/dist/tools/mcp-round.d.ts.map +1 -1
- package/dist/tools/mcp-stdio.d.ts +2 -1
- package/dist/tools/mcp-stdio.d.ts.map +1 -1
- package/dist/tools/mcp.d.ts +2 -78
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mount-download.d.ts +5 -0
- package/dist/tools/mount-download.d.ts.map +1 -1
- package/dist/tools/native-mcp.d.ts +1 -1
- package/dist/tools/native-mcp.d.ts.map +1 -1
- package/dist/tools/oauth-provider.d.ts +20 -1
- package/dist/tools/oauth-provider.d.ts.map +1 -1
- package/dist/tools/tool-logger.d.ts +1 -1
- package/dist/tools/tool-logger.d.ts.map +1 -1
- package/dist/tools/view-file.d.ts +9 -0
- package/dist/tools/view-file.d.ts.map +1 -1
- package/dist/tools.d.ts +2 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +505 -278
- package/llms-full.txt +473 -85
- package/llms.txt +1 -1
- package/package.json +2 -2
- package/dist/index-frfyw9fa.js +0 -33
- package/dist/index-x3fcszf8.js +0 -8
package/dist/react.js
CHANGED
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isRecord
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-tss6bk5c.js";
|
|
4
4
|
|
|
5
5
|
// src/react/cache-bridge.ts
|
|
6
6
|
function createCacheBridge(config) {
|
|
7
7
|
const freshWindow = config.freshWindow ?? 500;
|
|
8
|
+
const maxFreshKeys = config.maxFreshKeys ?? 1000;
|
|
9
|
+
if (!Number.isFinite(freshWindow) || freshWindow < 0) {
|
|
10
|
+
throw new Error("cacheBridge.freshWindow must be a non-negative finite number");
|
|
11
|
+
}
|
|
12
|
+
if (!Number.isInteger(maxFreshKeys) || maxFreshKeys < 1) {
|
|
13
|
+
throw new Error("cacheBridge.maxFreshKeys must be a positive integer");
|
|
14
|
+
}
|
|
8
15
|
const freshAt = new Map;
|
|
16
|
+
const expiryTimers = new Map;
|
|
9
17
|
let unsubscribers = [];
|
|
10
18
|
const isFresh = (key) => {
|
|
11
|
-
const
|
|
12
|
-
|
|
19
|
+
const serialised = JSON.stringify(key);
|
|
20
|
+
const ts = freshAt.get(serialised);
|
|
21
|
+
if (ts === undefined)
|
|
22
|
+
return false;
|
|
23
|
+
if (Date.now() - ts < freshWindow)
|
|
24
|
+
return true;
|
|
25
|
+
freshAt.delete(serialised);
|
|
26
|
+
return false;
|
|
27
|
+
};
|
|
28
|
+
const clearFresh = () => {
|
|
29
|
+
for (const timer of expiryTimers.values())
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
expiryTimers.clear();
|
|
32
|
+
freshAt.clear();
|
|
13
33
|
};
|
|
14
34
|
return {
|
|
15
35
|
connect() {
|
|
@@ -31,10 +51,31 @@ function createCacheBridge(config) {
|
|
|
31
51
|
for (const off of unsubscribers)
|
|
32
52
|
off();
|
|
33
53
|
unsubscribers = [];
|
|
54
|
+
clearFresh();
|
|
34
55
|
},
|
|
35
56
|
markFresh(key) {
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
const serialised = JSON.stringify(key);
|
|
58
|
+
const existingTimer = expiryTimers.get(serialised);
|
|
59
|
+
if (existingTimer)
|
|
60
|
+
clearTimeout(existingTimer);
|
|
61
|
+
freshAt.delete(serialised);
|
|
62
|
+
freshAt.set(serialised, Date.now());
|
|
63
|
+
expiryTimers.set(serialised, setTimeout(() => {
|
|
64
|
+
freshAt.delete(serialised);
|
|
65
|
+
expiryTimers.delete(serialised);
|
|
66
|
+
}, freshWindow));
|
|
67
|
+
while (freshAt.size > maxFreshKeys) {
|
|
68
|
+
const oldest = freshAt.keys().next().value;
|
|
69
|
+
if (oldest === undefined)
|
|
70
|
+
break;
|
|
71
|
+
freshAt.delete(oldest);
|
|
72
|
+
const timer = expiryTimers.get(oldest);
|
|
73
|
+
if (timer)
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
expiryTimers.delete(oldest);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
clearFresh
|
|
38
79
|
};
|
|
39
80
|
}
|
|
40
81
|
// src/react/cursor-query.ts
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
|
+
import type { AppError } from '../contract/errors';
|
|
2
3
|
export interface RealtimeEventDefinition<TArgs extends z.ZodType<unknown[]> = z.ZodType<unknown[]>, TAck extends z.ZodType | undefined = z.ZodType | undefined> {
|
|
3
4
|
args: TArgs;
|
|
4
5
|
ack?: TAck;
|
|
@@ -30,7 +31,9 @@ export interface RealtimeRejectedEvent {
|
|
|
30
31
|
event: string;
|
|
31
32
|
direction: RealtimeRejectDirection;
|
|
32
33
|
phase: 'arguments' | 'acknowledgement';
|
|
33
|
-
|
|
34
|
+
reason: 'unknown-event' | 'invalid-arguments' | 'invalid-acknowledgement-value' | 'missing-acknowledgement';
|
|
35
|
+
fault: 'peer' | 'local';
|
|
36
|
+
error: AppError<'REALTIME_CONTRACT_VIOLATION'>;
|
|
34
37
|
}
|
|
35
38
|
export type RealtimeRejectedEventHook = (rejected: RealtimeRejectedEvent) => void | Promise<void>;
|
|
36
39
|
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/realtime/contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/realtime/contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,WAAW,uBAAuB,CACtC,KAAK,SAAS,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EACzD,IAAI,SAAS,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,CAAC,CAAC,OAAO,GAAG,SAAS;IAE1D,IAAI,EAAE,KAAK,CAAC;IACZ,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;AAE5E,MAAM,WAAW,gBAAgB,CAC/B,eAAe,SAAS,qBAAqB,EAC7C,eAAe,SAAS,qBAAqB;IAE7C,cAAc,EAAE,eAAe,CAAC;IAChC,cAAc,EAAE,eAAe,CAAC;CACjC;AAED,wBAAgB,sBAAsB,CACpC,KAAK,CAAC,eAAe,SAAS,qBAAqB,EACnD,KAAK,CAAC,eAAe,SAAS,qBAAqB,EACnD,QAAQ,EAAE,gBAAgB,CAAC,eAAe,EAAE,eAAe,CAAC,sDAE7D;AAED,MAAM,MAAM,sBAAsB,CAAC,WAAW,SAAS,uBAAuB,IAAI;IAChF,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,GAAG,CAAC,WAAW,SAAS;QAAE,GAAG,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC,OAAO,CAAA;KAAE,GACzD,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,GAChC,EAAE,CAAC;CACR,CAAC;AAEF,MAAM,MAAM,qBAAqB,CAAC,WAAW,SAAS,uBAAuB,IAAI;IAC/E,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC;IAC1F,GAAG,CAAC,WAAW,SAAS;QAAE,GAAG,EAAE,MAAM,IAAI,SAAS,CAAC,CAAC,OAAO,CAAA;KAAE,GACzD,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,GACjC,EAAE,CAAC;CACR,CAAC;AAEF,MAAM,MAAM,oBAAoB,CAAC,WAAW,SAAS,uBAAuB,IAAI,CAC9E,GAAG,IAAI,EAAE,sBAAsB,CAAC,WAAW,CAAC,KACzC,IAAI,CAAC;AAEV,MAAM,MAAM,qBAAqB,CAAC,SAAS,SAAS,qBAAqB,IAAI;KAC1E,MAAM,IAAI,MAAM,SAAS,GAAG,oBAAoB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;CACrE,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAC/B,gBAAgB,GAChB,iBAAiB,GACjB,gBAAgB,GAChB,iBAAiB,CAAC;AAEtB,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,uBAAuB,CAAC;IACnC,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAAC;IACvC,MAAM,EACF,eAAe,GACf,mBAAmB,GACnB,+BAA+B,GAC/B,yBAAyB,CAAC;IAC9B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,KAAK,EAAE,QAAQ,CAAC,6BAA6B,CAAC,CAAC;CAChD;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,QAAQ,EAAE,qBAAqB,KAC5B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RealtimeRejectDirection, RealtimeRejectedEvent } from './contract';
|
|
2
|
+
export declare function realtimeContractViolation(options: {
|
|
3
|
+
event: string;
|
|
4
|
+
direction: RealtimeRejectDirection;
|
|
5
|
+
phase: 'arguments' | 'acknowledgement';
|
|
6
|
+
reason: RealtimeRejectedEvent['reason'];
|
|
7
|
+
fault: RealtimeRejectedEvent['fault'];
|
|
8
|
+
cause?: unknown;
|
|
9
|
+
}): RealtimeRejectedEvent;
|
|
10
|
+
//# sourceMappingURL=rejection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rejection.d.ts","sourceRoot":"","sources":["../../src/realtime/rejection.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEjF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,uBAAuB,CAAC;IACnC,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAAC;IACvC,MAAM,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACxC,KAAK,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GAAG,qBAAqB,CAkBxB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { StitchLogger } from '../logger';
|
|
1
2
|
import type { RealtimeEmitArguments, RealtimeEventHandler, RealtimeEventRegistry, RealtimeRejectDirection, RealtimeRejectedEventHook } from './contract';
|
|
2
3
|
interface ValidatedRealtimeSocketOptions<TInbound extends RealtimeEventRegistry, TOutbound extends RealtimeEventRegistry> {
|
|
3
4
|
target: object;
|
|
@@ -6,12 +7,24 @@ interface ValidatedRealtimeSocketOptions<TInbound extends RealtimeEventRegistry,
|
|
|
6
7
|
inboundDirection: RealtimeRejectDirection;
|
|
7
8
|
outboundDirection: RealtimeRejectDirection;
|
|
8
9
|
onRejected?: RealtimeRejectedEventHook;
|
|
10
|
+
logger?: StitchLogger;
|
|
9
11
|
subscribe?: (event: string, handler: (...args: unknown[]) => void) => () => void;
|
|
10
12
|
}
|
|
13
|
+
/** Runtime target forms supported by the realtime adapter and their required capabilities. */
|
|
14
|
+
export declare const REALTIME_TARGET_FORMS: ({
|
|
15
|
+
name: "Server";
|
|
16
|
+
capabilities: ("emit" | "off" | "on")[];
|
|
17
|
+
} | {
|
|
18
|
+
name: "Socket";
|
|
19
|
+
capabilities: ("emit" | "off" | "on")[];
|
|
20
|
+
} | {
|
|
21
|
+
name: "BroadcastOperator";
|
|
22
|
+
capabilities: "emit"[];
|
|
23
|
+
})[];
|
|
11
24
|
export interface ValidatedRealtimeSocket<TInbound extends RealtimeEventRegistry, TOutbound extends RealtimeEventRegistry> {
|
|
12
25
|
on<TEvent extends keyof TInbound & string>(event: TEvent, handler: RealtimeEventHandler<TInbound[TEvent]>): () => void;
|
|
13
26
|
emit<TEvent extends keyof TOutbound & string>(event: TEvent, ...args: RealtimeEmitArguments<TOutbound[TEvent]>): void;
|
|
14
27
|
}
|
|
15
|
-
export declare function createValidatedRealtimeSocket<const TInbound extends RealtimeEventRegistry, const TOutbound extends RealtimeEventRegistry>({ target, inbound, outbound, inboundDirection, outboundDirection, onRejected, subscribe, }: ValidatedRealtimeSocketOptions<TInbound, TOutbound>): ValidatedRealtimeSocket<TInbound, TOutbound>;
|
|
28
|
+
export declare function createValidatedRealtimeSocket<const TInbound extends RealtimeEventRegistry, const TOutbound extends RealtimeEventRegistry>({ target, inbound, outbound, inboundDirection, outboundDirection, onRejected, logger, subscribe, }: ValidatedRealtimeSocketOptions<TInbound, TOutbound>): ValidatedRealtimeSocket<TInbound, TOutbound>;
|
|
16
29
|
export {};
|
|
17
30
|
//# sourceMappingURL=socket.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/realtime/socket.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/realtime/socket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EACV,qBAAqB,EAErB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EAEvB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAGpB,UAAU,8BAA8B,CACtC,QAAQ,SAAS,qBAAqB,EACtC,SAAS,SAAS,qBAAqB;IAEvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,gBAAgB,EAAE,uBAAuB,CAAC;IAC1C,iBAAiB,EAAE,uBAAuB,CAAC;IAC3C,UAAU,CAAC,EAAE,yBAAyB,CAAC;IACvC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;CAClF;AAED,8FAA8F;AAC9F,eAAO,MAAM,qBAAqB;;;;;;;;;IAOhC,CAAC;AAEH,MAAM,WAAW,uBAAuB,CACtC,QAAQ,SAAS,qBAAqB,EACtC,SAAS,SAAS,qBAAqB;IAEvC,EAAE,CAAC,MAAM,SAAS,MAAM,QAAQ,GAAG,MAAM,EACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAC9C,MAAM,IAAI,CAAC;IACd,IAAI,CAAC,MAAM,SAAS,MAAM,SAAS,GAAG,MAAM,EAC1C,KAAK,EAAE,MAAM,EACb,GAAG,IAAI,EAAE,qBAAqB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAChD,IAAI,CAAC;CACT;AA+DD,wBAAgB,6BAA6B,CAC3C,KAAK,CAAC,QAAQ,SAAS,qBAAqB,EAC5C,KAAK,CAAC,SAAS,SAAS,qBAAqB,EAC7C,EACA,MAAM,EACN,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,SAAS,GACV,EAAE,8BAA8B,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,uBAAuB,CAC9E,QAAQ,EACR,SAAS,CACV,CA0HA"}
|
package/dist/server/cache.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
export interface CacheOptions {
|
|
2
|
+
/** Maximum retained entries. Oldest entries are evicted first. Default 1,000. */
|
|
3
|
+
maxEntries?: number;
|
|
4
|
+
}
|
|
1
5
|
/**
|
|
2
6
|
* In-memory key/value cache with a per-entry TTL. Expired entries are swept on
|
|
3
7
|
* a 30-second timer; `destroy()` stops it. For response `Cache-Control`
|
|
4
8
|
* headers use `cacheHeaders()` instead.
|
|
5
9
|
*/
|
|
6
|
-
export declare function createCache(): {
|
|
10
|
+
export declare function createCache(options?: CacheOptions): {
|
|
7
11
|
destroy: () => void;
|
|
8
12
|
get(key: string): unknown | null;
|
|
9
13
|
set(key: string, data: unknown, maxAgeSeconds: number): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/server/cache.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,WAAW;;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/server/cache.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,YAAiB;;aAYzC,MAAM,GAAG,OAAO,GAAG,IAAI;aAUvB,MAAM,QAAQ,OAAO,iBAAiB,MAAM;uBAalC,MAAM;;EAU5B;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,QAAQ,GAAG,SAAoB,GACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxB"}
|
package/dist/server/context.d.ts
CHANGED
|
@@ -3,25 +3,28 @@
|
|
|
3
3
|
* endpoint schemas and gathers request metadata (trace id, client info).
|
|
4
4
|
*/
|
|
5
5
|
import { type RuntimeContext } from '../contract';
|
|
6
|
+
import { type MultipartLifecycle } from './multipart';
|
|
6
7
|
import { type ClientIpOptions } from './request';
|
|
7
|
-
import type { MethodDef } from './types';
|
|
8
|
+
import type { AuthorizationContext, MethodDef } from './types';
|
|
8
9
|
/**
|
|
9
10
|
* Assemble everything knowable from the URL alone — path params, the request,
|
|
10
11
|
* trace id and client info — **before** any schema parsing. Bound first so a
|
|
11
12
|
* later validation failure still hands `onError` the path params and the
|
|
12
|
-
* request (an empty context loses both);
|
|
13
|
-
* with
|
|
13
|
+
* request (an empty context loses both); the two parsing phases then enrich it
|
|
14
|
+
* with schema-validated params and payload.
|
|
14
15
|
*
|
|
15
16
|
* `params` starts as the raw matched path params (a property of the URL, known
|
|
16
17
|
* the moment the route matched) and is replaced by the validated value when the
|
|
17
18
|
* endpoint declares a `paramsSchema`.
|
|
18
19
|
*/
|
|
19
|
-
export declare function buildBaseContext(req: Request, url: URL, pathParams: Record<string, string>, traceId: string, clientIp: ClientIpOptions):
|
|
20
|
+
export declare function buildBaseContext(req: Request, url: URL, pathParams: Record<string, string>, traceId: string, clientIp: ClientIpOptions): AuthorizationContext;
|
|
20
21
|
/**
|
|
21
22
|
* Parse `params` / `input` against the endpoint schemas and write them onto an
|
|
22
23
|
* already-assembled base context. A validation failure throws a `ZodError`
|
|
23
24
|
* here — the base context (path params, request) is preserved for `onError`.
|
|
24
25
|
*/
|
|
25
|
-
export declare function
|
|
26
|
+
export declare function parsePathParamsInto(ctx: RuntimeContext, method: MethodDef): void;
|
|
27
|
+
/** Parse query, JSON or multipart payload after pre-body authorization. */
|
|
28
|
+
export declare function parseRequestPayloadInto(ctx: RuntimeContext, req: Request, url: URL, method: MethodDef, maxJsonBodyBytes?: number): Promise<MultipartLifecycle | undefined>;
|
|
26
29
|
export declare function buildErrorContext(req: Request, url: URL, traceId: string, clientIp: ClientIpOptions): RuntimeContext;
|
|
27
30
|
//# 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;
|
|
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;AAE9D,OAAO,EAAE,KAAK,kBAAkB,EAAkB,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAmC,MAAM,WAAW,CAAC;AAElF,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAmC/D;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,eAAe,GACxB,oBAAoB,CAmBtB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAIhF;AAED,2EAA2E;AAC3E,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,SAAS,EACjB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CA+BzC;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":"AAoDA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAA2B,MAAM,SAAS,CAAC;AAIpF,wBAAgB,aAAa,CAAC,OAAO,GAAG,OAAO,EAC7C,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,GAC7B,YAAY,CAAC,OAAO,CAAC,CA8fvB"}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* NOT_FOUND: 'not_found', METHOD_NOT_ALLOWED: 'not_found',
|
|
22
22
|
* CONFLICT: 'conflict', RATE_LIMITED: 'rate_limited',
|
|
23
23
|
* INTERNAL_SERVER_ERROR: 'internal',
|
|
24
|
+
* REALTIME_CONTRACT_VIOLATION: 'internal',
|
|
24
25
|
* } satisfies Record<StitchErrorCode, string>,
|
|
25
26
|
* render: (info, ctx) => ({
|
|
26
27
|
* ok: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-hook.d.ts","sourceRoot":"","sources":["../../src/server/error-hook.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"error-hook.d.ts","sourceRoot":"","sources":["../../src/server/error-hook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAqB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzD,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,+FAA+F;IAC/F,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,oCAAoC;AACpC,MAAM,WAAW,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM;IAChE;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IAC7C,uDAAuD;IACvD;;;;;OAKG;IACH,MAAM,EAAE,CACN,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,cAAc,EACnB,QAAQ,CAAC,EAAE,SAAS,KACjB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,EAC/D,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,GACjC,WAAW,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CA0BxC"}
|
package/dist/server/file.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import type { RawRoute } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Build a basic static-file route. URL-derived paths pass both lexical and
|
|
4
|
+
* realpath containment checks, so an in-root symlink cannot escape `dir`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function staticRoute(prefix: string, dir: string): RawRoute;
|
|
1
7
|
/** An inclusive byte range `[start, end]`. */
|
|
2
8
|
export interface ByteRange {
|
|
3
9
|
start: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/server/file.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/server/file.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CA4BjE;AAED,8CAA8C;AAC9C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,IAAI,EAAE,MAAM,GACX,SAAS,GAAG,eAAe,GAAG,IAAI,CAkCpC;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9D;AA6ED,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC;IACtC,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6CAA6C;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwEvF"}
|
|
@@ -1,5 +1,35 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { ZodType } from 'zod';
|
|
2
|
+
import type { ContractDef, EndpointDef, MultipartDescriptor, RuntimeContext } from '../contract';
|
|
3
|
+
import type { EndpointHandlerContext, Handlers, MultipartReceiver, ServiceDef, StreamingMultipartImplementation } from './types';
|
|
4
|
+
type StreamingEndpoint = EndpointDef & {
|
|
5
|
+
multipart: MultipartDescriptor & {
|
|
6
|
+
delivery: 'stream';
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
type ReceiverMap<E extends StreamingEndpoint> = {
|
|
10
|
+
[K in keyof E['multipart']['files']]: MultipartReceiver;
|
|
11
|
+
};
|
|
12
|
+
type ReceiverValue<R> = R extends MultipartReceiver<infer V> ? V : never;
|
|
13
|
+
type StreamedFiles<E extends StreamingEndpoint, R extends ReceiverMap<E>> = {
|
|
14
|
+
[K in keyof E['multipart']['files']]: E['multipart']['files'][K] extends {
|
|
15
|
+
multiple: true;
|
|
16
|
+
} ? ReceiverValue<R[K]>[] : E['multipart']['files'][K] extends {
|
|
17
|
+
required: false;
|
|
18
|
+
} ? ReceiverValue<R[K]> | undefined : ReceiverValue<R[K]>;
|
|
19
|
+
};
|
|
20
|
+
type StreamingReturn<E extends EndpointDef> = E extends {
|
|
21
|
+
output: ZodType<infer O>;
|
|
22
|
+
} ? O | Promise<O> : void | Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Bind streaming multipart receivers to one endpoint while inferring the
|
|
25
|
+
* receiver values handed to its final handler.
|
|
26
|
+
*/
|
|
27
|
+
export declare function defineMultipartStream<const E extends StreamingEndpoint, const R extends ReceiverMap<E>>(endpoint: E, config: {
|
|
28
|
+
files: R & Record<Exclude<keyof R, keyof E['multipart']['files']>, never>;
|
|
29
|
+
handler: (ctx: EndpointHandlerContext<E, RuntimeContext> & {
|
|
30
|
+
files: StreamedFiles<E, R>;
|
|
31
|
+
}) => StreamingReturn<E>;
|
|
32
|
+
}): StreamingMultipartImplementation;
|
|
3
33
|
/**
|
|
4
34
|
* Bind a contract to its typed `handlers`, producing a `ServiceDef` to mount on
|
|
5
35
|
* `createServer`. Every handler is type-checked against its endpoint's schemas.
|
|
@@ -13,4 +43,5 @@ export declare function implement<T extends Record<string, EndpointDef>, TCtx ex
|
|
|
13
43
|
* the generic. The application declares its context shape in a single place.
|
|
14
44
|
*/
|
|
15
45
|
export declare function createImplement<TCtx extends RuntimeContext>(): <T extends Record<string, EndpointDef>>(contract: ContractDef<T, string>, handlers: Handlers<T, TCtx>) => ServiceDef;
|
|
46
|
+
export {};
|
|
16
47
|
//# sourceMappingURL=implement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../src/server/implement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../src/server/implement.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -2,27 +2,26 @@ export { AppError, appError, badRequest, conflict, forbidden, isStitchErrorCode,
|
|
|
2
2
|
export { errorCode, formatZodError, normalizeError, type ZodIssueSummary, zodIssues, } from '../internal/errors';
|
|
3
3
|
export { isWithinDir } from '../internal/within-dir';
|
|
4
4
|
export { type BunFetchComposition as FetchComposition, type BunFetchHandler as FetchHandler, type BunHandlerConfig as HandlerConfig, type BunRawRoute as RawRoute, type BunRawRouteContext as RawRouteContext, type BunServer, type BunServerConfig, createServer, type ServerPassthrough, } from './bun';
|
|
5
|
-
export { cacheHeaders, createCache } from './cache';
|
|
5
|
+
export { type CacheOptions, cacheHeaders, createCache } from './cache';
|
|
6
6
|
export { createHandler } from './create';
|
|
7
7
|
export { createErrorHook, type ErrorHookConfig, type ResolvedError, } from './error-hook';
|
|
8
8
|
export { createEventBus, type DefaultEventMap, type EventBus, type EventBusOptions, type EventHandler, } from './event-bus';
|
|
9
|
-
export { type ByteRange, parseByteRange, type ServeFileOptions, serveFile, weakETag, } from './file';
|
|
10
|
-
export { createImplement, implement } from './implement';
|
|
9
|
+
export { type ByteRange, parseByteRange, type ServeFileOptions, serveFile, staticRoute, weakETag, } from './file';
|
|
10
|
+
export { createImplement, defineMultipartStream, implement } from './implement';
|
|
11
11
|
export type { LogFormat } from './logger';
|
|
12
12
|
export { type AuthHook, type AuthHookConfig, type AuthRule, type BearerResolverConfig, createAuthHook, createBearerResolver, extractToken, type JwtPayload, type SignJwtOptions, signJwt, type VerifyJwtOptions, verifyJwt, } from './middleware/auth';
|
|
13
13
|
export { type CookieDef, type CookieOptions, defineCookie, parseCookies, serializeCookie, } from './middleware/cookies';
|
|
14
14
|
export { type CorsConfig, corsHeaders, corsPreflightResponse, DEFAULT_CORS_ALLOW_HEADERS, DEFAULT_CORS_EXPOSE_HEADERS, } from './middleware/cors';
|
|
15
15
|
export { deriveCodeChallenge, type PkceMethod, verifyPkce } from './middleware/pkce';
|
|
16
|
-
export { type MultipartResult, parseMultipart } from './multipart';
|
|
16
|
+
export { type MultipartLifecycle, type MultipartResult, parseMultipart } from './multipart';
|
|
17
17
|
export { generateOpenApiDocument, type OpenApiConfig, type OpenApiDocument, type OpenApiInfo, type OpenApiServer, openApiRoute, } from './openapi';
|
|
18
18
|
export { createRateLimiter, type RateLimitConfig } from './rate-limit';
|
|
19
19
|
export { errorResponse, parseBody, respondJson } from './raw';
|
|
20
20
|
export { bindRealtimeServer, type RealtimeServer, type RealtimeServerConnection, type RealtimeServerHandle, } from './realtime';
|
|
21
21
|
export { type ClientIpOptions, extractIp, generateTraceId, getClientInfo, resolveSocketIp, resolveTraceId, } from './request';
|
|
22
|
-
export { staticRoute } from './router';
|
|
23
22
|
export type { SocketIOServerConfig, SocketIOServerHandle } from './socket-io';
|
|
24
23
|
export { createSocketIOServer, socketIoLane } from './socket-io';
|
|
25
24
|
export { type ParseSSEOptions, parseSSE, streamSSE } from './stream';
|
|
26
|
-
export type { Handlers, LifecycleHooks, LoggingConfig, LogOutcome, MethodDef, OperationIdentity, RouteGroup, ServiceDef, StitchLogger, } from './types';
|
|
25
|
+
export type { AuthorizationContext, EndpointHandlerContext, Handlers, LifecycleHooks, LoggingConfig, LogOutcome, MethodDef, MultipartFileMetadata, MultipartReceiver, MultipartReceiverResult, OperationIdentity, RouteGroup, ServiceDef, StitchLogger, StreamingMultipartImplementation, } from './types';
|
|
27
26
|
export { type ComposedLane, composeWebSocketHandlers, type WebSocketComposeConfig, type WebSocketLane, webSocketLane, } from './websocket';
|
|
28
27
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,EACpB,YAAY,GACb,MAAM,aAAa,CAAC;AAIrB,OAAO,EACL,SAAS,EACT,cAAc,EACd,cAAc,EACd,KAAK,eAAe,EACpB,SAAS,GACV,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EACL,KAAK,mBAAmB,IAAI,gBAAgB,EAC5C,KAAK,eAAe,IAAI,YAAY,EACpC,KAAK,gBAAgB,IAAI,aAAa,EACtC,KAAK,WAAW,IAAI,QAAQ,EAC5B,KAAK,kBAAkB,IAAI,eAAe,EAC1C,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,YAAY,EACZ,KAAK,iBAAiB,GACvB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.js
CHANGED
|
@@ -4,13 +4,12 @@ import {
|
|
|
4
4
|
createHandler,
|
|
5
5
|
createImplement,
|
|
6
6
|
createSocketIOServer,
|
|
7
|
+
defineMultipartStream,
|
|
7
8
|
implement,
|
|
8
|
-
mimeForPath,
|
|
9
9
|
parseMultipart,
|
|
10
10
|
socketIoLane,
|
|
11
|
-
staticRoute,
|
|
12
11
|
webSocketLane
|
|
13
|
-
} from "../index-
|
|
12
|
+
} from "../index-44xysy8r.js";
|
|
14
13
|
import {
|
|
15
14
|
createAuthHook,
|
|
16
15
|
createBearerResolver,
|
|
@@ -23,20 +22,19 @@ import {
|
|
|
23
22
|
signJwt,
|
|
24
23
|
verifyJwt,
|
|
25
24
|
verifyPkce
|
|
26
|
-
} from "../index-
|
|
25
|
+
} from "../index-nrytvb30.js";
|
|
27
26
|
import {
|
|
28
27
|
DEFAULT_CORS_ALLOW_HEADERS,
|
|
29
28
|
DEFAULT_CORS_EXPOSE_HEADERS,
|
|
30
29
|
corsHeaders,
|
|
31
30
|
corsPreflightResponse
|
|
32
|
-
} from "../index-
|
|
31
|
+
} from "../index-r1qp4rve.js";
|
|
33
32
|
import {
|
|
33
|
+
isWithinDir,
|
|
34
34
|
jsonSchemaFields,
|
|
35
|
+
realPathWithinDir,
|
|
35
36
|
toJsonSchema
|
|
36
|
-
} from "../index-
|
|
37
|
-
import {
|
|
38
|
-
isWithinDir
|
|
39
|
-
} from "../index-x3fcszf8.js";
|
|
37
|
+
} from "../index-yxpe3phd.js";
|
|
40
38
|
import {
|
|
41
39
|
AppError,
|
|
42
40
|
STITCH_ERROR_STATUS,
|
|
@@ -60,7 +58,7 @@ import {
|
|
|
60
58
|
resolveTraceId,
|
|
61
59
|
unauthorized,
|
|
62
60
|
zodIssues
|
|
63
|
-
} from "../index-
|
|
61
|
+
} from "../index-ee621cmy.js";
|
|
64
62
|
// src/server/bun.ts
|
|
65
63
|
function createServer(config) {
|
|
66
64
|
const { routes, websocket, development, bun: bunExtra, port = 3000, hostname } = config;
|
|
@@ -103,7 +101,11 @@ function createSweptMap(options) {
|
|
|
103
101
|
}
|
|
104
102
|
|
|
105
103
|
// src/server/cache.ts
|
|
106
|
-
function createCache() {
|
|
104
|
+
function createCache(options = {}) {
|
|
105
|
+
const maxEntries = options.maxEntries ?? 1000;
|
|
106
|
+
if (!Number.isInteger(maxEntries) || maxEntries < 1) {
|
|
107
|
+
throw new Error("cache.maxEntries must be a positive integer");
|
|
108
|
+
}
|
|
107
109
|
const { store, destroy } = createSweptMap({
|
|
108
110
|
intervalMs: 30000,
|
|
109
111
|
isExpired: (entry, now) => entry.expiresAt < now
|
|
@@ -121,7 +123,17 @@ function createCache() {
|
|
|
121
123
|
return entry.data;
|
|
122
124
|
},
|
|
123
125
|
set(key, data, maxAgeSeconds) {
|
|
126
|
+
if (!Number.isFinite(maxAgeSeconds) || maxAgeSeconds < 0) {
|
|
127
|
+
throw new Error("cache maxAgeSeconds must be a non-negative finite number");
|
|
128
|
+
}
|
|
129
|
+
store.delete(key);
|
|
124
130
|
store.set(key, { data, expiresAt: Date.now() + maxAgeSeconds * 1000 });
|
|
131
|
+
while (store.size > maxEntries) {
|
|
132
|
+
const oldest = store.keys().next().value;
|
|
133
|
+
if (oldest === undefined)
|
|
134
|
+
break;
|
|
135
|
+
store.delete(oldest);
|
|
136
|
+
}
|
|
125
137
|
},
|
|
126
138
|
invalidate(prefix) {
|
|
127
139
|
for (const key of store.keys()) {
|
|
@@ -213,6 +225,78 @@ function createEventBus(options = {}) {
|
|
|
213
225
|
};
|
|
214
226
|
}
|
|
215
227
|
// src/server/file.ts
|
|
228
|
+
import { readFile, stat } from "node:fs/promises";
|
|
229
|
+
import { resolve } from "node:path";
|
|
230
|
+
|
|
231
|
+
// src/server/mime.ts
|
|
232
|
+
import { extname } from "node:path";
|
|
233
|
+
var MIME_BY_EXT = {
|
|
234
|
+
".html": "text/html; charset=utf-8",
|
|
235
|
+
".css": "text/css; charset=utf-8",
|
|
236
|
+
".js": "text/javascript; charset=utf-8",
|
|
237
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
238
|
+
".json": "application/json; charset=utf-8",
|
|
239
|
+
".svg": "image/svg+xml",
|
|
240
|
+
".png": "image/png",
|
|
241
|
+
".jpg": "image/jpeg",
|
|
242
|
+
".jpeg": "image/jpeg",
|
|
243
|
+
".gif": "image/gif",
|
|
244
|
+
".webp": "image/webp",
|
|
245
|
+
".avif": "image/avif",
|
|
246
|
+
".ico": "image/x-icon",
|
|
247
|
+
".woff2": "font/woff2",
|
|
248
|
+
".txt": "text/plain; charset=utf-8",
|
|
249
|
+
".wasm": "application/wasm",
|
|
250
|
+
".mp4": "video/mp4",
|
|
251
|
+
".webm": "video/webm",
|
|
252
|
+
".mov": "video/quicktime",
|
|
253
|
+
".ogv": "video/ogg",
|
|
254
|
+
".mp3": "audio/mpeg",
|
|
255
|
+
".m4a": "audio/mp4",
|
|
256
|
+
".wav": "audio/wav",
|
|
257
|
+
".flac": "audio/flac",
|
|
258
|
+
".oga": "audio/ogg",
|
|
259
|
+
".ogg": "audio/ogg",
|
|
260
|
+
".pdf": "application/pdf",
|
|
261
|
+
".zip": "application/zip"
|
|
262
|
+
};
|
|
263
|
+
function mimeForPath(path) {
|
|
264
|
+
return MIME_BY_EXT[extname(path).toLowerCase()] ?? "application/octet-stream";
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/server/file.ts
|
|
268
|
+
function staticRoute(prefix, dir) {
|
|
269
|
+
const cleanPrefix = prefix.replace(/\/+$/, "");
|
|
270
|
+
const root = resolve(dir.replace(/\/+$/, ""));
|
|
271
|
+
return {
|
|
272
|
+
method: "GET",
|
|
273
|
+
path: `${cleanPrefix}/*filePath`,
|
|
274
|
+
handler: async (req) => {
|
|
275
|
+
const pathname = new URL(req.url).pathname;
|
|
276
|
+
let rel;
|
|
277
|
+
try {
|
|
278
|
+
rel = decodeURIComponent(pathname.slice(cleanPrefix.length)).replace(/^\/+/, "");
|
|
279
|
+
} catch {
|
|
280
|
+
return new Response("Bad request", { status: 400 });
|
|
281
|
+
}
|
|
282
|
+
const target = resolve(root, rel);
|
|
283
|
+
if (!isWithinDir(root, target))
|
|
284
|
+
return new Response("Forbidden", { status: 403 });
|
|
285
|
+
const realTarget = await realPathWithinDir(root, target);
|
|
286
|
+
if (realTarget === null)
|
|
287
|
+
return new Response("Not found", { status: 404 });
|
|
288
|
+
const info = await stat(realTarget).catch(() => null);
|
|
289
|
+
if (!info?.isFile())
|
|
290
|
+
return new Response("Not found", { status: 404 });
|
|
291
|
+
return new Response(await readFile(realTarget), {
|
|
292
|
+
headers: {
|
|
293
|
+
"Content-Type": mimeForPath(realTarget),
|
|
294
|
+
"X-Content-Type-Options": "nosniff"
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
}
|
|
216
300
|
function parseByteRange(header, size) {
|
|
217
301
|
if (!header)
|
|
218
302
|
return null;
|
|
@@ -473,6 +557,9 @@ function generateOpenApiDocument(config) {
|
|
|
473
557
|
const operation = {
|
|
474
558
|
summary: method.desc,
|
|
475
559
|
operationId: `${service.name}_${key}`,
|
|
560
|
+
"x-stitchkit-scope": method.scope,
|
|
561
|
+
"x-stitchkit-has-input": Boolean(method.inputSchema),
|
|
562
|
+
"x-stitchkit-has-output": Boolean(method.outputSchema),
|
|
476
563
|
...parameters.length > 0 && { parameters },
|
|
477
564
|
responses
|
|
478
565
|
};
|
|
@@ -489,17 +576,37 @@ function generateOpenApiDocument(config) {
|
|
|
489
576
|
const inputJson = safeJson(method.inputSchema, "input");
|
|
490
577
|
const baseProps = isRecord(inputJson.properties) ? inputJson.properties : {};
|
|
491
578
|
const baseRequired = Array.isArray(inputJson.required) ? inputJson.required : [];
|
|
579
|
+
const fileProperties = {};
|
|
580
|
+
const requiredFiles = [];
|
|
581
|
+
for (const [field, policy] of Object.entries(method.multipart.files)) {
|
|
582
|
+
const binary = {
|
|
583
|
+
type: "string",
|
|
584
|
+
format: "binary",
|
|
585
|
+
...policy.maxBytes !== undefined && { maxLength: policy.maxBytes },
|
|
586
|
+
...policy.contentTypes !== undefined && {
|
|
587
|
+
"x-accepted-content-types": policy.contentTypes
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
fileProperties[field] = policy.multiple === true ? {
|
|
591
|
+
type: "array",
|
|
592
|
+
items: binary,
|
|
593
|
+
minItems: policy.required === false ? 0 : 1,
|
|
594
|
+
...policy.maxFiles !== undefined && { maxItems: policy.maxFiles }
|
|
595
|
+
} : binary;
|
|
596
|
+
if (policy.required !== false)
|
|
597
|
+
requiredFiles.push(field);
|
|
598
|
+
}
|
|
492
599
|
operation.requestBody = {
|
|
493
|
-
required:
|
|
600
|
+
required: baseRequired.length > 0 || requiredFiles.length > 0,
|
|
494
601
|
content: {
|
|
495
602
|
"multipart/form-data": {
|
|
496
603
|
schema: {
|
|
497
604
|
type: "object",
|
|
498
605
|
properties: {
|
|
499
606
|
...baseProps,
|
|
500
|
-
|
|
607
|
+
...fileProperties
|
|
501
608
|
},
|
|
502
|
-
required: [...baseRequired,
|
|
609
|
+
required: [...baseRequired, ...requiredFiles]
|
|
503
610
|
}
|
|
504
611
|
}
|
|
505
612
|
}
|
|
@@ -602,26 +709,37 @@ async function parseBody(req, schema) {
|
|
|
602
709
|
// src/server/stream.ts
|
|
603
710
|
function streamSSE(generator) {
|
|
604
711
|
const encoder = new TextEncoder;
|
|
712
|
+
let cancelled = false;
|
|
605
713
|
const stream = new ReadableStream({
|
|
606
714
|
async start(controller) {
|
|
607
715
|
try {
|
|
608
716
|
for await (const chunk of generator) {
|
|
717
|
+
if (cancelled)
|
|
718
|
+
return;
|
|
609
719
|
const data = JSON.stringify(chunk);
|
|
610
720
|
controller.enqueue(encoder.encode(`data: ${data}
|
|
611
721
|
|
|
612
722
|
`));
|
|
613
723
|
}
|
|
724
|
+
if (cancelled)
|
|
725
|
+
return;
|
|
614
726
|
controller.enqueue(encoder.encode(`data: [DONE]
|
|
615
727
|
|
|
616
728
|
`));
|
|
617
729
|
controller.close();
|
|
618
730
|
} catch (err) {
|
|
731
|
+
if (cancelled)
|
|
732
|
+
return;
|
|
619
733
|
const envelope = normalizeError(err).toJSON();
|
|
620
734
|
controller.enqueue(encoder.encode(`data: ${JSON.stringify(envelope)}
|
|
621
735
|
|
|
622
736
|
`));
|
|
623
737
|
controller.close();
|
|
624
738
|
}
|
|
739
|
+
},
|
|
740
|
+
async cancel() {
|
|
741
|
+
cancelled = true;
|
|
742
|
+
await generator.return(undefined);
|
|
625
743
|
}
|
|
626
744
|
});
|
|
627
745
|
return new Response(stream, {
|
|
@@ -703,6 +821,7 @@ export {
|
|
|
703
821
|
errorResponse2 as errorResponse,
|
|
704
822
|
errorCode,
|
|
705
823
|
deriveCodeChallenge,
|
|
824
|
+
defineMultipartStream,
|
|
706
825
|
defineCookie,
|
|
707
826
|
createSocketIOServer,
|
|
708
827
|
createServer,
|