@fitzzero/quickdraw-core 3.5.0 → 3.7.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 (33) hide show
  1. package/README.md +113 -64
  2. package/dist/client/index.d.ts +2 -2
  3. package/dist/client/index.js +61 -66
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/client/testing.d.ts +1 -1
  6. package/dist/client/testing.js.map +1 -1
  7. package/dist/server/express/index.d.ts +37 -0
  8. package/dist/server/express/index.js +60 -0
  9. package/dist/server/express/index.js.map +1 -0
  10. package/dist/server/index.d.ts +227 -1
  11. package/dist/server/index.js +400 -142
  12. package/dist/server/index.js.map +1 -1
  13. package/dist/server/testing-prisma.d.ts +101 -0
  14. package/dist/server/testing-prisma.js +172 -0
  15. package/dist/server/testing-prisma.js.map +1 -0
  16. package/dist/server/testing.js +5 -22
  17. package/dist/server/testing.js.map +1 -1
  18. package/dist/shared/index.js.map +1 -1
  19. package/dist/{types-BJj94_XW.d.ts → types-B1z5aXdR.d.ts} +11 -0
  20. package/eslint-config/index.mjs +1 -2
  21. package/eslint-plugin-quickdraw/index.mjs +15 -7
  22. package/eslint-plugin-quickdraw/rules/no-cross-service-mutations.mjs +31 -32
  23. package/eslint-plugin-quickdraw/rules/no-direct-prisma-mutations.mjs +17 -18
  24. package/eslint-plugin-quickdraw/rules/no-raw-button-strings.mjs +52 -0
  25. package/eslint-plugin-quickdraw/rules/no-raw-service-room-string.mjs +140 -0
  26. package/eslint-plugin-quickdraw/rules/no-raw-socket-emit.mjs +20 -22
  27. package/eslint-plugin-quickdraw/rules/no-raw-socket-on.mjs +17 -17
  28. package/eslint-plugin-quickdraw/rules/no-raw-tooltip-strings.mjs +59 -0
  29. package/eslint-plugin-quickdraw/rules/no-raw-typography-strings.mjs +52 -0
  30. package/eslint-plugin-quickdraw/rules/no-service-method-record.mjs +3 -3
  31. package/eslint-plugin-quickdraw/rules/no-unsafe-payload-cast.mjs +8 -8
  32. package/eslint-plugin-quickdraw/rules/require-zod-schema.mjs +15 -20
  33. package/package.json +74 -50
@@ -0,0 +1,60 @@
1
+ import { ipKeyGenerator, rateLimit } from 'express-rate-limit';
2
+
3
+ // src/server/express/rateLimit.ts
4
+ function handler(_req, res, _next, options) {
5
+ const retryAfterSec = Math.max(1, Math.ceil((options.windowMs ?? 6e4) / 1e3));
6
+ if (!res.getHeader("Retry-After")) {
7
+ res.setHeader("Retry-After", String(retryAfterSec));
8
+ }
9
+ res.status(options.statusCode ?? 429).json({ error: "Rate limit exceeded" });
10
+ }
11
+ var jsonLimiter = {
12
+ standardHeaders: true,
13
+ legacyHeaders: false,
14
+ handler
15
+ };
16
+ function stripIp(raw) {
17
+ const ip = raw ?? "unknown";
18
+ return ip.startsWith("::ffff:") ? ip.slice(7) : ip;
19
+ }
20
+ function bearerOrIp(req) {
21
+ const auth = req.headers.authorization ?? "";
22
+ if (auth.startsWith("Bearer ")) return auth.slice(7);
23
+ return ipKeyGenerator(stripIp(req.ip));
24
+ }
25
+ function createJsonRateLimiter(options) {
26
+ return rateLimit({ ...jsonLimiter, ...options });
27
+ }
28
+ function createAuthLimiter(overrides = {}) {
29
+ return createJsonRateLimiter({
30
+ windowMs: 15 * 60 * 1e3,
31
+ max: 20,
32
+ skip: (req) => req.path.endsWith("/status"),
33
+ ...overrides
34
+ });
35
+ }
36
+ function createAuthStatusLimiter(overrides = {}) {
37
+ return createJsonRateLimiter({
38
+ windowMs: 15 * 60 * 1e3,
39
+ max: 120,
40
+ ...overrides
41
+ });
42
+ }
43
+ function createWebhookLimiter(overrides = {}) {
44
+ return createJsonRateLimiter({
45
+ windowMs: 60 * 1e3,
46
+ max: 300,
47
+ ...overrides
48
+ });
49
+ }
50
+ function createPublicApiLimiter(overrides = {}) {
51
+ return createJsonRateLimiter({
52
+ windowMs: 60 * 1e3,
53
+ max: 60,
54
+ ...overrides
55
+ });
56
+ }
57
+
58
+ export { bearerOrIp, createAuthLimiter, createAuthStatusLimiter, createJsonRateLimiter, createPublicApiLimiter, createWebhookLimiter, stripIp };
59
+ //# sourceMappingURL=index.js.map
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/server/express/rateLimit.ts"],"names":[],"mappings":";;;AAqBA,SAAS,OAAA,CAAQ,IAAA,EAAe,GAAA,EAAe,KAAA,EAAqB,OAAA,EAAwB;AAC1F,EAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,MAAM,OAAA,CAAQ,QAAA,IAAY,GAAA,IAAU,GAAI,CAAC,CAAA;AAChF,EAAA,IAAI,CAAC,GAAA,CAAI,SAAA,CAAU,aAAa,CAAA,EAAG;AACjC,IAAA,GAAA,CAAI,SAAA,CAAU,aAAA,EAAe,MAAA,CAAO,aAAa,CAAC,CAAA;AAAA,EACpD;AACA,EAAA,GAAA,CAAI,MAAA,CAAO,QAAQ,UAAA,IAAc,GAAG,EAAE,IAAA,CAAK,EAAE,KAAA,EAAO,qBAAA,EAAuB,CAAA;AAC7E;AAEA,IAAM,WAAA,GAA8B;AAAA,EAClC,eAAA,EAAiB,IAAA;AAAA,EACjB,aAAA,EAAe,KAAA;AAAA,EACf;AACF,CAAA;AAGO,SAAS,QAAQ,GAAA,EAAiC;AACvD,EAAA,MAAM,KAAK,GAAA,IAAO,SAAA;AAClB,EAAA,OAAO,GAAG,UAAA,CAAW,SAAS,IAAI,EAAA,CAAG,KAAA,CAAM,CAAC,CAAA,GAAI,EAAA;AAClD;AAOO,SAAS,WAAW,GAAA,EAAsB;AAC/C,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,OAAA,CAAQ,aAAA,IAAiB,EAAA;AAC1C,EAAA,IAAI,KAAK,UAAA,CAAW,SAAS,GAAG,OAAO,IAAA,CAAK,MAAM,CAAC,CAAA;AACnD,EAAA,OAAO,cAAA,CAAe,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAC,CAAA;AACvC;AAKO,SAAS,sBAAsB,OAAA,EAAkD;AACtF,EAAA,OAAO,UAAU,EAAE,GAAG,WAAA,EAAa,GAAG,SAAS,CAAA;AACjD;AAGO,SAAS,iBAAA,CAAkB,SAAA,GAA4B,EAAC,EAA4B;AACzF,EAAA,OAAO,qBAAA,CAAsB;AAAA,IAC3B,QAAA,EAAU,KAAK,EAAA,GAAK,GAAA;AAAA,IACpB,GAAA,EAAK,EAAA;AAAA,IACL,MAAM,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,IAC1C,GAAG;AAAA,GACJ,CAAA;AACH;AAGO,SAAS,uBAAA,CAAwB,SAAA,GAA4B,EAAC,EAA4B;AAC/F,EAAA,OAAO,qBAAA,CAAsB;AAAA,IAC3B,QAAA,EAAU,KAAK,EAAA,GAAK,GAAA;AAAA,IACpB,GAAA,EAAK,GAAA;AAAA,IACL,GAAG;AAAA,GACJ,CAAA;AACH;AAGO,SAAS,oBAAA,CAAqB,SAAA,GAA4B,EAAC,EAA4B;AAC5F,EAAA,OAAO,qBAAA,CAAsB;AAAA,IAC3B,UAAU,EAAA,GAAK,GAAA;AAAA,IACf,GAAA,EAAK,GAAA;AAAA,IACL,GAAG;AAAA,GACJ,CAAA;AACH;AAGO,SAAS,sBAAA,CAAuB,SAAA,GAA4B,EAAC,EAA4B;AAC9F,EAAA,OAAO,qBAAA,CAAsB;AAAA,IAC3B,UAAU,EAAA,GAAK,GAAA;AAAA,IACf,GAAA,EAAK,EAAA;AAAA,IACL,GAAG;AAAA,GACJ,CAAA;AACH","file":"index.js","sourcesContent":["/**\n * Express rate-limit presets built on express-rate-limit.\n *\n * Lives in the dedicated `/server/express` subpath so the core `/server`\n * entry point carries no express-rate-limit dependency. All presets are\n * factories (not module-level singletons) so env/config is read at call time.\n *\n * Note: distinct from the Socket.IO `createRateLimiter` exported from\n * `/server` — these protect REST routes (OAuth, webhooks, public APIs).\n */\n\nimport type { NextFunction, Request, Response } from \"express\";\nimport {\n ipKeyGenerator,\n rateLimit,\n type Options,\n type RateLimitRequestHandler,\n} from \"express-rate-limit\";\n\ntype PartialOptions = Partial<Options>;\n\nfunction handler(_req: Request, res: Response, _next: NextFunction, options: Options): void {\n const retryAfterSec = Math.max(1, Math.ceil((options.windowMs ?? 60_000) / 1000));\n if (!res.getHeader(\"Retry-After\")) {\n res.setHeader(\"Retry-After\", String(retryAfterSec));\n }\n res.status(options.statusCode ?? 429).json({ error: \"Rate limit exceeded\" });\n}\n\nconst jsonLimiter: PartialOptions = {\n standardHeaders: true,\n legacyHeaders: false,\n handler,\n};\n\n/** Normalize IPv4-mapped IPv6 addresses (::ffff:1.2.3.4 → 1.2.3.4). */\nexport function stripIp(raw: string | undefined): string {\n const ip = raw ?? \"unknown\";\n return ip.startsWith(\"::ffff:\") ? ip.slice(7) : ip;\n}\n\n/**\n * Key by Bearer token when present, falling back to client IP. Lets\n * token-authenticated clients get their own bucket instead of sharing\n * a NAT'd IP.\n */\nexport function bearerOrIp(req: Request): string {\n const auth = req.headers.authorization ?? \"\";\n if (auth.startsWith(\"Bearer \")) return auth.slice(7);\n return ipKeyGenerator(stripIp(req.ip));\n}\n\n/**\n * Base factory: JSON 429 body + Retry-After header + standard headers.\n */\nexport function createJsonRateLimiter(options: PartialOptions): RateLimitRequestHandler {\n return rateLimit({ ...jsonLimiter, ...options });\n}\n\n/** OAuth flows: 20 requests / 15 min per IP (status sub-routes excluded). */\nexport function createAuthLimiter(overrides: PartialOptions = {}): RateLimitRequestHandler {\n return createJsonRateLimiter({\n windowMs: 15 * 60 * 1000,\n max: 20,\n skip: (req) => req.path.endsWith(\"/status\"),\n ...overrides,\n });\n}\n\n/** Auth status polling: 120 requests / 15 min per IP. */\nexport function createAuthStatusLimiter(overrides: PartialOptions = {}): RateLimitRequestHandler {\n return createJsonRateLimiter({\n windowMs: 15 * 60 * 1000,\n max: 120,\n ...overrides,\n });\n}\n\n/** Inbound webhooks: 300 requests / min per IP. */\nexport function createWebhookLimiter(overrides: PartialOptions = {}): RateLimitRequestHandler {\n return createJsonRateLimiter({\n windowMs: 60 * 1000,\n max: 300,\n ...overrides,\n });\n}\n\n/** Generic public API: 60 requests / min per IP. */\nexport function createPublicApiLimiter(overrides: PartialOptions = {}): RateLimitRequestHandler {\n return createJsonRateLimiter({\n windowMs: 60 * 1000,\n max: 60,\n ...overrides,\n });\n}\n"]}
@@ -827,6 +827,10 @@ interface DiscordUser {
827
827
  * Discord OAuth provider configuration.
828
828
  */
829
829
  declare const discordProvider: OAuthProvider<DiscordUser>;
830
+ /**
831
+ * Get Discord avatar URL.
832
+ */
833
+ declare function getDiscordAvatarUrl(user: DiscordUser): string;
830
834
 
831
835
  /**
832
836
  * Google user information.
@@ -843,6 +847,206 @@ interface GoogleUser {
843
847
  */
844
848
  declare const googleProvider: OAuthProvider<GoogleUser>;
845
849
 
850
+ /**
851
+ * Mock OAuth provider for local development and tests.
852
+ *
853
+ * Implements a real OAuth 2.0 authorization-code flow served by the app's own
854
+ * API, so `createOAuthURL` and `exchangeOAuthCode` work unchanged — the mock
855
+ * is just a provider whose authorize/token/userinfo endpoints the app mounts
856
+ * via `registerMockOAuthProvider`. Users are supplied by the app (typically
857
+ * seeded demo accounts); no real credentials are involved.
858
+ *
859
+ * Production hard-block: routes are never mounted when NODE_ENV is
860
+ * "production" or ENABLE_MOCK_OAUTH !== "true", and every handler re-checks
861
+ * NODE_ENV at request time. Apps should add a third layer and refuse to boot
862
+ * in production with the flag set.
863
+ */
864
+
865
+ interface MockOAuthUser {
866
+ id: string;
867
+ email: string;
868
+ name: string;
869
+ picture?: string | null;
870
+ }
871
+ declare const DEFAULT_MOCK_PATH_PREFIX = "/auth/mock/provider";
872
+ declare function isMockOAuthEnabled(): boolean;
873
+ interface MockOAuthProviderOptions {
874
+ /**
875
+ * Base URL the API server can use to reach itself for the token/userinfo
876
+ * exchange (server-side fetch). Defaults to apiBaseUrl — override in
877
+ * containers/codespaces where the public URL isn't self-reachable
878
+ * (e.g. "http://localhost:4000").
879
+ */
880
+ internalBaseUrl?: string;
881
+ /** Route prefix for the mock endpoints. Default: "/auth/mock/provider". */
882
+ pathPrefix?: string;
883
+ }
884
+ /**
885
+ * Create the mock OAuth provider definition.
886
+ *
887
+ * `parseUserInfo` returns a GoogleUser-compatible shape with `id` set to the
888
+ * user's email, so `providerAccountId` stays stable across database re-seeds.
889
+ */
890
+ declare function createMockOAuthProvider(apiBaseUrl: string, options?: MockOAuthProviderOptions): OAuthProvider<GoogleUser>;
891
+ interface MockRequest {
892
+ url?: string;
893
+ originalUrl?: string;
894
+ query?: Record<string, unknown>;
895
+ headers: Record<string, string | string[] | undefined>;
896
+ body?: unknown;
897
+ }
898
+ interface MockResponse {
899
+ status(code: number): MockResponse;
900
+ json(body: unknown): unknown;
901
+ send(body: string): unknown;
902
+ redirect(url: string): unknown;
903
+ }
904
+ type MockHandler = (req: MockRequest, res: MockResponse) => void | Promise<void>;
905
+ interface MockOAuthRouter {
906
+ get(path: string, handler: MockHandler): unknown;
907
+ post(path: string, handler: MockHandler): unknown;
908
+ }
909
+ interface RegisterMockOAuthOptions {
910
+ /**
911
+ * Supply the users shown in the dev login picker (typically seeded demo
912
+ * accounts). Injected so core never touches the app's database.
913
+ */
914
+ listUsers: () => Promise<MockOAuthUser[]>;
915
+ /** Route prefix — must match createMockOAuthProvider's. */
916
+ pathPrefix?: string;
917
+ /**
918
+ * Extra origins allowed for redirect_uri beyond CLIENT_URL /
919
+ * EXTRA_ALLOWED_ORIGINS / localhost / private LAN IPs.
920
+ */
921
+ allowedRedirectOrigins?: string[];
922
+ logger?: Logger;
923
+ }
924
+ /**
925
+ * Mount the mock OAuth provider endpoints (authorize, token, userinfo) on an
926
+ * Express-compatible router.
927
+ *
928
+ * No-ops (returning false) unless `isMockOAuthEnabled()` — i.e. in production
929
+ * or without ENABLE_MOCK_OAUTH=true the routes are never mounted.
930
+ */
931
+ declare function registerMockOAuthProvider(router: MockOAuthRouter, options: RegisterMockOAuthOptions): boolean;
932
+
933
+ /**
934
+ * Origin validation utility for OAuth redirect and CORS security.
935
+ */
936
+ declare const OAUTH_RETURN_ORIGIN_COOKIE = "oauth_return_origin";
937
+ interface ValidateOriginOptions {
938
+ /**
939
+ * The primary web client origin. Defaults to process.env.CLIENT_URL.
940
+ */
941
+ clientUrl?: string;
942
+ /**
943
+ * Additional exact-match origins. Defaults to the comma-separated
944
+ * process.env.EXTRA_ALLOWED_ORIGINS. Lets a single API back multiple web
945
+ * hosts (e.g. prod + staging).
946
+ */
947
+ extraAllowedOrigins?: string[];
948
+ /**
949
+ * App-specific origin patterns (e.g. preview-deploy subdomains).
950
+ */
951
+ allowedPatterns?: RegExp[];
952
+ /**
953
+ * Allow GitHub Codespace forwarded-port origins
954
+ * (https://{workspace}-{username}-{port}.app.github.dev). Default: true.
955
+ */
956
+ allowCodespaces?: boolean;
957
+ /**
958
+ * Allow http://localhost:* when NODE_ENV !== "production". Default: true.
959
+ */
960
+ allowLocalhostInDev?: boolean;
961
+ }
962
+ /**
963
+ * Validates if an origin is safe for OAuth redirect / CORS.
964
+ *
965
+ * Only the origin (scheme + host + port) is compared, never the path, to
966
+ * prevent path-injection bypasses.
967
+ *
968
+ * @param origin - The origin to validate
969
+ * @param options - Override env-derived defaults
970
+ * @returns The validated origin if allowed, null otherwise
971
+ */
972
+ declare function validateRedirectOrigin(origin: string, options?: ValidateOriginOptions): string | null;
973
+
974
+ /**
975
+ * Secure session cookie helpers.
976
+ *
977
+ * Uses a structural response type so the module works with Express (or any
978
+ * compatible framework) without a runtime/type dependency on it.
979
+ */
980
+ declare const SESSION_COOKIE = "session";
981
+ interface CookieSettings {
982
+ httpOnly: boolean;
983
+ secure: boolean;
984
+ sameSite: "lax" | "none";
985
+ path: string;
986
+ domain?: string;
987
+ maxAge?: number;
988
+ }
989
+ interface CookieResponse {
990
+ cookie(name: string, value: string, options: CookieSettings): unknown;
991
+ clearCookie(name: string, options: CookieSettings): unknown;
992
+ }
993
+ interface SessionCookieOptions {
994
+ /** Cookie name. Default: "session". */
995
+ cookieName?: string;
996
+ /** Lifetime in ms. Default: 30 days. */
997
+ maxAgeMs?: number;
998
+ /** Cookie domain. Defaults to process.env.COOKIE_DOMAIN. */
999
+ domain?: string;
1000
+ }
1001
+ declare function setSessionCookie(res: CookieResponse, jwt: string, options?: SessionCookieOptions): void;
1002
+ declare function clearSessionCookie(res: CookieResponse, options?: SessionCookieOptions): void;
1003
+
1004
+ /**
1005
+ * REST authentication middleware factory.
1006
+ *
1007
+ * Authenticates requests via session cookie or Bearer token, verifies the JWT,
1008
+ * then checks session revocation via an injected lookup (the app owns the
1009
+ * database). Uses structural request/response types so there is no runtime or
1010
+ * type dependency on Express.
1011
+ */
1012
+ interface AuthRequest {
1013
+ cookies?: Record<string, string>;
1014
+ headers: {
1015
+ authorization?: string;
1016
+ };
1017
+ userId?: string;
1018
+ }
1019
+ interface AuthResponse {
1020
+ status(code: number): {
1021
+ json(body: unknown): unknown;
1022
+ };
1023
+ }
1024
+ interface RequireAuthOptions {
1025
+ /**
1026
+ * Look up the session for a token. Return null when the session does not
1027
+ * exist; sessions past expiresAt are rejected. This mirrors the socket auth
1028
+ * path so a revoked/logged-out session can no longer authenticate REST
1029
+ * requests until the JWT naturally expires.
1030
+ */
1031
+ getSession: (token: string) => Promise<{
1032
+ expiresAt: Date;
1033
+ } | null>;
1034
+ /** JWT signing secret. Defaults to process.env.JWT_SECRET. */
1035
+ jwtSecret?: string;
1036
+ /** Cookie to read the JWT from. Default: "session". */
1037
+ cookieName?: string;
1038
+ }
1039
+ /**
1040
+ * Extract a JWT from the session cookie or Authorization header
1041
+ * (cookie takes priority).
1042
+ */
1043
+ declare function extractBearerOrCookieToken(req: AuthRequest, cookieName?: string): string | null;
1044
+ /**
1045
+ * Create an Express-compatible middleware that attaches req.userId on success
1046
+ * and responds 401 on failure.
1047
+ */
1048
+ declare function createRequireAuth(options: RequireAuthOptions): (req: AuthRequest, res: AuthResponse, next: () => void) => Promise<void>;
1049
+
846
1050
  /**
847
1051
  * Environment variable validation utilities.
848
1052
  * Helps ensure required environment variables are set before the application starts.
@@ -927,6 +1131,28 @@ declare function checkEnv(options: ValidateEnvOptions): EnvValidationResult;
927
1131
  */
928
1132
  declare function requireEnv(name: string, defaultValue?: string): string;
929
1133
 
1134
+ /**
1135
+ * AES-256-GCM encryption helpers for at-rest secrets (e.g. stored OAuth tokens).
1136
+ *
1137
+ * Requires ENCRYPTION_KEY: a 64-character hex string (32 bytes).
1138
+ * Ciphertext format: "iv:authTag:ciphertext" (all hex).
1139
+ */
1140
+
1141
+ declare function encrypt(plaintext: string): string;
1142
+ declare function decrypt(ciphertext: string): string;
1143
+ /**
1144
+ * Returns true when the value looks like AES-256-GCM ciphertext
1145
+ * (iv:authTag:data, all hex). Plaintext OAuth tokens (e.g. gho_xxx) will not match.
1146
+ */
1147
+ declare function isEncrypted(value: string): boolean;
1148
+ /**
1149
+ * Decrypt if the value is in encrypted format, otherwise return as-is.
1150
+ * Allows graceful handling of pre-migration plaintext tokens.
1151
+ */
1152
+ declare function decryptIfEncrypted(value: string): string;
1153
+ /** Safe wrapper that returns `null` instead of throwing on invalid/stale ciphertext. */
1154
+ declare function tryDecrypt(ciphertext: string, logger?: Logger): string | null;
1155
+
930
1156
  /**
931
1157
  * Options for customizing field generation.
932
1158
  */
@@ -1106,4 +1332,4 @@ declare function createMcpRoutes(router: Router, options: McpHttpRoutesOptions):
1106
1332
  */
1107
1333
  declare function generateToolMetadata(options: GenerateToolMetadataOptions): void;
1108
1334
 
1109
- export { AdminListPayload, AdminListResponse, AdminSetACLPayload, AdminSubscribersResponse, BaseService, BaseServiceInstance, BaseServiceOptions, type DiscordUser, type EnvValidationResult, type GenerateToolMetadataOptions, type GoogleUser, InstallAdminMethodsOptions, type JWTPayload, type McpHttpRoutesOptions, ServiceMethodContext as McpMethodContext, ServiceMethodDefinition as McpMethodDefinition, McpRegistry, type McpRegistryInstance, type McpRegistryOptions, type McpServiceInstance, type McpStdioServerOptions, type McpToolDefinition, type MethodSpec, type OAuthConfig, type OAuthProvider, type OAuthTokenResponse, PrismaDelegate, QuickdrawServerOptions, QuickdrawServerResult, QuickdrawSocket, type RateLimitOptions, type RateLimiter, type RedisAdapterOptions, type RedisAdapterResult, type ServiceInfo, type ServiceMethodInfo, ServiceRegistry, ServiceRegistryInstance, type ServiceRegistryOptions, type ServiceToolSpec, type ValidateEnvOptions, type ZodToAdminFieldsOptions, applyRateLimitMiddleware, bootstrapMcpServer, checkEnv, createJWT, createMcpRoutes, createMcpStdioServer, createOAuthURL, createQuickdrawServer, createRateLimiter, createTieredRateLimiter, discordProvider, exchangeOAuthCode, generateToolMetadata, getDefaultEntityFields, googleProvider, isRedisAdapterAvailable, mergeWithDefaultFields, requireEnv, setupRedisAdapter, validateEnv, verifyJWT, zodToAdminFields };
1335
+ export { AdminListPayload, AdminListResponse, AdminSetACLPayload, AdminSubscribersResponse, type AuthRequest, type AuthResponse, BaseService, BaseServiceInstance, BaseServiceOptions, type CookieResponse, type CookieSettings, DEFAULT_MOCK_PATH_PREFIX, type DiscordUser, type EnvValidationResult, type GenerateToolMetadataOptions, type GoogleUser, InstallAdminMethodsOptions, type JWTPayload, type McpHttpRoutesOptions, ServiceMethodContext as McpMethodContext, ServiceMethodDefinition as McpMethodDefinition, McpRegistry, type McpRegistryInstance, type McpRegistryOptions, type McpServiceInstance, type McpStdioServerOptions, type McpToolDefinition, type MethodSpec, type MockOAuthProviderOptions, type MockOAuthRouter, type MockOAuthUser, OAUTH_RETURN_ORIGIN_COOKIE, type OAuthConfig, type OAuthProvider, type OAuthTokenResponse, PrismaDelegate, QuickdrawServerOptions, QuickdrawServerResult, QuickdrawSocket, type RateLimitOptions, type RateLimiter, type RedisAdapterOptions, type RedisAdapterResult, type RegisterMockOAuthOptions, type RequireAuthOptions, SESSION_COOKIE, type ServiceInfo, type ServiceMethodInfo, ServiceRegistry, ServiceRegistryInstance, type ServiceRegistryOptions, type ServiceToolSpec, type SessionCookieOptions, type ValidateEnvOptions, type ValidateOriginOptions, type ZodToAdminFieldsOptions, applyRateLimitMiddleware, bootstrapMcpServer, checkEnv, clearSessionCookie, createJWT, createMcpRoutes, createMcpStdioServer, createMockOAuthProvider, createOAuthURL, createQuickdrawServer, createRateLimiter, createRequireAuth, createTieredRateLimiter, decrypt, decryptIfEncrypted, discordProvider, encrypt, exchangeOAuthCode, extractBearerOrCookieToken, generateToolMetadata, getDefaultEntityFields, getDiscordAvatarUrl, googleProvider, isEncrypted, isMockOAuthEnabled, isRedisAdapterAvailable, mergeWithDefaultFields, registerMockOAuthProvider, requireEnv, setSessionCookie, setupRedisAdapter, tryDecrypt, validateEnv, validateRedirectOrigin, verifyJWT, zodToAdminFields };