@boo-labs/server 1.0.2 → 1.0.3

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 (2) hide show
  1. package/package.json +1 -1
  2. package/types/index.d.ts +612 -76
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boo-labs/server",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A zero-dependency, frameworkless HTTP server for Node.js, built around Clean Architecture principles.",
5
5
  "keywords": [
6
6
  "http-server",
package/types/index.d.ts CHANGED
@@ -1,18 +1,16 @@
1
1
  /**
2
- * Type definitions for @boo/server
2
+ * Type definitions for @boo-labs/server
3
3
  *
4
4
  * Generated to support TypeScript consumers while keeping the core JS-based.
5
5
  */
6
6
 
7
+ // ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
7
8
  import * as http from 'node:http';
8
9
  import * as https from 'node:https';
9
10
  import * as http2 from 'node:http2';
10
11
  import * as stream from 'node:stream';
11
12
 
12
- // ═══════════════════════════════════════════════════════════════════════════
13
- // PRIMITIVE TYPES
14
- // ═══════════════════════════════════════════════════════════════════════════
15
-
13
+ // ━━ PRIMITIVE TYPES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
16
14
  /**
17
15
  * Represents an HTTP method supported by the routing layer.
18
16
  */
@@ -21,7 +19,7 @@ export type HTTPMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' |
21
19
  /**
22
20
  * Identifies an application-layer communication protocol.
23
21
  */
24
- export type Protocol = 'http' | 'https';
22
+ export type Protocol = 'http' | 'https' | 'ws' | 'wss' | 'grpc' | 'mqtt' | 'coap';
25
23
 
26
24
  /**
27
25
  * Identifies the transport implementation used by the server.
@@ -74,10 +72,10 @@ export type SystemErrorHandler = (
74
72
  */
75
73
  export type EventName = 'listen' | 'close' | 'error' | 'exchange:start' | 'exchange:end' | 'exchange:error';
76
74
 
77
- // ═══════════════════════════════════════════════════════════════════════════
78
- // VALUE OBJECTS
79
- // ═══════════════════════════════════════════════════════════════════════════
80
-
75
+ // ━━ VALUE OBJECTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
76
+ /**
77
+ * Plain object representation of an Address.
78
+ */
81
79
  export interface AddressInfo {
82
80
  address: string;
83
81
  port: number;
@@ -99,8 +97,12 @@ export interface Address {
99
97
  toObject(): AddressInfo;
100
98
  toJSON(): AddressInfo;
101
99
  toString(): string;
100
+ [Symbol.toPrimitive](hint: 'string' | 'number' | 'default'): string;
102
101
  }
103
102
 
103
+ /**
104
+ * Represents the data of a network endpoint.
105
+ */
104
106
  export interface EndpointData {
105
107
  protocol: Protocol;
106
108
  address: string;
@@ -126,12 +128,10 @@ export interface Endpoint {
126
128
  toObject(): EndpointData;
127
129
  toJSON(): EndpointData;
128
130
  toString(): string;
131
+ [Symbol.toPrimitive](hint: 'string' | 'number' | 'default'): string;
129
132
  }
130
133
 
131
- // ═══════════════════════════════════════════════════════════════════════════
132
- // REQUEST
133
- // ═══════════════════════════════════════════════════════════════════════════
134
-
134
+ // ━━ REQUEST ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
135
135
  /**
136
136
  * Immutable, case-insensitive view of incoming HTTP request headers.
137
137
  */
@@ -165,14 +165,32 @@ export interface Request {
165
165
  body(): Promise<unknown>;
166
166
  }
167
167
 
168
- // ═══════════════════════════════════════════════════════════════════════════
169
- // RESPONSE
170
- // ═══════════════════════════════════════════════════════════════════════════
168
+ // ━━ RESPONSE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
169
+ /**
170
+ * Represents a supported response header value.
171
+ */
172
+ export type ResponseHeaderValue = string | number | (string | number)[];
173
+
174
+ /**
175
+ * Mutable, validated collection of outgoing HTTP response headers.
176
+ */
177
+ export interface ResponseHeaders {
178
+ set(name: string, value: ResponseHeaderValue): void;
179
+ setMany(headers: Record<string, ResponseHeaderValue>): void;
180
+ append(name: string, value: string | number): void;
181
+ get(name: string): ResponseHeaderValue | undefined;
182
+ has(name: string): boolean;
183
+ remove(name: string): void;
184
+ ensureContentType(value: string): void;
185
+ lockContentType(): void;
186
+ getNames(): string[];
187
+ entries(): IterableIterator<[string, ResponseHeaderValue]>;
188
+ [Symbol.iterator](): IterableIterator<[string, ResponseHeaderValue]>;
189
+ toObject(): Record<string, ResponseHeaderValue>;
190
+ }
171
191
 
172
192
  /**
173
193
  * Represents an outgoing HTTP response.
174
- *
175
- * Instances are produced by the runtime and exposed as `exchange.response`.
176
194
  */
177
195
  export interface Response {
178
196
  readonly statusCode: number;
@@ -182,15 +200,13 @@ export interface Response {
182
200
  readonly bodyLength: number | undefined;
183
201
 
184
202
  status(code: number): this;
185
- setHeader(name: string, value: string | number | (string | number)[]): this;
186
- setHeaders(
187
- headers: Record<string, string | number | (string | number)[]>,
188
- ): this;
203
+ setHeader(name: string, value: ResponseHeaderValue): this;
204
+ setHeaders(headers: Record<string, ResponseHeaderValue>): this;
189
205
  appendHeader(name: string, value: string | number): this;
190
- getHeader(name: string): string | number | (string | number)[] | undefined;
206
+ getHeader(name: string): ResponseHeaderValue | undefined;
191
207
  hasHeader(name: string): boolean;
192
208
  removeHeader(name: string): this;
193
- getHeaders(): Readonly<Record<string, string | number | (string | number)[]>>;
209
+ getHeaders(): Readonly<Record<string, ResponseHeaderValue>>;
194
210
 
195
211
  json(data: unknown): this;
196
212
  html(content: string): this;
@@ -206,39 +222,100 @@ export interface Response {
206
222
  end(): this;
207
223
  }
208
224
 
209
- // ═══════════════════════════════════════════════════════════════════════════
210
- // EXCHANGE
211
- // ═══════════════════════════════════════════════════════════════════════════
225
+ // ━━ EXCHANGE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
226
+ /**
227
+ * Represents the processing outcome of an HTTP exchange.
228
+ */
229
+ export type ExchangeOutcome = 'pending' | 'success' | 'error';
230
+
231
+ /**
232
+ * Represents timing information captured when exchange processing starts.
233
+ */
234
+ export interface ExchangeStartTiming {
235
+ readonly startedAt: number;
236
+ readonly endedAt: undefined;
237
+ readonly duration: undefined;
238
+ }
239
+
240
+ /**
241
+ * Represents timing information captured for a non-terminal exchange error.
242
+ */
243
+ export interface ExchangeErrorTiming {
244
+ readonly startedAt: number;
245
+ readonly endedAt: undefined;
246
+ readonly duration: undefined;
247
+ }
212
248
 
213
- export interface ExchangeTiming {
214
- startedAt: number;
215
- endedAt?: number;
216
- duration?: number;
249
+ /**
250
+ * Represents timing information captured when exchange processing ends.
251
+ */
252
+ export interface ExchangeEndTiming {
253
+ readonly startedAt: number;
254
+ readonly endedAt: number;
255
+ readonly duration: number;
217
256
  }
218
257
 
219
- export interface ExchangeStartInfo {
220
- id: string;
221
- traceId: string;
222
- request: { method: string; pathname: string };
223
- timing: { startedAt: number };
258
+ /**
259
+ * Contains a snapshot of the relevant HTTP request information.
260
+ */
261
+ export interface ExchangeRequestInfo {
262
+ readonly method: string | undefined;
263
+ readonly pathname: string;
264
+ readonly ip: string | undefined;
265
+ readonly userAgent: string | undefined;
224
266
  }
225
267
 
226
- export interface ExchangeEndInfo {
227
- id: string;
228
- traceId: string;
229
- request: { method: string; pathname: string };
230
- outcome: 'success' | 'error';
231
- timing: ExchangeTiming;
268
+ /**
269
+ * Contains a snapshot of the relevant HTTP response information.
270
+ */
271
+ export interface ExchangeResponseInfo {
272
+ readonly statusCode: number;
273
+ }
274
+
275
+ /**
276
+ * Provides information about an exchange when processing starts.
277
+ */
278
+ export interface ExchangeStartInfo {
279
+ readonly id: string;
280
+ readonly traceId: string;
281
+ readonly timing: ExchangeStartTiming;
282
+ readonly request: ExchangeRequestInfo;
283
+ readonly response: ExchangeResponseInfo;
284
+ readonly outcome: 'pending';
285
+ readonly error: undefined;
232
286
  }
233
287
 
288
+ /**
289
+ * Provides information about an exchange when processing fails.
290
+ */
234
291
  export interface ExchangeErrorInfo {
235
- id: string;
236
- traceId: string;
237
- error: Error;
238
- request: { method: string; pathname: string };
239
- timing: ExchangeTiming;
292
+ readonly id: string;
293
+ readonly traceId: string;
294
+ readonly timing: ExchangeErrorTiming;
295
+ readonly request: ExchangeRequestInfo;
296
+ readonly response: ExchangeResponseInfo;
297
+ readonly outcome: 'error';
298
+ readonly error: Error;
240
299
  }
241
300
 
301
+ /**
302
+ * Provides information about an exchange when processing completes.
303
+ */
304
+ export interface ExchangeEndInfo {
305
+ readonly id: string;
306
+ readonly traceId: string;
307
+ readonly timing: ExchangeEndTiming;
308
+ readonly request: ExchangeRequestInfo;
309
+ readonly response: ExchangeResponseInfo;
310
+ readonly outcome: 'success' | 'error';
311
+ readonly error: Error | undefined;
312
+ }
313
+
314
+ /**
315
+ * Represents an exchange snapshot for any supported processing outcome.
316
+ */
317
+ export type ExchangeInfo = ExchangeStartInfo | ExchangeErrorInfo | ExchangeEndInfo;
318
+
242
319
  /**
243
320
  * Represents a single HTTP transaction.
244
321
  *
@@ -257,14 +334,17 @@ export interface Exchange {
257
334
  abort(): void;
258
335
  }
259
336
 
260
- // ═══════════════════════════════════════════════════════════════════════════
261
- // IPC
262
- // ═══════════════════════════════════════════════════════════════════════════
263
-
337
+ // ━━ IPC ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
338
+ /**
339
+ * Handler for an IPC invoke request.
340
+ */
264
341
  export type IPCHandler<T = unknown, R = unknown> = (
265
342
  data: T,
266
343
  ) => R | Promise<R>;
267
344
 
345
+ /**
346
+ * Listener for an IPC event.
347
+ */
268
348
  export type IPCEventListener<T = unknown> = (data: T) => void;
269
349
 
270
350
  /**
@@ -273,251 +353,493 @@ export type IPCEventListener<T = unknown> = (data: T) => void;
273
353
  * Accessible through `server.ipc` while the server is listening.
274
354
  */
275
355
  export interface IPCMain {
356
+ /**
357
+ * Registers or replaces an invoke handler for a channel.
358
+ */
276
359
  handle<T = unknown, R = unknown>(
277
360
  channel: string,
278
361
  handler: IPCHandler<T, R>,
279
362
  ): this;
363
+
364
+ /**
365
+ * Removes the invoke handler registered for a channel.
366
+ */
280
367
  removeHandler(channel: string): this;
368
+
369
+ /**
370
+ * Registers an event listener for a channel.
371
+ * Multiple listeners may be registered for the same channel.
372
+ */
281
373
  on<T = unknown>(channel: string, listener: IPCEventListener<T>): this;
374
+
375
+ /**
376
+ * Removes an event listener from a channel.
377
+ */
282
378
  off<T = unknown>(channel: string, listener: IPCEventListener<T>): this;
283
379
  }
284
380
 
285
- // ═══════════════════════════════════════════════════════════════════════════
286
- // CONFIGURATION INPUTS
287
- // ═══════════════════════════════════════════════════════════════════════════
288
-
381
+ // ━━ CONFIGURATION INPUTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
382
+ /**
383
+ * Represents the listen options accepted by the server configuration.
384
+ */
289
385
  export interface ListenOptionsInput {
386
+ /** The TCP port on which the server listens. */
290
387
  port?: number;
388
+ /** The hostname or IP address on which the server listens. */
291
389
  host?: string;
390
+ /** The maximum number of pending connections that may be queued. */
292
391
  backlog?: number;
293
392
  }
294
393
 
394
+ /**
395
+ * Represents the request options accepted by the server configuration.
396
+ */
295
397
  export interface RequestOptionsInput {
398
+ /** Maximum number of bytes allowed for the request body. */
296
399
  bodyLimit?: number;
400
+ /** Whether (and how much) to trust proxy headers. */
297
401
  trustProxy?: boolean | number;
298
402
  }
299
403
 
404
+ /**
405
+ * Represents the response options accepted by the server configuration.
406
+ */
300
407
  export interface ResponseOptionsInput {
408
+ /** Whether to generate a weak ETag for buffered bodies. */
301
409
  etag?: boolean;
410
+ /** Charset appended to eligible Content-Type headers when none is set. */
302
411
  defaultCharset?: string;
303
412
  }
304
413
 
414
+ /**
415
+ * Represents the static files middleware options accepted by the server configuration.
416
+ */
305
417
  export interface StaticOptionsInput {
418
+ /** Filesystem root directory for static files. */
306
419
  root: string;
420
+ /** Ordered list of index file names. */
307
421
  index?: readonly string[];
422
+ /** Cache-Control max-age value in seconds. */
308
423
  maxAge?: number;
424
+ /** Whether to generate ETag headers. */
309
425
  etag?: boolean;
426
+ /** Whether to generate Last-Modified headers. */
310
427
  lastModified?: boolean;
428
+ /** Whether to delegate to the next middleware when no file is found. */
311
429
  fallthrough?: boolean;
430
+ /** Extensions to try when the request has no extension. */
312
431
  extensions?: readonly string[];
432
+ /** Whether to serve dot-prefixed paths. */
313
433
  dotfiles?: boolean;
314
434
  }
315
435
 
436
+ /**
437
+ * Represents the CORS middleware options accepted by the server configuration.
438
+ */
316
439
  export interface CORSOptionsInput {
440
+ /** Allowed origin(s). Defaults to `'*'`. */
317
441
  origin?: true | string | readonly string[];
442
+ /** Allowed HTTP methods for preflight responses. */
318
443
  methods?: readonly string[];
444
+ /** Headers the client is allowed to send. */
319
445
  allowedHeaders?: readonly string[];
446
+ /** Headers the client is allowed to read from the response. */
320
447
  exposedHeaders?: readonly string[];
448
+ /** Whether the response may include credentials. Defaults to `false`. */
321
449
  credentials?: boolean;
450
+ /** How long (in seconds) the preflight response may be cached. */
322
451
  maxAge?: number;
452
+ /** Whether to call `next()` on successful preflight instead of ending the response. */
323
453
  preflightContinue?: boolean;
454
+ /** Status code used for successful preflight responses. Defaults to `204`. */
324
455
  optionsSuccessStatus?: number;
325
456
  }
326
457
 
458
+ /**
459
+ * Represents the security headers middleware options accepted by the server configuration.
460
+ * Every property accepts a string header value or `false` to omit the header.
461
+ */
327
462
  export interface SecurityHeadersOptionsInput {
463
+ /** Value for the Content-Security-Policy header, or `false` to omit it. */
328
464
  contentSecurityPolicy?: string | false;
465
+ /** Value for the Cross-Origin-Embedder-Policy header, or `false` to omit it. */
329
466
  crossOriginEmbedderPolicy?: string | false;
467
+ /** Value for the Cross-Origin-Opener-Policy header, or `false` to omit it. */
330
468
  crossOriginOpenerPolicy?: string | false;
469
+ /** Value for the Cross-Origin-Resource-Policy header, or `false` to omit it. */
331
470
  crossOriginResourcePolicy?: string | false;
471
+ /** Value for the Origin-Agent-Cluster header, or `false` to omit it. */
332
472
  originAgentCluster?: string | false;
473
+ /** Value for the Permissions-Policy header, or `false` to omit it. */
333
474
  permissionsPolicy?: string | false;
475
+ /** Value for the Referrer-Policy header, or `false` to omit it. */
334
476
  referrerPolicy?: string | false;
477
+ /** Value for the Strict-Transport-Security header, or `false` to omit it. */
335
478
  strictTransportSecurity?: string | false;
479
+ /** Value for the X-Content-Type-Options header, or `false` to omit it. */
336
480
  xContentTypeOptions?: string | false;
481
+ /** Value for the X-DNS-Prefetch-Control header, or `false` to omit it. */
337
482
  xDnsPrefetchControl?: string | false;
483
+ /** Value for the X-Download-Options header, or `false` to omit it. */
338
484
  xDownloadOptions?: string | false;
485
+ /** Value for the X-Frame-Options header, or `false` to omit it. */
339
486
  xFrameOptions?: string | false;
487
+ /** Value for the X-Permitted-Cross-Domain-Policies header, or `false` to omit it. */
340
488
  xPermittedCrossDomainPolicies?: string | false;
489
+ /** Value for the legacy X-XSS-Protection header, or `false` to omit it. */
341
490
  xXssProtection?: string | false;
342
491
  }
343
492
 
493
+ /**
494
+ * Represents the rate limit middleware options accepted by the server configuration.
495
+ */
344
496
  export interface RateLimitOptionsInput {
497
+ /** Duration of the rate-limit window in milliseconds. */
345
498
  windowMs?: number;
499
+ /** Maximum number of requests allowed per window per client. */
346
500
  max?: number;
501
+ /** HTTP status code returned when the limit is exceeded. */
347
502
  statusCode?: number;
503
+ /** JSON body sent when the limit is exceeded. */
348
504
  message?: Record<string, unknown>;
505
+ /** Whether to send the modern `RateLimit-*` headers. */
349
506
  standardHeaders?: boolean;
507
+ /** Whether to send the legacy `X-RateLimit-*` headers. */
350
508
  legacyHeaders?: boolean;
351
509
  }
352
510
 
511
+ /**
512
+ * Represents the cookie parser middleware options accepted by the server configuration.
513
+ */
353
514
  export interface CookieParserOptionsInput {
515
+ /** Whether cookie values are decoded with `decodeURIComponent`. */
354
516
  decode?: boolean;
355
517
  }
356
518
 
519
+ /**
520
+ * Represents the cookie session middleware options accepted by the server configuration.
521
+ */
357
522
  export interface CookieSessionOptionsInput {
523
+ /** Name of the session cookie. */
358
524
  name?: string;
525
+ /** Signing keys. Required when options are provided. */
359
526
  keys: readonly string[];
527
+ /** Cookie max-age in milliseconds. When omitted, the cookie is a session cookie. */
360
528
  maxAge?: number;
529
+ /** Cookie path attribute. */
361
530
  path?: string;
531
+ /** Cookie domain attribute. */
362
532
  domain?: string;
533
+ /** Whether the cookie is marked Secure. */
363
534
  secure?: boolean;
535
+ /** Whether the cookie is marked HttpOnly. */
364
536
  httpOnly?: boolean;
537
+ /** Cookie SameSite attribute. */
365
538
  sameSite?: 'Strict' | 'Lax' | 'None';
539
+ /** Whether an existing Set-Cookie header with the same name should be overwritten. */
366
540
  overwrite?: boolean;
367
541
  }
368
542
 
543
+ /**
544
+ * Represents the cookie middleware options accepted by the server configuration.
545
+ */
369
546
  export interface CookieOptionsInput {
547
+ /** Cookie parser configuration. */
370
548
  parser?: CookieParserOptionsInput;
549
+ /** Cookie session configuration. */
371
550
  session?: CookieSessionOptionsInput;
372
551
  }
373
552
 
553
+ /**
554
+ * Represents the CSRF middleware options accepted by the server configuration.
555
+ */
374
556
  export interface CSRFOptionsInput {
557
+ /** Name of the CSRF cookie. */
375
558
  cookieName?: string;
559
+ /** Name of the request header that must carry the token. */
376
560
  headerName?: string;
561
+ /** HTTP methods that skip CSRF validation. */
377
562
  safeMethods?: readonly string[];
563
+ /** Number of random bytes used to generate the token. */
378
564
  tokenBytes?: number;
565
+ /** Cookie Path attribute. */
379
566
  path?: string;
567
+ /** Cookie Domain attribute. */
380
568
  domain?: string;
569
+ /** Whether the cookie is marked Secure. */
381
570
  secure?: boolean;
571
+ /** Cookie SameSite attribute. */
382
572
  sameSite?: 'Strict' | 'Lax' | 'None';
383
573
  }
384
574
 
575
+ /**
576
+ * Represents the compression middleware options accepted by the server configuration.
577
+ */
385
578
  export interface CompressOptionsInput {
579
+ /** Minimum body size in bytes required to compress. Use `0` to compress any non-empty body. */
386
580
  threshold?: number;
581
+ /** Compression level passed to the underlying zlib implementation. */
387
582
  level?: number;
583
+ /** Compressible media types. When omitted, the default allow-list is used. */
388
584
  types?: readonly string[];
389
585
  }
390
586
 
587
+ /**
588
+ * Represents the base configuration options shared by all server configurations.
589
+ */
391
590
  export interface ServerConfigurationOptionsInputBase {
591
+ /** Server listening configuration. */
392
592
  listen?: ListenOptionsInput;
593
+ /** Request configuration. */
393
594
  request?: RequestOptionsInput;
595
+ /** Response configuration. */
394
596
  response?: ResponseOptionsInput;
597
+ /** Static files middleware configuration. */
395
598
  static?: StaticOptionsInput;
599
+ /** CORS middleware configuration. */
396
600
  cors?: CORSOptionsInput;
601
+ /** Security headers middleware configuration. */
397
602
  securityHeaders?: SecurityHeadersOptionsInput;
603
+ /** Rate limit middleware configuration. */
398
604
  rateLimit?: RateLimitOptionsInput;
605
+ /** Cookie middleware configuration. */
399
606
  cookie?: CookieOptionsInput;
607
+ /** CSRF middleware configuration. */
400
608
  csrf?: CSRFOptionsInput;
609
+ /** Compression middleware configuration. */
401
610
  compress?: CompressOptionsInput;
402
611
  }
403
612
 
404
- // ═══════════════════════════════════════════════════════════════════════════
405
- // SERVER CONFIGURATIONS
406
- // ═══════════════════════════════════════════════════════════════════════════
613
+ // ━━ SERVER CONFIGURATIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
614
+ /**
615
+ * Represents the normalized listen options.
616
+ */
407
617
  export interface ListenOptions {
618
+ /** The TCP port on which the server listens. */
408
619
  port: number | undefined;
620
+ /** The hostname or IP address on which the server listens. */
409
621
  host: string | undefined;
622
+ /** The maximum number of pending connections that may be queued. */
410
623
  backlog: number | undefined;
411
624
  }
412
625
 
626
+ /**
627
+ * Represents the normalized request options.
628
+ */
413
629
  export interface RequestOptions {
630
+ /** Maximum number of bytes allowed for the request body. */
414
631
  bodyLimit: number | undefined;
632
+ /** Whether (and how much) to trust proxy headers. */
415
633
  trustProxy: boolean | number | undefined;
416
634
  }
417
635
 
636
+ /**
637
+ * Represents the normalized response options.
638
+ */
418
639
  export interface ResponseOptions {
640
+ /** Whether to generate a weak ETag for buffered bodies. */
419
641
  etag: boolean | undefined;
642
+ /** Charset appended to eligible Content-Type headers when none is set. */
420
643
  defaultCharset: string | undefined;
421
644
  }
422
645
 
646
+ /**
647
+ * Represents the normalized static middleware options.
648
+ */
423
649
  export interface StaticOptions {
650
+ /** Absolute resolved path to the static files root directory. */
424
651
  root: string;
652
+ /** Ordered list of index file names. */
425
653
  index: readonly string[];
654
+ /** Cache-Control max-age value in seconds. */
426
655
  maxAge: number;
656
+ /** Whether to generate ETag headers. */
427
657
  etag: boolean;
658
+ /** Whether to generate Last-Modified headers. */
428
659
  lastModified: boolean;
660
+ /** Whether to delegate to the next middleware when no file is found. */
429
661
  fallthrough: boolean;
662
+ /** Extensions to try when the request has no extension. */
430
663
  extensions: readonly string[] | undefined;
664
+ /** Whether to serve dot-prefixed paths. */
431
665
  dotfiles: boolean;
432
666
  }
433
667
 
668
+ /**
669
+ * Represents the normalized CORS middleware options.
670
+ */
434
671
  export interface CORSOptions {
672
+ /** Allowed origin(s). */
435
673
  origin: true | string | readonly string[];
674
+ /** Allowed HTTP methods for preflight responses. */
436
675
  methods: readonly string[];
676
+ /** Headers the client is allowed to send, or `undefined` to reflect the request headers. */
437
677
  allowedHeaders: readonly string[] | undefined;
678
+ /** Headers the client is allowed to read from the response. */
438
679
  exposedHeaders: readonly string[] | undefined;
680
+ /** Whether the response may include credentials. */
439
681
  credentials: boolean;
682
+ /** How long (in seconds) the preflight response may be cached. */
440
683
  maxAge: number | undefined;
684
+ /** Whether to call `next()` on successful preflight instead of ending the response. */
441
685
  preflightContinue: boolean;
686
+ /** Status code used for successful preflight responses. */
442
687
  optionsSuccessStatus: number;
443
688
  }
444
689
 
690
+ /**
691
+ * Represents the normalized security headers middleware options.
692
+ */
445
693
  export interface SecurityHeadersOptions {
694
+ /** Value for the Content-Security-Policy header, or `false` to omit it. */
446
695
  contentSecurityPolicy: string | false;
696
+ /** Value for the Cross-Origin-Embedder-Policy header, or `false` to omit it. */
447
697
  crossOriginEmbedderPolicy: string | false;
698
+ /** Value for the Cross-Origin-Opener-Policy header, or `false` to omit it. */
448
699
  crossOriginOpenerPolicy: string | false;
700
+ /** Value for the Cross-Origin-Resource-Policy header, or `false` to omit it. */
449
701
  crossOriginResourcePolicy: string | false;
702
+ /** Value for the Origin-Agent-Cluster header, or `false` to omit it. */
450
703
  originAgentCluster: string | false;
704
+ /** Value for the Permissions-Policy header, or `false` to omit it. */
451
705
  permissionsPolicy: string | false;
706
+ /** Value for the Referrer-Policy header, or `false` to omit it. */
452
707
  referrerPolicy: string | false;
708
+ /** Value for the Strict-Transport-Security header, or `false` to omit it. */
453
709
  strictTransportSecurity: string | false;
710
+ /** Value for the X-Content-Type-Options header, or `false` to omit it. */
454
711
  xContentTypeOptions: string | false;
712
+ /** Value for the X-DNS-Prefetch-Control header, or `false` to omit it. */
455
713
  xDnsPrefetchControl: string | false;
714
+ /** Value for the X-Download-Options header, or `false` to omit it. */
456
715
  xDownloadOptions: string | false;
716
+ /** Value for the X-Frame-Options header, or `false` to omit it. */
457
717
  xFrameOptions: string | false;
718
+ /** Value for the X-Permitted-Cross-Domain-Policies header, or `false` to omit it. */
458
719
  xPermittedCrossDomainPolicies: string | false;
720
+ /** Value for the legacy X-XSS-Protection header, or `false` to omit it. */
459
721
  xXssProtection: string | false;
460
722
  }
461
723
 
724
+ /**
725
+ * Represents the normalized rate limit middleware options.
726
+ */
462
727
  export interface RateLimitOptions {
728
+ /** Duration of the rate-limit window in milliseconds. */
463
729
  windowMs: number;
730
+ /** Maximum number of requests allowed per window per client. */
464
731
  max: number;
732
+ /** HTTP status code returned when the limit is exceeded. */
465
733
  statusCode: number;
734
+ /** JSON body sent when the limit is exceeded. */
466
735
  message: Readonly<Record<string, unknown>>;
736
+ /** Whether to send the modern `RateLimit-*` headers. */
467
737
  standardHeaders: boolean;
738
+ /** Whether to send the legacy `X-RateLimit-*` headers. */
468
739
  legacyHeaders: boolean;
469
740
  }
470
741
 
742
+ /**
743
+ * Represents the normalized cookie parser middleware options.
744
+ */
471
745
  export interface CookieParserOptions {
746
+ /** Whether cookie values are decoded with `decodeURIComponent`. */
472
747
  decode: boolean;
473
748
  }
474
749
 
750
+ /**
751
+ * Represents the normalized cookie session middleware options.
752
+ */
475
753
  export interface CookieSessionOptions {
754
+ /** Name of the session cookie. */
476
755
  name: string;
756
+ /** Signing keys. The first key is used to sign; all keys are tried when verifying. */
477
757
  keys: readonly string[];
758
+ /** Cookie max-age in milliseconds. When `undefined`, the cookie is a session cookie. */
478
759
  maxAge: number | undefined;
760
+ /** Cookie path attribute. */
479
761
  path: string;
762
+ /** Cookie domain attribute. */
480
763
  domain: string | undefined;
764
+ /** Whether the cookie is marked Secure. */
481
765
  secure: boolean;
766
+ /** Whether the cookie is marked HttpOnly. */
482
767
  httpOnly: boolean;
768
+ /** Cookie SameSite attribute. */
483
769
  sameSite: 'Strict' | 'Lax' | 'None';
770
+ /** Whether an existing Set-Cookie header with the same name should be overwritten. */
484
771
  overwrite: boolean;
485
772
  }
486
773
 
774
+ /**
775
+ * Represents the normalized cookie middleware options.
776
+ */
487
777
  export interface CookieOptions {
778
+ /** Normalized cookie parser options. */
488
779
  parser: CookieParserOptions;
780
+ /** Normalized cookie session options. */
489
781
  session?: CookieSessionOptions;
490
782
  }
491
783
 
784
+ /**
785
+ * Represents the normalized CSRF middleware options.
786
+ */
492
787
  export interface CSRFOptions {
788
+ /** Name of the CSRF cookie. */
493
789
  cookieName: string;
790
+ /** Name of the request header that must carry the token. */
494
791
  headerName: string;
792
+ /** HTTP methods that skip CSRF validation. */
495
793
  safeMethods: readonly string[];
794
+ /** Number of random bytes used to generate the token. */
496
795
  tokenBytes: number;
796
+ /** Cookie Path attribute. */
497
797
  path: string;
798
+ /** Cookie Domain attribute. */
498
799
  domain: string | undefined;
800
+ /** Whether the cookie is marked Secure. */
499
801
  secure: boolean;
802
+ /** Cookie SameSite attribute. */
500
803
  sameSite: 'Strict' | 'Lax' | 'None';
501
804
  }
502
805
 
806
+ /**
807
+ * Represents the normalized compression middleware options.
808
+ */
503
809
  export interface CompressOptions {
810
+ /** Minimum body size in bytes required to compress. Use `0` to compress any non-empty body. */
504
811
  threshold: number;
812
+ /** Compression level passed to the underlying zlib implementation. */
505
813
  level: number;
814
+ /** Compressible media types. When `undefined`, the default allow-list is used. */
506
815
  types: readonly string[] | undefined;
507
816
  }
508
817
 
509
- // ── ServerConfigurationObject ─────────────────────────────────────────────
818
+ /**
819
+ * Represents the object representation of a server configuration.
820
+ */
510
821
  export interface ServerConfigurationObject {
822
+ /** Connection options forwarded to the adapter. */
511
823
  connection?: ServerConnectionOptions;
824
+ /** Normalized listen options. */
512
825
  listen?: ListenOptions;
826
+ /** Normalized request options. */
513
827
  request?: RequestOptions;
828
+ /** Normalized response options. */
514
829
  response?: ResponseOptions;
830
+ /** Normalized static options. */
515
831
  static?: StaticOptions;
832
+ /** Normalized CORS options. */
516
833
  cors?: CORSOptions;
834
+ /** Normalized security headers options. */
517
835
  securityHeaders?: SecurityHeadersOptions;
836
+ /** Normalized rate limit options. */
518
837
  rateLimit?: RateLimitOptions;
838
+ /** Normalized cookie options. */
519
839
  cookie?: CookieOptions;
840
+ /** Normalized CSRF options. */
520
841
  csrf?: CSRFOptions;
842
+ /** Normalized compression options. */
521
843
  compress?: CompressOptions;
522
844
  }
523
845
 
@@ -525,9 +847,37 @@ export interface ServerConfigurationObject {
525
847
  * Base contract shared by all server configurations.
526
848
  */
527
849
  export interface ServerConfiguration {
850
+ /** Transport identifier. */
528
851
  readonly transport: Transport;
852
+ /** Application-level protocol. */
529
853
  readonly protocol: Protocol;
854
+ /** Connection options forwarded to the adapter. */
530
855
  readonly connection: ServerConnectionOptions | undefined;
856
+
857
+ /** Normalized listen configuration. */
858
+ readonly listen: ListenOptions | undefined;
859
+ /** Normalized request configuration. */
860
+ readonly request: RequestOptions | undefined;
861
+ /** Normalized response configuration. */
862
+ readonly response: ResponseOptions | undefined;
863
+ /** Normalized static files configuration. */
864
+ readonly static: StaticOptions | undefined;
865
+ /** Normalized CORS configuration. */
866
+ readonly cors: CORSOptions | undefined;
867
+ /** Normalized security headers configuration. */
868
+ readonly securityHeaders: SecurityHeadersOptions | undefined;
869
+ /** Normalized rate limit configuration. */
870
+ readonly rateLimit: RateLimitOptions | undefined;
871
+ /** Normalized cookie configuration. */
872
+ readonly cookie: CookieOptions | undefined;
873
+ /** Normalized CSRF configuration. */
874
+ readonly csrf: CSRFOptions | undefined;
875
+ /** Normalized compression configuration. */
876
+ readonly compress: CompressOptions | undefined;
877
+
878
+ /**
879
+ * Returns a plain object representation of the server configuration.
880
+ */
531
881
  toObject(): ServerConfigurationObject;
532
882
  }
533
883
 
@@ -556,6 +906,16 @@ export declare class HttpServerConfiguration implements ServerConfiguration {
556
906
  readonly transport: 'h1';
557
907
  readonly protocol: 'http';
558
908
  readonly connection: http.ServerOptions | undefined;
909
+ readonly listen: ListenOptions | undefined;
910
+ readonly request: RequestOptions | undefined;
911
+ readonly response: ResponseOptions | undefined;
912
+ readonly static: StaticOptions | undefined;
913
+ readonly cors: CORSOptions | undefined;
914
+ readonly securityHeaders: SecurityHeadersOptions | undefined;
915
+ readonly rateLimit: RateLimitOptions | undefined;
916
+ readonly cookie: CookieOptions | undefined;
917
+ readonly csrf: CSRFOptions | undefined;
918
+ readonly compress: CompressOptions | undefined;
559
919
  toObject(): ServerConfigurationObject;
560
920
  }
561
921
 
@@ -564,6 +924,16 @@ export declare class HttpsServerConfiguration implements ServerConfiguration {
564
924
  readonly transport: 'h1s';
565
925
  readonly protocol: 'https';
566
926
  readonly connection: https.ServerOptions | undefined;
927
+ readonly listen: ListenOptions | undefined;
928
+ readonly request: RequestOptions | undefined;
929
+ readonly response: ResponseOptions | undefined;
930
+ readonly static: StaticOptions | undefined;
931
+ readonly cors: CORSOptions | undefined;
932
+ readonly securityHeaders: SecurityHeadersOptions | undefined;
933
+ readonly rateLimit: RateLimitOptions | undefined;
934
+ readonly cookie: CookieOptions | undefined;
935
+ readonly csrf: CSRFOptions | undefined;
936
+ readonly compress: CompressOptions | undefined;
567
937
  toObject(): ServerConfigurationObject;
568
938
  }
569
939
 
@@ -574,6 +944,16 @@ export declare class Http2CleartextServerConfiguration
574
944
  readonly transport: 'h2c';
575
945
  readonly protocol: 'http';
576
946
  readonly connection: http2.ServerOptions | undefined;
947
+ readonly listen: ListenOptions | undefined;
948
+ readonly request: RequestOptions | undefined;
949
+ readonly response: ResponseOptions | undefined;
950
+ readonly static: StaticOptions | undefined;
951
+ readonly cors: CORSOptions | undefined;
952
+ readonly securityHeaders: SecurityHeadersOptions | undefined;
953
+ readonly rateLimit: RateLimitOptions | undefined;
954
+ readonly cookie: CookieOptions | undefined;
955
+ readonly csrf: CSRFOptions | undefined;
956
+ readonly compress: CompressOptions | undefined;
577
957
  toObject(): ServerConfigurationObject;
578
958
  }
579
959
 
@@ -584,32 +964,107 @@ export declare class Http2SecureServerConfiguration
584
964
  readonly transport: 'h2';
585
965
  readonly protocol: 'https';
586
966
  readonly connection: http2.SecureServerOptions | undefined;
967
+ readonly listen: ListenOptions | undefined;
968
+ readonly request: RequestOptions | undefined;
969
+ readonly response: ResponseOptions | undefined;
970
+ readonly static: StaticOptions | undefined;
971
+ readonly cors: CORSOptions | undefined;
972
+ readonly securityHeaders: SecurityHeadersOptions | undefined;
973
+ readonly rateLimit: RateLimitOptions | undefined;
974
+ readonly cookie: CookieOptions | undefined;
975
+ readonly csrf: CSRFOptions | undefined;
976
+ readonly compress: CompressOptions | undefined;
587
977
  toObject(): ServerConfigurationObject;
588
978
  }
589
979
 
590
- // ═══════════════════════════════════════════════════════════════════════════
591
- // ROUTER
592
- // ═══════════════════════════════════════════════════════════════════════════
980
+ // ━━ ROUTER ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
981
+ /**
982
+ * Represents the options used to create an exchange layer.
983
+ */
984
+ export interface ExchangeLayerOptions {
985
+ method: HTTPMethod;
986
+ pathnamePattern: string;
987
+ middleware: MiddlewareFunction;
988
+ }
989
+
990
+ /**
991
+ * Represents the result produced by composing a router.
992
+ */
993
+ export interface RouterComposition {
994
+ middlewares: MiddlewareFunction[];
995
+ layersOptions: ExchangeLayerOptions[];
996
+ }
593
997
 
998
+ /**
999
+ * Defines HTTP middleware pipelines by pathname pattern and method.
1000
+ *
1001
+ * Provides a fluent API for registering middleware.
1002
+ */
594
1003
  export declare class Router {
595
1004
  constructor();
596
1005
 
1006
+ /**
1007
+ * Registers middleware for all routes in the router.
1008
+ */
597
1009
  use(...middlewares: MiddlewareFunction[]): this;
1010
+
1011
+ /**
1012
+ * Registers middleware for all HTTP methods.
1013
+ *
1014
+ * @param pathnamePattern - The pathname pattern to match.
1015
+ * @param middlewares - The middleware functions to execute.
1016
+ */
598
1017
  all(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1018
+
1019
+ /**
1020
+ * Registers middleware for GET requests.
1021
+ */
599
1022
  get(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1023
+
1024
+ /**
1025
+ * Registers middleware for QUERY requests.
1026
+ */
1027
+ query(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1028
+
1029
+ /**
1030
+ * Registers middleware for POST requests.
1031
+ */
600
1032
  post(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1033
+
1034
+ /**
1035
+ * Registers middleware for PUT requests.
1036
+ */
601
1037
  put(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1038
+
1039
+ /**
1040
+ * Registers middleware for PATCH requests.
1041
+ */
602
1042
  patch(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1043
+
1044
+ /**
1045
+ * Registers middleware for DELETE requests.
1046
+ */
603
1047
  delete(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1048
+
1049
+ /**
1050
+ * Registers middleware for HEAD requests.
1051
+ */
604
1052
  head(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
1053
+
1054
+ /**
1055
+ * Registers middleware for TRACE requests.
1056
+ */
605
1057
  trace(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
606
- query(pathnamePattern: string, ...middlewares: MiddlewareFunction[]): this;
607
- }
608
1058
 
609
- // ═══════════════════════════════════════════════════════════════════════════
610
- // EVENTS
611
- // ═══════════════════════════════════════════════════════════════════════════
1059
+ /**
1060
+ * Composes the registered exchange layer options.
1061
+ *
1062
+ * @returns The composed router configuration.
1063
+ */
1064
+ compose(): RouterComposition;
1065
+ }
612
1066
 
1067
+ // ━━ EVENTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
613
1068
  export interface ListenEventData {
614
1069
  endpoint: Endpoint;
615
1070
  address: Address;
@@ -620,64 +1075,148 @@ export interface CloseEventData {
620
1075
  elapsed: number;
621
1076
  }
622
1077
 
623
- // ═══════════════════════════════════════════════════════════════════════════
624
- // SERVER
625
- // ═══════════════════════════════════════════════════════════════════════════
626
-
1078
+ // ━━ SERVER ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1079
+ /**
1080
+ * The central entry point for configuring and controlling the application server.
1081
+ *
1082
+ * It manages the server lifecycle, middleware and route registration, and
1083
+ * server event notifications. The server remains inactive until `listen()`
1084
+ * is called.
1085
+ */
627
1086
  export declare class Server {
628
1087
  constructor(configuration: ServerConfiguration);
629
1088
 
1089
+ /**
1090
+ * The current lifecycle state of the server.
1091
+ */
630
1092
  readonly state: ServerState;
1093
+
1094
+ /**
1095
+ * Whether the server is currently listening for incoming requests.
1096
+ */
631
1097
  readonly listening: boolean;
1098
+
1099
+ /**
1100
+ * The IPC subsystem owned by the server.
1101
+ *
1102
+ * Available only while the server is listening. Accessing this property
1103
+ * before `listen()` resolves throws a `ServerError`.
1104
+ */
632
1105
  readonly ipc: IPCMain;
633
1106
 
634
1107
  // ── Registration ─────────────────────────────────────────────────────────
1108
+
1109
+ /**
1110
+ * Registers middleware for all HTTP methods.
1111
+ */
635
1112
  use(
636
1113
  pathnamePattern: string | MiddlewareFunction,
637
1114
  ...middlewares: MiddlewareFunction[]
638
1115
  ): this;
1116
+
1117
+ /**
1118
+ * Registers middleware for GET requests.
1119
+ */
639
1120
  get(
640
1121
  pathnamePattern: string | MiddlewareFunction,
641
1122
  ...middlewares: MiddlewareFunction[]
642
1123
  ): this;
1124
+
1125
+ /**
1126
+ * Registers middleware for POST requests.
1127
+ */
643
1128
  post(
644
1129
  pathnamePattern: string | MiddlewareFunction,
645
1130
  ...middlewares: MiddlewareFunction[]
646
1131
  ): this;
1132
+
1133
+ /**
1134
+ * Registers middleware for PUT requests.
1135
+ */
647
1136
  put(
648
1137
  pathnamePattern: string | MiddlewareFunction,
649
1138
  ...middlewares: MiddlewareFunction[]
650
1139
  ): this;
1140
+
1141
+ /**
1142
+ * Registers middleware for PATCH requests.
1143
+ */
651
1144
  patch(
652
1145
  pathnamePattern: string | MiddlewareFunction,
653
1146
  ...middlewares: MiddlewareFunction[]
654
1147
  ): this;
1148
+
1149
+ /**
1150
+ * Registers middleware for DELETE requests.
1151
+ */
655
1152
  delete(
656
1153
  pathnamePattern: string | MiddlewareFunction,
657
1154
  ...middlewares: MiddlewareFunction[]
658
1155
  ): this;
1156
+
1157
+ /**
1158
+ * Registers middleware for HEAD requests.
1159
+ */
659
1160
  head(
660
1161
  pathnamePattern: string | MiddlewareFunction,
661
1162
  ...middlewares: MiddlewareFunction[]
662
1163
  ): this;
1164
+
1165
+ /**
1166
+ * Registers middleware for TRACE requests.
1167
+ */
663
1168
  trace(
664
1169
  pathnamePattern: string | MiddlewareFunction,
665
1170
  ...middlewares: MiddlewareFunction[]
666
1171
  ): this;
1172
+
1173
+ /**
1174
+ * Registers middleware for QUERY requests.
1175
+ */
667
1176
  query(
668
1177
  pathnamePattern: string | MiddlewareFunction,
669
1178
  ...middlewares: MiddlewareFunction[]
670
1179
  ): this;
671
1180
 
1181
+ /**
1182
+ * Mounts a router instance at a specific pathname prefix.
1183
+ *
1184
+ * @param pathnamePattern - Pathname prefix where the router is mounted.
1185
+ * @param router - Router instance to mount.
1186
+ */
672
1187
  mount(pathnamePattern: string, router: Router): this;
1188
+
1189
+ /**
1190
+ * Registers a custom handler for requests that do not match any route.
1191
+ *
1192
+ * @param handler - The handler function executed on unmatched routes.
1193
+ */
673
1194
  notFound(handler: NotFoundHandler): this;
1195
+
1196
+ /**
1197
+ * Registers a handler for errors raised during request processing.
1198
+ *
1199
+ * @param handler - The error handling function.
1200
+ */
674
1201
  systemError(handler: SystemErrorHandler): this;
675
1202
 
676
1203
  // ── Lifecycle ────────────────────────────────────────────────────────────
1204
+
1205
+ /**
1206
+ * Starts listening for incoming requests.
1207
+ *
1208
+ * Transitions the server state from `idle` to `starting`, and upon success,
1209
+ * to `listening`.
1210
+ */
677
1211
  listen(): Promise<void>;
1212
+
1213
+ /**
1214
+ * Stops the server and releases associated network resources.
1215
+ */
678
1216
  close(): Promise<void>;
679
1217
 
680
1218
  // ── Events (typed overloads) ─────────────────────────────────────────────
1219
+ // No JSDoc needed here. The literals and callback types are self-documenting.
681
1220
  on(event: 'listen', listener: (data: ListenEventData) => void): this;
682
1221
  on(event: 'close', listener: (data: CloseEventData) => void): this;
683
1222
  on(event: 'error', listener: (error: Error) => void): this;
@@ -712,8 +1251,5 @@ export declare class Server {
712
1251
  [Symbol.asyncDispose](): Promise<void>;
713
1252
  }
714
1253
 
715
- // ═══════════════════════════════════════════════════════════════════════════
716
- // DEFAULT EXPORT
717
- // ═══════════════════════════════════════════════════════════════════════════
718
-
1254
+ // ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
719
1255
  export default Server;