@travetto/web-http 8.0.0-alpha.3 → 8.0.0-alpha.30
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/README.md +45 -19
- package/__index__.ts +1 -1
- package/package.json +4 -4
- package/src/config.ts +10 -10
- package/src/http.ts +15 -12
- package/src/node.ts +3 -4
- package/src/tls.ts +3 -4
- package/src/types.ts +2 -2
- package/support/cli.web_http.ts +13 -7
- package/support/test/dispatcher.ts +10 -11
package/README.md
CHANGED
|
@@ -13,10 +13,38 @@ npm install @travetto/web-http
|
|
|
13
13
|
yarn add @travetto/web-http
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
This module provides basic for running [http](https://nodejs.org/api/http.html). [https](https://nodejs.org/api/https.html)
|
|
16
|
+
This module provides basic for running [http](https://nodejs.org/api/http.html). [https](https://nodejs.org/api/https.html) and [http2](https://nodejs.org/api/http2.html) servers, along with support for tls key generation during development.
|
|
17
|
+
|
|
18
|
+
## CLI - web:http
|
|
19
|
+
By default, the framework provides a default [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) for [WebHttpServer](https://github.com/travetto/travetto/tree/main/module/web-http/src/types.ts#L19) that will follow default behaviors, and spin up the server.
|
|
20
|
+
|
|
21
|
+
**Terminal: Help for web:http**
|
|
22
|
+
```bash
|
|
23
|
+
$ trv web:http --help
|
|
24
|
+
|
|
25
|
+
Usage: web:http [options]
|
|
26
|
+
|
|
27
|
+
Description:
|
|
28
|
+
Start the configured web HTTP server for a module.
|
|
29
|
+
|
|
30
|
+
Initializes registry and server bindings, supports restart-aware development
|
|
31
|
+
flags, and can attempt to clear conflicting port owners in local workflows.
|
|
32
|
+
|
|
33
|
+
Options:
|
|
34
|
+
-p, --port <number> Port to run on
|
|
35
|
+
--kill-conflict, --no-kill-conflict Kill conflicting port owner (default: true)
|
|
36
|
+
-m, --module <module> Module to run for
|
|
37
|
+
--profile <string> Application profiles
|
|
38
|
+
--restart-on-change, --no-restart-on-change Should the invocation automatically restart on source changes (default: true)
|
|
39
|
+
-d, --debug-ipc Should the invocation support debugging via IPC (e.g. from VSCode)
|
|
40
|
+
--help display help for command
|
|
41
|
+
|
|
42
|
+
Examples:
|
|
43
|
+
Starting a web server on port 8000
|
|
44
|
+
trv web:http -m <MODULE> -p 8000
|
|
45
|
+
```
|
|
17
46
|
|
|
18
47
|
## Running a Server
|
|
19
|
-
By default, the framework provides a default [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L27) for [WebHttpServer](https://github.com/travetto/travetto/tree/main/module/web-http/src/types.ts#L19) that will follow default behaviors, and spin up the server.
|
|
20
48
|
|
|
21
49
|
**Terminal: Standard application**
|
|
22
50
|
```bash
|
|
@@ -89,7 +117,6 @@ Listening on port { port: 3000 }
|
|
|
89
117
|
**Code: Standard Web Http Config**
|
|
90
118
|
```typescript
|
|
91
119
|
export class WebHttpConfig {
|
|
92
|
-
|
|
93
120
|
/**
|
|
94
121
|
* What version of HTTP to use
|
|
95
122
|
* Version 2 requires SSL for direct browser access
|
|
@@ -125,8 +152,8 @@ export class WebHttpConfig {
|
|
|
125
152
|
|
|
126
153
|
@PostConstruct()
|
|
127
154
|
async finalizeConfig(): Promise<void> {
|
|
128
|
-
this.tls ??=
|
|
129
|
-
this.port =
|
|
155
|
+
this.tls ??= this.httpVersion === '2' || !!this.tlsKeys;
|
|
156
|
+
this.port = this.port < 0 ? await NetUtil.getFreePort() : this.port;
|
|
130
157
|
this.bindAddress ||= NetUtil.getLocalAddress();
|
|
131
158
|
|
|
132
159
|
if (!this.tls) {
|
|
@@ -138,9 +165,10 @@ export class WebHttpConfig {
|
|
|
138
165
|
}
|
|
139
166
|
this.tlsKeys = await WebTlsUtil.generateKeyPair();
|
|
140
167
|
} else {
|
|
141
|
-
if (this.tlsKeys.key.length < 100) {
|
|
142
|
-
|
|
143
|
-
this.tlsKeys.
|
|
168
|
+
if (this.tlsKeys.key.length < 100) {
|
|
169
|
+
// We have files or resources
|
|
170
|
+
this.tlsKeys.key = await RuntimeResources.readUTF8(this.tlsKeys.key);
|
|
171
|
+
this.tlsKeys.cert = await RuntimeResources.readUTF8(this.tlsKeys.cert);
|
|
144
172
|
}
|
|
145
173
|
}
|
|
146
174
|
|
|
@@ -150,21 +178,20 @@ export class WebHttpConfig {
|
|
|
150
178
|
```
|
|
151
179
|
|
|
152
180
|
### Creating a Custom CLI Entry Point
|
|
153
|
-
To customize a Web server, you may need to construct an entry point using the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#
|
|
181
|
+
To customize a Web server, you may need to construct an entry point using the [@CliCommand](https://github.com/travetto/travetto/tree/main/module/cli/src/registry/decorator.ts#L20) decorator. This could look like:
|
|
154
182
|
|
|
155
183
|
**Code: Application entry point for Web Applications**
|
|
156
184
|
```typescript
|
|
157
|
-
import { Env, toConcrete } from '@travetto/runtime';
|
|
158
185
|
import { CliCommand } from '@travetto/cli';
|
|
159
186
|
import { DependencyRegistryIndex } from '@travetto/di';
|
|
160
187
|
import { Registry } from '@travetto/registry';
|
|
161
|
-
import {
|
|
188
|
+
import { Env, toConcrete } from '@travetto/runtime';
|
|
189
|
+
import { WebHttpConfig, type WebHttpServer } from '@travetto/web-http';
|
|
162
190
|
|
|
163
191
|
import './config-override.ts';
|
|
164
192
|
|
|
165
193
|
@CliCommand({ runTarget: true })
|
|
166
194
|
export class SampleApp {
|
|
167
|
-
|
|
168
195
|
preMain(): void {
|
|
169
196
|
Env.NODE_ENV.set('production');
|
|
170
197
|
}
|
|
@@ -260,7 +287,6 @@ Listening on port { port: 3000 }
|
|
|
260
287
|
**Code: Implementation**
|
|
261
288
|
```typescript
|
|
262
289
|
export class NodeWebHttpServer implements WebHttpServer {
|
|
263
|
-
|
|
264
290
|
@Inject()
|
|
265
291
|
serverConfig: WebHttpConfig;
|
|
266
292
|
|
|
@@ -271,7 +297,7 @@ export class NodeWebHttpServer implements WebHttpServer {
|
|
|
271
297
|
configService: ConfigurationService;
|
|
272
298
|
|
|
273
299
|
async serve(): Promise<WebServerHandle> {
|
|
274
|
-
const handle = await WebHttpUtil.startHttpServer({ ...this.serverConfig, dispatcher: this.router
|
|
300
|
+
const handle = await WebHttpUtil.startHttpServer({ ...this.serverConfig, dispatcher: this.router });
|
|
275
301
|
console.log('Initialized', await this.configService.initBanner());
|
|
276
302
|
console.log('Listening', { port: this.serverConfig.port });
|
|
277
303
|
return handle;
|
|
@@ -279,7 +305,7 @@ export class NodeWebHttpServer implements WebHttpServer {
|
|
|
279
305
|
}
|
|
280
306
|
```
|
|
281
307
|
|
|
282
|
-
Current the [NodeWebHttpServer](https://github.com/travetto/travetto/tree/main/module/web-http/src/node.ts#L13) is the only provided [WebHttpServer](https://github.com/travetto/travetto/tree/main/module/web-http/src/types.ts#L19) implementation.
|
|
308
|
+
Current the [NodeWebHttpServer](https://github.com/travetto/travetto/tree/main/module/web-http/src/node.ts#L13) is the only provided [WebHttpServer](https://github.com/travetto/travetto/tree/main/module/web-http/src/types.ts#L19) implementation. It supports http/1.1, http/2, and tls, and is the same foundation as used by express, koa, and other popular frameworks.
|
|
283
309
|
|
|
284
310
|
## Standard Utilities
|
|
285
311
|
The module also provides standard utilities for starting http servers programmatically:
|
|
@@ -315,18 +341,18 @@ static buildHandler(dispatcher: WebDispatcher): (request: HttpRequest, response:
|
|
|
315
341
|
return async (request: HttpRequest, response: HttpResponse): Promise<void> => {
|
|
316
342
|
const webRequest = this.toWebRequest(request);
|
|
317
343
|
const webResponse = await dispatcher.dispatch({ request: webRequest });
|
|
318
|
-
this.respondToServerResponse(webResponse, response);
|
|
344
|
+
await this.respondToServerResponse(webResponse, response);
|
|
319
345
|
};
|
|
320
346
|
}
|
|
321
347
|
```
|
|
322
348
|
|
|
323
349
|
we can see the structure for integrating the server behavior with the [Web API](https://github.com/travetto/travetto/tree/main/module/web#readme "Declarative support for creating Web Applications") module dispatcher:
|
|
324
|
-
* Converting the node primitive request to a
|
|
350
|
+
* Converting the node primitive request to a [WebRequest](https://github.com/travetto/travetto/tree/main/module/web/src/types/request.ts#L11)
|
|
325
351
|
* Dispatching the request through the framework
|
|
326
352
|
* Receiving the [WebResponse](https://github.com/travetto/travetto/tree/main/module/web/src/types/response.ts#L3) and sending that back over the primitive response.
|
|
327
353
|
|
|
328
354
|
## TLS Support
|
|
329
|
-
Additionally the framework supports TLS out of the box, by allowing you to specify your public and private keys for the cert.
|
|
355
|
+
Additionally the framework supports TLS out of the box, by allowing you to specify your public and private keys for the cert. In dev mode, the framework will also automatically generate a self-signed cert if:
|
|
330
356
|
* TLS support is configured
|
|
331
357
|
* [node-forge](https://www.npmjs.com/package/node-forge) is installed
|
|
332
358
|
* Not running in production
|
|
@@ -334,4 +360,4 @@ Additionally the framework supports TLS out of the box, by allowing you to speci
|
|
|
334
360
|
|
|
335
361
|
This is useful for local development where you implicitly trust the cert.
|
|
336
362
|
|
|
337
|
-
TLS support can be enabled by setting `web.http.tls: true` in your config. The key/cert can be specified as string directly in the config file/environment variables.
|
|
363
|
+
TLS support can be enabled by setting `web.http.tls: true` in your config. The key/cert can be specified as string directly in the config file/environment variables. The key/cert can also be specified as a path to be picked up by [RuntimeResources](https://github.com/travetto/travetto/tree/main/module/runtime/src/resources.ts#L8).
|
package/__index__.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/web-http",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.30",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Web HTTP Server Support",
|
|
6
6
|
"keywords": [
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
"directory": "module/web-http"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@travetto/web": "^8.0.0-alpha.
|
|
30
|
+
"@travetto/web": "^8.0.0-alpha.29"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
|
-
"@travetto/cli": "^8.0.0-alpha.
|
|
34
|
-
"@travetto/test": "^8.0.0-alpha.
|
|
33
|
+
"@travetto/cli": "^8.0.0-alpha.32",
|
|
34
|
+
"@travetto/test": "^8.0.0-alpha.25"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"@travetto/test": {
|
package/src/config.ts
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { Config, EnvVar } from '@travetto/config';
|
|
2
|
+
import { PostConstruct } from '@travetto/di';
|
|
3
|
+
import { Runtime, RuntimeError, RuntimeResources } from '@travetto/runtime';
|
|
2
4
|
import { Ignore, Secret } from '@travetto/schema';
|
|
3
|
-
import { RuntimeError, Runtime, RuntimeResources } from '@travetto/runtime';
|
|
4
5
|
import { NetUtil } from '@travetto/web';
|
|
5
|
-
import { PostConstruct } from '@travetto/di';
|
|
6
6
|
|
|
7
|
-
import type { WebSecureKeyPair } from './types.ts';
|
|
8
7
|
import { WebTlsUtil } from './tls.ts';
|
|
8
|
+
import type { WebSecureKeyPair } from './types.ts';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Web HTTP configuration
|
|
12
12
|
*/
|
|
13
13
|
@Config('web.http')
|
|
14
14
|
export class WebHttpConfig {
|
|
15
|
-
|
|
16
15
|
/**
|
|
17
16
|
* What version of HTTP to use
|
|
18
17
|
* Version 2 requires SSL for direct browser access
|
|
@@ -48,8 +47,8 @@ export class WebHttpConfig {
|
|
|
48
47
|
|
|
49
48
|
@PostConstruct()
|
|
50
49
|
async finalizeConfig(): Promise<void> {
|
|
51
|
-
this.tls ??=
|
|
52
|
-
this.port =
|
|
50
|
+
this.tls ??= this.httpVersion === '2' || !!this.tlsKeys;
|
|
51
|
+
this.port = this.port < 0 ? await NetUtil.getFreePort() : this.port;
|
|
53
52
|
this.bindAddress ||= NetUtil.getLocalAddress();
|
|
54
53
|
|
|
55
54
|
if (!this.tls) {
|
|
@@ -61,12 +60,13 @@ export class WebHttpConfig {
|
|
|
61
60
|
}
|
|
62
61
|
this.tlsKeys = await WebTlsUtil.generateKeyPair();
|
|
63
62
|
} else {
|
|
64
|
-
if (this.tlsKeys.key.length < 100) {
|
|
65
|
-
|
|
66
|
-
this.tlsKeys.
|
|
63
|
+
if (this.tlsKeys.key.length < 100) {
|
|
64
|
+
// We have files or resources
|
|
65
|
+
this.tlsKeys.key = await RuntimeResources.readUTF8(this.tlsKeys.key);
|
|
66
|
+
this.tlsKeys.cert = await RuntimeResources.readUTF8(this.tlsKeys.cert);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
this.fetchUrl = `${this.tls ? 'https' : 'http'}://${this.bindAddress}:${this.port}`;
|
|
71
71
|
}
|
|
72
|
-
}
|
|
72
|
+
}
|
package/src/http.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type net from 'node:net';
|
|
2
1
|
import http from 'node:http';
|
|
3
2
|
import http2 from 'node:http2';
|
|
4
3
|
import https from 'node:https';
|
|
4
|
+
import type net from 'node:net';
|
|
5
5
|
import { TLSSocket } from 'node:tls';
|
|
6
6
|
|
|
7
|
-
import { WebBodyUtil, WebCommonUtil, type WebDispatcher, WebRequest, WebResponse } from '@travetto/web';
|
|
8
7
|
import { type BinaryType, BinaryUtil, castTo, ShutdownManager } from '@travetto/runtime';
|
|
8
|
+
import { WebBodyUtil, WebCommonUtil, type WebDispatcher, WebRequest, WebResponse } from '@travetto/web';
|
|
9
9
|
|
|
10
10
|
import type { WebSecureKeyPair, WebServerHandle } from './types.ts';
|
|
11
11
|
|
|
@@ -24,7 +24,6 @@ type WebHttpServerConfig = {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export class WebHttpUtil {
|
|
27
|
-
|
|
28
27
|
/**
|
|
29
28
|
* Build a simple request handler
|
|
30
29
|
* @param dispatcher
|
|
@@ -33,7 +32,7 @@ export class WebHttpUtil {
|
|
|
33
32
|
return async (request: HttpRequest, response: HttpResponse): Promise<void> => {
|
|
34
33
|
const webRequest = this.toWebRequest(request);
|
|
35
34
|
const webResponse = await dispatcher.dispatch({ request: webRequest });
|
|
36
|
-
this.respondToServerResponse(webResponse, response);
|
|
35
|
+
await this.respondToServerResponse(webResponse, response);
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
38
|
|
|
@@ -69,9 +68,7 @@ export class WebHttpUtil {
|
|
|
69
68
|
socket.on('close', () => activeConnections.delete(socket));
|
|
70
69
|
});
|
|
71
70
|
|
|
72
|
-
target.listen(config.port, config.bindAddress)
|
|
73
|
-
.on('error', reject)
|
|
74
|
-
.on('listening', resolve);
|
|
71
|
+
target.listen(config.port, config.bindAddress).on('error', reject).on('listening', resolve);
|
|
75
72
|
|
|
76
73
|
await promise;
|
|
77
74
|
|
|
@@ -115,7 +112,7 @@ export class WebHttpUtil {
|
|
|
115
112
|
},
|
|
116
113
|
httpMethod: castTo(request.method?.toUpperCase()),
|
|
117
114
|
path,
|
|
118
|
-
httpQuery: Object.fromEntries(new URLSearchParams(query))
|
|
115
|
+
httpQuery: Object.fromEntries(new URLSearchParams(query))
|
|
119
116
|
},
|
|
120
117
|
headers: request.headers,
|
|
121
118
|
body: WebBodyUtil.markRawBinary(request)
|
|
@@ -127,14 +124,20 @@ export class WebHttpUtil {
|
|
|
127
124
|
*/
|
|
128
125
|
static async respondToServerResponse(webResponse: WebResponse, response: HttpResponse): Promise<void> {
|
|
129
126
|
const binaryResponse = new WebResponse<BinaryType>({ context: webResponse.context, ...WebBodyUtil.toBinaryMessage(webResponse) });
|
|
130
|
-
binaryResponse.headers.forEach((value, key) =>
|
|
127
|
+
binaryResponse.headers.forEach((value, key) => {
|
|
128
|
+
response.setHeader(key, value);
|
|
129
|
+
});
|
|
131
130
|
response.statusCode = WebCommonUtil.getStatusCode(binaryResponse);
|
|
132
131
|
|
|
133
132
|
if (binaryResponse.body) {
|
|
134
|
-
|
|
133
|
+
try {
|
|
134
|
+
await BinaryUtil.pipeline(binaryResponse.body, response);
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('Failed to send response', { error });
|
|
137
|
+
}
|
|
135
138
|
}
|
|
136
|
-
if (!response.closed) {
|
|
139
|
+
if (!response.closed && !response.destroyed) {
|
|
137
140
|
response.end();
|
|
138
141
|
}
|
|
139
142
|
}
|
|
140
|
-
}
|
|
143
|
+
}
|
package/src/node.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { ConfigurationService } from '@travetto/config';
|
|
1
2
|
import { Inject, Injectable } from '@travetto/di';
|
|
2
3
|
import type { StandardWebRouter } from '@travetto/web';
|
|
3
|
-
import type { ConfigurationService } from '@travetto/config';
|
|
4
4
|
|
|
5
5
|
import type { WebHttpConfig } from './config.ts';
|
|
6
6
|
import { WebHttpUtil } from './http.ts';
|
|
@@ -11,7 +11,6 @@ import type { WebHttpServer, WebServerHandle } from './types.ts';
|
|
|
11
11
|
*/
|
|
12
12
|
@Injectable()
|
|
13
13
|
export class NodeWebHttpServer implements WebHttpServer {
|
|
14
|
-
|
|
15
14
|
@Inject()
|
|
16
15
|
serverConfig: WebHttpConfig;
|
|
17
16
|
|
|
@@ -22,9 +21,9 @@ export class NodeWebHttpServer implements WebHttpServer {
|
|
|
22
21
|
configService: ConfigurationService;
|
|
23
22
|
|
|
24
23
|
async serve(): Promise<WebServerHandle> {
|
|
25
|
-
const handle = await WebHttpUtil.startHttpServer({ ...this.serverConfig, dispatcher: this.router
|
|
24
|
+
const handle = await WebHttpUtil.startHttpServer({ ...this.serverConfig, dispatcher: this.router });
|
|
26
25
|
console.log('Initialized', await this.configService.initBanner());
|
|
27
26
|
console.log('Listening', { port: this.serverConfig.port });
|
|
28
27
|
return handle;
|
|
29
28
|
}
|
|
30
|
-
}
|
|
29
|
+
}
|
package/src/tls.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Runtime } from '@travetto/runtime';
|
|
1
|
+
import { type Any, Runtime } from '@travetto/runtime';
|
|
2
2
|
|
|
3
3
|
import type { WebSecureKeyPair } from './types.ts';
|
|
4
4
|
|
|
@@ -6,13 +6,12 @@ import type { WebSecureKeyPair } from './types.ts';
|
|
|
6
6
|
* Utils for generating key pairs
|
|
7
7
|
*/
|
|
8
8
|
export class WebTlsUtil {
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* Generate TLS key pair on demand
|
|
12
11
|
* @param subj The subject for the app
|
|
13
12
|
*/
|
|
14
13
|
static async generateKeyPair(subj = { C: 'US', ST: 'CA', O: 'TRAVETTO', OU: 'WEB', CN: 'DEV' }): Promise<WebSecureKeyPair> {
|
|
15
|
-
let forge;
|
|
14
|
+
let forge: Any;
|
|
16
15
|
|
|
17
16
|
try {
|
|
18
17
|
forge = (await import('node-forge')).default;
|
|
@@ -47,4 +46,4 @@ export class WebTlsUtil {
|
|
|
47
46
|
key: pki.privateKeyToPem(keys.privateKey)
|
|
48
47
|
};
|
|
49
48
|
}
|
|
50
|
-
}
|
|
49
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Any } from '@travetto/runtime';
|
|
2
2
|
|
|
3
|
-
export type WebSecureKeyPair = { cert: string
|
|
3
|
+
export type WebSecureKeyPair = { cert: string; key: string };
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Handle for a web server
|
|
@@ -18,4 +18,4 @@ export type WebServerHandle<T = Any> = {
|
|
|
18
18
|
*/
|
|
19
19
|
export interface WebHttpServer {
|
|
20
20
|
serve(): Promise<WebServerHandle>;
|
|
21
|
-
}
|
|
21
|
+
}
|
package/support/cli.web_http.ts
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CliCommand, type CliCommandShape, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag } from '@travetto/cli';
|
|
2
2
|
import { DependencyRegistryIndex } from '@travetto/di';
|
|
3
|
-
import { CliCommand, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag, type CliCommandShape } from '@travetto/cli';
|
|
4
|
-
import { NetUtil } from '@travetto/web';
|
|
5
3
|
import { Registry } from '@travetto/registry';
|
|
4
|
+
import { Runtime, toConcrete } from '@travetto/runtime';
|
|
5
|
+
import { NetUtil } from '@travetto/web';
|
|
6
6
|
|
|
7
7
|
import type { WebHttpServer } from '../src/types.ts';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Start the configured web HTTP server for a module.
|
|
11
|
+
*
|
|
12
|
+
* Initializes registry and server bindings, supports restart-aware development
|
|
13
|
+
* flags, and can attempt to clear conflicting port owners in local workflows.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* Starting a web server on port 8000
|
|
17
|
+
* > trv web:http -m <MODULE> -p 8000
|
|
11
18
|
*/
|
|
12
19
|
@CliCommand()
|
|
13
20
|
export class WebHttpCommand implements CliCommandShape {
|
|
14
|
-
|
|
15
21
|
/** Port to run on */
|
|
16
22
|
port?: number;
|
|
17
23
|
|
|
@@ -25,7 +31,7 @@ export class WebHttpCommand implements CliCommandShape {
|
|
|
25
31
|
profile: string[];
|
|
26
32
|
|
|
27
33
|
@CliRestartOnChangeFlag()
|
|
28
|
-
restartOnChange: boolean =
|
|
34
|
+
restartOnChange: boolean = Runtime.localDevelopment;
|
|
29
35
|
|
|
30
36
|
@CliDebugIpcFlag()
|
|
31
37
|
debugIpc?: boolean;
|
|
@@ -53,4 +59,4 @@ export class WebHttpCommand implements CliCommandShape {
|
|
|
53
59
|
throw err;
|
|
54
60
|
}
|
|
55
61
|
}
|
|
56
|
-
}
|
|
62
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Inject, Injectable } from '@travetto/di';
|
|
2
|
-
import { type WebFilterContext, WebResponse, type WebDispatcher, WebBodyUtil } from '@travetto/web';
|
|
3
2
|
import { BinaryUtil, castTo } from '@travetto/runtime';
|
|
3
|
+
import { WebBodyUtil, type WebDispatcher, type WebFilterContext, WebResponse } from '@travetto/web';
|
|
4
4
|
|
|
5
5
|
import { WebTestDispatchUtil } from '@travetto/web/support/test/dispatch-util.ts';
|
|
6
6
|
|
|
@@ -11,22 +11,21 @@ import type { WebHttpConfig } from '../../src/config.ts';
|
|
|
11
11
|
*/
|
|
12
12
|
@Injectable()
|
|
13
13
|
export class FetchWebDispatcher implements WebDispatcher {
|
|
14
|
-
|
|
15
14
|
@Inject()
|
|
16
15
|
config: WebHttpConfig;
|
|
17
16
|
|
|
18
17
|
async dispatch({ request }: WebFilterContext): Promise<WebResponse> {
|
|
19
18
|
const baseRequest = await WebTestDispatchUtil.applyRequestBody(request);
|
|
20
19
|
const finalPath = WebTestDispatchUtil.buildPath(baseRequest);
|
|
21
|
-
const body: RequestInit['body'] = WebBodyUtil.isRawBinary(request.body)
|
|
22
|
-
await BinaryUtil.toBinaryArray(request.body)
|
|
23
|
-
castTo(request.body);
|
|
24
|
-
const {
|
|
20
|
+
const body: RequestInit['body'] = WebBodyUtil.isRawBinary(request.body)
|
|
21
|
+
? await BinaryUtil.toBinaryArray(request.body)
|
|
22
|
+
: castTo(request.body);
|
|
23
|
+
const {
|
|
24
|
+
context: { httpMethod: method },
|
|
25
|
+
headers
|
|
26
|
+
} = request;
|
|
25
27
|
|
|
26
|
-
const response = await fetch(
|
|
27
|
-
`${this.config.fetchUrl}${finalPath}`,
|
|
28
|
-
{ method, headers, body }
|
|
29
|
-
);
|
|
28
|
+
const response = await fetch(`${this.config.fetchUrl}${finalPath}`, { method, headers, body });
|
|
30
29
|
|
|
31
30
|
return await WebTestDispatchUtil.finalizeResponseBody(
|
|
32
31
|
new WebResponse({
|
|
@@ -36,4 +35,4 @@ export class FetchWebDispatcher implements WebDispatcher {
|
|
|
36
35
|
})
|
|
37
36
|
);
|
|
38
37
|
}
|
|
39
|
-
}
|
|
38
|
+
}
|