@nodefony/http 10.0.0-alpha.1

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 (155) hide show
  1. package/LICENSE +544 -0
  2. package/README.md +77 -0
  3. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateParam.js +8 -0
  6. package/dist/index.js +108 -0
  7. package/dist/nodefony/command/assetsPublishCommand.js +102 -0
  8. package/dist/nodefony/command/certificatesCommand.js +47 -0
  9. package/dist/nodefony/command/networkCommand.js +27 -0
  10. package/dist/nodefony/command/proxyGenerateCommand.js +66 -0
  11. package/dist/nodefony/config/config.js +335 -0
  12. package/dist/nodefony/config/defineModuleConfig.js +93 -0
  13. package/dist/nodefony/interfaces/IContext.js +1 -0
  14. package/dist/nodefony/interfaces/ICookie.js +1 -0
  15. package/dist/nodefony/interfaces/IErrorRenderer.js +1 -0
  16. package/dist/nodefony/interfaces/IHttpConfig.js +1 -0
  17. package/dist/nodefony/interfaces/IHttpKernel.js +1 -0
  18. package/dist/nodefony/interfaces/IRequest.js +1 -0
  19. package/dist/nodefony/interfaces/IRequestLogger.js +1 -0
  20. package/dist/nodefony/interfaces/IResponse.js +1 -0
  21. package/dist/nodefony/interfaces/ISession.js +1 -0
  22. package/dist/nodefony/interfaces/IUpload.js +1 -0
  23. package/dist/nodefony/interfaces/index.js +1 -0
  24. package/dist/nodefony/service/HttpAdminApi.js +376 -0
  25. package/dist/nodefony/service/ProfilerAdminApi.js +73 -0
  26. package/dist/nodefony/service/audit-logger.js +159 -0
  27. package/dist/nodefony/service/certificates.js +545 -0
  28. package/dist/nodefony/service/error-renderer.js +320 -0
  29. package/dist/nodefony/service/http-kernel.js +948 -0
  30. package/dist/nodefony/service/pretty-request-logger.js +72 -0
  31. package/dist/nodefony/service/request-logger.js +54 -0
  32. package/dist/nodefony/service/servers/clientError.js +20 -0
  33. package/dist/nodefony/service/servers/server-http.js +135 -0
  34. package/dist/nodefony/service/servers/server-https.js +204 -0
  35. package/dist/nodefony/service/servers/server-static.js +192 -0
  36. package/dist/nodefony/service/servers/server-websocket-secure.js +104 -0
  37. package/dist/nodefony/service/servers/server-websocket.js +104 -0
  38. package/dist/nodefony/service/servers/serverShutdown.js +31 -0
  39. package/dist/nodefony/service/servers/wsHeartbeat.js +64 -0
  40. package/dist/nodefony/service/sessions/sessions-service.js +580 -0
  41. package/dist/nodefony/service/trace.js +72 -0
  42. package/dist/nodefony/service/upload/upload-service.js +171 -0
  43. package/dist/nodefony/src/assets/collectAssets.js +34 -0
  44. package/dist/nodefony/src/assets/prebuiltUi.js +125 -0
  45. package/dist/nodefony/src/context/Context.js +415 -0
  46. package/dist/nodefony/src/context/domainMatcher.js +88 -0
  47. package/dist/nodefony/src/context/forwarded.js +185 -0
  48. package/dist/nodefony/src/context/http/HttpContext.js +309 -0
  49. package/dist/nodefony/src/context/http/Request.js +543 -0
  50. package/dist/nodefony/src/context/http/Response.js +368 -0
  51. package/dist/nodefony/src/context/http/parser.js +188 -0
  52. package/dist/nodefony/src/context/http/urlFastPath.js +103 -0
  53. package/dist/nodefony/src/context/http2/Request.js +29 -0
  54. package/dist/nodefony/src/context/http2/Response.js +97 -0
  55. package/dist/nodefony/src/context/metaData.js +47 -0
  56. package/dist/nodefony/src/context/requestId.js +41 -0
  57. package/dist/nodefony/src/context/trustProxy.js +167 -0
  58. package/dist/nodefony/src/context/websocket/Response.js +181 -0
  59. package/dist/nodefony/src/context/websocket/WebsocketContext.js +389 -0
  60. package/dist/nodefony/src/context/websocket/wsBackpressure.js +56 -0
  61. package/dist/nodefony/src/context/websocket/wsLogContent.js +68 -0
  62. package/dist/nodefony/src/cookies/cookie.js +258 -0
  63. package/dist/nodefony/src/errors/httpError.js +69 -0
  64. package/dist/nodefony/src/profiler/FrameProfile.js +95 -0
  65. package/dist/nodefony/src/profiler/Profiler.js +139 -0
  66. package/dist/nodefony/src/proxy/generateProxyConfig.js +157 -0
  67. package/dist/nodefony/src/rateLimit/IRateLimitStore.js +1 -0
  68. package/dist/nodefony/src/rateLimit/MemoryRateLimitStore.js +146 -0
  69. package/dist/nodefony/src/rateLimit/WsConnectionCounter.js +64 -0
  70. package/dist/nodefony/src/rateLimit/rateLimitFilters.js +20 -0
  71. package/dist/nodefony/src/servers/portBinder.js +114 -0
  72. package/dist/nodefony/src/session/session.js +390 -0
  73. package/dist/nodefony/src/session/storage/MemorySessionStorage.js +185 -0
  74. package/dist/nodefony/src/session/storage/RevocationGuardStorage.js +137 -0
  75. package/dist/nodefony/src/session/storage/sessionFilters.js +83 -0
  76. package/dist/nodefony/src/session/storage/sessionSort.js +53 -0
  77. package/dist/types/index.d.ts +83 -0
  78. package/dist/types/nodefony/command/assetsPublishCommand.d.ts +23 -0
  79. package/dist/types/nodefony/command/certificatesCommand.d.ts +17 -0
  80. package/dist/types/nodefony/command/networkCommand.d.ts +8 -0
  81. package/dist/types/nodefony/command/proxyGenerateCommand.d.ts +19 -0
  82. package/dist/types/nodefony/config/config.d.ts +197 -0
  83. package/dist/types/nodefony/config/defineModuleConfig.d.ts +39 -0
  84. package/dist/types/nodefony/interfaces/IContext.d.ts +138 -0
  85. package/dist/types/nodefony/interfaces/ICookie.d.ts +47 -0
  86. package/dist/types/nodefony/interfaces/IErrorRenderer.d.ts +55 -0
  87. package/dist/types/nodefony/interfaces/IHttpConfig.d.ts +12 -0
  88. package/dist/types/nodefony/interfaces/IHttpKernel.d.ts +10 -0
  89. package/dist/types/nodefony/interfaces/IRequest.d.ts +35 -0
  90. package/dist/types/nodefony/interfaces/IRequestLogger.d.ts +31 -0
  91. package/dist/types/nodefony/interfaces/IResponse.d.ts +39 -0
  92. package/dist/types/nodefony/interfaces/ISession.d.ts +283 -0
  93. package/dist/types/nodefony/interfaces/IUpload.d.ts +66 -0
  94. package/dist/types/nodefony/interfaces/index.d.ts +7 -0
  95. package/dist/types/nodefony/service/HttpAdminApi.d.ts +18 -0
  96. package/dist/types/nodefony/service/ProfilerAdminApi.d.ts +23 -0
  97. package/dist/types/nodefony/service/audit-logger.d.ts +143 -0
  98. package/dist/types/nodefony/service/certificates.d.ts +246 -0
  99. package/dist/types/nodefony/service/error-renderer.d.ts +74 -0
  100. package/dist/types/nodefony/service/http-kernel.d.ts +377 -0
  101. package/dist/types/nodefony/service/pretty-request-logger.d.ts +25 -0
  102. package/dist/types/nodefony/service/request-logger.d.ts +18 -0
  103. package/dist/types/nodefony/service/servers/clientError.d.ts +14 -0
  104. package/dist/types/nodefony/service/servers/server-http.d.ts +42 -0
  105. package/dist/types/nodefony/service/servers/server-https.d.ts +41 -0
  106. package/dist/types/nodefony/service/servers/server-static.d.ts +62 -0
  107. package/dist/types/nodefony/service/servers/server-websocket-secure.d.ts +29 -0
  108. package/dist/types/nodefony/service/servers/server-websocket.d.ts +29 -0
  109. package/dist/types/nodefony/service/servers/serverShutdown.d.ts +27 -0
  110. package/dist/types/nodefony/service/servers/wsHeartbeat.d.ts +46 -0
  111. package/dist/types/nodefony/service/sessions/sessions-service.d.ts +218 -0
  112. package/dist/types/nodefony/service/trace.d.ts +39 -0
  113. package/dist/types/nodefony/service/upload/upload-service.d.ts +61 -0
  114. package/dist/types/nodefony/src/assets/collectAssets.d.ts +35 -0
  115. package/dist/types/nodefony/src/assets/prebuiltUi.d.ts +99 -0
  116. package/dist/types/nodefony/src/context/Context.d.ts +195 -0
  117. package/dist/types/nodefony/src/context/domainMatcher.d.ts +67 -0
  118. package/dist/types/nodefony/src/context/forwarded.d.ts +95 -0
  119. package/dist/types/nodefony/src/context/http/HttpContext.d.ts +85 -0
  120. package/dist/types/nodefony/src/context/http/Request.d.ts +203 -0
  121. package/dist/types/nodefony/src/context/http/Response.d.ts +68 -0
  122. package/dist/types/nodefony/src/context/http/parser.d.ts +65 -0
  123. package/dist/types/nodefony/src/context/http/urlFastPath.d.ts +52 -0
  124. package/dist/types/nodefony/src/context/http2/Request.d.ts +14 -0
  125. package/dist/types/nodefony/src/context/http2/Response.d.ts +20 -0
  126. package/dist/types/nodefony/src/context/metaData.d.ts +58 -0
  127. package/dist/types/nodefony/src/context/requestId.d.ts +28 -0
  128. package/dist/types/nodefony/src/context/trustProxy.d.ts +77 -0
  129. package/dist/types/nodefony/src/context/websocket/Response.d.ts +53 -0
  130. package/dist/types/nodefony/src/context/websocket/WebsocketContext.d.ts +125 -0
  131. package/dist/types/nodefony/src/context/websocket/wsBackpressure.d.ts +73 -0
  132. package/dist/types/nodefony/src/context/websocket/wsLogContent.d.ts +37 -0
  133. package/dist/types/nodefony/src/cookies/cookie.d.ts +88 -0
  134. package/dist/types/nodefony/src/errors/httpError.d.ts +15 -0
  135. package/dist/types/nodefony/src/profiler/FrameProfile.d.ts +110 -0
  136. package/dist/types/nodefony/src/profiler/Profiler.d.ts +192 -0
  137. package/dist/types/nodefony/src/proxy/generateProxyConfig.d.ts +76 -0
  138. package/dist/types/nodefony/src/rateLimit/IRateLimitStore.d.ts +98 -0
  139. package/dist/types/nodefony/src/rateLimit/MemoryRateLimitStore.d.ts +40 -0
  140. package/dist/types/nodefony/src/rateLimit/WsConnectionCounter.d.ts +37 -0
  141. package/dist/types/nodefony/src/rateLimit/rateLimitFilters.d.ts +18 -0
  142. package/dist/types/nodefony/src/servers/portBinder.d.ts +102 -0
  143. package/dist/types/nodefony/src/session/session.d.ts +171 -0
  144. package/dist/types/nodefony/src/session/storage/MemorySessionStorage.d.ts +77 -0
  145. package/dist/types/nodefony/src/session/storage/RevocationGuardStorage.d.ts +81 -0
  146. package/dist/types/nodefony/src/session/storage/sessionFilters.d.ts +102 -0
  147. package/dist/types/nodefony/src/session/storage/sessionSort.d.ts +45 -0
  148. package/docs/cookies.md +365 -0
  149. package/docs/index.md +163 -0
  150. package/docs/observabilite.md +460 -0
  151. package/docs/rate-limit.md +372 -0
  152. package/docs/servers.md +935 -0
  153. package/docs/session.md +768 -0
  154. package/docs/upload.md +460 -0
  155. package/package.json +101 -0
@@ -0,0 +1,39 @@
1
+ import type { IHttpConfig, IHttpConfigInput } from "../interfaces/IHttpConfig.js";
2
+ /**
3
+ * Sous-ensemble structurel du kernel nécessaire aux défauts dérivés — découple
4
+ * le builder du type `Kernel`/`IKernel` (testable sans kernel complet). Tous les
5
+ * champs sont optionnels : un kernel absent ou minimal retombe sur les fallbacks.
6
+ */
7
+ export interface IKernelConfigDefaults {
8
+ tmpDir?: {
9
+ path?: unknown;
10
+ } | null;
11
+ domain?: string;
12
+ projectName?: string;
13
+ /** Environnement courant — pilote les défauts secure-by-default (ex. `Server:`). */
14
+ environment?: string;
15
+ }
16
+ /**
17
+ * Builder type-safe de la configuration de `@nodefony/http`.
18
+ *
19
+ * ⭐ TL;DR : MACHINERIE DE BOOT — on n'édite (presque) jamais ce fichier. Même
20
+ * pattern que `nodefony.config.ts` ↔ `defineConfig()` du core : `config.ts` PORTE
21
+ * la config (schéma + défauts), `define<X>Config()` la VALIDE au boot (parse +
22
+ * env + freeze) et publie le JSON Schema Studio.
23
+ *
24
+ * Aligné sur `defineRedisConfig` / `defineSecurityConfig` : source unique =
25
+ * `./config.ts` (Zod) ; le builder VALIDE puis complète les défauts kernel.
26
+ *
27
+ * @param config - configuration brute (sections omises = défauts sûrs).
28
+ * @param kernel - kernel courant, pour les défauts dérivés (tmpDir, domain).
29
+ * @returns config validée et complétée (NON gelée — les services la mutent).
30
+ * @throws BootConfigurationError si un champ est invalide ou une clé inconnue —
31
+ * `parseModuleConfig` (cœur) porte le message ET le type d'erreur, pour que le
32
+ * refus interrompe le boot en développement comme en production.
33
+ */
34
+ export declare function defineHttpConfig(config?: IHttpConfigInput, kernel?: IKernelConfigDefaults | null): IHttpConfig;
35
+ /**
36
+ * JSON Schema introspectable de la config HTTP — destiné au formulaire
37
+ * d'édition Studio (futur) et à la documentation générée.
38
+ */
39
+ export declare function httpConfigJsonSchema(): unknown;
@@ -0,0 +1,138 @@
1
+ import type { URL } from "node:url";
2
+ import type { ICookie } from "./ICookie.js";
3
+ import type { ISession } from "./ISession.js";
4
+ import type { HTTPMethodType } from "./IRequest.js";
5
+ export type ServerType = "http" | "https" | "http2" | "http3" | "websocket" | "websocket-secure";
6
+ export type SchemeType = "http" | "https" | "ws" | "wss";
7
+ export type WebSocketStateType = "handshake" | "connected" | "closed" | "error" | "message" | null;
8
+ export type CookiesMap = Record<string, ICookie>;
9
+ export type PhaseName = "parse" | "resolve" | "firewall" | "initialize" | "action" | "render" | "send" | (string & {});
10
+ export interface PhaseTiming {
11
+ name: PhaseName;
12
+ startMs: number;
13
+ endMs?: number;
14
+ durationMs?: number;
15
+ }
16
+ /** Issue de la traversée d'une zone firewall. */
17
+ export type SecurityOutcome =
18
+ /** Identité authentifiée (un authenticator a résolu un token). */
19
+ "granted"
20
+ /** Anonyme EXPLICITE (authenticator `anonymous` listé par la zone). */
21
+ | "anonymous"
22
+ /** Refus par POLITIQUE (aucune preuve présentée en zone fermée → 401). */
23
+ | "denied"
24
+ /** Preuve PRÉSENTÉE mais invalide (l'acteur a échoué une preuve → 401). */
25
+ | "failure"
26
+ /** Backoff NIST actif (429). */
27
+ | "throttled"
28
+ /** Route exemptée (`bypassFirewall`) — la zone est traversée sans auth. */
29
+ | "bypass";
30
+ /**
31
+ * Décision du firewall sur CETTE requête — matière de la « radiographie »
32
+ * (Studio / debug bar) : la zone dit ce qui était POSSIBLE (via
33
+ * `context.security`), cette trace dit ce qui s'est RÉELLEMENT passé.
34
+ *
35
+ * Le contrat vit ici (et non dans `@nodefony/security`) parce que
36
+ * `@nodefony/http` ne peut pas importer le module de sécurité (cycle) : http
37
+ * porte le champ, security le REMPLIT — exactement le pattern de
38
+ * `profilerQueries` (buffer porté par http, rempli par les adapters ORM).
39
+ *
40
+ * **Dev-only** : alloué par le firewall UNIQUEMENT si `context.profiling` est
41
+ * vrai (profiler actif → jamais en production). Le chemin nominal de succès
42
+ * n'émet aucun événement d'audit (le volume n'est pas un signal) : sans cette
43
+ * trace, une requête qui PASSE ne laisse aucune empreinte de sa zone.
44
+ */
45
+ export interface ISecurityTrace {
46
+ /** Authenticator qui a résolu le token — `null` si aucun n'a abouti. */
47
+ authenticator: string | null;
48
+ /** Ce qui s'est passé. */
49
+ outcome: SecurityOutcome;
50
+ /** Motif du refus (`no_credentials`, `invalid_credentials`…), `null` si succès. */
51
+ reason: string | null;
52
+ /**
53
+ * Identité résolue par le firewall. Le token vit dans l'ALS (pas sur
54
+ * `context.user`) : sans ce champ, une requête authentifiée s'affiche
55
+ * « anonyme » alors qu'elle porte des rôles.
56
+ */
57
+ user: string | null;
58
+ /** Rôles portés par le token résolu, `null` hors succès. */
59
+ roles: string[] | null;
60
+ }
61
+ export type AfterResponseHandler = (ctx: IContext) => void | Promise<void>;
62
+ export interface IContext {
63
+ requestId: string;
64
+ readonly cspNonce: string;
65
+ cspDirectives: Record<string, readonly string[]> | null;
66
+ csrfProtect: boolean;
67
+ csrfExempt: boolean;
68
+ csrfToken: string | null;
69
+ type: ServerType;
70
+ scheme: SchemeType;
71
+ method: HTTPMethodType | null;
72
+ url: string;
73
+ domain: string;
74
+ request: object | null;
75
+ response: object | null;
76
+ secure: boolean;
77
+ finished: boolean;
78
+ cleaned: boolean;
79
+ webSocketState: WebSocketStateType;
80
+ isJson: boolean;
81
+ isHtml: boolean;
82
+ remoteAddress: string | null | undefined;
83
+ originUrl: URL | null | undefined;
84
+ session: ISession | null | undefined;
85
+ cookieSession: ICookie | null | undefined;
86
+ cookies: CookiesMap;
87
+ user: unknown;
88
+ error: Error | null | undefined;
89
+ metaData: object;
90
+ readonly phases: PhaseTiming[];
91
+ phaseStart(name: PhaseName): void;
92
+ phaseEnd(name: PhaseName): void;
93
+ profiling: boolean;
94
+ securityTrace: ISecurityTrace | null;
95
+ onAfterResponse(fn: AfterResponseHandler): void;
96
+ readonly signal: AbortSignal;
97
+ addRequestCookie(cookie: ICookie): ICookie;
98
+ getRequestCookies(name?: string): CookiesMap | ICookie | null;
99
+ setCookie(cookie: ICookie): void;
100
+ parseCookies(): void;
101
+ getRequest(): object | null;
102
+ getResponse(): object | null;
103
+ isValidDomain(): boolean;
104
+ saveSession(): Promise<ISession | null>;
105
+ hasSession(): boolean;
106
+ getCookieSession(name: string): ICookie | null;
107
+ getSessionCookieName(): string;
108
+ setMetaData(obj?: Record<string, unknown>): object;
109
+ }
110
+ export interface IHttpContext extends IContext {
111
+ proxy: object | null;
112
+ isRedirect: boolean;
113
+ handle(): Promise<object>;
114
+ render(chunk: unknown, encoding?: BufferEncoding, status?: string | number, headers?: Record<string, string | number>): Promise<object>;
115
+ send(chunk?: unknown, encoding?: BufferEncoding): Promise<object>;
116
+ end(): Promise<object>;
117
+ redirect(url: string, status?: number | string, headers?: Record<string, string | number>): unknown;
118
+ getHostName(): string | undefined;
119
+ getRemoteAddress(): string | null | undefined;
120
+ getHost(): string | undefined;
121
+ getUserAgent(): string | undefined;
122
+ }
123
+ export interface IWebsocketContext extends IContext {
124
+ acceptedProtocol?: string;
125
+ connection: unknown | null;
126
+ rejected: boolean;
127
+ port: number | string;
128
+ wsUrl: URL | null;
129
+ queryGet: Record<string, string>;
130
+ connect(): Promise<unknown>;
131
+ handle(data?: unknown[]): Promise<object>;
132
+ close(reasonCode: number, description: string): unknown;
133
+ send(data?: Buffer | string | null, encoding?: BufferEncoding): Promise<object>;
134
+ broadcast(data: Buffer | string): void;
135
+ getRemoteAddress(): string | null | undefined;
136
+ getHost(): string | undefined;
137
+ getUserAgent(): string | undefined;
138
+ }
@@ -0,0 +1,47 @@
1
+ export type SameSiteType = "Strict" | "Lax" | "None";
2
+ export type PriorityType = "High" | "Medium" | "Low" | undefined;
3
+ export interface ICookieOptions {
4
+ maxAge?: number;
5
+ path?: string;
6
+ domain?: string;
7
+ secure?: boolean;
8
+ expires?: Date | string | number;
9
+ sameSite?: SameSiteType;
10
+ httpOnly?: boolean;
11
+ signed?: boolean;
12
+ secret?: string;
13
+ priority?: PriorityType;
14
+ }
15
+ export interface IWsCookie {
16
+ name: string;
17
+ value: string;
18
+ maxage?: number;
19
+ domain?: string;
20
+ path?: string;
21
+ expires?: Date;
22
+ httponly?: boolean;
23
+ secure?: boolean;
24
+ }
25
+ export interface ICookie {
26
+ name: string;
27
+ value: unknown;
28
+ options: ICookieOptions;
29
+ signed?: boolean;
30
+ originalMaxAge?: number;
31
+ expires?: Date;
32
+ maxAge?: number;
33
+ path?: string;
34
+ domain?: string | undefined;
35
+ httpOnly?: boolean;
36
+ secure?: boolean;
37
+ sameSite?: SameSiteType;
38
+ priority?: string;
39
+ setValue(value: unknown): unknown;
40
+ toString(): string;
41
+ serialize(): string;
42
+ serializeWebSocket(): IWsCookie;
43
+ clearCookie(): void;
44
+ sign(val: string, secret: string): string;
45
+ unsign(val?: string, secret?: string): string | false;
46
+ getMaxAge(): number | undefined;
47
+ }
@@ -0,0 +1,55 @@
1
+ import type { IHttpContext, IWebsocketContext } from "./IContext.js";
2
+ /**
3
+ * Result of rendering an error for an HTTP response.
4
+ * `body` will be passed verbatim to `context.render()` (which JSON-stringifies).
5
+ * `status` and `message` go into ServerResponse.writeHead().
6
+ * `headers` are optional extra headers (e.g. Allow for 405, WWW-Authenticate for 401).
7
+ */
8
+ export interface IErrorHttpResult {
9
+ status: number;
10
+ message: string;
11
+ body: unknown;
12
+ headers?: Record<string, string | number>;
13
+ }
14
+ /**
15
+ * Aide jointe au corps d'erreur — ce que le développeur doit faire, en clair.
16
+ *
17
+ * **Jamais en production**, et ce n'est pas une précaution de confort : une
18
+ * aide nomme la table et la colonne en cause, c'est-à-dire de la cartographie
19
+ * de schéma offerte à qui frappe la porte. Le même parti-pris que le message
20
+ * opaque des pannes 5xx.
21
+ *
22
+ * Le champ est ADDITIONNEL, sur le modèle de `fields` en validation : un client
23
+ * qui l'ignore lit le corps exactement comme avant.
24
+ */
25
+ export interface IErrorHint {
26
+ /** Famille d'aide — un seul cas aujourd'hui, la base en retard sur le code. */
27
+ readonly kind: "schema-mismatch";
28
+ /** Le fait, en français, sans jargon de pilote. */
29
+ readonly message: string;
30
+ /** Les gestes possibles, du plus probable au moins probable. Copiables tels quels. */
31
+ readonly actions: readonly string[];
32
+ }
33
+ /**
34
+ * Result of rendering an error for a WebSocket close frame.
35
+ * `code` MUST be a valid WS close code (1000-4999). RFC 6455 §7.4.
36
+ * `reason` is a UTF-8 string sent in the close frame (max 123 bytes).
37
+ */
38
+ export interface IErrorWebsocketResult {
39
+ code: number;
40
+ reason: string;
41
+ }
42
+ /**
43
+ * Unified error rendering contract — HTTP + WebSocket.
44
+ * The default implementation preserves the legacy Nodefony JSON error shape:
45
+ * { code, message, error: HttpError.toJSON(), nodefony: { requestId, scheme, ... }, result }
46
+ *
47
+ * Override via `httpKernel.setErrorRenderer(custom)` to customise:
48
+ * - hide stack traces in prod
49
+ * - emit RFC 7807 problem+json
50
+ * - inject auth challenge headers
51
+ */
52
+ export interface IErrorRenderer {
53
+ renderHttp(error: Error, context: IHttpContext): IErrorHttpResult;
54
+ renderWebsocket(error: Error, context: IWebsocketContext): IErrorWebsocketResult;
55
+ }
@@ -0,0 +1,12 @@
1
+ import type { HttpConfig, HttpConfigInput } from "../config/config.js";
2
+ /**
3
+ * Configuration validée de `@nodefony/http` (sortie du parse Zod + défauts
4
+ * kernel appliqués par le builder). Source de vérité = `../config/config.ts`.
5
+ */
6
+ export type IHttpConfig = HttpConfig;
7
+ /**
8
+ * Configuration brute fournie par l'application (toutes sections optionnelles —
9
+ * les sections omises reçoivent leurs défauts). Entrée du builder
10
+ * {@link import("../config/defineModuleConfig").defineHttpConfig}.
11
+ */
12
+ export type IHttpConfigInput = HttpConfigInput;
@@ -0,0 +1,10 @@
1
+ import type { ServerType } from "./IContext.js";
2
+ export interface IHttpKernel {
3
+ domain: string;
4
+ httpPort?: number;
5
+ httpsPort?: number;
6
+ handle(request: unknown, response: unknown, type: ServerType): Promise<unknown>;
7
+ handleFrontController(context: object, checkFirewall?: boolean): Promise<unknown>;
8
+ onError(error: unknown, context?: object, extraHeaders?: object): Promise<object>;
9
+ isValidDomain(context: object): boolean;
10
+ }
@@ -0,0 +1,35 @@
1
+ import type { URL } from "node:url";
2
+ import type { ICookie } from "./ICookie.js";
3
+ export type HTTPMethodType = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE" | "PATCH" | "WEBSOCKET";
4
+ export interface IRequest {
5
+ url: URL | string;
6
+ method: HTTPMethodType | null | undefined;
7
+ getMethod(): HTTPMethodType | null | undefined;
8
+ getHeader(name: string): string | string[] | undefined;
9
+ getHeaders(): Record<string, string | string[] | undefined>;
10
+ }
11
+ export interface IHttpRequest extends IRequest {
12
+ url: URL;
13
+ query: Record<string, unknown>;
14
+ queryGet: Record<string, unknown>;
15
+ queryPost: Record<string, unknown>;
16
+ queryFile: unknown[];
17
+ remoteAddress: string | null | undefined;
18
+ acceptHtml: boolean;
19
+ getRemoteAddress(): string | null | undefined;
20
+ getHost(): string | undefined;
21
+ getHostName(): string | undefined;
22
+ getUserAgent(): string | undefined;
23
+ getOrigin(): string | undefined;
24
+ getCookies(): Record<string, ICookie>;
25
+ }
26
+ export interface IHttp2Request extends IHttpRequest {
27
+ stream: unknown;
28
+ }
29
+ export interface IWsRequest extends IRequest {
30
+ url: URL;
31
+ query: Record<string, string>;
32
+ queryGet: Record<string, string>;
33
+ path: string;
34
+ cookies?: Record<string, ICookie>;
35
+ }
@@ -0,0 +1,31 @@
1
+ import type { Severity } from "nodefony";
2
+ import type { IHttpContext, IWebsocketContext } from "./IContext.js";
3
+ /**
4
+ * Result of rendering a request log entry. Returned by IRequestLogger and
5
+ * passed verbatim to `context.log(text, severity, msgid)`.
6
+ */
7
+ export interface IRequestLogEntry {
8
+ text: string;
9
+ severity: Severity;
10
+ msgid: string;
11
+ }
12
+ /**
13
+ * Unified per-request logger contract — HTTP + WebSocket.
14
+ *
15
+ * The default implementation preserves the legacy Nodefony "URL : ... FROM : ...
16
+ * ORIGIN : ... ID : <uuid>" colored format. Swap via
17
+ * `httpKernel.setRequestLogger(custom)` to:
18
+ * - emit JSON access logs (audit / P3.1)
19
+ * - render NCSA Common Log Format
20
+ * - pretty-format with one colored line per request (P3.2)
21
+ */
22
+ export interface IRequestLogger {
23
+ renderHttp(context: IHttpContext, error?: Error | null): IRequestLogEntry;
24
+ renderWebsocket(context: IWebsocketContext, error?: Error | null, acceptedProtocol?: string | null): IRequestLogEntry;
25
+ /**
26
+ * Optional audit-sampling gate, evaluated by `Context.logRequest()` BEFORE
27
+ * `renderHttp`. Return `false` to skip the log entirely (no object alloc, no
28
+ * `JSON.stringify`). Absent ⇒ always log (loggers without sampling).
29
+ */
30
+ shouldSample?(context: IHttpContext, error?: Error | null): boolean;
31
+ }
@@ -0,0 +1,39 @@
1
+ import type { ICookie } from "./ICookie.js";
2
+ export interface IResponse {
3
+ statusCode: number;
4
+ statusMessage: string;
5
+ encoding: BufferEncoding;
6
+ body: Buffer | null;
7
+ cookies: Record<string, ICookie>;
8
+ addCookie(cookie: ICookie): ICookie;
9
+ send(data?: Buffer | string | null, encoding?: BufferEncoding): Promise<unknown>;
10
+ clean(): void;
11
+ }
12
+ export interface IHttpResponse extends IResponse {
13
+ headers: Record<string, unknown>;
14
+ contentType: string;
15
+ setStatusCode(code: number | string, message?: string): {
16
+ code: number;
17
+ message: string;
18
+ };
19
+ getStatusCode(): number;
20
+ getStatusMessage(): string;
21
+ isHeaderSent(): boolean;
22
+ setHeader(name: string, value: string | number | string[]): void;
23
+ getHeader(name: string): string | number | string[] | undefined;
24
+ setHeaders(headers: Record<string, string | number>): void;
25
+ setContentType(type: string): void;
26
+ setBody(data: unknown): void;
27
+ redirect(url: string, code?: number): Promise<IHttpResponse>;
28
+ isHtml(): boolean;
29
+ setTimeout(ms: number): void;
30
+ deleteCookie(cookie: ICookie): void;
31
+ setCookie(cookie: ICookie): void;
32
+ }
33
+ export interface IWebsocketResponse extends IResponse {
34
+ connection: unknown | null;
35
+ webSocketVersion?: number;
36
+ setConnection(connection: unknown): unknown;
37
+ broadcast(data: Buffer | string): void;
38
+ close(code?: number, message?: string): Promise<void>;
39
+ }