@technomoron/api-server-base 2.0.0-beta.21 → 2.0.0-beta.23

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 (177) hide show
  1. package/dist/cjs/common/types.cjs +10 -0
  2. package/dist/cjs/common/types.d.ts +137 -0
  3. package/dist/cjs/{api-module.cjs → server/src/api-module.cjs} +8 -0
  4. package/dist/{esm → cjs/server/src}/api-module.d.ts +15 -0
  5. package/dist/cjs/{api-server-base.cjs → server/src/api-server-base.cjs} +669 -627
  6. package/dist/{esm → cjs/server/src}/api-server-base.d.ts +105 -78
  7. package/dist/cjs/{auth-api/auth-module.js → server/src/auth-api/auth-module.cjs} +96 -76
  8. package/dist/cjs/{auth-api → server/src/auth-api}/auth-module.d.ts +1 -1
  9. package/dist/cjs/{auth-api/compat-auth-storage.js → server/src/auth-api/compat-auth-storage.cjs} +4 -4
  10. package/dist/cjs/{auth-api/mem-auth-store.js → server/src/auth-api/mem-auth-store.cjs} +7 -7
  11. package/dist/cjs/{auth-api/module.js → server/src/auth-api/module.cjs} +1 -1
  12. package/dist/cjs/server/src/auth-api/schemas.cjs +171 -0
  13. package/dist/cjs/server/src/auth-api/schemas.d.ts +21 -0
  14. package/dist/cjs/{auth-api/sql-auth-store.js → server/src/auth-api/sql-auth-store.cjs} +8 -8
  15. package/dist/cjs/{auth-api/user-id.js → server/src/auth-api/user-id.cjs} +12 -3
  16. package/dist/{esm → cjs/server/src}/auth-cookie-options.d.ts +5 -3
  17. package/dist/cjs/server/src/base/client-info.cjs +285 -0
  18. package/dist/cjs/server/src/base/client-info.d.ts +27 -0
  19. package/dist/cjs/server/src/base/error-utils.cjs +50 -0
  20. package/dist/cjs/server/src/base/error-utils.d.ts +16 -0
  21. package/dist/cjs/server/src/base/request-utils.cjs +27 -0
  22. package/dist/cjs/server/src/base/request-utils.d.ts +8 -0
  23. package/dist/cjs/{index.cjs → server/src/index.cjs} +24 -15
  24. package/dist/{esm → cjs/server/src}/index.d.ts +7 -0
  25. package/dist/cjs/server/src/limiter/auth-rate-limiter.cjs +35 -0
  26. package/dist/cjs/server/src/limiter/auth-rate-limiter.d.ts +12 -0
  27. package/dist/cjs/server/src/limiter/fixed-window.cjs +41 -0
  28. package/dist/cjs/server/src/limiter/fixed-window.d.ts +11 -0
  29. package/dist/cjs/{oauth/base.js → server/src/oauth/base.cjs} +1 -0
  30. package/dist/cjs/{oauth → server/src/oauth}/base.d.ts +8 -1
  31. package/dist/cjs/{oauth/memory.js → server/src/oauth/memory.cjs} +7 -4
  32. package/dist/{esm → cjs/server/src}/oauth/memory.d.ts +1 -1
  33. package/dist/cjs/{oauth/models.js → server/src/oauth/models.cjs} +2 -2
  34. package/dist/cjs/{oauth/sequelize.js → server/src/oauth/sequelize.cjs} +11 -7
  35. package/dist/{esm → cjs/server/src}/oauth/sequelize.d.ts +1 -1
  36. package/dist/cjs/{passkey/base.js → server/src/passkey/base.cjs} +1 -0
  37. package/dist/{esm → cjs/server/src}/passkey/base.d.ts +11 -0
  38. package/dist/cjs/{passkey/memory.js → server/src/passkey/memory.cjs} +2 -2
  39. package/dist/cjs/{passkey/models.js → server/src/passkey/models.cjs} +1 -1
  40. package/dist/cjs/{passkey/sequelize.js → server/src/passkey/sequelize.cjs} +3 -3
  41. package/dist/cjs/{passkey/service.js → server/src/passkey/service.cjs} +17 -3
  42. package/dist/{esm → cjs/server/src}/passkey/service.d.ts +1 -1
  43. package/dist/cjs/{sequelize-utils.js → server/src/sequelize-utils.cjs} +4 -5
  44. package/dist/cjs/{token/base.js → server/src/token/base.cjs} +4 -0
  45. package/dist/{esm → cjs/server/src}/token/base.d.ts +7 -0
  46. package/dist/cjs/{token/memory.js → server/src/token/memory.cjs} +15 -20
  47. package/dist/cjs/{token/sequelize.js → server/src/token/sequelize.cjs} +25 -11
  48. package/dist/cjs/server/src/upload/memory.cjs +92 -0
  49. package/dist/cjs/server/src/upload/memory.d.ts +17 -0
  50. package/dist/cjs/server/src/upload/tus-module.cjs +270 -0
  51. package/dist/cjs/server/src/upload/tus-module.d.ts +38 -0
  52. package/dist/cjs/server/src/upload/types.d.ts +8 -0
  53. package/dist/cjs/{user/base.js → server/src/user/base.cjs} +1 -0
  54. package/dist/cjs/{user → server/src/user}/base.d.ts +9 -0
  55. package/dist/cjs/{user/memory.js → server/src/user/memory.cjs} +29 -7
  56. package/dist/cjs/{user/sequelize.js → server/src/user/sequelize.cjs} +33 -8
  57. package/dist/cjs/server/src/user/types.cjs +2 -0
  58. package/dist/esm/common/types.d.ts +137 -0
  59. package/dist/esm/common/types.js +9 -0
  60. package/dist/{cjs → esm/server/src}/api-module.d.ts +15 -0
  61. package/dist/esm/{api-module.js → server/src/api-module.js} +8 -0
  62. package/dist/{cjs → esm/server/src}/api-server-base.d.ts +105 -78
  63. package/dist/esm/{api-server-base.js → server/src/api-server-base.js} +658 -616
  64. package/dist/esm/{auth-api → server/src/auth-api}/auth-module.d.ts +1 -1
  65. package/dist/esm/{auth-api → server/src/auth-api}/auth-module.js +92 -72
  66. package/dist/esm/{auth-api → server/src/auth-api}/compat-auth-storage.js +3 -3
  67. package/dist/esm/server/src/auth-api/schemas.d.ts +21 -0
  68. package/dist/esm/server/src/auth-api/schemas.js +168 -0
  69. package/dist/esm/{auth-api → server/src/auth-api}/user-id.js +12 -3
  70. package/dist/{cjs → esm/server/src}/auth-cookie-options.d.ts +5 -3
  71. package/dist/esm/server/src/base/client-info.d.ts +27 -0
  72. package/dist/esm/server/src/base/client-info.js +282 -0
  73. package/dist/esm/server/src/base/error-utils.d.ts +16 -0
  74. package/dist/esm/server/src/base/error-utils.js +44 -0
  75. package/dist/esm/server/src/base/request-utils.d.ts +8 -0
  76. package/dist/esm/server/src/base/request-utils.js +23 -0
  77. package/dist/{cjs → esm/server/src}/index.d.ts +7 -0
  78. package/dist/esm/{index.js → server/src/index.js} +4 -0
  79. package/dist/esm/server/src/limiter/auth-rate-limiter.d.ts +12 -0
  80. package/dist/esm/server/src/limiter/auth-rate-limiter.js +32 -0
  81. package/dist/esm/server/src/limiter/fixed-window.d.ts +11 -0
  82. package/dist/esm/server/src/limiter/fixed-window.js +37 -0
  83. package/dist/esm/{oauth → server/src/oauth}/base.d.ts +8 -1
  84. package/dist/esm/server/src/oauth/base.js +3 -0
  85. package/dist/{cjs → esm/server/src}/oauth/memory.d.ts +1 -1
  86. package/dist/esm/{oauth → server/src/oauth}/memory.js +5 -2
  87. package/dist/{cjs → esm/server/src}/oauth/sequelize.d.ts +1 -1
  88. package/dist/esm/{oauth → server/src/oauth}/sequelize.js +6 -2
  89. package/dist/{cjs → esm/server/src}/passkey/base.d.ts +11 -0
  90. package/dist/esm/server/src/passkey/base.js +3 -0
  91. package/dist/{cjs → esm/server/src}/passkey/service.d.ts +1 -1
  92. package/dist/esm/{passkey → server/src/passkey}/service.js +17 -3
  93. package/dist/esm/{sequelize-utils.js → server/src/sequelize-utils.js} +4 -5
  94. package/dist/{cjs → esm/server/src}/token/base.d.ts +7 -0
  95. package/dist/esm/{token → server/src/token}/base.js +4 -0
  96. package/dist/esm/{token → server/src/token}/memory.js +14 -19
  97. package/dist/esm/{token → server/src/token}/sequelize.js +22 -8
  98. package/dist/esm/server/src/upload/memory.d.ts +17 -0
  99. package/dist/esm/server/src/upload/memory.js +86 -0
  100. package/dist/esm/server/src/upload/tus-module.d.ts +38 -0
  101. package/dist/esm/server/src/upload/tus-module.js +266 -0
  102. package/dist/esm/server/src/upload/types.d.ts +8 -0
  103. package/dist/esm/{user → server/src/user}/base.d.ts +9 -0
  104. package/dist/esm/{user → server/src/user}/base.js +1 -0
  105. package/dist/esm/{user → server/src/user}/memory.js +27 -5
  106. package/dist/esm/{user → server/src/user}/sequelize.js +30 -5
  107. package/dist/esm/server/src/user/types.js +1 -0
  108. package/docs/swagger/openapi.json +411 -125
  109. package/package.json +129 -134
  110. package/README.txt +0 -213
  111. package/dist/esm/oauth/base.js +0 -2
  112. package/dist/esm/passkey/base.js +0 -2
  113. /package/dist/cjs/{auth-api → server/src/auth-api}/compat-auth-storage.d.ts +0 -0
  114. /package/dist/cjs/{auth-api → server/src/auth-api}/mem-auth-store.d.ts +0 -0
  115. /package/dist/cjs/{auth-api → server/src/auth-api}/module.d.ts +0 -0
  116. /package/dist/cjs/{auth-api → server/src/auth-api}/sql-auth-store.d.ts +0 -0
  117. /package/dist/cjs/{auth-api/storage.js → server/src/auth-api/storage.cjs} +0 -0
  118. /package/dist/cjs/{auth-api → server/src/auth-api}/storage.d.ts +0 -0
  119. /package/dist/cjs/{auth-api/types.js → server/src/auth-api/types.cjs} +0 -0
  120. /package/dist/cjs/{auth-api → server/src/auth-api}/types.d.ts +0 -0
  121. /package/dist/cjs/{auth-api → server/src/auth-api}/user-id.d.ts +0 -0
  122. /package/dist/cjs/{auth-cookie-options.js → server/src/auth-cookie-options.cjs} +0 -0
  123. /package/dist/cjs/{oauth → server/src/oauth}/models.d.ts +0 -0
  124. /package/dist/cjs/{oauth/types.js → server/src/oauth/types.cjs} +0 -0
  125. /package/dist/cjs/{oauth → server/src/oauth}/types.d.ts +0 -0
  126. /package/dist/cjs/{passkey/config.js → server/src/passkey/config.cjs} +0 -0
  127. /package/dist/cjs/{passkey → server/src/passkey}/config.d.ts +0 -0
  128. /package/dist/cjs/{passkey → server/src/passkey}/memory.d.ts +0 -0
  129. /package/dist/cjs/{passkey → server/src/passkey}/models.d.ts +0 -0
  130. /package/dist/cjs/{passkey → server/src/passkey}/sequelize.d.ts +0 -0
  131. /package/dist/cjs/{passkey/types.js → server/src/passkey/types.cjs} +0 -0
  132. /package/dist/cjs/{passkey → server/src/passkey}/types.d.ts +0 -0
  133. /package/dist/cjs/{sequelize-utils.d.ts → server/src/sequelize-utils.d.ts} +0 -0
  134. /package/dist/cjs/{token → server/src/token}/memory.d.ts +0 -0
  135. /package/dist/cjs/{token → server/src/token}/sequelize.d.ts +0 -0
  136. /package/dist/cjs/{token/types.js → server/src/token/types.cjs} +0 -0
  137. /package/dist/cjs/{token → server/src/token}/types.d.ts +0 -0
  138. /package/dist/cjs/{user/types.js → server/src/upload/types.cjs} +0 -0
  139. /package/dist/cjs/{user → server/src/user}/memory.d.ts +0 -0
  140. /package/dist/cjs/{user → server/src/user}/sequelize.d.ts +0 -0
  141. /package/dist/cjs/{user → server/src/user}/types.d.ts +0 -0
  142. /package/dist/esm/{auth-api → server/src/auth-api}/compat-auth-storage.d.ts +0 -0
  143. /package/dist/esm/{auth-api → server/src/auth-api}/mem-auth-store.d.ts +0 -0
  144. /package/dist/esm/{auth-api → server/src/auth-api}/mem-auth-store.js +0 -0
  145. /package/dist/esm/{auth-api → server/src/auth-api}/module.d.ts +0 -0
  146. /package/dist/esm/{auth-api → server/src/auth-api}/module.js +0 -0
  147. /package/dist/esm/{auth-api → server/src/auth-api}/sql-auth-store.d.ts +0 -0
  148. /package/dist/esm/{auth-api → server/src/auth-api}/sql-auth-store.js +0 -0
  149. /package/dist/esm/{auth-api → server/src/auth-api}/storage.d.ts +0 -0
  150. /package/dist/esm/{auth-api → server/src/auth-api}/storage.js +0 -0
  151. /package/dist/esm/{auth-api → server/src/auth-api}/types.d.ts +0 -0
  152. /package/dist/esm/{auth-api → server/src/auth-api}/types.js +0 -0
  153. /package/dist/esm/{auth-api → server/src/auth-api}/user-id.d.ts +0 -0
  154. /package/dist/esm/{auth-cookie-options.js → server/src/auth-cookie-options.js} +0 -0
  155. /package/dist/esm/{oauth → server/src/oauth}/models.d.ts +0 -0
  156. /package/dist/esm/{oauth → server/src/oauth}/models.js +0 -0
  157. /package/dist/esm/{oauth → server/src/oauth}/types.d.ts +0 -0
  158. /package/dist/esm/{oauth → server/src/oauth}/types.js +0 -0
  159. /package/dist/esm/{passkey → server/src/passkey}/config.d.ts +0 -0
  160. /package/dist/esm/{passkey → server/src/passkey}/config.js +0 -0
  161. /package/dist/esm/{passkey → server/src/passkey}/memory.d.ts +0 -0
  162. /package/dist/esm/{passkey → server/src/passkey}/memory.js +0 -0
  163. /package/dist/esm/{passkey → server/src/passkey}/models.d.ts +0 -0
  164. /package/dist/esm/{passkey → server/src/passkey}/models.js +0 -0
  165. /package/dist/esm/{passkey → server/src/passkey}/sequelize.d.ts +0 -0
  166. /package/dist/esm/{passkey → server/src/passkey}/sequelize.js +0 -0
  167. /package/dist/esm/{passkey → server/src/passkey}/types.d.ts +0 -0
  168. /package/dist/esm/{passkey → server/src/passkey}/types.js +0 -0
  169. /package/dist/esm/{sequelize-utils.d.ts → server/src/sequelize-utils.d.ts} +0 -0
  170. /package/dist/esm/{token → server/src/token}/memory.d.ts +0 -0
  171. /package/dist/esm/{token → server/src/token}/sequelize.d.ts +0 -0
  172. /package/dist/esm/{token → server/src/token}/types.d.ts +0 -0
  173. /package/dist/esm/{token → server/src/token}/types.js +0 -0
  174. /package/dist/esm/{user → server/src/upload}/types.js +0 -0
  175. /package/dist/esm/{user → server/src/user}/memory.d.ts +0 -0
  176. /package/dist/esm/{user → server/src/user}/sequelize.d.ts +0 -0
  177. /package/dist/esm/{user → server/src/user}/types.d.ts +0 -0
@@ -4,7 +4,10 @@ export type ApiHandler<Data = unknown> = (apiReq: ApiRequest) => Promise<ApiHand
4
4
  export type ApiAuthType = 'none' | 'maybe' | 'yes' | 'strict' | 'apikey';
5
5
  export type ApiAuthClass = 'any' | 'admin';
6
6
  export interface ApiKey {
7
+ /** Real user identity — who the key belongs to. */
7
8
  uid: unknown;
9
+ /** Effective user identity — who the key acts as. When set, the request is treated as impersonation (isImpersonating() === true). */
10
+ euid?: unknown;
8
11
  }
9
12
  export type ApiRoute = {
10
13
  method: 'get' | 'post' | 'put' | 'patch' | 'delete';
@@ -14,17 +17,29 @@ export type ApiRoute = {
14
17
  type: ApiAuthType;
15
18
  req: ApiAuthClass;
16
19
  };
20
+ schema?: {
21
+ body?: Record<string, unknown>;
22
+ querystring?: Record<string, unknown>;
23
+ params?: Record<string, unknown>;
24
+ };
17
25
  };
26
+ /** Base class for feature modules mounted into {@link ApiServer}. */
18
27
  export declare class ApiModule<T = unknown> {
19
28
  private _server?;
29
+ /** The server instance this module is mounted on. */
20
30
  get server(): T;
21
31
  set server(value: T);
32
+ /** Route namespace under `apiBasePath`. */
22
33
  namespace: string;
23
34
  mountpath: string;
24
35
  static defaultNamespace: string;
25
36
  constructor(opts?: {
26
37
  namespace?: string;
27
38
  });
39
+ /** Optional pre-mount configuration validation hook. */
28
40
  checkConfig(): boolean;
41
+ /** Return all routes exposed by this module. */
29
42
  defineRoutes(): ApiRoute[];
43
+ /** Optional mount-time hook for modules that need direct server integration. */
44
+ onMount(): void;
30
45
  }
@@ -1,4 +1,6 @@
1
+ /** Base class for feature modules mounted into {@link ApiServer}. */
1
2
  export class ApiModule {
3
+ /** The server instance this module is mounted on. */
2
4
  get server() {
3
5
  if (this._server === undefined) {
4
6
  throw new Error('ApiModule.server is not set. Mount the module with ApiServer.api(...) before using it.');
@@ -12,11 +14,17 @@ export class ApiModule {
12
14
  this.mountpath = '';
13
15
  this.namespace = opts.namespace ?? this.constructor.defaultNamespace ?? '';
14
16
  }
17
+ /** Optional pre-mount configuration validation hook. */
15
18
  checkConfig() {
16
19
  return true;
17
20
  }
21
+ /** Return all routes exposed by this module. */
18
22
  defineRoutes() {
19
23
  return [];
20
24
  }
25
+ /** Optional mount-time hook for modules that need direct server integration. */
26
+ onMount() {
27
+ return;
28
+ }
21
29
  }
22
30
  ApiModule.defaultNamespace = '';
@@ -4,41 +4,80 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import { Application, Request, Response, type ErrorRequestHandler, type RequestHandler } from 'express';
7
+ import { type FastifyInstance, type FastifyReply, type FastifyRequest } from 'fastify';
8
8
  import { ApiModule } from './api-module.js';
9
+ import { type ClientInfo } from './base/client-info.js';
9
10
  import { TokenStore, type JwtDecodeResult, type JwtSignPayload, type JwtSignResult, type JwtVerifyResult } from './token/base.js';
10
- import type { ApiAuthClass, ApiAuthType, ApiKey } from './api-module.js';
11
+ import type { ApiAuthClass, ApiAuthType, ApiHandler, ApiKey } from './api-module.js';
11
12
  import type { AuthProviderModule } from './auth-api/module.js';
12
13
  import type { AuthAdapter, AuthIdentifier } from './auth-api/types.js';
13
- import type { OAuthStore } from './oauth/base.js';
14
14
  import type { AuthCodeData, AuthCodeRequest, OAuthClient } from './oauth/types.js';
15
- import type { PasskeyService } from './passkey/service.js';
16
15
  import type { PasskeyChallenge, PasskeyChallengeParams, StoredPasskeyCredential, PasskeyVerificationParams, PasskeyVerificationResult } from './passkey/types.js';
17
16
  import type { Token } from './token/types.js';
18
- import type { UserStore } from './user/base.js';
19
17
  import type { JwtPayload, SignOptions, VerifyOptions } from 'jsonwebtoken';
20
- export type { Application, Request, Response, NextFunction, Router } from 'express';
21
- export type { Multer } from 'multer';
22
18
  export type { JwtPayload, SignOptions, VerifyOptions } from 'jsonwebtoken';
23
- export interface ExtendedReq extends Request {
24
- file?: Express.Multer.File;
25
- files?: Express.Multer.File[] | {
26
- [fieldname: string]: Express.Multer.File[];
19
+ export type { ClientAgentProfile, ClientInfo } from './base/client-info.js';
20
+ export interface ApiCookieOptions {
21
+ httpOnly?: boolean;
22
+ secure?: boolean;
23
+ sameSite?: 'lax' | 'strict' | 'none';
24
+ domain?: string;
25
+ path?: string;
26
+ maxAge?: number;
27
+ expires?: Date;
28
+ }
29
+ export interface ApiUploadedFile {
30
+ fieldname: string;
31
+ originalname: string;
32
+ encoding: string;
33
+ mimetype: string;
34
+ size?: number;
35
+ buffer?: Buffer;
36
+ filepath?: string;
37
+ }
38
+ export interface ExtendedReq {
39
+ method: string;
40
+ url: string;
41
+ originalUrl?: string;
42
+ headers: Record<string, string | string[] | undefined>;
43
+ query: Record<string, unknown>;
44
+ body: unknown;
45
+ params: Record<string, unknown>;
46
+ cookies?: Record<string, string>;
47
+ ip?: string;
48
+ ips?: string[];
49
+ socket?: {
50
+ remoteAddress?: string;
27
51
  };
52
+ protocol?: string;
53
+ file?: ApiUploadedFile;
54
+ files?: ApiUploadedFile[] | Record<string, ApiUploadedFile[]>;
55
+ apiReq?: ApiRequest;
56
+ }
57
+ export interface ApiResponse {
58
+ locals: Record<string, unknown>;
59
+ headersSent: boolean;
60
+ status: (code: number) => ApiResponse;
61
+ json: (payload: unknown) => void;
62
+ send: (payload: unknown) => void;
63
+ cookie: (name: string, value: string, options?: ApiCookieOptions) => void;
64
+ clearCookie: (name: string, options?: ApiCookieOptions) => void;
28
65
  }
29
66
  export interface ApiTokenData extends JwtPayload, Partial<Token> {
30
67
  uid: unknown;
31
68
  iat?: number;
32
69
  exp?: number;
33
70
  }
71
+ export type ApiAuthMethod = 'bearer' | 'cookie' | 'param' | 'apikey' | null;
34
72
  export interface ApiRequest {
35
73
  server: ApiServer;
36
74
  req: ExtendedReq;
37
- res: Response;
75
+ res: ApiResponse;
38
76
  tokenData?: ApiTokenData | null;
39
77
  token?: string;
40
78
  authToken?: Token | null;
41
79
  apiKey?: ApiKey | null;
80
+ authMethod?: ApiAuthMethod;
42
81
  clientInfo?: ClientInfo;
43
82
  realUid?: AuthIdentifier | null;
44
83
  getClientInfo: () => ClientInfo;
@@ -47,32 +86,13 @@ export interface ApiRequest {
47
86
  getRealUid: () => AuthIdentifier | null;
48
87
  isImpersonating: () => boolean;
49
88
  }
50
- export interface ExpressApiRequest extends ExtendedReq {
51
- apiReq?: ApiRequest;
52
- }
89
+ export type ExpressApiRequest = ExtendedReq;
53
90
  export interface ExpressApiLocals {
54
91
  apiReq?: ApiRequest;
55
92
  }
56
- export interface ClientAgentProfile {
57
- ua: string;
58
- browser: string;
59
- os: string;
60
- device: string;
61
- }
62
- export interface ClientInfo extends ClientAgentProfile {
63
- ip: string | null;
64
- ipchain: string[];
65
- }
66
- export interface ApiServerAuthStores {
67
- userStore: UserStore<unknown, unknown>;
68
- tokenStore: TokenStore;
69
- passkeyService?: PasskeyService;
70
- oauthStore?: OAuthStore;
71
- canImpersonate?: (params: {
72
- realUserId: AuthIdentifier;
73
- effectiveUserId: AuthIdentifier;
74
- }) => boolean | Promise<boolean>;
75
- }
93
+ type CompatNext = (error?: unknown) => void;
94
+ type CompatRequestHandler = (req: ExtendedReq, res: ApiResponse, next: CompatNext) => unknown;
95
+ type CompatErrorHandler = (err: unknown, req: ExtendedReq, res: ApiResponse, next: CompatNext) => unknown;
76
96
  export { ApiModule } from './api-module.js';
77
97
  export type { ApiHandler, ApiAuthType, ApiAuthClass, ApiRoute, ApiKey } from './api-module.js';
78
98
  export interface ApiErrorParams {
@@ -100,21 +120,15 @@ export interface ApiServerConf {
100
120
  swaggerPath?: string;
101
121
  accessSecret: string;
102
122
  refreshSecret: string;
103
- /** Cookie domain for auth cookies. Prefer leaving empty for localhost/development. */
104
123
  cookieDomain: string;
105
- /** Cookie path for auth cookies. */
106
124
  cookiePath?: string;
107
- /** Cookie SameSite attribute for auth cookies. */
108
125
  cookieSameSite?: 'lax' | 'strict' | 'none';
109
- /**
110
- * Cookie Secure attribute for auth cookies.
111
- * - true: always secure
112
- * - false: never secure
113
- * - 'auto': secure when request is HTTPS (or forwarded as HTTPS)
114
- */
115
126
  cookieSecure?: boolean | 'auto';
116
- /** Cookie HttpOnly attribute for auth cookies. */
117
127
  cookieHttpOnly?: boolean;
128
+ apiKeyPrefix: string;
129
+ apiKeyEnabled: boolean;
130
+ tokenParam: string;
131
+ tokenParamLocation: 'body' | 'query' | 'body-query';
118
132
  accessCookie: string;
119
133
  refreshCookie: string;
120
134
  accessExpiry: number;
@@ -128,60 +142,51 @@ export interface ApiServerConf {
128
142
  apiVersion: string;
129
143
  minClientVersion: string;
130
144
  tokenStore?: TokenStore;
131
- authStores?: ApiServerAuthStores;
132
145
  onStartError?: (error: Error) => void;
146
+ /**
147
+ * Controls trust in proxy headers (X-Forwarded-For, Forwarded, X-Real-IP).
148
+ * - `true` (default): trust all forwarded headers
149
+ * - `false`: only use the socket address, ignore forwarded headers
150
+ * - number: trust that many rightmost forwarded entries (e.g., 1 = one reverse proxy)
151
+ */
152
+ trustProxy: boolean | number;
133
153
  }
154
+ /** Core Fastify-based API server with module mounting and auth integration hooks. */
134
155
  export declare class ApiServer {
135
- app: Application;
156
+ readonly app: ((req: import('node:http').IncomingMessage, res: import('node:http').ServerResponse) => void) & {
157
+ listen: (...args: unknown[]) => import('node:http').Server;
158
+ };
159
+ readonly fastify: FastifyInstance;
136
160
  readonly config: ApiServerConf;
137
161
  readonly startedAt: number;
138
162
  private readonly apiBasePath;
139
- private readonly apiRouter;
140
163
  private finalized;
141
164
  private storageAdapter;
142
165
  private moduleAdapter;
143
- private serverAuthAdapter;
144
- private apiNotFoundHandler;
145
166
  private apiErrorHandlerInstalled;
146
167
  private tokenStoreAdapter;
147
- private userStoreAdapter;
148
- private passkeyServiceAdapter;
149
- private oauthStoreAdapter;
150
- private canImpersonateAdapter;
151
168
  private readonly jwtHelper;
169
+ private compatGlobalErrorHandler;
170
+ private readonly readyPromise;
152
171
  private currReqDeprecationWarned;
153
- /**
154
- * @deprecated ApiServer does not track a global "current request". This value is always null.
155
- * Use the per-request ApiRequest passed to handlers, or `req.apiReq` / `res.locals.apiReq`
156
- * when mounting raw Express endpoints.
157
- */
158
172
  get currReq(): ApiRequest | null;
159
173
  set currReq(_value: ApiRequest | null);
160
174
  constructor(config?: Partial<ApiServerConf>);
175
+ private setupRuntime;
176
+ private readRawBody;
177
+ private parseRawBody;
161
178
  private assertNotFinalized;
162
- private toApiRouterPath;
163
179
  finalize(): this;
164
180
  authStorage<UserRow, SafeUser>(storage: AuthAdapter<UserRow, SafeUser>): this;
165
- /**
166
- * @deprecated Use {@link ApiServer.authStorage} instead.
167
- */
168
181
  useAuthStorage<UserRow, SafeUser>(storage: AuthAdapter<UserRow, SafeUser>): this;
169
182
  authModule<UserRow>(module: AuthProviderModule<UserRow>): this;
170
- /**
171
- * @deprecated Use {@link ApiServer.authModule} instead.
172
- */
173
183
  useAuthModule<UserRow>(module: AuthProviderModule<UserRow>): this;
174
184
  getAuthStorage<UserRow = unknown, SafeUser = unknown>(): AuthAdapter<UserRow, SafeUser>;
175
185
  getAuthModule<UserRow = unknown>(): AuthProviderModule<UserRow>;
176
186
  setTokenStore(store: TokenStore): this;
177
187
  getTokenStore(): TokenStore | null;
178
- private ensureUserStore;
179
- private ensureTokenStore;
180
- private ensurePasskeyService;
181
188
  listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
182
189
  deletePasskeyCredential(credentialId: Buffer | string): Promise<boolean>;
183
- private ensureOAuthStore;
184
- private getServerAuthAdapter;
185
190
  getUser(identifier: AuthIdentifier): Promise<unknown | null>;
186
191
  getUserPasswordHash(user: unknown): string;
187
192
  getUserId(user: unknown): AuthIdentifier;
@@ -221,39 +226,61 @@ export declare class ApiServer {
221
226
  }): Promise<boolean>;
222
227
  guessExceptionText(error: unknown, defMsg?: string): string;
223
228
  protected authorize(apiReq: ApiRequest, requiredClass: ApiAuthClass): Promise<void>;
224
- private middlewares;
229
+ /**
230
+ * Authenticate and authorise an incoming Fastify request outside of the
231
+ * standard `defineRoutes` pipeline (e.g. TUS upload routes that need full
232
+ * control over their own response format).
233
+ *
234
+ * Throws `ApiError` on auth failure — callers should catch it and respond
235
+ * with the appropriate HTTP status code.
236
+ */
237
+ resolveRequest(request: FastifyRequest, reply: FastifyReply, auth: {
238
+ type: ApiAuthType;
239
+ req?: ApiAuthClass;
240
+ }): Promise<ApiRequest>;
225
241
  private installStaticDirs;
226
242
  private installPingHandler;
227
243
  private loadSwaggerSpec;
244
+ private readPackageVersion;
228
245
  private installSwaggerHandler;
229
246
  private normalizeApiBasePath;
230
247
  private installApiNotFoundHandler;
231
248
  private installApiErrorHandler;
232
- private describeMissingEndpoint;
233
249
  start(): this;
234
250
  private internalServerErrorMessage;
251
+ private logUnhandledError;
235
252
  private verifyJWT;
236
253
  private jwtCookieOptions;
237
254
  private setAccessCookie;
238
255
  private tryRefreshAccessToken;
239
256
  private authenticate;
240
257
  private tryAuthenticateApiKey;
258
+ private resolveTokenFromRequest;
259
+ private readNamedValue;
241
260
  private requiresAuthToken;
242
261
  private shouldValidateStoredToken;
243
262
  private assertStoredAccessToken;
244
263
  private normalizeAuthIdentifier;
245
264
  private extractTokenUserId;
246
265
  private resolveRealUserId;
247
- useExpress(path: string, ...handlers: Array<RequestHandler | ErrorRequestHandler>): this;
248
- useExpress(...handlers: Array<RequestHandler | ErrorRequestHandler>): this;
266
+ private toExtendedReq;
249
267
  private createApiRequest;
268
+ useExpress(path: string, ...handlers: Array<CompatRequestHandler | CompatErrorHandler>): this;
269
+ useExpress(...handlers: Array<CompatRequestHandler | CompatErrorHandler>): this;
270
+ private runCompatHandlers;
271
+ private runCompatErrorHandlers;
250
272
  expressAuth(auth: {
251
273
  type: ApiAuthType;
252
274
  req: ApiAuthClass;
253
- }): RequestHandler;
254
- expressErrorHandler(): ErrorRequestHandler;
255
- private handle_request;
275
+ }): CompatRequestHandler;
276
+ expressErrorHandler(): CompatErrorHandler;
277
+ private handleRequest;
278
+ protected handle_request(handler: ApiHandler, auth: {
279
+ type: ApiAuthType;
280
+ req: ApiAuthClass;
281
+ }): (req: ExtendedReq, res: ApiResponse, next: (error?: unknown) => void) => Promise<void>;
256
282
  api<T extends ApiModule<unknown>>(module: T): this;
283
+ private joinRoutePath;
257
284
  dumpRequest(apiReq: ApiRequest): void;
258
285
  private formatDebugValue;
259
286
  dumpResponse(apiReq: ApiRequest, payload: unknown, status: number): void;