@valkyrjaio/valkyrja 26.1.0 → 26.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/Valkyrja/Application/Constant/ApplicationInfo.ts +2 -2
  4. package/src/Valkyrja/Application/Data/CliConfig.ts +1 -1
  5. package/src/Valkyrja/Application/Data/Contract/CliConfigContract.ts +1 -1
  6. package/src/Valkyrja/Application/Data/Contract/HttpConfigContract.ts +1 -1
  7. package/src/Valkyrja/Application/Data/HttpConfig.ts +1 -1
  8. package/src/Valkyrja/Application/Kernel/Valkyrja.ts +9 -6
  9. package/src/Valkyrja/Application/Provider/HttpApplicationComponentProvider.ts +13 -1
  10. package/src/Valkyrja/Cli/Interaction/Enum/BackgroundColor.ts +2 -4
  11. package/src/Valkyrja/Cli/Interaction/Enum/Style.ts +12 -14
  12. package/src/Valkyrja/Cli/Interaction/Enum/TextColor.ts +2 -4
  13. package/src/Valkyrja/Cli/Interaction/Format/BackgroundColorFormat.ts +2 -2
  14. package/src/Valkyrja/Cli/Interaction/Format/StyleFormat.ts +2 -2
  15. package/src/Valkyrja/Cli/Interaction/Format/TextColorFormat.ts +2 -2
  16. package/src/Valkyrja/Cli/Interaction/Option/Factory/OptionFactory.ts +6 -3
  17. package/src/Valkyrja/Cli/Middleware/Constant/CliMiddlewareServiceId.ts +2 -1
  18. package/src/Valkyrja/Cli/Middleware/Contract/ProcessExitingMiddlewareContract.ts +22 -0
  19. package/src/Valkyrja/Cli/Middleware/Handler/Contract/HandlerContract.ts +2 -2
  20. package/src/Valkyrja/Cli/Middleware/Handler/Contract/{ExitedHandlerContract.ts → ProcessExitingHandlerContract.ts} +5 -5
  21. package/src/Valkyrja/Cli/Middleware/Handler/{ExitedHandler.ts → ProcessExitingHandler.ts} +5 -5
  22. package/src/Valkyrja/Cli/Middleware/Provider/CliMiddlewareServiceProvider.ts +11 -7
  23. package/src/Valkyrja/Cli/Routing/Data/Contract/RouteContract.ts +3 -3
  24. package/src/Valkyrja/Cli/Routing/Data/Route.ts +7 -7
  25. package/src/Valkyrja/Cli/Routing/Dispatcher/Router.ts +5 -11
  26. package/src/Valkyrja/Cli/Routing/Provider/CliRoutingServiceProvider.ts +4 -2
  27. package/src/Valkyrja/Cli/Server/Handler/InputHandler.ts +4 -4
  28. package/src/Valkyrja/Cli/Server/Provider/CliServerServiceProvider.ts +4 -2
  29. package/src/Valkyrja/Http/Message/Header/Factory/CookieFactory.ts +4 -5
  30. package/src/Valkyrja/Http/Message/Header/Factory/HeaderFactory.ts +2 -2
  31. package/src/Valkyrja/Http/Message/Header/Header.ts +8 -2
  32. package/src/Valkyrja/Http/Message/Header/Value/Component/Component.ts +3 -3
  33. package/src/Valkyrja/Http/Message/Provider/HttpMessageComponentProvider.ts +39 -0
  34. package/src/Valkyrja/Http/Message/Uri/Factory/UriFactory.ts +1 -1
  35. package/src/Valkyrja/Http/Middleware/Constant/HttpMiddlewareServiceId.ts +2 -1
  36. package/src/Valkyrja/Http/Middleware/Contract/{TerminatedMiddlewareContract.ts → ResponseSentMiddlewareContract.ts} +7 -3
  37. package/src/Valkyrja/Http/Middleware/Handler/Contract/HandlerContract.ts +2 -2
  38. package/src/Valkyrja/Http/Middleware/Handler/Contract/{TerminatedHandlerContract.ts → ResponseSentHandlerContract.ts} +3 -3
  39. package/src/Valkyrja/Http/Middleware/Handler/{TerminatedHandler.ts → ResponseSentHandler.ts} +8 -5
  40. package/src/Valkyrja/Http/Middleware/Provider/HttpMiddlewareComponentProvider.ts +39 -0
  41. package/src/Valkyrja/Http/Middleware/Provider/HttpMiddlewareServiceProvider.ts +96 -0
  42. package/src/Valkyrja/Http/Routing/Data/Contract/RouteContract.ts +6 -4
  43. package/src/Valkyrja/Http/Routing/Data/DynamicRoute.ts +3 -3
  44. package/src/Valkyrja/Http/Routing/Data/Route.ts +9 -9
  45. package/src/Valkyrja/Http/Routing/Dispatcher/Router.ts +4 -4
  46. package/src/Valkyrja/Http/Routing/Provider/HttpRoutingComponentProvider.ts +39 -0
  47. package/src/Valkyrja/Http/Routing/Provider/HttpRoutingServiceProvider.ts +141 -0
  48. package/src/Valkyrja/Http/Server/Handler/RequestHandler.ts +8 -7
  49. package/src/Valkyrja/Http/Server/Provider/HttpServerComponentProvider.ts +39 -0
  50. package/src/Valkyrja/Http/Server/Provider/HttpServerServiceProvider.ts +56 -0
  51. package/src/Valkyrja/Validation/Validator/Validator.ts +1 -4
  52. package/src/Valkyrja/Cli/Middleware/Contract/ExitedMiddlewareContract.ts +0 -22
package/README.md CHANGED
@@ -15,7 +15,7 @@ does the heavy lifting so you can focus on your application.
15
15
  <p>
16
16
  <a href="https://www.npmjs.com/package/@valkyrjaio/valkyrja"><img src="https://img.shields.io/npm/v/@valkyrjaio/valkyrja.svg" alt="Latest Version on npm"></a>
17
17
  <a href="https://www.npmjs.com/package/@valkyrjaio/valkyrja"><img src="https://img.shields.io/node/v/@valkyrjaio/valkyrja.svg" alt="Supported Node.js Version"></a>
18
- <a href="https://www.npmjs.com/package/@valkyrjaio/valkyrja"><img src="https://img.shields.io/npm/l/@valkyrjaio/valkyrja.svg" alt="License"></a>
18
+ <a href="https://github.com/valkyrjaio/valkyrja-ts/blob/26.x/LICENSE.md"><img src="https://img.shields.io/github/license/valkyrjaio/valkyrja-ts.svg" alt="License"></a>
19
19
  <a href="https://github.com/valkyrjaio/valkyrja-ts/actions/workflows/ci.yml?query=branch%3A26.x"><img src="https://github.com/valkyrjaio/valkyrja-ts/actions/workflows/ci.yml/badge.svg?branch=26.x" alt="CI Status"></a>
20
20
  </p>
21
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@valkyrjaio/valkyrja",
3
- "version": "26.1.0",
3
+ "version": "26.3.0",
4
4
  "description": "The Valkyrja Framework.",
5
5
  "keywords": [
6
6
  "framework",
@@ -8,8 +8,8 @@
8
8
  */
9
9
 
10
10
  export class ApplicationInfo {
11
- static readonly VERSION = '26.1.0' as const;
12
- static readonly VERSION_BUILD_DATE_TIME = 'June 17 2026 19:35:02 MST' as const;
11
+ static readonly VERSION = '26.3.0' as const;
12
+ static readonly VERSION_BUILD_DATE_TIME = 'July 25 2026 20:40:59 MST' as const;
13
13
  static readonly ASCII = `
14
14
  _ _ _
15
15
  /\\ /\\__ _| | | ___ _ _ __(_) __ _
@@ -46,6 +46,6 @@ export class CliConfig implements CliConfigContract {
46
46
  CliServerServiceId.LogThrowableCaughtMiddleware,
47
47
  CliServerServiceId.OutputThrowableCaughtMiddleware,
48
48
  ],
49
- public readonly exitedMiddleware: string[] = [],
49
+ public readonly processExitingMiddleware: string[] = [],
50
50
  ) {}
51
51
  }
@@ -17,7 +17,7 @@ export interface CliConfigContract extends ConfigContract {
17
17
  readonly routeNotMatchedMiddleware: string[];
18
18
  readonly routeDispatchedMiddleware: string[];
19
19
  readonly throwableCaughtMiddleware: string[];
20
- readonly exitedMiddleware: string[];
20
+ readonly processExitingMiddleware: string[];
21
21
  }
22
22
 
23
23
  export namespace CliConfigContract {
@@ -16,7 +16,7 @@ export interface HttpConfigContract extends ConfigContract {
16
16
  readonly routeDispatchedMiddleware: string[];
17
17
  readonly throwableCaughtMiddleware: string[];
18
18
  readonly sendingResponseMiddleware: string[];
19
- readonly terminatedMiddleware: string[];
19
+ readonly responseSentMiddleware: string[];
20
20
  }
21
21
 
22
22
  export namespace HttpConfigContract {
@@ -36,6 +36,6 @@ export class HttpConfig implements HttpConfigContract {
36
36
  public readonly routeDispatchedMiddleware: string[] = [],
37
37
  public readonly throwableCaughtMiddleware: string[] = [],
38
38
  public readonly sendingResponseMiddleware: string[] = [],
39
- public readonly terminatedMiddleware: string[] = [],
39
+ public readonly responseSentMiddleware: string[] = [],
40
40
  ) {}
41
41
  }
@@ -47,18 +47,21 @@ export class Valkyrja implements ApplicationContract {
47
47
  return this.providers;
48
48
  }
49
49
 
50
- const providers: ComponentProviderContract[][] = [];
51
-
52
50
  for (const provider of this.config.providers) {
53
- providers.push(provider.getComponentProviders(this));
54
- providers.push([provider]);
51
+ this.collectProviders(provider);
55
52
  }
56
53
 
57
- this.providers = [...new Set(providers.flat())];
58
-
59
54
  return this.providers;
60
55
  }
61
56
 
57
+ protected collectProviders(provider: ComponentProviderContract): void {
58
+ for (const subProvider of provider.getComponentProviders(this)) {
59
+ this.collectProviders(subProvider);
60
+ }
61
+
62
+ this.providers.push(provider);
63
+ }
64
+
62
65
  getContainerProviders(): ServiceProviderContract[] {
63
66
  if (this.serviceProviders.length > 0) {
64
67
  return this.serviceProviders;
@@ -8,6 +8,11 @@
8
8
  */
9
9
 
10
10
  import { ContainerComponentProvider } from '../../Container/Provider/ContainerComponentProvider.ts';
11
+ import { HttpMessageComponentProvider } from '../../Http/Message/Provider/HttpMessageComponentProvider.ts';
12
+ import { HttpMiddlewareComponentProvider } from '../../Http/Middleware/Provider/HttpMiddlewareComponentProvider.ts';
13
+ import { HttpRoutingCliComponentProvider } from '../../Http/Routing/Provider/HttpRoutingCliComponentProvider.ts';
14
+ import { HttpRoutingComponentProvider } from '../../Http/Routing/Provider/HttpRoutingComponentProvider.ts';
15
+ import { HttpServerComponentProvider } from '../../Http/Server/Provider/HttpServerComponentProvider.ts';
11
16
  import { ApplicationComponentProvider } from './ApplicationComponentProvider.ts';
12
17
 
13
18
  import type { ApplicationContract } from '../Kernel/Contract/ApplicationContract.ts';
@@ -15,6 +20,13 @@ import type { ComponentProviderContract } from './Contract/ComponentProviderCont
15
20
 
16
21
  export class HttpApplicationComponentProvider extends ApplicationComponentProvider {
17
22
  override getComponentProviders(_app: ApplicationContract): ComponentProviderContract[] {
18
- return [new ContainerComponentProvider()];
23
+ return [
24
+ new ContainerComponentProvider(),
25
+ new HttpMessageComponentProvider(),
26
+ new HttpMiddlewareComponentProvider(),
27
+ new HttpRoutingComponentProvider(),
28
+ new HttpRoutingCliComponentProvider(),
29
+ new HttpServerComponentProvider(),
30
+ ];
19
31
  }
20
32
  }
@@ -26,8 +26,6 @@ export enum BackgroundColor {
26
26
  LIGHT_WHITE = 107,
27
27
  }
28
28
 
29
- export namespace BackgroundColor {
30
- export function getDefault(): number {
31
- return 49;
32
- }
29
+ export function backgroundColorDefault(): number {
30
+ return 49;
33
31
  }
@@ -15,19 +15,17 @@ export enum Style {
15
15
  CONCEAL = 8,
16
16
  }
17
17
 
18
- export namespace Style {
19
- export function getDefault(style: Style): number {
20
- switch (style) {
21
- case Style.BOLD:
22
- return 22;
23
- case Style.UNDERSCORE:
24
- return 24;
25
- case Style.BLINK:
26
- return 25;
27
- case Style.INVERSE:
28
- return 27;
29
- case Style.CONCEAL:
30
- return 28;
31
- }
18
+ export function styleDefault(style: Style): number {
19
+ switch (style) {
20
+ case Style.BOLD:
21
+ return 22;
22
+ case Style.UNDERSCORE:
23
+ return 24;
24
+ case Style.BLINK:
25
+ return 25;
26
+ case Style.INVERSE:
27
+ return 27;
28
+ case Style.CONCEAL:
29
+ return 28;
32
30
  }
33
31
  }
@@ -26,8 +26,6 @@ export enum TextColor {
26
26
  LIGHT_WHITE = 97,
27
27
  }
28
28
 
29
- export namespace TextColor {
30
- export function getDefault(): number {
31
- return 39;
32
- }
29
+ export function textColorDefault(): number {
30
+ return 39;
33
31
  }
@@ -7,11 +7,11 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
 
10
- import { BackgroundColor } from '../Enum/BackgroundColor.ts';
10
+ import { BackgroundColor, backgroundColorDefault } from '../Enum/BackgroundColor.ts';
11
11
  import { Format } from './Format.ts';
12
12
 
13
13
  export class BackgroundColorFormat extends Format {
14
14
  constructor(backgroundColor: BackgroundColor) {
15
- super(String(backgroundColor), String(BackgroundColor.getDefault()));
15
+ super(String(backgroundColor), String(backgroundColorDefault()));
16
16
  }
17
17
  }
@@ -7,11 +7,11 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
 
10
- import { Style } from '../Enum/Style.ts';
10
+ import { Style, styleDefault } from '../Enum/Style.ts';
11
11
  import { Format } from './Format.ts';
12
12
 
13
13
  export class StyleFormat extends Format {
14
14
  constructor(style: Style) {
15
- super(String(style), String(Style.getDefault(style)));
15
+ super(String(style), String(styleDefault(style)));
16
16
  }
17
17
  }
@@ -7,11 +7,11 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
 
10
- import { TextColor } from '../Enum/TextColor.ts';
10
+ import { TextColor, textColorDefault } from '../Enum/TextColor.ts';
11
11
  import { Format } from './Format.ts';
12
12
 
13
13
  export class TextColorFormat extends Format {
14
14
  constructor(textColor: TextColor) {
15
- super(String(textColor), String(TextColor.getDefault()));
15
+ super(String(textColor), String(textColorDefault()));
16
16
  }
17
17
  }
@@ -18,9 +18,12 @@ export abstract class OptionFactory {
18
18
  OptionFactory.validateArgIsOption(arg);
19
19
 
20
20
  const type = OptionFactory.getOptionType(arg);
21
- const parts = arg.split('=');
22
- const name = (parts[0] ?? '').replace(/^-+/, '').trim();
23
- const value = parts[1] ?? '';
21
+ // The name is everything before the first '='; the value is the segment after it (if any).
22
+ const name = arg
23
+ .replace(/=[\s\S]*$/, '')
24
+ .replace(/^-+/, '')
25
+ .trim();
26
+ const value = arg.split('=')[1] ?? '';
24
27
 
25
28
  OptionFactory.validateNonEmptyName(name);
26
29
 
@@ -18,5 +18,6 @@ export class CliMiddlewareServiceId {
18
18
  'Valkyrja.Cli.Middleware.Handler.RouteDispatchedHandlerContract' as const;
19
19
  static readonly ThrowableCaughtHandlerContract =
20
20
  'Valkyrja.Cli.Middleware.Handler.ThrowableCaughtHandlerContract' as const;
21
- static readonly ExitedHandlerContract = 'Valkyrja.Cli.Middleware.Handler.ExitedHandlerContract' as const;
21
+ static readonly ProcessExitingHandlerContract =
22
+ 'Valkyrja.Cli.Middleware.Handler.ProcessExitingHandlerContract' as const;
22
23
  }
@@ -0,0 +1,22 @@
1
+ /*
2
+ * This file is part of the Valkyrja package.
3
+ *
4
+ * (c) Melech Mizrachi <melechmizrachi@gmail.com>
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+
10
+ import type { InputContract } from '../../Interaction/Input/Contract/InputContract.ts';
11
+ import type { OutputContract } from '../../Interaction/Output/Contract/OutputContract.ts';
12
+ import type { ProcessExitingHandlerContract } from '../Handler/Contract/ProcessExitingHandlerContract.ts';
13
+
14
+ export interface ProcessExitingMiddlewareContract {
15
+ processExiting(input: InputContract, output: OutputContract, handler: ProcessExitingHandlerContract): void;
16
+ }
17
+
18
+ export namespace ProcessExitingMiddlewareContract {
19
+ export function instanceOf(value: unknown): value is ProcessExitingMiddlewareContract {
20
+ return typeof value === 'object' && value !== null && 'processExiting' in value;
21
+ }
22
+ }
@@ -7,7 +7,7 @@
7
7
  * file that was distributed with this source code.
8
8
  */
9
9
 
10
- import type { ExitedMiddlewareContract } from '../../Contract/ExitedMiddlewareContract.ts';
10
+ import type { ProcessExitingMiddlewareContract } from '../../Contract/ProcessExitingMiddlewareContract.ts';
11
11
  import type { InputReceivedMiddlewareContract } from '../../Contract/InputReceivedMiddlewareContract.ts';
12
12
  import type { RouteDispatchedMiddlewareContract } from '../../Contract/RouteDispatchedMiddlewareContract.ts';
13
13
  import type { RouteMatchedMiddlewareContract } from '../../Contract/RouteMatchedMiddlewareContract.ts';
@@ -20,7 +20,7 @@ export type AnyMiddlewareContract =
20
20
  | RouteNotMatchedMiddlewareContract
21
21
  | RouteDispatchedMiddlewareContract
22
22
  | ThrowableCaughtMiddlewareContract
23
- | ExitedMiddlewareContract;
23
+ | ProcessExitingMiddlewareContract;
24
24
 
25
25
  export interface HandlerContract {
26
26
  add(...middleware: string[]): void;
@@ -11,12 +11,12 @@ import type { InputContract } from '../../../Interaction/Input/Contract/InputCon
11
11
  import type { OutputContract } from '../../../Interaction/Output/Contract/OutputContract.ts';
12
12
  import type { HandlerContract } from './HandlerContract.ts';
13
13
 
14
- export interface ExitedHandlerContract extends HandlerContract {
15
- exited(input: InputContract, output: OutputContract): void;
14
+ export interface ProcessExitingHandlerContract extends HandlerContract {
15
+ processExiting(input: InputContract, output: OutputContract): void;
16
16
  }
17
17
 
18
- export namespace ExitedHandlerContract {
19
- export function instanceOf(value: unknown): value is ExitedHandlerContract {
20
- return typeof value === 'object' && value !== null && 'exited' in value;
18
+ export namespace ProcessExitingHandlerContract {
19
+ export function instanceOf(value: unknown): value is ProcessExitingHandlerContract {
20
+ return typeof value === 'object' && value !== null && 'processExiting' in value;
21
21
  }
22
22
  }
@@ -9,16 +9,16 @@
9
9
 
10
10
  import type { InputContract } from '../../Interaction/Input/Contract/InputContract.ts';
11
11
  import type { OutputContract } from '../../Interaction/Output/Contract/OutputContract.ts';
12
- import type { ExitedMiddlewareContract } from '../Contract/ExitedMiddlewareContract.ts';
12
+ import type { ProcessExitingMiddlewareContract } from '../Contract/ProcessExitingMiddlewareContract.ts';
13
13
  import { Handler } from './Abstract/Handler.ts';
14
- import type { ExitedHandlerContract } from './Contract/ExitedHandlerContract.ts';
14
+ import type { ProcessExitingHandlerContract } from './Contract/ProcessExitingHandlerContract.ts';
15
15
 
16
- export class ExitedHandler extends Handler implements ExitedHandlerContract {
17
- exited(input: InputContract, output: OutputContract): void {
16
+ export class ProcessExitingHandler extends Handler implements ProcessExitingHandlerContract {
17
+ processExiting(input: InputContract, output: OutputContract): void {
18
18
  const next = this.next;
19
19
 
20
20
  if (next !== null) {
21
- this.getMiddleware<ExitedMiddlewareContract>(next).exited(input, output, this);
21
+ this.getMiddleware<ProcessExitingMiddlewareContract>(next).processExiting(input, output, this);
22
22
  }
23
23
  }
24
24
  }
@@ -12,13 +12,13 @@ import type { CliConfigContract } from '../../../Application/Data/Contract/CliCo
12
12
  import type { ContainerContract } from '../../../Container/Manager/Contract/ContainerContract.ts';
13
13
  import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
14
14
  import { CliMiddlewareServiceId } from '../Constant/CliMiddlewareServiceId.ts';
15
- import type { ExitedHandlerContract } from '../Handler/Contract/ExitedHandlerContract.ts';
15
+ import type { ProcessExitingHandlerContract } from '../Handler/Contract/ProcessExitingHandlerContract.ts';
16
16
  import type { InputReceivedHandlerContract } from '../Handler/Contract/InputReceivedHandlerContract.ts';
17
17
  import type { RouteDispatchedHandlerContract } from '../Handler/Contract/RouteDispatchedHandlerContract.ts';
18
18
  import type { RouteMatchedHandlerContract } from '../Handler/Contract/RouteMatchedHandlerContract.ts';
19
19
  import type { RouteNotMatchedHandlerContract } from '../Handler/Contract/RouteNotMatchedHandlerContract.ts';
20
20
  import type { ThrowableCaughtHandlerContract } from '../Handler/Contract/ThrowableCaughtHandlerContract.ts';
21
- import { ExitedHandler } from '../Handler/ExitedHandler.ts';
21
+ import { ProcessExitingHandler } from '../Handler/ProcessExitingHandler.ts';
22
22
  import { InputReceivedHandler } from '../Handler/InputReceivedHandler.ts';
23
23
  import { RouteDispatchedHandler } from '../Handler/RouteDispatchedHandler.ts';
24
24
  import { RouteMatchedHandler } from '../Handler/RouteMatchedHandler.ts';
@@ -38,7 +38,8 @@ export class CliMiddlewareServiceProvider implements ServiceProviderContract {
38
38
  CliMiddlewareServiceProvider.publishRouteNotMatchedHandler,
39
39
  [CliMiddlewareServiceId.RouteDispatchedHandlerContract]:
40
40
  CliMiddlewareServiceProvider.publishRouteDispatchedHandler,
41
- [CliMiddlewareServiceId.ExitedHandlerContract]: CliMiddlewareServiceProvider.publishExitedHandler,
41
+ [CliMiddlewareServiceId.ProcessExitingHandlerContract]:
42
+ CliMiddlewareServiceProvider.publishProcessExitingHandler,
42
43
  };
43
44
  }
44
45
 
@@ -107,13 +108,16 @@ export class CliMiddlewareServiceProvider implements ServiceProviderContract {
107
108
  handler.add(...config.routeNotMatchedMiddleware);
108
109
  }
109
110
 
110
- static publishExitedHandler(this: void, container: ContainerContract): void {
111
+ static publishProcessExitingHandler(this: void, container: ContainerContract): void {
111
112
  const config = container.getSingleton<CliConfigContract>(ApplicationServiceId.CliConfigContract);
112
113
 
113
- const handler = new ExitedHandler(container);
114
+ const handler = new ProcessExitingHandler(container);
114
115
 
115
- container.setSingleton<ExitedHandlerContract>(CliMiddlewareServiceId.ExitedHandlerContract, handler);
116
+ container.setSingleton<ProcessExitingHandlerContract>(
117
+ CliMiddlewareServiceId.ProcessExitingHandlerContract,
118
+ handler,
119
+ );
116
120
 
117
- handler.add(...config.exitedMiddleware);
121
+ handler.add(...config.processExitingMiddleware);
118
122
  }
119
123
  }
@@ -43,9 +43,9 @@ export interface RouteContract {
43
43
  getThrowableCaughtMiddleware(): string[];
44
44
  withThrowableCaughtMiddleware(...middleware: string[]): this;
45
45
  withAddedThrowableCaughtMiddleware(...middleware: string[]): this;
46
- getExitedMiddleware(): string[];
47
- withExitedMiddleware(...middleware: string[]): this;
48
- withAddedExitedMiddleware(...middleware: string[]): this;
46
+ getProcessExitingMiddleware(): string[];
47
+ withProcessExitingMiddleware(...middleware: string[]): this;
48
+ withAddedProcessExitingMiddleware(...middleware: string[]): this;
49
49
  getHandler(): (container: ContainerContract, route: RouteContract) => OutputContract;
50
50
  withHandler(handler: (container: ContainerContract, route: RouteContract) => OutputContract): this;
51
51
  }
@@ -27,7 +27,7 @@ export class Route implements RouteContract {
27
27
  protected routeMatchedMiddleware: string[] = [],
28
28
  protected routeDispatchedMiddleware: string[] = [],
29
29
  protected throwableCaughtMiddleware: string[] = [],
30
- protected exitedMiddleware: string[] = [],
30
+ protected processExitingMiddleware: string[] = [],
31
31
  protected arguments_: ArgumentParameterContract[] = [],
32
32
  protected options: OptionParameterContract[] = [],
33
33
  ) {}
@@ -183,19 +183,19 @@ export class Route implements RouteContract {
183
183
  return clone;
184
184
  }
185
185
 
186
- getExitedMiddleware(): string[] {
187
- return this.exitedMiddleware;
186
+ getProcessExitingMiddleware(): string[] {
187
+ return this.processExitingMiddleware;
188
188
  }
189
189
 
190
- withExitedMiddleware(...middleware: string[]): this {
190
+ withProcessExitingMiddleware(...middleware: string[]): this {
191
191
  const clone = ObjectFactory.clone(this);
192
- clone.exitedMiddleware = middleware;
192
+ clone.processExitingMiddleware = middleware;
193
193
  return clone;
194
194
  }
195
195
 
196
- withAddedExitedMiddleware(...middleware: string[]): this {
196
+ withAddedProcessExitingMiddleware(...middleware: string[]): this {
197
197
  const clone = ObjectFactory.clone(this);
198
- clone.exitedMiddleware = [...this.exitedMiddleware, ...middleware];
198
+ clone.processExitingMiddleware = [...this.processExitingMiddleware, ...middleware];
199
199
  return clone;
200
200
  }
201
201
 
@@ -15,8 +15,8 @@ import { ErrorMessage } from '../../Interaction/Message/ErrorMessage.ts';
15
15
  import type { OutputContract } from '../../Interaction/Output/Contract/OutputContract.ts';
16
16
  import { OutputFactory } from '../../Interaction/Output/Factory/OutputFactory.ts';
17
17
  import type { OutputFactoryContract } from '../../Interaction/Output/Factory/Contract/OutputFactoryContract.ts';
18
- import { ExitedHandler } from '../../Middleware/Handler/ExitedHandler.ts';
19
- import type { ExitedHandlerContract } from '../../Middleware/Handler/Contract/ExitedHandlerContract.ts';
18
+ import { ProcessExitingHandler } from '../../Middleware/Handler/ProcessExitingHandler.ts';
19
+ import type { ProcessExitingHandlerContract } from '../../Middleware/Handler/Contract/ProcessExitingHandlerContract.ts';
20
20
  import { RouteDispatchedHandler } from '../../Middleware/Handler/RouteDispatchedHandler.ts';
21
21
  import type { RouteDispatchedHandlerContract } from '../../Middleware/Handler/Contract/RouteDispatchedHandlerContract.ts';
22
22
  import { RouteMatchedHandler } from '../../Middleware/Handler/RouteMatchedHandler.ts';
@@ -44,7 +44,7 @@ export class Router implements RouterContract {
44
44
  protected routeMatchedHandler: RouteMatchedHandlerContract = new RouteMatchedHandler(),
45
45
  protected routeNotMatchedHandler: RouteNotMatchedHandlerContract = new RouteNotMatchedHandler(),
46
46
  protected routeDispatchedHandler: RouteDispatchedHandlerContract = new RouteDispatchedHandler(),
47
- protected exitedHandler: ExitedHandlerContract = new ExitedHandler(),
47
+ protected processExitingHandler: ProcessExitingHandlerContract = new ProcessExitingHandler(),
48
48
  ) {}
49
49
 
50
50
  dispatch(input: InputContract): OutputContract {
@@ -99,13 +99,7 @@ export class Router implements RouterContract {
99
99
  const argumentParameters = route.getArguments();
100
100
  const updatedParams: ArgumentParameterContract[] = [];
101
101
 
102
- for (let i = 0; i < argumentParameters.length; i++) {
103
- const param = argumentParameters[i];
104
-
105
- if (param === undefined) {
106
- continue;
107
- }
108
-
102
+ for (const [i, param] of argumentParameters.entries()) {
109
103
  let paramArguments: typeof arguments_ = [];
110
104
 
111
105
  if (param.getValueMode() === ArgumentValueMode.ARRAY) {
@@ -144,7 +138,7 @@ export class Router implements RouterContract {
144
138
  this.routeMatchedHandler.add(...route.getRouteMatchedMiddleware());
145
139
  this.routeDispatchedHandler.add(...route.getRouteDispatchedMiddleware());
146
140
  this.throwableCaughtHandler.add(...route.getThrowableCaughtMiddleware());
147
- this.exitedHandler.add(...route.getExitedMiddleware());
141
+ this.processExitingHandler.add(...route.getProcessExitingMiddleware());
148
142
 
149
143
  this.container.setSingleton<RouteContract>(CliRoutingServiceId.RouteContract, route);
150
144
  }
@@ -14,7 +14,7 @@ import type { ServiceProviderContract } from '../../../Container/Provider/Contra
14
14
  import { CliInteractionServiceId } from '../../Interaction/Constant/CliInteractionServiceId.ts';
15
15
  import type { OutputFactoryContract } from '../../Interaction/Output/Factory/Contract/OutputFactoryContract.ts';
16
16
  import { CliMiddlewareServiceId } from '../../Middleware/Constant/CliMiddlewareServiceId.ts';
17
- import type { ExitedHandlerContract } from '../../Middleware/Handler/Contract/ExitedHandlerContract.ts';
17
+ import type { ProcessExitingHandlerContract } from '../../Middleware/Handler/Contract/ProcessExitingHandlerContract.ts';
18
18
  import type { RouteDispatchedHandlerContract } from '../../Middleware/Handler/Contract/RouteDispatchedHandlerContract.ts';
19
19
  import type { RouteMatchedHandlerContract } from '../../Middleware/Handler/Contract/RouteMatchedHandlerContract.ts';
20
20
  import type { RouteNotMatchedHandlerContract } from '../../Middleware/Handler/Contract/RouteNotMatchedHandlerContract.ts';
@@ -52,7 +52,9 @@ export class CliRoutingServiceProvider implements ServiceProviderContract {
52
52
  container.getSingleton<RouteDispatchedHandlerContract>(
53
53
  CliMiddlewareServiceId.RouteDispatchedHandlerContract,
54
54
  ),
55
- container.getSingleton<ExitedHandlerContract>(CliMiddlewareServiceId.ExitedHandlerContract),
55
+ container.getSingleton<ProcessExitingHandlerContract>(
56
+ CliMiddlewareServiceId.ProcessExitingHandlerContract,
57
+ ),
56
58
  ),
57
59
  );
58
60
  }
@@ -20,8 +20,8 @@ import { NewLine } from '../../Interaction/Message/NewLine.ts';
20
20
  import type { OutputContract } from '../../Interaction/Output/Contract/OutputContract.ts';
21
21
  import { OutputFactory } from '../../Interaction/Output/Factory/OutputFactory.ts';
22
22
  import type { OutputFactoryContract } from '../../Interaction/Output/Factory/Contract/OutputFactoryContract.ts';
23
- import type { ExitedHandlerContract } from '../../Middleware/Handler/Contract/ExitedHandlerContract.ts';
24
- import { ExitedHandler } from '../../Middleware/Handler/ExitedHandler.ts';
23
+ import type { ProcessExitingHandlerContract } from '../../Middleware/Handler/Contract/ProcessExitingHandlerContract.ts';
24
+ import { ProcessExitingHandler } from '../../Middleware/Handler/ProcessExitingHandler.ts';
25
25
  import type { InputReceivedHandlerContract } from '../../Middleware/Handler/Contract/InputReceivedHandlerContract.ts';
26
26
  import { InputReceivedHandler } from '../../Middleware/Handler/InputReceivedHandler.ts';
27
27
  import type { ThrowableCaughtHandlerContract } from '../../Middleware/Handler/Contract/ThrowableCaughtHandlerContract.ts';
@@ -38,7 +38,7 @@ export class InputHandler implements InputHandlerContract {
38
38
  protected router: RouterContract = new Router(),
39
39
  protected inputReceivedHandler: InputReceivedHandlerContract = new InputReceivedHandler(),
40
40
  protected throwableCaughtHandler: ThrowableCaughtHandlerContract = new ThrowableCaughtHandler(),
41
- protected exitedHandler: ExitedHandlerContract = new ExitedHandler(),
41
+ protected processExitingHandler: ProcessExitingHandlerContract = new ProcessExitingHandler(),
42
42
  protected interactionConfig: CliInteractionConfigContract = new CliInteractionConfig(),
43
43
  protected outputFactory: OutputFactoryContract = new OutputFactory(),
44
44
  ) {}
@@ -59,7 +59,7 @@ export class InputHandler implements InputHandlerContract {
59
59
  }
60
60
 
61
61
  exit(input: InputContract, output: OutputContract): void {
62
- this.exitedHandler.exited(input, output);
62
+ this.processExitingHandler.processExiting(input, output);
63
63
  }
64
64
 
65
65
  run(input: InputContract): void {
@@ -16,7 +16,7 @@ import { CliInteractionServiceId } from '../../Interaction/Constant/CliInteracti
16
16
  import type { CliInteractionConfigContract } from '../../Interaction/Data/Contract/CliInteractionConfigContract.ts';
17
17
  import type { OutputFactoryContract } from '../../Interaction/Output/Factory/Contract/OutputFactoryContract.ts';
18
18
  import { CliMiddlewareServiceId } from '../../Middleware/Constant/CliMiddlewareServiceId.ts';
19
- import type { ExitedHandlerContract } from '../../Middleware/Handler/Contract/ExitedHandlerContract.ts';
19
+ import type { ProcessExitingHandlerContract } from '../../Middleware/Handler/Contract/ProcessExitingHandlerContract.ts';
20
20
  import type { InputReceivedHandlerContract } from '../../Middleware/Handler/Contract/InputReceivedHandlerContract.ts';
21
21
  import type { ThrowableCaughtHandlerContract } from '../../Middleware/Handler/Contract/ThrowableCaughtHandlerContract.ts';
22
22
  import type { RouteCollectionContract } from '../../Routing/Collection/Contract/RouteCollectionContract.ts';
@@ -82,7 +82,9 @@ export class CliServerServiceProvider implements ServiceProviderContract {
82
82
  container.getSingleton<ThrowableCaughtHandlerContract>(
83
83
  CliMiddlewareServiceId.ThrowableCaughtHandlerContract,
84
84
  ),
85
- container.getSingleton<ExitedHandlerContract>(CliMiddlewareServiceId.ExitedHandlerContract),
85
+ container.getSingleton<ProcessExitingHandlerContract>(
86
+ CliMiddlewareServiceId.ProcessExitingHandlerContract,
87
+ ),
86
88
  container.getSingleton<CliInteractionConfigContract>(
87
89
  CliInteractionServiceId.CliInteractionConfigContract,
88
90
  ),
@@ -14,11 +14,10 @@ export abstract class CookieFactory {
14
14
  /(?:^[\n]?[ \t]*|;[ ])(?<name>[!#$%&'*+\-.0-9A-Z^_`a-z|~]+)=(?<DQUOTE>"?)(?<value>[\x21\x23-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]*)(?<DQCLOSE>"?)(?=[\n]?[ \t]*$|;[ ])/g;
15
15
  let match: RegExpExecArray | null;
16
16
  while ((match = pattern.exec(cookieHeader)) !== null) {
17
- const name = match.groups?.['name'] ?? '';
18
- const value = match.groups?.['value'] ?? '';
19
- if (name !== '') {
20
- cookies[name] = decodeURIComponent(value);
21
- }
17
+ // The pattern only matches when both named groups are present, and `name` requires at
18
+ // least one character, so the groups are always defined non-empty strings here.
19
+ const { name, value } = match.groups as Record<'name' | 'value', string>;
20
+ cookies[name] = decodeURIComponent(value);
22
21
  }
23
22
  return cookies;
24
23
  }
@@ -34,13 +34,13 @@ export abstract class HeaderFactory {
34
34
  const lf = value.charCodeAt(i + 1);
35
35
  const ws = value.charCodeAt(i + 2);
36
36
  if (lf === 10 && (ws === 9 || ws === 32)) {
37
- result += (value[i] ?? '') + (value[i + 1] ?? '');
37
+ result += value.charAt(i) + value.charAt(i + 1);
38
38
  i++;
39
39
  }
40
40
  continue;
41
41
  }
42
42
  if (!HeaderFactory.isInvalidValueAscii(ascii)) {
43
- result += value[i] ?? '';
43
+ result += value.charAt(i);
44
44
  }
45
45
  }
46
46
  return result;
@@ -74,11 +74,17 @@ export class Header implements HeaderContract {
74
74
  }
75
75
 
76
76
  getHeaderLine(): string {
77
- return this.name + ': ' + this.valuesToString();
77
+ return this.valuesToString();
78
78
  }
79
79
 
80
80
  toString(): string {
81
- return this.getHeaderLine();
81
+ const values = this.valuesToString();
82
+
83
+ if (values === '') {
84
+ return '';
85
+ }
86
+
87
+ return this.name + ': ' + values;
82
88
  }
83
89
 
84
90
  protected updateValues(...values: Array<ValueContract | string>): void {
@@ -21,9 +21,9 @@ export class Component implements ComponentContract {
21
21
 
22
22
  static fromValue(value: string): Component {
23
23
  const deliminator = '=';
24
- if (value.includes(deliminator)) {
25
- const [token, ...rest] = value.split(deliminator);
26
- return new Component(token?.trim() ?? '', rest.join(deliminator).trim());
24
+ const index = value.indexOf(deliminator);
25
+ if (index !== -1) {
26
+ return new Component(value.slice(0, index).trim(), value.slice(index + 1).trim());
27
27
  }
28
28
  return new Component(value.trim());
29
29
  }