stitchkit 0.49.2 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +3 -3
- package/dist/contract/errors-factory.d.ts +27 -6
- package/dist/contract/errors-factory.d.ts.map +1 -1
- package/dist/contract/factory.d.ts +15 -2
- package/dist/contract/factory.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 +1 -1
- package/dist/{index-z992nfbx.js → index-8mt47qk7.js} +127 -123
- package/dist/{index-jewp9r0a.js → index-8qghvg18.js} +1 -1
- package/dist/{index-h05ygjqx.js → index-bmnhqtya.js} +4 -1
- package/dist/{index-p9d4cxt5.js → index-gff2mxzk.js} +1 -1
- package/dist/{index-0hj37z43.js → index-h55e1wyq.js} +2 -2
- package/dist/{index-v58mwa19.js → index-psrxjvbw.js} +2 -2
- package/dist/{index-45dz4m51.js → index-trz4ate5.js} +6 -2
- package/dist/{index-03j2t778.js → index-tw7mhqgy.js} +15 -4
- package/dist/index-ynts85ew.js +246 -0
- package/dist/index.js +1 -1
- package/dist/node.d.ts +3 -2
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +15 -6
- package/dist/observability/index.js +3 -3
- package/dist/server/implement.d.ts +101 -8
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +4 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +19 -11
- package/dist/server/middleware/auth.d.ts +63 -3
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/process-signals.d.ts +117 -0
- package/dist/server/process-signals.d.ts.map +1 -0
- package/dist/server/types.d.ts +38 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/testing.js +2 -2
- package/dist/tools/list-names.d.ts +13 -1
- package/dist/tools/list-names.d.ts.map +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +13 -8
- package/llms-full.txt +404 -39
- package/package.json +1 -1
- package/dist/index-r1qp4rve.js +0 -57
package/dist/cli.js
CHANGED
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
emitResult,
|
|
5
5
|
parseCliArgs,
|
|
6
6
|
pollUntilDone
|
|
7
|
-
} from "./index-
|
|
7
|
+
} from "./index-h55e1wyq.js";
|
|
8
8
|
import"./index-yxpe3phd.js";
|
|
9
|
-
import"./index-
|
|
10
|
-
import"./index-
|
|
9
|
+
import"./index-8qghvg18.js";
|
|
10
|
+
import"./index-bmnhqtya.js";
|
|
11
11
|
export {
|
|
12
12
|
pollUntilDone,
|
|
13
13
|
parseCliArgs,
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Declare an application's domain errors once. Each definition owns its HTTP
|
|
3
|
-
* status and optional Zod schema for structured
|
|
4
|
-
* construct (but do not throw) branded `AppError`
|
|
3
|
+
* status, its default message and an optional Zod schema for structured
|
|
4
|
+
* details; generated factories construct (but do not throw) branded `AppError`
|
|
5
|
+
* instances.
|
|
5
6
|
*
|
|
6
7
|
* ```ts
|
|
7
8
|
* export const appErrors = defineErrors({
|
|
8
|
-
* SESSION_NOT_FOUND: { status: 404 },
|
|
9
|
+
* SESSION_NOT_FOUND: { status: 404, message: 'No such session' },
|
|
9
10
|
* QUOTA_EXCEEDED: {
|
|
10
11
|
* status: 429,
|
|
12
|
+
* message: 'Monthly quota exhausted',
|
|
11
13
|
* details: z.object({ retryAfterSeconds: z.number().int().positive() }),
|
|
12
14
|
* },
|
|
13
15
|
* })
|
|
14
16
|
*
|
|
15
|
-
* throw appErrors.errors.SESSION_NOT_FOUND(
|
|
17
|
+
* throw appErrors.errors.SESSION_NOT_FOUND()
|
|
16
18
|
* throw appErrors.errors.QUOTA_EXCEEDED({
|
|
17
19
|
* details: { retryAfterSeconds: 30 },
|
|
18
20
|
* hint: 'Wait for the current window to expire',
|
|
@@ -23,12 +25,20 @@ import { z } from 'zod';
|
|
|
23
25
|
import { AppError } from './errors';
|
|
24
26
|
/** Supported structured-details schemas: a required or optional Zod object. */
|
|
25
27
|
export type ErrorDetailsSchema = z.ZodObject | z.ZodOptional<z.ZodObject>;
|
|
26
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* One domain error definition. Omitting `details` forbids structured details.
|
|
30
|
+
*
|
|
31
|
+
* `message` is the code's default human-readable text: without it `AppError`
|
|
32
|
+
* falls back to the code itself, and every `throw` site has to repeat the
|
|
33
|
+
* sentence. A per-call `message` still wins.
|
|
34
|
+
*/
|
|
27
35
|
export type ErrorDefinition = {
|
|
28
36
|
readonly status: number;
|
|
37
|
+
readonly message?: string;
|
|
29
38
|
readonly details?: never;
|
|
30
39
|
} | {
|
|
31
40
|
readonly status: number;
|
|
41
|
+
readonly message?: string;
|
|
32
42
|
readonly details: ErrorDetailsSchema;
|
|
33
43
|
};
|
|
34
44
|
export type ErrorDefinitions = Record<string, ErrorDefinition>;
|
|
@@ -70,8 +80,19 @@ export type ErrorFactory<TCode extends string, TDefinition extends ErrorDefiniti
|
|
|
70
80
|
export type ErrorFactories<TDefinitions extends ErrorDefinitions> = {
|
|
71
81
|
readonly [TCode in keyof TDefinitions]: ErrorFactory<TCode & string, TDefinitions[TCode]>;
|
|
72
82
|
};
|
|
83
|
+
/**
|
|
84
|
+
* `const` inference keeps only the keys a definition actually wrote, so a
|
|
85
|
+
* registry that mixes codes with and without `message` has no common `message`
|
|
86
|
+
* key — and `definitions[code].message`, the whole point of declaring it, would
|
|
87
|
+
* not type-check. Normalising the optional key restores that lookup.
|
|
88
|
+
*
|
|
89
|
+
* A declared literal stays literal (`'gone' & string` is `'gone'`); this only
|
|
90
|
+
* adds the key where a definition omitted it.
|
|
91
|
+
*/
|
|
73
92
|
export type FrozenErrorDefinitions<TDefinitions extends ErrorDefinitions> = {
|
|
74
|
-
readonly [TCode in keyof TDefinitions]: Readonly<TDefinitions[TCode]
|
|
93
|
+
readonly [TCode in keyof TDefinitions]: Readonly<TDefinitions[TCode]> & {
|
|
94
|
+
readonly message?: string;
|
|
95
|
+
};
|
|
75
96
|
};
|
|
76
97
|
/** The immutable handle returned by `defineErrors`. */
|
|
77
98
|
export interface DefinedErrors<TDefinitions extends ErrorDefinitions> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors-factory.d.ts","sourceRoot":"","sources":["../../src/contract/errors-factory.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors-factory.d.ts","sourceRoot":"","sources":["../../src/contract/errors-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,14 +39,27 @@ export interface ScopedContractDef<T extends Record<string, EndpointDef> = Recor
|
|
|
39
39
|
scope: TScope;
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* An endpoint authored through the factory: the per-endpoint `scope` override is
|
|
44
|
+
* held to the same union as the contract's.
|
|
45
|
+
*
|
|
46
|
+
* Constraining the type parameter (rather than intersecting the argument) keeps
|
|
47
|
+
* `T` itself unchanged, so `ExplicitToolExposureEndpoints<T>` and the boundary
|
|
48
|
+
* mapping below still see the endpoints the caller wrote. The check is
|
|
49
|
+
* structural, so it also covers `HeadEndpointDef`, which declares its own
|
|
50
|
+
* `scope` outside `EndpointDefBase`.
|
|
51
|
+
*/
|
|
52
|
+
export type FactoryScopedEndpoint<TScope extends string> = EndpointDef & {
|
|
53
|
+
scope?: TScope;
|
|
54
|
+
};
|
|
42
55
|
/** A `defineContract` whose `scope` is required and typed to `TScope`. */
|
|
43
|
-
export type ScopedDefineContract<TScope extends string> = <const TContractScope extends TScope, const T extends Record<string,
|
|
56
|
+
export type ScopedDefineContract<TScope extends string> = <const TContractScope extends TScope, const T extends Record<string, FactoryScopedEndpoint<TScope>>>(meta: {
|
|
44
57
|
prefix: string;
|
|
45
58
|
scope: TContractScope;
|
|
46
59
|
meta?: Record<string, unknown>;
|
|
47
60
|
}, endpoints: T) => ScopedContractDef<T, TContractScope>;
|
|
48
61
|
/** Scoped contract authoring where every omitted exposure becomes HTTP-only. */
|
|
49
|
-
export type ExplicitScopedDefineContract<TScope extends string> = <const TContractScope extends TScope, const T extends Record<string,
|
|
62
|
+
export type ExplicitScopedDefineContract<TScope extends string> = <const TContractScope extends TScope, const T extends Record<string, FactoryScopedEndpoint<TScope>>>(meta: {
|
|
50
63
|
prefix: string;
|
|
51
64
|
scope: TContractScope;
|
|
52
65
|
meta?: Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/contract/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGlF,MAAM,MAAM,2BAA2B,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,YAAY,EAAE,2BAA2B,CAAC;CAC3C;AAED,MAAM,MAAM,6BAA6B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI;KAChF,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,MAAM,EAAE,SAAS,SAAS,EAAE,CAAA;KAAE,GACzD,CAAC,CAAC,CAAC,CAAC,GACJ,CAAC,CAAC,CAAC,CAAC,GAAG;QAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;KAAE;CACzC,CAAC;AAEF,oFAAoF;AACpF,MAAM,WAAW,iBAAiB,CAChC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACnE,MAAM,SAAS,MAAM,GAAG,MAAM,CAC9B,SAAQ,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAED,0EAA0E;AAC1E,MAAM,MAAM,oBAAoB,CAAC,MAAM,SAAS,MAAM,IAAI,CACxD,KAAK,CAAC,cAAc,SAAS,MAAM,EACnC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/contract/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGlF,MAAM,MAAM,2BAA2B,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,YAAY,EAAE,2BAA2B,CAAC;CAC3C;AAED,MAAM,MAAM,6BAA6B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI;KAChF,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,MAAM,EAAE,SAAS,SAAS,EAAE,CAAA;KAAE,GACzD,CAAC,CAAC,CAAC,CAAC,GACJ,CAAC,CAAC,CAAC,CAAC,GAAG;QAAE,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;KAAE;CACzC,CAAC;AAEF,oFAAoF;AACpF,MAAM,WAAW,iBAAiB,CAChC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACnE,MAAM,SAAS,MAAM,GAAG,MAAM,CAC9B,SAAQ,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC;IAC9B,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,CAAC,MAAM,SAAS,MAAM,IAAI,WAAW,GAAG;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,oBAAoB,CAAC,MAAM,SAAS,MAAM,IAAI,CACxD,KAAK,CAAC,cAAc,SAAS,MAAM,EACnC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,EAE7D,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAC/E,SAAS,EAAE,CAAC,KACT,iBAAiB,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;AAE1C,gFAAgF;AAChF,MAAM,MAAM,4BAA4B,CAAC,MAAM,SAAS,MAAM,IAAI,CAChE,KAAK,CAAC,cAAc,SAAS,MAAM,EACnC,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,EAE7D,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAC/E,SAAS,EAAE,CAAC,KACT,iBAAiB,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,SAAS,MAAM,KAAK;IAC9D,cAAc,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;CAC9C,CAAC;AACF,wBAAgB,qBAAqB,CAAC,MAAM,SAAS,MAAM,EACzD,MAAM,EAAE,qBAAqB,GAC5B;IACD,cAAc,EAAE,4BAA4B,CAAC,MAAM,CAAC,CAAC;CACtD,CAAC"}
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ALL_TRANSPORTS, type BodyHttpSuccessStatus, type ClientRequestOptions, type ContractDef, type ContractMeta, defineContract, type EndpointDef, type EndpointFn, type EndpointMcpInputRequired, type EndpointMcpPolicy, type EndpointResponseMeta, type EndpointToolAnnotations, type EndpointUiMeta, type FileDescriptor, type HandlerContext, type HeadEndpointDef, type HttpMethod, type HttpSuccessStatus, type MultipartBufferedFiles, type MultipartDescriptor, type MultipartFile, type MultipartFilePolicy, type ResponseMetadata, type RuntimeContext, type ScopedEndpointFn, type ScopedHttpClient, type ScopedUrlBuilder, type ScopedUrlFn, type Transport, type TransportSource, type TypedClient, type TypedHttpClient, type TypedUrlBuilder, } from './define';
|
|
2
2
|
export { AppError, appError, badRequest, conflict, type ErrorEnvelope, forbidden, isStitchErrorCode, notFound, rateLimited, STITCH_ERROR_STATUS, type StitchErrorCode, unauthorized, } from './errors';
|
|
3
3
|
export { type DefinedAppError, type DefinedErrors, defineErrors, type ErrorDefinition, type ErrorDefinitions, type ErrorDetailsOutput, type ErrorDetailsSchema, type ErrorFactories, type ErrorFactory, type ErrorFactoryArguments, type FrozenErrorDefinitions, } from './errors-factory';
|
|
4
|
-
export { type ContractFactoryConfig, type ContractFactoryToolExposure, createContractFactory, type ExplicitScopedDefineContract, type ExplicitToolExposureEndpoints, type ScopedContractDef, type ScopedDefineContract, } from './factory';
|
|
4
|
+
export { type ContractFactoryConfig, type ContractFactoryToolExposure, createContractFactory, type ExplicitScopedDefineContract, type ExplicitToolExposureEndpoints, type FactoryScopedEndpoint, type ScopedContractDef, type ScopedDefineContract, } from './factory';
|
|
5
5
|
export { decodeCursor, encodeCursor, type Paginated, paginatedSchema, } from './pagination';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,KAAK,aAAa,EAClB,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,EACpB,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,EAClC,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,SAAS,EACd,eAAe,GAChB,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contract/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,KAAK,aAAa,EAClB,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,KAAK,eAAe,EACpB,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,YAAY,EACZ,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,qBAAqB,EACrB,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,SAAS,EACd,eAAe,GAChB,MAAM,cAAc,CAAC"}
|
package/dist/contract/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
assertCorsConfig,
|
|
3
3
|
corsHeaders,
|
|
4
4
|
corsPreflightResponse
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-ynts85ew.js";
|
|
6
6
|
import {
|
|
7
7
|
AppError,
|
|
8
8
|
badRequest,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
getClientInfo,
|
|
12
12
|
getRequestContext,
|
|
13
13
|
isUnsafeKey,
|
|
14
|
-
mergeMeta,
|
|
15
14
|
normalizeError,
|
|
16
15
|
parseQueryParams,
|
|
17
16
|
recordedErrorMessage,
|
|
@@ -23,15 +22,13 @@ import {
|
|
|
23
22
|
setRequestError,
|
|
24
23
|
validateDeclaredOutput,
|
|
25
24
|
zodIssues
|
|
26
|
-
} from "./index-
|
|
25
|
+
} from "./index-8qghvg18.js";
|
|
27
26
|
import {
|
|
28
27
|
__require,
|
|
29
|
-
callRuntimeHandler,
|
|
30
28
|
isRecord,
|
|
31
29
|
parseTrailingWildcard,
|
|
32
|
-
resolveTraceContext
|
|
33
|
-
|
|
34
|
-
} from "./index-h05ygjqx.js";
|
|
30
|
+
resolveTraceContext
|
|
31
|
+
} from "./index-bmnhqtya.js";
|
|
35
32
|
|
|
36
33
|
// src/server/multipart.ts
|
|
37
34
|
var DEFAULT_MAX_REQUEST_BYTES = 25 * 1024 * 1024;
|
|
@@ -1607,131 +1604,138 @@ function createServerLifecycle(getAdapter) {
|
|
|
1607
1604
|
};
|
|
1608
1605
|
}
|
|
1609
1606
|
|
|
1610
|
-
// src/server/
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1607
|
+
// src/server/process-signals.ts
|
|
1608
|
+
var DEFAULT_SIGNALS = ["SIGINT", "SIGTERM"];
|
|
1609
|
+
var defaultSignalSource = {
|
|
1610
|
+
on: (signal, handler) => {
|
|
1611
|
+
process.on(signal, handler);
|
|
1612
|
+
},
|
|
1613
|
+
off: (signal, handler) => {
|
|
1614
|
+
process.off(signal, handler);
|
|
1615
|
+
},
|
|
1616
|
+
raiseDefault: (signal) => {
|
|
1617
|
+
if (process.listenerCount(signal) > 0)
|
|
1618
|
+
return false;
|
|
1619
|
+
process.kill(process.pid, signal);
|
|
1620
|
+
return true;
|
|
1623
1621
|
}
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
};
|
|
1622
|
+
};
|
|
1623
|
+
var bound = new WeakSet;
|
|
1624
|
+
function reportError(phase, error, onError) {
|
|
1625
|
+
try {
|
|
1626
|
+
onError?.(phase, error);
|
|
1627
|
+
} catch {}
|
|
1631
1628
|
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1629
|
+
function guard(run, phase, onError) {
|
|
1630
|
+
try {
|
|
1631
|
+
run();
|
|
1632
|
+
} catch (error) {
|
|
1633
|
+
reportError(phase, error, onError);
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
function bindProcessSignals(handle, options = {}) {
|
|
1637
|
+
if (bound.has(handle)) {
|
|
1638
|
+
throw new Error("[stitchkit] bindProcessSignals: this server is already bound; close the first binding before creating another");
|
|
1639
|
+
}
|
|
1640
|
+
bound.add(handle);
|
|
1641
|
+
const signals = [...new Set(options.signals ?? DEFAULT_SIGNALS)];
|
|
1642
|
+
const source = options.signalSource ?? defaultSignalSource;
|
|
1643
|
+
const budgets = ShutdownOptionsSchema.omit({ signal: true }).parse(options.shutdown ?? {});
|
|
1644
|
+
const controller = new AbortController;
|
|
1645
|
+
const handlers = [];
|
|
1646
|
+
let started = false;
|
|
1647
|
+
let sameTurnAsStart = false;
|
|
1648
|
+
let settled = false;
|
|
1649
|
+
let closed = false;
|
|
1650
|
+
let resolveChain = () => {
|
|
1651
|
+
return;
|
|
1652
|
+
};
|
|
1653
|
+
let rejectChain = () => {
|
|
1654
|
+
return;
|
|
1655
|
+
};
|
|
1656
|
+
const promise = new Promise((resolve, reject) => {
|
|
1657
|
+
resolveChain = resolve;
|
|
1658
|
+
rejectChain = reject;
|
|
1659
|
+
});
|
|
1660
|
+
promise.catch(() => {
|
|
1661
|
+
return;
|
|
1662
|
+
});
|
|
1663
|
+
const removeListeners = () => {
|
|
1664
|
+
if (closed)
|
|
1665
|
+
return;
|
|
1666
|
+
closed = true;
|
|
1667
|
+
for (const [signal, handler] of handlers)
|
|
1668
|
+
source.off(signal, handler);
|
|
1669
|
+
if (!started)
|
|
1670
|
+
bound.delete(handle);
|
|
1671
|
+
};
|
|
1672
|
+
const close = () => {
|
|
1673
|
+
const hadStarted = started;
|
|
1674
|
+
removeListeners();
|
|
1675
|
+
if (!hadStarted)
|
|
1676
|
+
resolveChain(undefined);
|
|
1677
|
+
};
|
|
1678
|
+
const run = async (signal) => {
|
|
1679
|
+
try {
|
|
1680
|
+
await options.onShutdown?.(signal);
|
|
1681
|
+
} catch (error) {
|
|
1682
|
+
reportError("prepare", error, options.onError);
|
|
1641
1683
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1684
|
+
let result;
|
|
1685
|
+
try {
|
|
1686
|
+
result = await handle.shutdown({ ...budgets, signal: controller.signal });
|
|
1687
|
+
} catch (error) {
|
|
1688
|
+
settled = true;
|
|
1689
|
+
rejectChain(error);
|
|
1690
|
+
reportError("shutdown", error, options.onError);
|
|
1691
|
+
removeListeners();
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
settled = true;
|
|
1695
|
+
resolveChain(result);
|
|
1696
|
+
try {
|
|
1697
|
+
await options.onComplete?.(result);
|
|
1698
|
+
} catch (error) {
|
|
1699
|
+
reportError("complete", error, options.onError);
|
|
1700
|
+
} finally {
|
|
1701
|
+
removeListeners();
|
|
1644
1702
|
}
|
|
1645
|
-
const streamingHandler = isStreamingImplementation(typedHandler) ? typedHandler : undefined;
|
|
1646
|
-
const regularHandler = typeof typedHandler === "function" ? typedHandler : undefined;
|
|
1647
|
-
methods[String(key)] = {
|
|
1648
|
-
method: endpoint.method,
|
|
1649
|
-
path: endpoint.path,
|
|
1650
|
-
desc: endpoint.desc,
|
|
1651
|
-
serviceName: contract.meta.prefix,
|
|
1652
|
-
key: String(key),
|
|
1653
|
-
toolName: "toolName" in endpoint ? endpoint.toolName : undefined,
|
|
1654
|
-
expose: endpoint.rawResponse || endpoint.rawBody || endpoint.responseMeta ? HTTP_ONLY : endpoint.expose,
|
|
1655
|
-
scope: endpoint.scope ?? groupScope,
|
|
1656
|
-
paramsSchema: endpoint.params,
|
|
1657
|
-
inputSchema: endpoint.input,
|
|
1658
|
-
outputSchema: endpoint.output,
|
|
1659
|
-
multipart: endpoint.multipart,
|
|
1660
|
-
multipartReceivers: streamingHandler?.receivers,
|
|
1661
|
-
maxJsonBodyBytes: endpoint.maxJsonBodyBytes,
|
|
1662
|
-
idempotent: endpoint.idempotent,
|
|
1663
|
-
ui: "ui" in endpoint ? endpoint.ui : undefined,
|
|
1664
|
-
annotations: "annotations" in endpoint ? endpoint.annotations : undefined,
|
|
1665
|
-
mcp: "mcp" in endpoint ? endpoint.mcp : undefined,
|
|
1666
|
-
meta: mergeMeta(contract.meta.meta, endpoint.meta),
|
|
1667
|
-
rawResponse: endpoint.rawResponse,
|
|
1668
|
-
rawBody: endpoint.rawBody,
|
|
1669
|
-
responseMeta: endpoint.responseMeta,
|
|
1670
|
-
contentType: "contentType" in endpoint ? endpoint.contentType : undefined,
|
|
1671
|
-
handler: streamingHandler ? (ctx) => streamingHandler.execute(ctx, ctx.files ?? {}) : (ctx) => {
|
|
1672
|
-
if (!regularHandler) {
|
|
1673
|
-
throw new Error(`[stitchkit] implement: missing handler for "${contract.meta.prefix}.${String(key)}"`);
|
|
1674
|
-
}
|
|
1675
|
-
return callRuntimeHandler(regularHandler, ctx);
|
|
1676
|
-
}
|
|
1677
|
-
};
|
|
1678
|
-
}
|
|
1679
|
-
return {
|
|
1680
|
-
name: contract.meta.prefix,
|
|
1681
|
-
prefix: contract.meta.prefix,
|
|
1682
|
-
scope: groupScope,
|
|
1683
|
-
methods
|
|
1684
1703
|
};
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
}
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
}
|
|
1695
|
-
function bindRegistry(contracts, handlers) {
|
|
1696
|
-
const contractKeys = Object.keys(contracts);
|
|
1697
|
-
const handlerKeys = Object.keys(handlers);
|
|
1698
|
-
const missing = contractKeys.filter((key) => !Object.hasOwn(handlers, key));
|
|
1699
|
-
const extra = handlerKeys.filter((key) => !Object.hasOwn(contracts, key));
|
|
1700
|
-
if (missing.length > 0 || extra.length > 0) {
|
|
1701
|
-
throw new Error(`[stitchkit] implementRegistry: registry mismatch (missing: ${missing.join(", ") || "none"}; extra: ${extra.join(", ") || "none"})`);
|
|
1702
|
-
}
|
|
1703
|
-
const prefixes = new Map;
|
|
1704
|
-
const services = [];
|
|
1705
|
-
for (const [key, candidate] of Object.entries(contracts)) {
|
|
1706
|
-
if (!isImplementationContract(candidate)) {
|
|
1707
|
-
throw new TypeError(`[stitchkit] implementRegistry: registry entry "${key}" must be one contract; composed arrays and namespaces are not supported`);
|
|
1704
|
+
const onSignal = (signal) => {
|
|
1705
|
+
if (!started) {
|
|
1706
|
+
started = true;
|
|
1707
|
+
sameTurnAsStart = true;
|
|
1708
|
+
queueMicrotask(() => {
|
|
1709
|
+
sameTurnAsStart = false;
|
|
1710
|
+
});
|
|
1711
|
+
run(signal).catch((error) => reportError("shutdown", error, options.onError));
|
|
1712
|
+
return;
|
|
1708
1713
|
}
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
if (
|
|
1712
|
-
|
|
1714
|
+
if (sameTurnAsStart)
|
|
1715
|
+
return;
|
|
1716
|
+
if (!settled && !controller.signal.aborted) {
|
|
1717
|
+
controller.abort();
|
|
1718
|
+
guard(() => options.onRepeatedSignal?.(signal, "force"), "shutdown", options.onError);
|
|
1719
|
+
return;
|
|
1713
1720
|
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1721
|
+
removeListeners();
|
|
1722
|
+
guard(() => options.onRepeatedSignal?.(signal, "escalate"), "shutdown", options.onError);
|
|
1723
|
+
let restored = false;
|
|
1724
|
+
try {
|
|
1725
|
+
restored = source.raiseDefault(signal);
|
|
1726
|
+
} catch (error) {
|
|
1727
|
+
reportError("shutdown", error, options.onError);
|
|
1718
1728
|
}
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
const missingEndpoints = endpointKeys.filter((endpointKey) => !Object.hasOwn(entryHandlers, endpointKey));
|
|
1722
|
-
const extraEndpoints = handlerEntryKeys.filter((endpointKey) => !Object.hasOwn(contract.endpoints, endpointKey));
|
|
1723
|
-
if (missingEndpoints.length > 0 || extraEndpoints.length > 0) {
|
|
1724
|
-
throw new Error(`[stitchkit] implementRegistry: handlers for "${key}" mismatch (missing: ${missingEndpoints.join(", ") || "none"}; extra: ${extraEndpoints.join(", ") || "none"})`);
|
|
1729
|
+
if (!restored) {
|
|
1730
|
+
guard(() => options.onEscalationBlocked?.(signal), "shutdown", options.onError);
|
|
1725
1731
|
}
|
|
1726
|
-
|
|
1732
|
+
};
|
|
1733
|
+
for (const signal of signals) {
|
|
1734
|
+
const handler = () => onSignal(signal);
|
|
1735
|
+
handlers.push([signal, handler]);
|
|
1736
|
+
source.on(signal, handler);
|
|
1727
1737
|
}
|
|
1728
|
-
return
|
|
1729
|
-
}
|
|
1730
|
-
function implementRegistry(contracts, handlers) {
|
|
1731
|
-
return bindRegistry(contracts, handlers);
|
|
1732
|
-
}
|
|
1733
|
-
function createImplementRegistry() {
|
|
1734
|
-
return (contracts, handlers) => bindRegistry(contracts, handlers);
|
|
1738
|
+
return { promise, close };
|
|
1735
1739
|
}
|
|
1736
1740
|
|
|
1737
1741
|
// src/realtime/rejection.ts
|
|
@@ -2148,4 +2152,4 @@ function socketIoLane(websocket) {
|
|
|
2148
2152
|
});
|
|
2149
2153
|
}
|
|
2150
2154
|
|
|
2151
|
-
export { parseMultipart, createHandler, ShutdownStateSchema, ShutdownOptionsSchema, ShutdownStatusSchema, ShutdownResultSchema, createServerLifecycle,
|
|
2155
|
+
export { parseMultipart, createHandler, ShutdownStateSchema, ShutdownOptionsSchema, ShutdownStatusSchema, ShutdownResultSchema, createServerLifecycle, bindProcessSignals, bindRealtimeServer, webSocketLane, composeWebSocketHandlers, createSocketIOServer, socketIoLane };
|
|
@@ -136,6 +136,9 @@ function callRuntimeHandler(handler, context) {
|
|
|
136
136
|
}
|
|
137
137
|
return Reflect.apply(handler, undefined, [context]);
|
|
138
138
|
}
|
|
139
|
+
function transportResult(value) {
|
|
140
|
+
return value;
|
|
141
|
+
}
|
|
139
142
|
function mapObject(source, mapper) {
|
|
140
143
|
const result = {};
|
|
141
144
|
for (const [key, value] of typedEntries(source)) {
|
|
@@ -146,4 +149,4 @@ function mapObject(source, mapper) {
|
|
|
146
149
|
return result;
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
export { __require, parseTrailingWildcard, typedEntries, isRecord, callRuntimeHandler, mapObject, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, resolvePropagationContext };
|
|
152
|
+
export { __require, parseTrailingWildcard, typedEntries, isRecord, callRuntimeHandler, transportResult, mapObject, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, resolvePropagationContext };
|
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
runWithRequestContext,
|
|
15
15
|
safeJsonParse,
|
|
16
16
|
validateDeclaredOutput
|
|
17
|
-
} from "./index-
|
|
17
|
+
} from "./index-8qghvg18.js";
|
|
18
18
|
import {
|
|
19
19
|
isRecord
|
|
20
|
-
} from "./index-
|
|
20
|
+
} from "./index-bmnhqtya.js";
|
|
21
21
|
|
|
22
22
|
// src/tools/coerce.ts
|
|
23
23
|
import { z } from "zod";
|
|
@@ -295,6 +295,9 @@ function validateDefinition(code, definition) {
|
|
|
295
295
|
if (definition.details !== undefined && !isErrorDetailsSchema(definition.details)) {
|
|
296
296
|
throw new Error(`[stitchkit] Error "${code}" details must be a Zod object or optional Zod object`);
|
|
297
297
|
}
|
|
298
|
+
if (definition.message !== undefined && (typeof definition.message !== "string" || definition.message.trim() === "")) {
|
|
299
|
+
throw new Error(`[stitchkit] Error "${code}" message must be a non-empty string`);
|
|
300
|
+
}
|
|
298
301
|
}
|
|
299
302
|
function defineErrors(source) {
|
|
300
303
|
const definitions = mapObjectTypeBoundary(source, (code, definition) => {
|
|
@@ -306,14 +309,15 @@ function defineErrors(source) {
|
|
|
306
309
|
const errors = mapObjectTypeBoundary(definitions, (code, definition) => {
|
|
307
310
|
const name = String(code);
|
|
308
311
|
return (options = {}) => {
|
|
312
|
+
const message = options.message ?? definition.message;
|
|
309
313
|
if (definition.details === undefined) {
|
|
310
314
|
if ("details" in options) {
|
|
311
315
|
throw new Error(`[stitchkit] Error "${name}" does not declare details`);
|
|
312
316
|
}
|
|
313
|
-
return new AppError(name,
|
|
317
|
+
return new AppError(name, message, definition.status, undefined, options.hint);
|
|
314
318
|
}
|
|
315
319
|
const details = definition.details.parse(options.details);
|
|
316
|
-
return new AppError(name,
|
|
320
|
+
return new AppError(name, message, definition.status, details, options.hint);
|
|
317
321
|
};
|
|
318
322
|
});
|
|
319
323
|
Object.freeze(errors);
|
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
isUnsafeKey,
|
|
6
6
|
safeJsonParse,
|
|
7
7
|
unauthorized
|
|
8
|
-
} from "./index-
|
|
8
|
+
} from "./index-8qghvg18.js";
|
|
9
9
|
import {
|
|
10
10
|
isRecord
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-bmnhqtya.js";
|
|
12
12
|
|
|
13
13
|
// src/server/middleware/cookies.ts
|
|
14
14
|
function parseCookies(header) {
|
|
@@ -150,6 +150,9 @@ function extractToken(req, cookieName) {
|
|
|
150
150
|
}
|
|
151
151
|
return null;
|
|
152
152
|
}
|
|
153
|
+
function isThenable(value) {
|
|
154
|
+
return "then" in value && typeof value.then === "function";
|
|
155
|
+
}
|
|
153
156
|
function createAuthHook(config) {
|
|
154
157
|
const onAnonymous = config.onAnonymous ?? (() => unauthorized());
|
|
155
158
|
const onForbidden = config.onForbidden ?? (() => forbidden());
|
|
@@ -159,10 +162,18 @@ function createAuthHook(config) {
|
|
|
159
162
|
const scope = endpoint.scope ?? config.defaultScope;
|
|
160
163
|
if (!scope)
|
|
161
164
|
return;
|
|
162
|
-
const
|
|
163
|
-
if (!
|
|
165
|
+
const entry = Object.hasOwn(config.rules, scope) ? config.rules[scope] : undefined;
|
|
166
|
+
if (!entry) {
|
|
164
167
|
throw new Error(`[stitchkit] auth: no rule for scope "${scope}"`);
|
|
165
168
|
}
|
|
169
|
+
const rule = typeof entry === "object" ? entry.rule : entry;
|
|
170
|
+
if (typeof entry === "object" && entry.inject && identity !== null) {
|
|
171
|
+
const fields = entry.inject(identity, ctx);
|
|
172
|
+
if (isThenable(fields)) {
|
|
173
|
+
throw new Error(`[stitchkit] auth: the inject of scope "${scope}" must be synchronous — an async inject merges a Promise, not fields`);
|
|
174
|
+
}
|
|
175
|
+
Object.assign(ctx, fields);
|
|
176
|
+
}
|
|
166
177
|
if (rule === "public")
|
|
167
178
|
return;
|
|
168
179
|
if (!identity) {
|