@valkyrjaio/valkyrja 26.2.0 → 26.4.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.
- package/package.json +1 -1
- package/src/Valkyrja/Application/Constant/ApplicationInfo.ts +2 -2
- package/src/Valkyrja/Application/Entry/Cli.ts +3 -1
- package/src/Valkyrja/Application/Entry/Http.ts +37 -7
- package/src/Valkyrja/Application/Entry/WorkerHttp.ts +122 -0
- package/src/Valkyrja/Application/Kernel/Valkyrja.ts +9 -6
- package/src/Valkyrja/Application/Provider/HttpApplicationComponentProvider.ts +13 -1
- package/src/Valkyrja/Cli/Interaction/Input/Factory/InputFactory.ts +8 -1
- package/src/Valkyrja/Cli/Interaction/Option/Factory/OptionFactory.ts +5 -6
- package/src/Valkyrja/Cli/Routing/Data/OptionParameter.ts +8 -0
- package/src/Valkyrja/Http/Message/Header/Collection/HeaderCollection.ts +19 -1
- package/src/Valkyrja/Http/Message/Provider/HttpMessageComponentProvider.ts +39 -0
- package/src/Valkyrja/Http/Middleware/Provider/HttpMiddlewareComponentProvider.ts +39 -0
- package/src/Valkyrja/Http/Middleware/Provider/HttpMiddlewareServiceProvider.ts +96 -0
- package/src/Valkyrja/Http/Routing/Constant/Regex.ts +2 -2
- package/src/Valkyrja/Http/Routing/Provider/HttpRoutingComponentProvider.ts +39 -0
- package/src/Valkyrja/Http/Routing/Provider/HttpRoutingServiceProvider.ts +141 -0
- package/src/Valkyrja/Http/Server/Handler/RequestHandler.ts +4 -3
- package/src/Valkyrja/Http/Server/Provider/HttpServerComponentProvider.ts +39 -0
- package/src/Valkyrja/Http/Server/Provider/HttpServerServiceProvider.ts +56 -0
- package/src/Valkyrja/Application/Entry/Abstract/WorkerHttp.ts +0 -83
package/package.json
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
export class ApplicationInfo {
|
|
11
|
-
static readonly VERSION = '26.
|
|
12
|
-
static readonly VERSION_BUILD_DATE_TIME = 'July
|
|
11
|
+
static readonly VERSION = '26.4.0' as const;
|
|
12
|
+
static readonly VERSION_BUILD_DATE_TIME = 'July 27 2026 22:05:07 MST' as const;
|
|
13
13
|
static readonly ASCII = `
|
|
14
14
|
_ _ _
|
|
15
15
|
/\\ /\\__ _| | | ___ _ _ __(_) __ _
|
|
@@ -29,6 +29,8 @@ export class Cli extends App {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
static getInput(config: CliConfigContract): InputContract {
|
|
32
|
-
|
|
32
|
+
// process.argv leads with the interpreter path, so drop it: the factory expects the vector
|
|
33
|
+
// to start with the caller, followed by the command name and the rest of the args.
|
|
34
|
+
return InputFactory.fromGlobals(process.argv.slice(1), config.applicationName, config.defaultCommandName);
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { createServer } from 'node:http';
|
|
11
|
-
import type { IncomingMessage } from 'node:http';
|
|
11
|
+
import type { IncomingMessage, Server, ServerResponse } from 'node:http';
|
|
12
12
|
|
|
13
13
|
import { App } from './Abstract/App.ts';
|
|
14
14
|
import { HttpServerServiceId } from '../../Http/Server/Constant/HttpServerServiceId.ts';
|
|
@@ -20,6 +20,14 @@ import type { RequestHandlerContract } from '../../Http/Server/Handler/Contract/
|
|
|
20
20
|
|
|
21
21
|
export class Http extends App {
|
|
22
22
|
static run(config: HttpConfigContract, port: number = 3000): void {
|
|
23
|
+
const server = this.createServer((req, res) => {
|
|
24
|
+
this.handle(config, req, res);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
this.listen(server, port);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static handle(config: HttpConfigContract, nodeRequest: IncomingMessage, nodeResponse: ServerResponse): void {
|
|
23
31
|
const app = this.start(config);
|
|
24
32
|
const container = app.getContainer();
|
|
25
33
|
|
|
@@ -27,15 +35,37 @@ export class Http extends App {
|
|
|
27
35
|
|
|
28
36
|
const handler = container.getSingleton<RequestHandlerContract>(HttpServerServiceId.RequestHandlerContract);
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
const request = this.getRequest(req);
|
|
32
|
-
handler.run(request, res);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
server.listen(port);
|
|
38
|
+
handler.run(this.getRequest(nodeRequest), nodeResponse);
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
static getRequest(nodeRequest: IncomingMessage): ServerRequestContract {
|
|
39
42
|
return RequestFactory.fromNodeRequest(nodeRequest);
|
|
40
43
|
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create the native HTTP server.
|
|
47
|
+
*
|
|
48
|
+
* Overridable runtime seam wrapping Node's socket-creating `createServer`, so
|
|
49
|
+
* tests can substitute a double without opening a real socket. Ignored for
|
|
50
|
+
* coverage because it is irreducible runtime I/O that only runs against a live
|
|
51
|
+
* server.
|
|
52
|
+
*/
|
|
53
|
+
/* v8 ignore start */
|
|
54
|
+
static createServer(handler: (request: IncomingMessage, response: ServerResponse) => void): Server {
|
|
55
|
+
return createServer(handler);
|
|
56
|
+
}
|
|
57
|
+
/* v8 ignore stop */
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Bind the server to the given port.
|
|
61
|
+
*
|
|
62
|
+
* Overridable runtime seam wrapping Node's socket-binding `listen`, so tests
|
|
63
|
+
* can substitute a double without binding a real port. Ignored for coverage
|
|
64
|
+
* because it is irreducible runtime I/O that only runs against a live server.
|
|
65
|
+
*/
|
|
66
|
+
/* v8 ignore start */
|
|
67
|
+
static listen(server: Server, port: number): void {
|
|
68
|
+
server.listen(port);
|
|
69
|
+
}
|
|
70
|
+
/* v8 ignore stop */
|
|
41
71
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
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 { createServer } from 'node:http';
|
|
11
|
+
import type { IncomingMessage, Server, ServerResponse } from 'node:http';
|
|
12
|
+
|
|
13
|
+
import { ChildApplication } from '../Kernel/ChildApplication.ts';
|
|
14
|
+
import { ChildContainer } from '../../Container/Manager/ChildContainer.ts';
|
|
15
|
+
import { ApplicationServiceId } from '../Constant/ApplicationServiceId.ts';
|
|
16
|
+
import { ContainerServiceId } from '../../Container/Constant/ContainerServiceId.ts';
|
|
17
|
+
import { HttpServerServiceId } from '../../Http/Server/Constant/HttpServerServiceId.ts';
|
|
18
|
+
import { HttpRoutingServiceId } from '../../Http/Routing/Constant/HttpRoutingServiceId.ts';
|
|
19
|
+
import { RequestFactory } from '../../Http/Message/Request/Factory/RequestFactory.ts';
|
|
20
|
+
import { App } from './Abstract/App.ts';
|
|
21
|
+
|
|
22
|
+
import type { ApplicationContract } from '../Kernel/Contract/ApplicationContract.ts';
|
|
23
|
+
import type { ContainerContract } from '../../Container/Manager/Contract/ContainerContract.ts';
|
|
24
|
+
import type { ContainerData } from '../../Container/Data/ContainerData.ts';
|
|
25
|
+
import type { HttpConfigContract } from '../Data/Contract/HttpConfigContract.ts';
|
|
26
|
+
import type { ServerRequestContract } from '../../Http/Message/Request/Contract/ServerRequestContract.ts';
|
|
27
|
+
import type { RequestHandlerContract } from '../../Http/Server/Handler/Contract/RequestHandlerContract.ts';
|
|
28
|
+
import type { RouteCollectionContract } from '../../Http/Routing/Collection/Contract/RouteCollectionContract.ts';
|
|
29
|
+
|
|
30
|
+
export class WorkerHttp extends App {
|
|
31
|
+
static run(config: HttpConfigContract, port: number = 3000): void {
|
|
32
|
+
const app = this.bootstrap(config);
|
|
33
|
+
const data = app.getContainer().getData();
|
|
34
|
+
|
|
35
|
+
const server = this.createServer((req, res) => {
|
|
36
|
+
this.handle(app, data, req, res);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
this.listen(server, port);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static bootstrap(config: HttpConfigContract): ApplicationContract {
|
|
43
|
+
const app = this.start(config);
|
|
44
|
+
const container = app.getContainer();
|
|
45
|
+
|
|
46
|
+
this.bootstrapThrowableHandler(app, container);
|
|
47
|
+
this.bootstrapParentServices(app);
|
|
48
|
+
|
|
49
|
+
return app;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static handle(
|
|
53
|
+
app: ApplicationContract,
|
|
54
|
+
data: ContainerData,
|
|
55
|
+
nodeRequest: IncomingMessage,
|
|
56
|
+
nodeResponse: ServerResponse,
|
|
57
|
+
): void {
|
|
58
|
+
const request = this.getRequest(nodeRequest);
|
|
59
|
+
const childContainer = this.getChildContainer(app, data);
|
|
60
|
+
const childApp = this.getChildApplication(app, childContainer);
|
|
61
|
+
|
|
62
|
+
this.bootstrapChildContainer(childApp, childContainer);
|
|
63
|
+
this.handleRequest(childContainer, request, nodeResponse);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static getChildApplication(app: ApplicationContract, container: ContainerContract): ApplicationContract {
|
|
67
|
+
return new ChildApplication(app, container);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static getChildContainer(app: ApplicationContract, data: ContainerData): ContainerContract {
|
|
71
|
+
return new ChildContainer(app.getContainer(), data);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static bootstrapChildContainer(app: ApplicationContract, container: ContainerContract): void {
|
|
75
|
+
container.setSingleton(ApplicationServiceId.ApplicationContract, app);
|
|
76
|
+
container.setSingleton(ContainerServiceId.Contract, container);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static handleRequest(
|
|
80
|
+
container: ContainerContract,
|
|
81
|
+
request: ServerRequestContract,
|
|
82
|
+
nodeResponse: ServerResponse,
|
|
83
|
+
): void {
|
|
84
|
+
const handler = container.getSingleton<RequestHandlerContract>(HttpServerServiceId.RequestHandlerContract);
|
|
85
|
+
handler.run(request, nodeResponse);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
static getRequest(nodeRequest: IncomingMessage): ServerRequestContract {
|
|
89
|
+
return RequestFactory.fromNodeRequest(nodeRequest);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static bootstrapParentServices(app: ApplicationContract): void {
|
|
93
|
+
app.getContainer().getSingleton<RouteCollectionContract>(HttpRoutingServiceId.RouteCollectionContract);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Create the native HTTP server.
|
|
98
|
+
*
|
|
99
|
+
* Overridable runtime seam wrapping Node's socket-creating `createServer`, so
|
|
100
|
+
* tests can substitute a double without opening a real socket. Ignored for
|
|
101
|
+
* coverage because it is irreducible runtime I/O that only runs against a live
|
|
102
|
+
* server.
|
|
103
|
+
*/
|
|
104
|
+
/* v8 ignore start */
|
|
105
|
+
static createServer(handler: (request: IncomingMessage, response: ServerResponse) => void): Server {
|
|
106
|
+
return createServer(handler);
|
|
107
|
+
}
|
|
108
|
+
/* v8 ignore stop */
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Bind the server to the given port.
|
|
112
|
+
*
|
|
113
|
+
* Overridable runtime seam wrapping Node's socket-binding `listen`, so tests
|
|
114
|
+
* can substitute a double without binding a real port. Ignored for coverage
|
|
115
|
+
* because it is irreducible runtime I/O that only runs against a live server.
|
|
116
|
+
*/
|
|
117
|
+
/* v8 ignore start */
|
|
118
|
+
static listen(server: Server, port: number): void {
|
|
119
|
+
server.listen(port);
|
|
120
|
+
}
|
|
121
|
+
/* v8 ignore stop */
|
|
122
|
+
}
|
|
@@ -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
|
-
|
|
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 [
|
|
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
|
}
|
|
@@ -25,11 +25,18 @@ export abstract class InputFactory {
|
|
|
25
25
|
): InputContract {
|
|
26
26
|
const arguments_ = [];
|
|
27
27
|
const options = [];
|
|
28
|
+
let endOfOptions = false;
|
|
28
29
|
|
|
29
30
|
for (const [key, arg] of args.entries()) {
|
|
30
31
|
if (key === 0) {
|
|
31
32
|
applicationName = arg;
|
|
32
|
-
} else if (arg
|
|
33
|
+
} else if (!endOfOptions && arg === '--') {
|
|
34
|
+
// POSIX end-of-options marker: the `--` itself is consumed, and every arg after
|
|
35
|
+
// it is an operand — never an option, however many dashes it starts with. A
|
|
36
|
+
// second `--` is therefore an ordinary operand.
|
|
37
|
+
endOfOptions = true;
|
|
38
|
+
} else if (!endOfOptions && arg !== '-' && arg.startsWith('-')) {
|
|
39
|
+
// A lone `-` is an operand by convention (it names standard input), not an option.
|
|
33
40
|
options.push(...OptionFactory.fromArg(arg));
|
|
34
41
|
} else if (key === 1) {
|
|
35
42
|
commandName = arg;
|
|
@@ -18,12 +18,11 @@ export abstract class OptionFactory {
|
|
|
18
18
|
OptionFactory.validateArgIsOption(arg);
|
|
19
19
|
|
|
20
20
|
const type = OptionFactory.getOptionType(arg);
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const value = arg.split('=')[1] ?? '';
|
|
21
|
+
// Split on the first `=` only, so a value that itself contains one survives intact
|
|
22
|
+
// (`--expr=a=b` yields `a=b`, not `a`).
|
|
23
|
+
const separatorIndex = arg.indexOf('=');
|
|
24
|
+
const name = (separatorIndex === -1 ? arg : arg.slice(0, separatorIndex)).replace(/^-+/, '').trim();
|
|
25
|
+
const value = separatorIndex === -1 ? '' : arg.slice(separatorIndex + 1);
|
|
27
26
|
|
|
28
27
|
OptionFactory.validateNonEmptyName(name);
|
|
29
28
|
|
|
@@ -176,6 +176,14 @@ export class OptionParameter extends Parameter implements OptionParameterContrac
|
|
|
176
176
|
valid = valid && this.options.length <= 1;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
if (this.validValues.length > 0) {
|
|
180
|
+
for (const option of this.options) {
|
|
181
|
+
if (!this.validValues.includes(option.getValue())) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
179
187
|
return valid;
|
|
180
188
|
}
|
|
181
189
|
|
|
@@ -101,10 +101,28 @@ export class HeaderCollection implements HeaderCollectionContract {
|
|
|
101
101
|
withAddedHeaders(...headers: HeaderContract[]): this {
|
|
102
102
|
const clone = ObjectFactory.clone(this);
|
|
103
103
|
clone.headers = { ...this.headers };
|
|
104
|
-
|
|
104
|
+
for (const header of headers) {
|
|
105
|
+
clone.addHeader(header);
|
|
106
|
+
}
|
|
105
107
|
return clone;
|
|
106
108
|
}
|
|
107
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Add a header, merging its values into an existing header of the same name.
|
|
112
|
+
*/
|
|
113
|
+
protected addHeader(header: HeaderContract): void {
|
|
114
|
+
const name = header.getNormalizedName();
|
|
115
|
+
const existing = this.headers[name];
|
|
116
|
+
|
|
117
|
+
if (existing === undefined) {
|
|
118
|
+
this.headers[name] = header;
|
|
119
|
+
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.headers[name] = existing.withAddedValues(...header.getValues());
|
|
124
|
+
}
|
|
125
|
+
|
|
108
126
|
protected setHeaders(...headers: HeaderContract[]): void {
|
|
109
127
|
this.setHeadersOnCollection(this, ...headers);
|
|
110
128
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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 { HttpMessageServiceProvider } from './HttpMessageServiceProvider.ts';
|
|
11
|
+
|
|
12
|
+
import type { ApplicationContract } from '../../../Application/Kernel/Contract/ApplicationContract.ts';
|
|
13
|
+
import type { ComponentProviderContract } from '../../../Application/Provider/Contract/ComponentProviderContract.ts';
|
|
14
|
+
import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
|
|
15
|
+
import type { ListenerProviderContract } from '../../../Event/Provider/Contract/ListenerProviderContract.ts';
|
|
16
|
+
import type { CliRouteProviderContract } from '../../../Cli/Routing/Provider/Contract/CliRouteProviderContract.ts';
|
|
17
|
+
import type { HttpRouteProviderContract } from '../../Routing/Provider/Contract/HttpRouteProviderContract.ts';
|
|
18
|
+
|
|
19
|
+
export class HttpMessageComponentProvider implements ComponentProviderContract {
|
|
20
|
+
getComponentProviders(_app: ApplicationContract): ComponentProviderContract[] {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getContainerProviders(_app: ApplicationContract): ServiceProviderContract[] {
|
|
25
|
+
return [new HttpMessageServiceProvider()];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getEventProviders(_app: ApplicationContract): ListenerProviderContract[] {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getCliProviders(_app: ApplicationContract): CliRouteProviderContract[] {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getHttpProviders(_app: ApplicationContract): HttpRouteProviderContract[] {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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 { HttpMiddlewareServiceProvider } from './HttpMiddlewareServiceProvider.ts';
|
|
11
|
+
|
|
12
|
+
import type { ApplicationContract } from '../../../Application/Kernel/Contract/ApplicationContract.ts';
|
|
13
|
+
import type { ComponentProviderContract } from '../../../Application/Provider/Contract/ComponentProviderContract.ts';
|
|
14
|
+
import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
|
|
15
|
+
import type { ListenerProviderContract } from '../../../Event/Provider/Contract/ListenerProviderContract.ts';
|
|
16
|
+
import type { CliRouteProviderContract } from '../../../Cli/Routing/Provider/Contract/CliRouteProviderContract.ts';
|
|
17
|
+
import type { HttpRouteProviderContract } from '../../Routing/Provider/Contract/HttpRouteProviderContract.ts';
|
|
18
|
+
|
|
19
|
+
export class HttpMiddlewareComponentProvider implements ComponentProviderContract {
|
|
20
|
+
getComponentProviders(_app: ApplicationContract): ComponentProviderContract[] {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getContainerProviders(_app: ApplicationContract): ServiceProviderContract[] {
|
|
25
|
+
return [new HttpMiddlewareServiceProvider()];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getEventProviders(_app: ApplicationContract): ListenerProviderContract[] {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getCliProviders(_app: ApplicationContract): CliRouteProviderContract[] {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getHttpProviders(_app: ApplicationContract): HttpRouteProviderContract[] {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
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 { ContainerContract } from '../../../Container/Manager/Contract/ContainerContract.ts';
|
|
11
|
+
import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
|
|
12
|
+
import { HttpMiddlewareServiceId } from '../Constant/HttpMiddlewareServiceId.ts';
|
|
13
|
+
import type { RequestReceivedHandlerContract } from '../Handler/Contract/RequestReceivedHandlerContract.ts';
|
|
14
|
+
import type { ResponseSentHandlerContract } from '../Handler/Contract/ResponseSentHandlerContract.ts';
|
|
15
|
+
import type { RouteDispatchedHandlerContract } from '../Handler/Contract/RouteDispatchedHandlerContract.ts';
|
|
16
|
+
import type { RouteMatchedHandlerContract } from '../Handler/Contract/RouteMatchedHandlerContract.ts';
|
|
17
|
+
import type { RouteNotMatchedHandlerContract } from '../Handler/Contract/RouteNotMatchedHandlerContract.ts';
|
|
18
|
+
import type { SendingResponseHandlerContract } from '../Handler/Contract/SendingResponseHandlerContract.ts';
|
|
19
|
+
import type { ThrowableCaughtHandlerContract } from '../Handler/Contract/ThrowableCaughtHandlerContract.ts';
|
|
20
|
+
import { RequestReceivedHandler } from '../Handler/RequestReceivedHandler.ts';
|
|
21
|
+
import { ResponseSentHandler } from '../Handler/ResponseSentHandler.ts';
|
|
22
|
+
import { RouteDispatchedHandler } from '../Handler/RouteDispatchedHandler.ts';
|
|
23
|
+
import { RouteMatchedHandler } from '../Handler/RouteMatchedHandler.ts';
|
|
24
|
+
import { RouteNotMatchedHandler } from '../Handler/RouteNotMatchedHandler.ts';
|
|
25
|
+
import { SendingResponseHandler } from '../Handler/SendingResponseHandler.ts';
|
|
26
|
+
import { ThrowableCaughtHandler } from '../Handler/ThrowableCaughtHandler.ts';
|
|
27
|
+
|
|
28
|
+
export class HttpMiddlewareServiceProvider implements ServiceProviderContract {
|
|
29
|
+
publishers(): Record<string, (container: ContainerContract) => void> {
|
|
30
|
+
return {
|
|
31
|
+
[HttpMiddlewareServiceId.RequestReceivedHandlerContract]:
|
|
32
|
+
HttpMiddlewareServiceProvider.publishRequestReceivedHandler,
|
|
33
|
+
[HttpMiddlewareServiceId.ThrowableCaughtHandlerContract]:
|
|
34
|
+
HttpMiddlewareServiceProvider.publishThrowableCaughtHandler,
|
|
35
|
+
[HttpMiddlewareServiceId.RouteMatchedHandlerContract]:
|
|
36
|
+
HttpMiddlewareServiceProvider.publishRouteMatchedHandler,
|
|
37
|
+
[HttpMiddlewareServiceId.RouteNotMatchedHandlerContract]:
|
|
38
|
+
HttpMiddlewareServiceProvider.publishRouteNotMatchedHandler,
|
|
39
|
+
[HttpMiddlewareServiceId.RouteDispatchedHandlerContract]:
|
|
40
|
+
HttpMiddlewareServiceProvider.publishRouteDispatchedHandler,
|
|
41
|
+
[HttpMiddlewareServiceId.SendingResponseHandlerContract]:
|
|
42
|
+
HttpMiddlewareServiceProvider.publishSendingResponseHandler,
|
|
43
|
+
[HttpMiddlewareServiceId.ResponseSentHandlerContract]:
|
|
44
|
+
HttpMiddlewareServiceProvider.publishResponseSentHandler,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static publishRequestReceivedHandler(this: void, container: ContainerContract): void {
|
|
49
|
+
container.setSingleton<RequestReceivedHandlerContract>(
|
|
50
|
+
HttpMiddlewareServiceId.RequestReceivedHandlerContract,
|
|
51
|
+
new RequestReceivedHandler(container),
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static publishThrowableCaughtHandler(this: void, container: ContainerContract): void {
|
|
56
|
+
container.setSingleton<ThrowableCaughtHandlerContract>(
|
|
57
|
+
HttpMiddlewareServiceId.ThrowableCaughtHandlerContract,
|
|
58
|
+
new ThrowableCaughtHandler(container),
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static publishRouteMatchedHandler(this: void, container: ContainerContract): void {
|
|
63
|
+
container.setSingleton<RouteMatchedHandlerContract>(
|
|
64
|
+
HttpMiddlewareServiceId.RouteMatchedHandlerContract,
|
|
65
|
+
new RouteMatchedHandler(container),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static publishRouteNotMatchedHandler(this: void, container: ContainerContract): void {
|
|
70
|
+
container.setSingleton<RouteNotMatchedHandlerContract>(
|
|
71
|
+
HttpMiddlewareServiceId.RouteNotMatchedHandlerContract,
|
|
72
|
+
new RouteNotMatchedHandler(container),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static publishRouteDispatchedHandler(this: void, container: ContainerContract): void {
|
|
77
|
+
container.setSingleton<RouteDispatchedHandlerContract>(
|
|
78
|
+
HttpMiddlewareServiceId.RouteDispatchedHandlerContract,
|
|
79
|
+
new RouteDispatchedHandler(container),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static publishSendingResponseHandler(this: void, container: ContainerContract): void {
|
|
84
|
+
container.setSingleton<SendingResponseHandlerContract>(
|
|
85
|
+
HttpMiddlewareServiceId.SendingResponseHandlerContract,
|
|
86
|
+
new SendingResponseHandler(container),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static publishResponseSentHandler(this: void, container: ContainerContract): void {
|
|
91
|
+
container.setSingleton<ResponseSentHandlerContract>(
|
|
92
|
+
HttpMiddlewareServiceId.ResponseSentHandlerContract,
|
|
93
|
+
new ResponseSentHandler(container),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -42,8 +42,8 @@ export class Regex {
|
|
|
42
42
|
static readonly ALPHA_NUM = '[a-zA-Z0-9]+';
|
|
43
43
|
static readonly ALPHA_NUM_UNDERSCORE = '\\w+';
|
|
44
44
|
|
|
45
|
-
static readonly START = '
|
|
46
|
-
static readonly END = '
|
|
45
|
+
static readonly START = '^';
|
|
46
|
+
static readonly END = '$';
|
|
47
47
|
|
|
48
48
|
static readonly START_CAPTURE_GROUP = '(';
|
|
49
49
|
static readonly START_NON_CAPTURE_GROUP = '(?:';
|
|
@@ -0,0 +1,39 @@
|
|
|
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 { HttpRoutingServiceProvider } from './HttpRoutingServiceProvider.ts';
|
|
11
|
+
|
|
12
|
+
import type { ApplicationContract } from '../../../Application/Kernel/Contract/ApplicationContract.ts';
|
|
13
|
+
import type { ComponentProviderContract } from '../../../Application/Provider/Contract/ComponentProviderContract.ts';
|
|
14
|
+
import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
|
|
15
|
+
import type { ListenerProviderContract } from '../../../Event/Provider/Contract/ListenerProviderContract.ts';
|
|
16
|
+
import type { CliRouteProviderContract } from '../../../Cli/Routing/Provider/Contract/CliRouteProviderContract.ts';
|
|
17
|
+
import type { HttpRouteProviderContract } from './Contract/HttpRouteProviderContract.ts';
|
|
18
|
+
|
|
19
|
+
export class HttpRoutingComponentProvider implements ComponentProviderContract {
|
|
20
|
+
getComponentProviders(_app: ApplicationContract): ComponentProviderContract[] {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getContainerProviders(_app: ApplicationContract): ServiceProviderContract[] {
|
|
25
|
+
return [new HttpRoutingServiceProvider()];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getEventProviders(_app: ApplicationContract): ListenerProviderContract[] {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getCliProviders(_app: ApplicationContract): CliRouteProviderContract[] {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getHttpProviders(_app: ApplicationContract): HttpRouteProviderContract[] {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
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 { ApplicationServiceId } from '../../../Application/Constant/ApplicationServiceId.ts';
|
|
11
|
+
import type { ApplicationContract } from '../../../Application/Kernel/Contract/ApplicationContract.ts';
|
|
12
|
+
import type { ContainerContract } from '../../../Container/Manager/Contract/ContainerContract.ts';
|
|
13
|
+
import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
|
|
14
|
+
import { HttpMessageServiceId } from '../../Message/Constant/HttpMessageServiceId.ts';
|
|
15
|
+
import type { ResponseFactoryContract } from '../../Message/Response/Factory/Contract/ResponseFactoryContract.ts';
|
|
16
|
+
import { HttpMiddlewareServiceId } from '../../Middleware/Constant/HttpMiddlewareServiceId.ts';
|
|
17
|
+
import type { ResponseSentHandlerContract } from '../../Middleware/Handler/Contract/ResponseSentHandlerContract.ts';
|
|
18
|
+
import type { RouteDispatchedHandlerContract } from '../../Middleware/Handler/Contract/RouteDispatchedHandlerContract.ts';
|
|
19
|
+
import type { RouteMatchedHandlerContract } from '../../Middleware/Handler/Contract/RouteMatchedHandlerContract.ts';
|
|
20
|
+
import type { RouteNotMatchedHandlerContract } from '../../Middleware/Handler/Contract/RouteNotMatchedHandlerContract.ts';
|
|
21
|
+
import type { SendingResponseHandlerContract } from '../../Middleware/Handler/Contract/SendingResponseHandlerContract.ts';
|
|
22
|
+
import type { ThrowableCaughtHandlerContract } from '../../Middleware/Handler/Contract/ThrowableCaughtHandlerContract.ts';
|
|
23
|
+
import type { RouteCollectionContract } from '../Collection/Contract/RouteCollectionContract.ts';
|
|
24
|
+
import { RouteCollection } from '../Collection/RouteCollection.ts';
|
|
25
|
+
import { HttpRoutingServiceId } from '../Constant/HttpRoutingServiceId.ts';
|
|
26
|
+
import { HttpRoutingData } from '../Data/HttpRoutingData.ts';
|
|
27
|
+
import type { RouterContract } from '../Dispatcher/Contract/RouterContract.ts';
|
|
28
|
+
import { Router } from '../Dispatcher/Router.ts';
|
|
29
|
+
import type { RoutingResponseFactoryContract } from '../Factory/Contract/RoutingResponseFactoryContract.ts';
|
|
30
|
+
import { RoutingResponseFactory } from '../Factory/RoutingResponseFactory.ts';
|
|
31
|
+
import type { MatcherContract } from '../Matcher/Contract/MatcherContract.ts';
|
|
32
|
+
import { Matcher } from '../Matcher/Matcher.ts';
|
|
33
|
+
import type { ProcessorContract } from '../Processor/Contract/ProcessorContract.ts';
|
|
34
|
+
import { Processor } from '../Processor/Processor.ts';
|
|
35
|
+
import type { UrlContract } from '../Url/Contract/UrlContract.ts';
|
|
36
|
+
import { Url } from '../Url/Url.ts';
|
|
37
|
+
|
|
38
|
+
export class HttpRoutingServiceProvider implements ServiceProviderContract {
|
|
39
|
+
publishers(): Record<string, (container: ContainerContract) => void> {
|
|
40
|
+
return {
|
|
41
|
+
[HttpRoutingServiceId.RouterContract]: HttpRoutingServiceProvider.publishRouter,
|
|
42
|
+
[HttpRoutingServiceId.RouteCollectionContract]: HttpRoutingServiceProvider.publishRouteCollection,
|
|
43
|
+
[HttpRoutingServiceId.MatcherContract]: HttpRoutingServiceProvider.publishMatcher,
|
|
44
|
+
[HttpRoutingServiceId.UrlContract]: HttpRoutingServiceProvider.publishUrl,
|
|
45
|
+
[HttpRoutingServiceId.ProcessorContract]: HttpRoutingServiceProvider.publishProcessor,
|
|
46
|
+
[HttpRoutingServiceId.RoutingResponseFactory]: HttpRoutingServiceProvider.publishResponseFactory,
|
|
47
|
+
[HttpRoutingServiceId.HttpRoutingData]: HttpRoutingServiceProvider.publishData,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static publishRouter(this: void, container: ContainerContract): void {
|
|
52
|
+
container.setSingleton<RouterContract>(
|
|
53
|
+
HttpRoutingServiceId.RouterContract,
|
|
54
|
+
new Router(
|
|
55
|
+
container,
|
|
56
|
+
container.getSingleton<MatcherContract>(HttpRoutingServiceId.MatcherContract),
|
|
57
|
+
container.getSingleton<ResponseFactoryContract>(HttpMessageServiceId.ResponseFactoryContract),
|
|
58
|
+
container.getSingleton<ThrowableCaughtHandlerContract>(
|
|
59
|
+
HttpMiddlewareServiceId.ThrowableCaughtHandlerContract,
|
|
60
|
+
),
|
|
61
|
+
container.getSingleton<RouteMatchedHandlerContract>(
|
|
62
|
+
HttpMiddlewareServiceId.RouteMatchedHandlerContract,
|
|
63
|
+
),
|
|
64
|
+
container.getSingleton<RouteNotMatchedHandlerContract>(
|
|
65
|
+
HttpMiddlewareServiceId.RouteNotMatchedHandlerContract,
|
|
66
|
+
),
|
|
67
|
+
container.getSingleton<RouteDispatchedHandlerContract>(
|
|
68
|
+
HttpMiddlewareServiceId.RouteDispatchedHandlerContract,
|
|
69
|
+
),
|
|
70
|
+
container.getSingleton<SendingResponseHandlerContract>(
|
|
71
|
+
HttpMiddlewareServiceId.SendingResponseHandlerContract,
|
|
72
|
+
),
|
|
73
|
+
container.getSingleton<ResponseSentHandlerContract>(
|
|
74
|
+
HttpMiddlewareServiceId.ResponseSentHandlerContract,
|
|
75
|
+
),
|
|
76
|
+
),
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static publishRouteCollection(this: void, container: ContainerContract): void {
|
|
81
|
+
const collection = new RouteCollection();
|
|
82
|
+
|
|
83
|
+
container.setSingleton<RouteCollectionContract>(HttpRoutingServiceId.RouteCollectionContract, collection);
|
|
84
|
+
|
|
85
|
+
const app = container.getSingleton<ApplicationContract>(ApplicationServiceId.ApplicationContract);
|
|
86
|
+
|
|
87
|
+
if (app.getDebugMode()) {
|
|
88
|
+
HttpRoutingServiceProvider.publishData(container);
|
|
89
|
+
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const data = container.getSingleton<HttpRoutingData>(HttpRoutingServiceId.HttpRoutingData);
|
|
94
|
+
|
|
95
|
+
collection.setFromData(data);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static publishMatcher(this: void, container: ContainerContract): void {
|
|
99
|
+
container.setSingleton<MatcherContract>(
|
|
100
|
+
HttpRoutingServiceId.MatcherContract,
|
|
101
|
+
new Matcher(container.getSingleton<RouteCollectionContract>(HttpRoutingServiceId.RouteCollectionContract)),
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static publishUrl(this: void, container: ContainerContract): void {
|
|
106
|
+
container.setSingleton<UrlContract>(
|
|
107
|
+
HttpRoutingServiceId.UrlContract,
|
|
108
|
+
new Url(container.getSingleton<RouteCollectionContract>(HttpRoutingServiceId.RouteCollectionContract)),
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
static publishProcessor(this: void, container: ContainerContract): void {
|
|
113
|
+
container.setSingleton<ProcessorContract>(HttpRoutingServiceId.ProcessorContract, new Processor());
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static publishResponseFactory(this: void, container: ContainerContract): void {
|
|
117
|
+
container.setSingleton<RoutingResponseFactoryContract>(
|
|
118
|
+
HttpRoutingServiceId.RoutingResponseFactory,
|
|
119
|
+
new RoutingResponseFactory(
|
|
120
|
+
container.getSingleton<ResponseFactoryContract>(HttpMessageServiceId.ResponseFactoryContract),
|
|
121
|
+
container.getSingleton<UrlContract>(HttpRoutingServiceId.UrlContract),
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
static publishData(this: void, container: ContainerContract): void {
|
|
127
|
+
const collection = container.getSingleton<RouteCollectionContract>(
|
|
128
|
+
HttpRoutingServiceId.RouteCollectionContract,
|
|
129
|
+
);
|
|
130
|
+
const app = container.getSingleton<ApplicationContract>(ApplicationServiceId.ApplicationContract);
|
|
131
|
+
const processor = container.getSingleton<ProcessorContract>(HttpRoutingServiceId.ProcessorContract);
|
|
132
|
+
|
|
133
|
+
for (const provider of app.getHttpProviders()) {
|
|
134
|
+
for (const route of provider.getRoutes()) {
|
|
135
|
+
collection.add(processor.route(route));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
container.setSingleton(HttpRoutingServiceId.HttpRoutingData, collection.getData());
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -98,11 +98,12 @@ export class RequestHandler implements RequestHandlerContract {
|
|
|
98
98
|
|
|
99
99
|
const requestAfterMiddleware = this.requestReceivedHandler.requestReceived(request);
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
// If the return value after middleware is a response return it.
|
|
102
|
+
if ('getStatusCode' in requestAfterMiddleware) {
|
|
103
|
+
return requestAfterMiddleware;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
const updatedRequest = requestAfterMiddleware
|
|
106
|
+
const updatedRequest = requestAfterMiddleware;
|
|
106
107
|
|
|
107
108
|
this.container.setSingleton(HttpMessageServiceId.ServerRequestContract, updatedRequest);
|
|
108
109
|
|
|
@@ -0,0 +1,39 @@
|
|
|
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 { HttpServerServiceProvider } from './HttpServerServiceProvider.ts';
|
|
11
|
+
|
|
12
|
+
import type { ApplicationContract } from '../../../Application/Kernel/Contract/ApplicationContract.ts';
|
|
13
|
+
import type { ComponentProviderContract } from '../../../Application/Provider/Contract/ComponentProviderContract.ts';
|
|
14
|
+
import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
|
|
15
|
+
import type { ListenerProviderContract } from '../../../Event/Provider/Contract/ListenerProviderContract.ts';
|
|
16
|
+
import type { CliRouteProviderContract } from '../../../Cli/Routing/Provider/Contract/CliRouteProviderContract.ts';
|
|
17
|
+
import type { HttpRouteProviderContract } from '../../Routing/Provider/Contract/HttpRouteProviderContract.ts';
|
|
18
|
+
|
|
19
|
+
export class HttpServerComponentProvider implements ComponentProviderContract {
|
|
20
|
+
getComponentProviders(_app: ApplicationContract): ComponentProviderContract[] {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getContainerProviders(_app: ApplicationContract): ServiceProviderContract[] {
|
|
25
|
+
return [new HttpServerServiceProvider()];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getEventProviders(_app: ApplicationContract): ListenerProviderContract[] {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getCliProviders(_app: ApplicationContract): CliRouteProviderContract[] {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getHttpProviders(_app: ApplicationContract): HttpRouteProviderContract[] {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
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 { ApplicationServiceId } from '../../../Application/Constant/ApplicationServiceId.ts';
|
|
11
|
+
import type { ApplicationContract } from '../../../Application/Kernel/Contract/ApplicationContract.ts';
|
|
12
|
+
import type { ContainerContract } from '../../../Container/Manager/Contract/ContainerContract.ts';
|
|
13
|
+
import type { ServiceProviderContract } from '../../../Container/Provider/Contract/ServiceProviderContract.ts';
|
|
14
|
+
import { HttpMiddlewareServiceId } from '../../Middleware/Constant/HttpMiddlewareServiceId.ts';
|
|
15
|
+
import type { RequestReceivedHandlerContract } from '../../Middleware/Handler/Contract/RequestReceivedHandlerContract.ts';
|
|
16
|
+
import type { ResponseSentHandlerContract } from '../../Middleware/Handler/Contract/ResponseSentHandlerContract.ts';
|
|
17
|
+
import type { SendingResponseHandlerContract } from '../../Middleware/Handler/Contract/SendingResponseHandlerContract.ts';
|
|
18
|
+
import type { ThrowableCaughtHandlerContract } from '../../Middleware/Handler/Contract/ThrowableCaughtHandlerContract.ts';
|
|
19
|
+
import { HttpRoutingServiceId } from '../../Routing/Constant/HttpRoutingServiceId.ts';
|
|
20
|
+
import type { RouterContract } from '../../Routing/Dispatcher/Contract/RouterContract.ts';
|
|
21
|
+
import { HttpServerServiceId } from '../Constant/HttpServerServiceId.ts';
|
|
22
|
+
import type { RequestHandlerContract } from '../Handler/Contract/RequestHandlerContract.ts';
|
|
23
|
+
import { RequestHandler } from '../Handler/RequestHandler.ts';
|
|
24
|
+
|
|
25
|
+
export class HttpServerServiceProvider implements ServiceProviderContract {
|
|
26
|
+
publishers(): Record<string, (container: ContainerContract) => void> {
|
|
27
|
+
return {
|
|
28
|
+
[HttpServerServiceId.RequestHandlerContract]: HttpServerServiceProvider.publishRequestHandler,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static publishRequestHandler(this: void, container: ContainerContract): void {
|
|
33
|
+
const app = container.getSingleton<ApplicationContract>(ApplicationServiceId.ApplicationContract);
|
|
34
|
+
|
|
35
|
+
container.setSingleton<RequestHandlerContract>(
|
|
36
|
+
HttpServerServiceId.RequestHandlerContract,
|
|
37
|
+
new RequestHandler(
|
|
38
|
+
container,
|
|
39
|
+
container.getSingleton<RouterContract>(HttpRoutingServiceId.RouterContract),
|
|
40
|
+
container.getSingleton<RequestReceivedHandlerContract>(
|
|
41
|
+
HttpMiddlewareServiceId.RequestReceivedHandlerContract,
|
|
42
|
+
),
|
|
43
|
+
container.getSingleton<ThrowableCaughtHandlerContract>(
|
|
44
|
+
HttpMiddlewareServiceId.ThrowableCaughtHandlerContract,
|
|
45
|
+
),
|
|
46
|
+
container.getSingleton<SendingResponseHandlerContract>(
|
|
47
|
+
HttpMiddlewareServiceId.SendingResponseHandlerContract,
|
|
48
|
+
),
|
|
49
|
+
container.getSingleton<ResponseSentHandlerContract>(
|
|
50
|
+
HttpMiddlewareServiceId.ResponseSentHandlerContract,
|
|
51
|
+
),
|
|
52
|
+
app.getDebugMode(),
|
|
53
|
+
),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,83 +0,0 @@
|
|
|
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 { IncomingMessage, ServerResponse } from 'node:http';
|
|
11
|
-
|
|
12
|
-
import { ChildApplication } from '../../Kernel/ChildApplication.ts';
|
|
13
|
-
import { ChildContainer } from '../../../Container/Manager/ChildContainer.ts';
|
|
14
|
-
import { ApplicationServiceId } from '../../Constant/ApplicationServiceId.ts';
|
|
15
|
-
import { ContainerServiceId } from '../../../Container/Constant/ContainerServiceId.ts';
|
|
16
|
-
import { HttpServerServiceId } from '../../../Http/Server/Constant/HttpServerServiceId.ts';
|
|
17
|
-
import { HttpRoutingServiceId } from '../../../Http/Routing/Constant/HttpRoutingServiceId.ts';
|
|
18
|
-
import { RequestFactory } from '../../../Http/Message/Request/Factory/RequestFactory.ts';
|
|
19
|
-
import { App } from './App.ts';
|
|
20
|
-
|
|
21
|
-
import type { ApplicationContract } from '../../Kernel/Contract/ApplicationContract.ts';
|
|
22
|
-
import type { ContainerContract } from '../../../Container/Manager/Contract/ContainerContract.ts';
|
|
23
|
-
import type { ContainerData } from '../../../Container/Data/ContainerData.ts';
|
|
24
|
-
import type { HttpConfigContract } from '../../Data/Contract/HttpConfigContract.ts';
|
|
25
|
-
import type { ServerRequestContract } from '../../../Http/Message/Request/Contract/ServerRequestContract.ts';
|
|
26
|
-
import type { RequestHandlerContract } from '../../../Http/Server/Handler/Contract/RequestHandlerContract.ts';
|
|
27
|
-
import type { RouteCollectionContract } from '../../../Http/Routing/Collection/Contract/RouteCollectionContract.ts';
|
|
28
|
-
|
|
29
|
-
export abstract class WorkerHttp extends App {
|
|
30
|
-
static bootstrap(config: HttpConfigContract): ApplicationContract {
|
|
31
|
-
const app = this.start(config);
|
|
32
|
-
const container = app.getContainer();
|
|
33
|
-
|
|
34
|
-
this.bootstrapThrowableHandler(app, container);
|
|
35
|
-
this.bootstrapParentServices(app);
|
|
36
|
-
|
|
37
|
-
return app;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
static handle(
|
|
41
|
-
app: ApplicationContract,
|
|
42
|
-
data: ContainerData,
|
|
43
|
-
nodeRequest: IncomingMessage,
|
|
44
|
-
nodeResponse: ServerResponse,
|
|
45
|
-
): void {
|
|
46
|
-
const request = this.getRequest(nodeRequest);
|
|
47
|
-
const childContainer = this.getChildContainer(app, data);
|
|
48
|
-
const childApp = this.getChildApplication(app, childContainer);
|
|
49
|
-
|
|
50
|
-
this.bootstrapChildContainer(childApp, childContainer);
|
|
51
|
-
this.handleRequest(childContainer, request, nodeResponse);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
static getChildApplication(app: ApplicationContract, container: ContainerContract): ApplicationContract {
|
|
55
|
-
return new ChildApplication(app, container);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static getChildContainer(app: ApplicationContract, data: ContainerData): ContainerContract {
|
|
59
|
-
return new ChildContainer(app.getContainer(), data);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
static bootstrapChildContainer(app: ApplicationContract, container: ContainerContract): void {
|
|
63
|
-
container.setSingleton(ApplicationServiceId.ApplicationContract, app);
|
|
64
|
-
container.setSingleton(ContainerServiceId.Contract, container);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
static handleRequest(
|
|
68
|
-
container: ContainerContract,
|
|
69
|
-
request: ServerRequestContract,
|
|
70
|
-
nodeResponse: ServerResponse,
|
|
71
|
-
): void {
|
|
72
|
-
const handler = container.getSingleton<RequestHandlerContract>(HttpServerServiceId.RequestHandlerContract);
|
|
73
|
-
handler.run(request, nodeResponse);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
static getRequest(nodeRequest: IncomingMessage): ServerRequestContract {
|
|
77
|
-
return RequestFactory.fromNodeRequest(nodeRequest);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
static bootstrapParentServices(app: ApplicationContract): void {
|
|
81
|
-
app.getContainer().getSingleton<RouteCollectionContract>(HttpRoutingServiceId.RouteCollectionContract);
|
|
82
|
-
}
|
|
83
|
-
}
|