stitchkit 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +11 -10
  2. package/dist/browser/client.d.ts.map +1 -1
  3. package/dist/browser/socket-io.d.ts +17 -0
  4. package/dist/browser/socket-io.d.ts.map +1 -1
  5. package/dist/cli.d.ts +23 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +21 -0
  8. package/dist/contract/define.d.ts +35 -2
  9. package/dist/contract/define.d.ts.map +1 -1
  10. package/dist/contract/index.d.ts +1 -1
  11. package/dist/contract/index.d.ts.map +1 -1
  12. package/dist/contract/index.js +2 -1
  13. package/dist/index-0ed3bx43.js +33 -0
  14. package/dist/index-0ma1eqv4.js +1007 -0
  15. package/dist/index-1cf8jkhf.js +219 -0
  16. package/dist/index-37x76zdn.js +4 -0
  17. package/dist/{index-dpj1jcys.js → index-3qmtdfpa.js} +156 -4
  18. package/dist/index-48ffdxgk.js +6 -0
  19. package/dist/{index-4kz3aqpx.js → index-78q1qm7v.js} +4 -1
  20. package/dist/{index-kckky6zw.js → index-afzt3nmx.js} +1 -1
  21. package/dist/{index-4b1j82gp.js → index-d4rwrjbc.js} +1 -1
  22. package/dist/{index-0t460v7k.js → index-vhdvv00d.js} +1 -1
  23. package/dist/index-x3fcszf8.js +8 -0
  24. package/dist/index.js +16 -4
  25. package/dist/internal/http-input.d.ts +13 -0
  26. package/dist/internal/http-input.d.ts.map +1 -0
  27. package/dist/internal/secure-fetch.d.ts +27 -0
  28. package/dist/internal/secure-fetch.d.ts.map +1 -0
  29. package/dist/internal/within-dir.d.ts.map +1 -1
  30. package/dist/node.d.ts +10 -1
  31. package/dist/node.d.ts.map +1 -1
  32. package/dist/node.js +38 -7
  33. package/dist/observability/audit.d.ts.map +1 -1
  34. package/dist/observability/event.d.ts +4 -0
  35. package/dist/observability/event.d.ts.map +1 -1
  36. package/dist/observability/index.js +3 -0
  37. package/dist/react.js +2 -0
  38. package/dist/server/implement.d.ts.map +1 -1
  39. package/dist/server/index.d.ts +5 -2
  40. package/dist/server/index.d.ts.map +1 -1
  41. package/dist/server/index.js +172 -216
  42. package/dist/server/middleware/auth.d.ts +17 -0
  43. package/dist/server/middleware/auth.d.ts.map +1 -1
  44. package/dist/server/middleware/pkce.d.ts +17 -0
  45. package/dist/server/middleware/pkce.d.ts.map +1 -0
  46. package/dist/server/node.d.ts +9 -0
  47. package/dist/server/node.d.ts.map +1 -1
  48. package/dist/server/openapi.d.ts +52 -0
  49. package/dist/server/openapi.d.ts.map +1 -0
  50. package/dist/server/socket-io.d.ts +60 -15
  51. package/dist/server/socket-io.d.ts.map +1 -1
  52. package/dist/server/types.d.ts +5 -1
  53. package/dist/server/types.d.ts.map +1 -1
  54. package/dist/server/websocket.d.ts +73 -0
  55. package/dist/server/websocket.d.ts.map +1 -0
  56. package/dist/tools/cli-args.d.ts +68 -0
  57. package/dist/tools/cli-args.d.ts.map +1 -0
  58. package/dist/tools/cli-format.d.ts +39 -0
  59. package/dist/tools/cli-format.d.ts.map +1 -0
  60. package/dist/tools/cli-wait.d.ts +45 -0
  61. package/dist/tools/cli-wait.d.ts.map +1 -0
  62. package/dist/tools/cli.d.ts +77 -0
  63. package/dist/tools/cli.d.ts.map +1 -0
  64. package/dist/tools/coerce.d.ts.map +1 -1
  65. package/dist/tools/json-schema.d.ts +29 -4
  66. package/dist/tools/json-schema.d.ts.map +1 -1
  67. package/dist/tools/mcp-app.d.ts +59 -0
  68. package/dist/tools/mcp-app.d.ts.map +1 -0
  69. package/dist/tools/mcp-handler.d.ts +18 -0
  70. package/dist/tools/mcp-handler.d.ts.map +1 -1
  71. package/dist/tools/mcp.d.ts +9 -0
  72. package/dist/tools/mcp.d.ts.map +1 -1
  73. package/dist/tools/mount-download.d.ts +30 -0
  74. package/dist/tools/mount-download.d.ts.map +1 -0
  75. package/dist/tools/mount-upload.d.ts +19 -0
  76. package/dist/tools/mount-upload.d.ts.map +1 -0
  77. package/dist/tools/mount-wait.d.ts +36 -0
  78. package/dist/tools/mount-wait.d.ts.map +1 -0
  79. package/dist/tools/mount.d.ts +6 -2
  80. package/dist/tools/mount.d.ts.map +1 -1
  81. package/dist/tools/native-result.d.ts +17 -0
  82. package/dist/tools/native-result.d.ts.map +1 -0
  83. package/dist/tools/oauth-metadata.d.ts +28 -0
  84. package/dist/tools/oauth-metadata.d.ts.map +1 -0
  85. package/dist/tools/oauth-provider.d.ts +85 -0
  86. package/dist/tools/oauth-provider.d.ts.map +1 -0
  87. package/dist/tools/remote.d.ts +2 -2
  88. package/dist/tools/remote.d.ts.map +1 -1
  89. package/dist/tools/toolkit.d.ts +51 -0
  90. package/dist/tools/toolkit.d.ts.map +1 -0
  91. package/dist/tools/view-file.d.ts +12 -0
  92. package/dist/tools/view-file.d.ts.map +1 -1
  93. package/dist/tools/wait-core.d.ts +33 -0
  94. package/dist/tools/wait-core.d.ts.map +1 -0
  95. package/dist/tools.d.ts +12 -1
  96. package/dist/tools.d.ts.map +1 -1
  97. package/dist/tools.js +587 -421
  98. package/package.json +22 -9
  99. package/dist/index-q6ja2qwq.js +0 -7
@@ -1 +1 @@
1
- {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/observability/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,MAAM,EAAE,eAAe,CAAC;IACxB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,mDAAmD;IACnD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,EAAE,IAAI,CAAC;CACjB"}
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/observability/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,mCAAmC;IACnC,MAAM,EAAE,eAAe,CAAC;IACxB,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,6EAA6E;IAC7E,UAAU,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,OAAO,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,mDAAmD;IACnD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,EAAE,IAAI,CAAC;CACjB"}
@@ -8,6 +8,7 @@ import {
8
8
  import {
9
9
  isRecord
10
10
  } from "../index-809wc1tt.js";
11
+ import"../index-37x76zdn.js";
11
12
 
12
13
  // src/observability/context.ts
13
14
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -257,6 +258,8 @@ function createAuditHook(config) {
257
258
  resultSize: measure.resultSize,
258
259
  responseBytes: measure.responseBytes,
259
260
  userId: readString(context.userId),
261
+ authMethod: readString(context.authMethod),
262
+ clientId: readString(context.clientId),
260
263
  ipAddress: readString(context.ipAddress),
261
264
  userAgent: readString(context.userAgent),
262
265
  startedAt: new Date(Date.now() - durationMs)
package/dist/react.js CHANGED
@@ -1,3 +1,5 @@
1
+ import"./index-37x76zdn.js";
2
+
1
3
  // src/react/cache-bridge.ts
2
4
  function createCacheBridge(config) {
3
5
  const freshWindow = config.freshWindow ?? 500;
@@ -1 +1 @@
1
- {"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../src/server/implement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAa,UAAU,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,IAAI,SAAS,cAAc,GAAG,cAAc,EAC5C,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,UAAU,CAoC3E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAS,cAAc,MACjD,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC3C,UAAU,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAChC,UAAU,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,KAC1B,UAAU,CACd"}
1
+ {"version":3,"file":"implement.d.ts","sourceRoot":"","sources":["../../src/server/implement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,KAAK,EAAE,QAAQ,EAAa,UAAU,EAAE,MAAM,SAAS,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,IAAI,SAAS,cAAc,GAAG,cAAc,EAC5C,QAAQ,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,UAAU,CAsC3E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAS,cAAc,MACjD,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC3C,UAAU,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,EAChC,UAAU,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,KAC1B,UAAU,CACd"}
@@ -3,15 +3,18 @@ export { cacheHeaders, createCache } from './cache';
3
3
  export { createHandler, createServer } from './create';
4
4
  export { createEventBus, type EventBus } from './event-bus';
5
5
  export { createImplement, implement } from './implement';
6
- export { type AuthHook, type AuthHookConfig, type AuthRule, type BearerResolverConfig, createAuthHook, createBearerResolver, extractToken, type JwtPayload, verifyJwt, } from './middleware/auth';
6
+ export { type AuthHook, type AuthHookConfig, type AuthRule, type BearerResolverConfig, createAuthHook, createBearerResolver, extractToken, type JwtPayload, type SignJwtOptions, signJwt, verifyJwt, } from './middleware/auth';
7
7
  export { type CookieDef, type CookieOptions, defineCookie, parseCookies, serializeCookie, } from './middleware/cookies';
8
8
  export { type CorsConfig, corsHeaders, corsPreflightResponse, } from './middleware/cors';
9
+ export { deriveCodeChallenge, type PkceMethod, verifyPkce } from './middleware/pkce';
9
10
  export { parseMultipart } from './multipart';
11
+ export { generateOpenApiDocument, type OpenApiConfig, type OpenApiDocument, type OpenApiInfo, type OpenApiServer, openApiRoute, } from './openapi';
10
12
  export { createRateLimiter, type RateLimitConfig } from './rate-limit';
11
13
  export { type ClientIpOptions, extractIp, generateTraceId, getClientInfo, resolveSocketIp, resolveTraceId, } from './request';
12
14
  export { staticRoute } from './router';
13
15
  export type { SocketIOServerConfig, SocketIOServerHandle } from './socket-io';
14
- export { createSocketIOServer } from './socket-io';
16
+ export { createSocketIOServer, socketIoLane } from './socket-io';
15
17
  export { type ParseSSEOptions, parseSSE, streamSSE } from './stream';
16
18
  export type { BunServer, BunServerConfig, HandlerConfig, Handlers, LifecycleHooks, MethodDef, RawRoute, RawRouteContext, RouteGroup, ServerPassthrough, ServiceDef, StitchLogger, } from './types';
19
+ export { type ComposedLane, composeWebSocketHandlers, type WebSocketComposeConfig, type WebSocketLane, webSocketLane, } from './websocket';
17
20
  //# sourceMappingURL=index.d.ts.map
@@ -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,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,oBAAoB,EACzB,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,KAAK,UAAU,EACf,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,UAAU,EACf,WAAW,EACX,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EACL,KAAK,eAAe,EACpB,SAAS,EACT,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,KAAK,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrE,YAAY,EACV,SAAS,EACT,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,EACd,SAAS,EACT,QAAQ,EACR,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,SAAS,CAAC"}
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,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,KAAK,oBAAoB,EACzB,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,OAAO,EACP,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,KAAK,UAAU,EACf,WAAW,EACX,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,uBAAuB,EACvB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EACL,KAAK,eAAe,EACpB,SAAS,EACT,eAAe,EACf,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,KAAK,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrE,YAAY,EACV,SAAS,EACT,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,EACd,SAAS,EACT,QAAQ,EACR,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,KAAK,YAAY,EACjB,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,aAAa,GACd,MAAM,aAAa,CAAC"}
@@ -1,17 +1,42 @@
1
1
  import {
2
2
  parseSSE,
3
3
  streamSSE
4
- } from "../index-4b1j82gp.js";
4
+ } from "../index-d4rwrjbc.js";
5
5
  import {
6
+ createAuthHook,
7
+ createBearerResolver,
8
+ defineCookie,
9
+ deriveCodeChallenge,
10
+ extractToken,
11
+ parseCookies,
12
+ serializeCookie,
13
+ signJwt,
14
+ verifyJwt,
15
+ verifyPkce
16
+ } from "../index-1cf8jkhf.js";
17
+ import {
18
+ inputIsQuery
19
+ } from "../index-48ffdxgk.js";
20
+ import {
21
+ jsonSchemaFields,
22
+ toJsonSchema
23
+ } from "../index-0ed3bx43.js";
24
+ import {
25
+ composeWebSocketHandlers,
6
26
  corsHeaders,
7
27
  corsPreflightResponse,
8
28
  createHandler,
29
+ createImplement,
9
30
  createServer,
31
+ createSocketIOServer,
32
+ implement,
10
33
  parseMultipart,
11
- staticRoute
12
- } from "../index-dpj1jcys.js";
13
- import"../index-q6ja2qwq.js";
14
- import"../index-0t460v7k.js";
34
+ socketIoLane,
35
+ staticRoute,
36
+ webSocketLane
37
+ } from "../index-3qmtdfpa.js";
38
+ import"../index-x3fcszf8.js";
39
+ import"../index-vhdvv00d.js";
15
40
  import {
16
41
  AppError,
17
42
  appError,
@@ -21,7 +46,7 @@ import {
21
46
  notFound,
22
47
  rateLimited,
23
48
  unauthorized
24
- } from "../index-kckky6zw.js";
49
+ } from "../index-afzt3nmx.js";
25
50
  import {
26
51
  extractIp,
27
52
  generateTraceId,
@@ -29,13 +54,11 @@ import {
29
54
  resolveSocketIp,
30
55
  resolveTraceId
31
56
  } from "../index-mwmpw6j1.js";
32
- import {
33
- isUnsafeKey,
34
- safeJsonParse
35
- } from "../index-kzfs85xp.js";
57
+ import"../index-kzfs85xp.js";
36
58
  import {
37
59
  isRecord
38
60
  } from "../index-809wc1tt.js";
61
+ import"../index-37x76zdn.js";
39
62
  // src/server/swept-map.ts
40
63
  function createSweptMap(options) {
41
64
  const store = new Map;
@@ -146,194 +169,150 @@ function createEventBus(options = {}) {
146
169
  }
147
170
  };
148
171
  }
149
- // src/server/implement.ts
150
- function implement(contract, handlers) {
151
- const methods = {};
152
- const groupScope = contract.meta.scope ?? "public";
153
- for (const [key, endpoint] of Object.entries(contract.endpoints)) {
154
- const typedHandler = handlers[key];
155
- methods[key] = {
156
- method: endpoint.method,
157
- path: endpoint.path,
158
- desc: endpoint.desc,
159
- toolName: "toolName" in endpoint ? endpoint.toolName : undefined,
160
- expose: endpoint.expose,
161
- scope: endpoint.scope ?? groupScope,
162
- paramsSchema: endpoint.params,
163
- inputSchema: endpoint.input,
164
- outputSchema: endpoint.output,
165
- multipart: endpoint.multipart,
166
- handler: (ctx) => typedHandler(ctx)
167
- };
168
- }
169
- return {
170
- name: contract.meta.prefix,
171
- prefix: contract.meta.prefix,
172
- scope: groupScope,
173
- methods
174
- };
172
+ // src/server/openapi.ts
173
+ var ERROR_ENVELOPE_SCHEMA = {
174
+ type: "object",
175
+ properties: {
176
+ error: {
177
+ type: "object",
178
+ properties: {
179
+ code: { type: "string" },
180
+ message: { type: "string" },
181
+ details: {},
182
+ hint: { type: "string" }
183
+ },
184
+ required: ["code"]
185
+ }
186
+ },
187
+ required: ["error"]
188
+ };
189
+ function joinPath(...parts) {
190
+ const joined = parts.filter((p) => Boolean(p)).map((part) => part.replace(/^\/+|\/+$/g, "")).filter(Boolean).join("/");
191
+ return `/${joined}`;
175
192
  }
176
- function createImplement() {
177
- return (contract, handlers) => implement(contract, handlers);
193
+ function toOpenApiPath(path) {
194
+ return path.replace(/:([^/]+)/g, "{$1}");
178
195
  }
179
- // src/server/middleware/cookies.ts
180
- function parseCookies(header) {
181
- if (!header)
196
+ function safeJson(schema, io) {
197
+ if (!schema)
198
+ return {};
199
+ try {
200
+ return toJsonSchema(schema, io, "any");
201
+ } catch {
182
202
  return {};
183
- const cookies = {};
184
- for (const pair of header.split(";")) {
185
- const eq = pair.indexOf("=");
186
- if (eq === -1)
187
- continue;
188
- const key = pair.slice(0, eq).trim();
189
- if (!key || isUnsafeKey(key))
190
- continue;
191
- const raw = pair.slice(eq + 1).trim();
192
- try {
193
- cookies[key] = decodeURIComponent(raw);
194
- } catch {
195
- cookies[key] = raw;
196
- }
197
203
  }
198
- return cookies;
199
204
  }
200
- function serializeCookie(name, value, opts = {}) {
201
- let cookie = `${name}=${encodeURIComponent(value)}`;
202
- if (opts.maxAge !== undefined)
203
- cookie += `; Max-Age=${opts.maxAge}`;
204
- if (opts.path)
205
- cookie += `; Path=${opts.path}`;
206
- if (opts.domain)
207
- cookie += `; Domain=${opts.domain}`;
208
- if (opts.secure)
209
- cookie += "; Secure";
210
- if (opts.httpOnly)
211
- cookie += "; HttpOnly";
212
- if (opts.sameSite)
213
- cookie += `; SameSite=${opts.sameSite}`;
214
- return cookie;
215
- }
216
- function defineCookie(config) {
217
- const { name, ...options } = config;
205
+ function errorResponse(description) {
218
206
  return {
219
- get(req) {
220
- return parseCookies(req.headers.get("cookie"))[name];
221
- },
222
- set(value) {
223
- return serializeCookie(name, value, options);
224
- },
225
- clear() {
226
- return serializeCookie(name, "", { ...options, maxAge: 0 });
227
- }
207
+ description,
208
+ content: { "application/json": { schema: ERROR_ENVELOPE_SCHEMA } }
228
209
  };
229
210
  }
230
-
231
- // src/server/middleware/auth.ts
232
- var MAX_TOKEN_BYTES = 8192;
233
- function decodeBase64Url(segment) {
234
- if (!/^[A-Za-z0-9_-]*$/.test(segment) || segment.length % 4 === 1) {
235
- throw new Error("invalid base64url segment");
236
- }
237
- const b64 = segment.replace(/-/g, "+").replace(/_/g, "/");
238
- const padded = b64.padEnd(Math.ceil(b64.length / 4) * 4, "=");
239
- return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
240
- }
241
- async function verifyJwt(token, secret, options = {}) {
242
- if (!secret)
243
- throw new Error("verifyJwt: a non-empty secret is required");
244
- if (token.length > MAX_TOKEN_BYTES)
245
- throw unauthorized("Token too large");
246
- const [headerB64, payloadB64, signatureB64] = token.split(".");
247
- if (!headerB64 || !payloadB64 || !signatureB64)
248
- throw unauthorized("Invalid token format");
249
- let header;
250
- let payloadRaw;
251
- let signature;
252
- try {
253
- const decoder = new TextDecoder;
254
- header = JSON.parse(decoder.decode(decodeBase64Url(headerB64)));
255
- payloadRaw = safeJsonParse(decoder.decode(decodeBase64Url(payloadB64)));
256
- signature = decodeBase64Url(signatureB64);
257
- } catch {
258
- throw unauthorized("Malformed token");
259
- }
260
- if (!isRecord(payloadRaw))
261
- throw unauthorized("Malformed token");
262
- const payload = payloadRaw;
263
- if (header.alg !== "HS256")
264
- throw unauthorized("Unsupported token algorithm");
265
- const encoder = new TextEncoder;
266
- const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
267
- const data = encoder.encode(`${headerB64}.${payloadB64}`);
268
- const valid = await crypto.subtle.verify("HMAC", key, signature, data);
269
- if (!valid)
270
- throw unauthorized("Invalid token signature");
271
- const leeway = options.leewaySeconds ?? 60;
272
- const now = Date.now() / 1000;
273
- if ("exp" in payload) {
274
- if (typeof payload.exp !== "number")
275
- throw unauthorized("Malformed token");
276
- if (payload.exp < now - leeway)
277
- throw unauthorized("Token expired");
278
- }
279
- if ("nbf" in payload) {
280
- if (typeof payload.nbf !== "number")
281
- throw unauthorized("Malformed token");
282
- if (payload.nbf > now + leeway)
283
- throw unauthorized("Token not yet valid");
284
- }
285
- if (options.issuer !== undefined && payload.iss !== options.issuer) {
286
- throw unauthorized("Token issuer mismatch");
287
- }
288
- if (options.audience !== undefined) {
289
- const aud = payload.aud;
290
- const ok = Array.isArray(aud) ? aud.includes(options.audience) : aud === options.audience;
291
- if (!ok)
292
- throw unauthorized("Token audience mismatch");
293
- }
294
- return payload;
295
- }
296
- function extractToken(req, cookieName) {
297
- const authHeader = req.headers.get("authorization");
298
- if (authHeader?.startsWith("Bearer "))
299
- return authHeader.slice(7);
300
- if (cookieName) {
301
- const cookies = parseCookies(req.headers.get("cookie"));
302
- return cookies[cookieName] ?? null;
211
+ function errorResponses(scope) {
212
+ const responses = {
213
+ "400": errorResponse("Validation error"),
214
+ "500": errorResponse("Server error")
215
+ };
216
+ if (scope && scope !== "public") {
217
+ responses["401"] = errorResponse("Unauthorized");
218
+ responses["403"] = errorResponse("Forbidden");
303
219
  }
304
- return null;
220
+ return responses;
305
221
  }
306
- function createAuthHook(config) {
307
- const onAnonymous = config.onAnonymous ?? (() => unauthorized());
308
- const onForbidden = config.onForbidden ?? (() => forbidden());
309
- return async (ctx, endpoint) => {
310
- const identity = ctx.source === "http" ? await config.resolve(ctx) : await config.resolveFromContext?.(ctx) ?? null;
311
- config.inject?.(ctx, identity);
312
- const scope = endpoint.scope ?? config.defaultScope;
313
- if (!scope)
314
- return;
315
- const rule = config.rules[scope];
316
- if (!rule) {
317
- throw new Error(`[stitchkit] auth: no rule for scope "${scope}"`);
318
- }
319
- if (rule === "public")
320
- return;
321
- if (!identity) {
322
- onAnonymous();
323
- return;
222
+ function generateOpenApiDocument(config) {
223
+ const groups = [
224
+ ...(config.services ?? []).map((service) => ({ pathPrefix: undefined, service })),
225
+ ...(config.groups ?? []).flatMap((group) => group.services.map((service) => ({ pathPrefix: group.pathPrefix, service })))
226
+ ];
227
+ const paths = {};
228
+ for (const { pathPrefix, service } of groups) {
229
+ for (const [key, method] of Object.entries(service.methods)) {
230
+ if (method.expose && !method.expose.includes("HTTP"))
231
+ continue;
232
+ const servicePath = joinPath("/", service.prefix, method.path === "/" ? "" : method.path);
233
+ const fullPath = toOpenApiPath(pathPrefix ? joinPath(pathPrefix, servicePath) : servicePath);
234
+ const parameters = [];
235
+ for (const field of jsonSchemaFields(safeJson(method.paramsSchema, "input"))) {
236
+ parameters.push({
237
+ name: field.name,
238
+ in: "path",
239
+ required: true,
240
+ schema: field.schema,
241
+ ...field.description && { description: field.description }
242
+ });
243
+ }
244
+ const inputInQuery = inputIsQuery(method.method);
245
+ if (inputInQuery && method.inputSchema) {
246
+ for (const field of jsonSchemaFields(safeJson(method.inputSchema, "input"))) {
247
+ parameters.push({
248
+ name: field.name,
249
+ in: "query",
250
+ required: field.required,
251
+ schema: field.schema,
252
+ ...field.description && { description: field.description }
253
+ });
254
+ }
255
+ }
256
+ const responses = { ...errorResponses(method.scope) };
257
+ if (method.outputSchema) {
258
+ responses["200"] = {
259
+ description: "Success",
260
+ content: { "application/json": { schema: safeJson(method.outputSchema, "output") } }
261
+ };
262
+ } else {
263
+ responses["204"] = { description: "No content" };
264
+ }
265
+ const operation = {
266
+ summary: method.desc,
267
+ operationId: `${service.name}_${key}`,
268
+ ...parameters.length > 0 && { parameters },
269
+ responses
270
+ };
271
+ if (!inputInQuery && (method.inputSchema || method.multipart)) {
272
+ if (method.multipart) {
273
+ const inputJson = safeJson(method.inputSchema, "input");
274
+ const baseProps = isRecord(inputJson.properties) ? inputJson.properties : {};
275
+ const baseRequired = Array.isArray(inputJson.required) ? inputJson.required : [];
276
+ operation.requestBody = {
277
+ required: true,
278
+ content: {
279
+ "multipart/form-data": {
280
+ schema: {
281
+ type: "object",
282
+ properties: {
283
+ ...baseProps,
284
+ [method.multipart]: { type: "string", format: "binary" }
285
+ },
286
+ required: [...baseRequired, method.multipart]
287
+ }
288
+ }
289
+ }
290
+ };
291
+ } else if (method.inputSchema) {
292
+ const required = jsonSchemaFields(safeJson(method.inputSchema, "input")).some((f) => f.required);
293
+ operation.requestBody = {
294
+ required,
295
+ content: { "application/json": { schema: safeJson(method.inputSchema, "input") } }
296
+ };
297
+ }
298
+ }
299
+ const pathItem = paths[fullPath] ?? {};
300
+ pathItem[method.method.toLowerCase()] = operation;
301
+ paths[fullPath] = pathItem;
324
302
  }
325
- if (rule === "authenticated")
326
- return;
327
- if (!await rule(identity, ctx))
328
- onForbidden();
303
+ }
304
+ return {
305
+ openapi: "3.1.0",
306
+ info: config.info,
307
+ ...config.servers && { servers: config.servers },
308
+ paths
329
309
  };
330
310
  }
331
- function createBearerResolver(config) {
332
- return async (req) => {
333
- const token = extractToken(req);
334
- if (!token)
335
- return null;
336
- return config.lookup(token, req);
311
+ function openApiRoute(path, document) {
312
+ return {
313
+ method: "GET",
314
+ path,
315
+ handler: () => Response.json(document)
337
316
  };
338
317
  }
339
318
  // src/server/rate-limit.ts
@@ -383,42 +362,15 @@ function createRateLimiter() {
383
362
  }
384
363
  };
385
364
  }
386
- // src/server/socket-io.ts
387
- import { Server as BunEngine } from "@socket.io/bun-engine";
388
- import { Server as SocketIOServer } from "socket.io";
389
- function createSocketIOServer(config) {
390
- const path = config.path ?? "/socket.io/";
391
- const io = new SocketIOServer({
392
- path,
393
- cors: {
394
- origin: config.cors.origin,
395
- credentials: config.cors.credentials ?? true,
396
- methods: ["GET", "POST"]
397
- },
398
- transports: config.transports ?? ["websocket", "polling"],
399
- pingTimeout: config.pingTimeout ?? 20000,
400
- pingInterval: config.pingInterval ?? 1e4
401
- });
402
- const engine = new BunEngine({ path });
403
- io.bind(engine);
404
- const { websocket } = engine.handler();
405
- const route = {
406
- method: "ALL",
407
- path: `${path.replace(/\/+$/, "")}/*`,
408
- handler: (req, ctx) => {
409
- if (!ctx.server) {
410
- throw new Error("[stitchkit] createSocketIOServer route needs a running Bun server — mount it via createServer.");
411
- }
412
- return engine.handleRequest(req, ctx.server);
413
- }
414
- };
415
- return { io, websocket, route };
416
- }
417
365
  export {
366
+ webSocketLane,
367
+ verifyPkce,
418
368
  verifyJwt,
419
369
  unauthorized,
420
370
  streamSSE,
421
371
  staticRoute,
372
+ socketIoLane,
373
+ signJwt,
422
374
  serializeCookie,
423
375
  resolveTraceId,
424
376
  resolveSocketIp,
@@ -426,13 +378,16 @@ export {
426
378
  parseSSE,
427
379
  parseMultipart,
428
380
  parseCookies,
381
+ openApiRoute,
429
382
  notFound,
430
383
  implement,
431
384
  getClientInfo,
432
385
  generateTraceId,
386
+ generateOpenApiDocument,
433
387
  forbidden,
434
388
  extractToken,
435
389
  extractIp,
390
+ deriveCodeChallenge,
436
391
  defineCookie,
437
392
  createSocketIOServer,
438
393
  createServer,
@@ -446,6 +401,7 @@ export {
446
401
  corsPreflightResponse,
447
402
  corsHeaders,
448
403
  conflict,
404
+ composeWebSocketHandlers,
449
405
  cacheHeaders,
450
406
  badRequest,
451
407
  appError,
@@ -13,6 +13,23 @@ export interface VerifyJwtOptions {
13
13
  audience?: string;
14
14
  }
15
15
  export declare function verifyJwt(token: string, secret: string, options?: VerifyJwtOptions): Promise<JwtPayload>;
16
+ /** Tuning for `signJwt`. */
17
+ export interface SignJwtOptions {
18
+ /** Lifetime in seconds — sets `exp` to now + this. Omit for no expiry. */
19
+ expiresInSec?: number;
20
+ /** `iss` claim. */
21
+ issuer?: string;
22
+ /** `aud` claim. */
23
+ audience?: string;
24
+ /** `sub` claim. */
25
+ subject?: string;
26
+ }
27
+ /**
28
+ * Sign a payload as an HS256 JWT — the issuing counterpart of `verifyJwt`.
29
+ * Used to mint OAuth access tokens whose audience binds them to one resource.
30
+ * `iat` is always set; `exp` / `iss` / `aud` / `sub` follow `options`.
31
+ */
32
+ export declare function signJwt(payload: JwtPayload, secret: string, options?: SignJwtOptions): Promise<string>;
16
33
  export declare function extractToken(req: Request, cookieName?: string): string | null;
17
34
  /**
18
35
  * Per-scope access predicate. `endpoint.scope` selects which rule applies:
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,8BAA8B;AAC9B,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAgErB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU7E;AAUD;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,CAAC,SAAS,IAC1B,QAAQ,GACR,eAAe,GACf,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AAExF,MAAM,WAAW,cAAc,CAAC,SAAS;IACvC,kEAAkE;IAClE,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5D;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC3F,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3C,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAC5E,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC;IAC1B,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,KAAK,CAAC;CAC3B;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,GAAG,QAAQ,CAgCrF;AAID;;;;GAIG;AACH,MAAM,WAAW,oBAAoB,CAAC,SAAS;IAC7C,4EAA4E;IAC5E,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;CACpE;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAC5C,MAAM,EAAE,oBAAoB,CAAC,SAAS,CAAC,GACtC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAM7C"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * PKCE (RFC 7636) verification for the OAuth authorization-code flow. The client
3
+ * sends a `code_challenge` at `/authorize` and the matching `code_verifier` at
4
+ * `/token`; the server confirms they correspond so an intercepted code is
5
+ * useless without the verifier.
6
+ */
7
+ /** The only PKCE method OAuth 2.1 permits for public clients. */
8
+ export type PkceMethod = 'S256';
9
+ /** Derive the S256 `code_challenge` from a `code_verifier`. */
10
+ export declare function deriveCodeChallenge(verifier: string): Promise<string>;
11
+ /**
12
+ * Verify a `code_verifier` against the stored S256 `code_challenge`. S256 is the
13
+ * only method OAuth 2.1 permits for public clients — `plain` is intentionally
14
+ * not supported (it offers no protection against a leaked challenge).
15
+ */
16
+ export declare function verifyPkce(verifier: string, challenge: string): Promise<boolean>;
17
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../../src/server/middleware/pkce.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,iEAAiE;AACjE,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAQhC,+DAA+D;AAC/D,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3E;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAItF"}
@@ -1,7 +1,16 @@
1
+ import type { Server as HttpServer } from 'node:http';
1
2
  import type { HandlerConfig } from './types';
2
3
  export interface NodeServerConfig extends HandlerConfig {
3
4
  port?: number;
4
5
  hostname?: string;
6
+ /**
7
+ * A Socket.IO handle from `createSocketIOServer` — attached to the underlying
8
+ * `node:http.Server` (srvx `server.node.server`) once it is listening, so
9
+ * Socket.IO owns the HTTP `upgrade` event on the same port.
10
+ */
11
+ socket?: {
12
+ attach(server: HttpServer): void;
13
+ };
5
14
  }
6
15
  export interface NodeServerHandle {
7
16
  url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgBnF"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE;QAAE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA6BnF"}