@travetto/web-http 7.1.4 → 8.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,7 +16,7 @@ yarn add @travetto/web-http
16
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
17
 
18
18
  ## 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#L98) 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.
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
20
 
21
21
  **Terminal: Standard application**
22
22
  ```bash
@@ -123,23 +123,24 @@ export class WebHttpConfig {
123
123
  @Ignore()
124
124
  fetchUrl: string;
125
125
 
126
- async postConstruct(): Promise<void> {
126
+ @PostConstruct()
127
+ async finalizeConfig(): Promise<void> {
127
128
  this.tls ??= (this.httpVersion === '2' || !!this.tlsKeys);
128
129
  this.port = (this.port < 0 ? await NetUtil.getFreePort() : this.port);
129
- this.bindAddress ||= await NetUtil.getLocalAddress();
130
+ this.bindAddress ||= NetUtil.getLocalAddress();
130
131
 
131
132
  if (!this.tls) {
132
133
  // Clear out keys if tls is not set
133
134
  this.tlsKeys = undefined;
134
135
  } else if (!this.tlsKeys) {
135
136
  if (Runtime.production) {
136
- throw new AppError('Default tls keys are only valid for development use, please specify a config value at web.tls.keys');
137
+ throw new RuntimeError('Default tls keys are only valid for development use, please specify a config value at web.tls.keys');
137
138
  }
138
139
  this.tlsKeys = await WebTlsUtil.generateKeyPair();
139
140
  } else {
140
141
  if (this.tlsKeys.key.length < 100) { // We have files or resources
141
- this.tlsKeys.key = (await RuntimeResources.read(this.tlsKeys.key, true)).toString('utf8');
142
- this.tlsKeys.cert = (await RuntimeResources.read(this.tlsKeys.cert, true)).toString('utf8');
142
+ this.tlsKeys.key = await RuntimeResources.readText(this.tlsKeys.key);
143
+ this.tlsKeys.cert = await RuntimeResources.readText(this.tlsKeys.cert);
143
144
  }
144
145
  }
145
146
 
@@ -149,7 +150,7 @@ export class WebHttpConfig {
149
150
  ```
150
151
 
151
152
  ### Creating a Custom CLI Entry Point
152
- 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#L98) decorator. This could look like:
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#L27) decorator. This could look like:
153
154
 
154
155
  **Code: Application entry point for Web Applications**
155
156
  ```typescript
@@ -203,7 +204,7 @@ Initialized {
203
204
  }
204
205
  },
205
206
  runtime: {
206
- production: true,
207
+ production: false,
207
208
  role: 'std',
208
209
  debug: false,
209
210
  resourcePaths: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/web-http",
3
- "version": "7.1.4",
3
+ "version": "8.0.0-alpha.1",
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": "^7.1.4"
30
+ "@travetto/web": "^8.0.0-alpha.1"
31
31
  },
32
32
  "peerDependencies": {
33
- "@travetto/cli": "^7.1.4",
34
- "@travetto/test": "^7.1.4"
33
+ "@travetto/cli": "^8.0.0-alpha.1",
34
+ "@travetto/test": "^8.0.0-alpha.1"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@travetto/test": {
package/src/config.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { Config, EnvVar } from '@travetto/config';
2
2
  import { Ignore, Secret } from '@travetto/schema';
3
- import { AppError, Runtime, RuntimeResources } from '@travetto/runtime';
3
+ import { RuntimeError, Runtime, RuntimeResources } from '@travetto/runtime';
4
4
  import { NetUtil } from '@travetto/web';
5
+ import { PostConstruct } from '@travetto/di';
5
6
 
6
7
  import type { WebSecureKeyPair } from './types.ts';
7
8
  import { WebTlsUtil } from './tls.ts';
@@ -45,23 +46,24 @@ export class WebHttpConfig {
45
46
  @Ignore()
46
47
  fetchUrl: string;
47
48
 
48
- async postConstruct(): Promise<void> {
49
+ @PostConstruct()
50
+ async finalizeConfig(): Promise<void> {
49
51
  this.tls ??= (this.httpVersion === '2' || !!this.tlsKeys);
50
52
  this.port = (this.port < 0 ? await NetUtil.getFreePort() : this.port);
51
- this.bindAddress ||= await NetUtil.getLocalAddress();
53
+ this.bindAddress ||= NetUtil.getLocalAddress();
52
54
 
53
55
  if (!this.tls) {
54
56
  // Clear out keys if tls is not set
55
57
  this.tlsKeys = undefined;
56
58
  } else if (!this.tlsKeys) {
57
59
  if (Runtime.production) {
58
- throw new AppError('Default tls keys are only valid for development use, please specify a config value at web.tls.keys');
60
+ throw new RuntimeError('Default tls keys are only valid for development use, please specify a config value at web.tls.keys');
59
61
  }
60
62
  this.tlsKeys = await WebTlsUtil.generateKeyPair();
61
63
  } else {
62
64
  if (this.tlsKeys.key.length < 100) { // We have files or resources
63
- this.tlsKeys.key = (await RuntimeResources.read(this.tlsKeys.key, true)).toString('utf8');
64
- this.tlsKeys.cert = (await RuntimeResources.read(this.tlsKeys.cert, true)).toString('utf8');
65
+ this.tlsKeys.key = await RuntimeResources.readText(this.tlsKeys.key);
66
+ this.tlsKeys.cert = await RuntimeResources.readText(this.tlsKeys.cert);
65
67
  }
66
68
  }
67
69
 
package/src/http.ts CHANGED
@@ -2,11 +2,10 @@ import type net from 'node:net';
2
2
  import http from 'node:http';
3
3
  import http2 from 'node:http2';
4
4
  import https from 'node:https';
5
- import { pipeline } from 'node:stream/promises';
6
5
  import { TLSSocket } from 'node:tls';
7
6
 
8
7
  import { WebBodyUtil, WebCommonUtil, type WebDispatcher, WebRequest, WebResponse } from '@travetto/web';
9
- import { BinaryUtil, castTo, ShutdownManager } from '@travetto/runtime';
8
+ import { type BinaryType, BinaryUtil, castTo, ShutdownManager } from '@travetto/runtime';
10
9
 
11
10
  import type { WebSecureKeyPair, WebServerHandle } from './types.ts';
12
11
 
@@ -119,7 +118,7 @@ export class WebHttpUtil {
119
118
  httpQuery: Object.fromEntries(new URLSearchParams(query)),
120
119
  },
121
120
  headers: request.headers,
122
- body: WebBodyUtil.markRaw(request)
121
+ body: WebBodyUtil.markRawBinary(request)
123
122
  });
124
123
  }
125
124
 
@@ -127,18 +126,14 @@ export class WebHttpUtil {
127
126
  * Send WebResponse to outbound http response
128
127
  */
129
128
  static async respondToServerResponse(webResponse: WebResponse, response: HttpResponse): Promise<void> {
130
- const binaryResponse = new WebResponse({ context: webResponse.context, ...WebBodyUtil.toBinaryMessage(webResponse) });
129
+ const binaryResponse = new WebResponse<BinaryType>({ context: webResponse.context, ...WebBodyUtil.toBinaryMessage(webResponse) });
131
130
  binaryResponse.headers.forEach((value, key) => response.setHeader(key, value));
132
131
  response.statusCode = WebCommonUtil.getStatusCode(binaryResponse);
133
- const body = binaryResponse.body;
134
132
 
135
- if (BinaryUtil.isReadable(body)) {
136
- await pipeline(body, response);
137
- } else {
138
- if (body) {
139
- // Weird type union that http2 uses
140
- 'stream' in response ? response.write(body) : response.write(body);
141
- }
133
+ if (binaryResponse.body) {
134
+ await BinaryUtil.pipeline(binaryResponse.body, response);
135
+ }
136
+ if (!response.closed) {
142
137
  response.end();
143
138
  }
144
139
  }
@@ -1,6 +1,6 @@
1
1
  import { Runtime, toConcrete } from '@travetto/runtime';
2
2
  import { DependencyRegistryIndex } from '@travetto/di';
3
- import { CliCommand, type CliCommandShape } from '@travetto/cli';
3
+ import { CliCommand, CliDebugIpcFlag, CliModuleFlag, CliProfilesFlag, CliRestartOnChangeFlag, type CliCommandShape } from '@travetto/cli';
4
4
  import { NetUtil } from '@travetto/web';
5
5
  import { Registry } from '@travetto/registry';
6
6
 
@@ -9,7 +9,7 @@ import type { WebHttpServer } from '../src/types.ts';
9
9
  /**
10
10
  * Run a web server
11
11
  */
12
- @CliCommand({ runTarget: true, with: { debugIpc: 'optional', restartOnChange: true, module: true, profiles: true } })
12
+ @CliCommand()
13
13
  export class WebHttpCommand implements CliCommandShape {
14
14
 
15
15
  /** Port to run on */
@@ -18,7 +18,19 @@ export class WebHttpCommand implements CliCommandShape {
18
18
  /** Kill conflicting port owner */
19
19
  killConflict?: boolean = Runtime.localDevelopment;
20
20
 
21
- preMain(): void {
21
+ @CliModuleFlag({ short: 'm' })
22
+ module: string;
23
+
24
+ @CliProfilesFlag()
25
+ profile: string[];
26
+
27
+ @CliRestartOnChangeFlag()
28
+ restartOnChange: boolean = true;
29
+
30
+ @CliDebugIpcFlag()
31
+ debugIpc?: boolean;
32
+
33
+ finalize(): void {
22
34
  if (this.port) {
23
35
  process.env.WEB_HTTP_PORT = `${this.port}`;
24
36
  }
@@ -1,16 +1,11 @@
1
- import type { Readable } from 'node:stream';
2
- import { buffer } from 'node:stream/consumers';
3
-
4
1
  import { Inject, Injectable } from '@travetto/di';
5
2
  import { type WebFilterContext, WebResponse, type WebDispatcher, WebBodyUtil } from '@travetto/web';
6
- import { castTo } from '@travetto/runtime';
3
+ import { BinaryUtil, castTo } from '@travetto/runtime';
7
4
 
8
5
  import { WebTestDispatchUtil } from '@travetto/web/support/test/dispatch-util.ts';
9
6
 
10
7
  import type { WebHttpConfig } from '../../src/config.ts';
11
8
 
12
- const toBuffer = (src: Buffer | Readable) => Buffer.isBuffer(src) ? src : buffer(src);
13
-
14
9
  /**
15
10
  * Support for invoking http requests against the server
16
11
  */
@@ -23,7 +18,9 @@ export class FetchWebDispatcher implements WebDispatcher {
23
18
  async dispatch({ request }: WebFilterContext): Promise<WebResponse> {
24
19
  const baseRequest = await WebTestDispatchUtil.applyRequestBody(request);
25
20
  const finalPath = WebTestDispatchUtil.buildPath(baseRequest);
26
- const body: RequestInit['body'] = WebBodyUtil.isRaw(request.body) ? await toBuffer(request.body) : castTo(request.body);
21
+ const body: RequestInit['body'] = WebBodyUtil.isRawBinary(request.body) ?
22
+ await BinaryUtil.toBinaryArray(request.body) :
23
+ castTo(request.body);
27
24
  const { context: { httpMethod: method }, headers } = request;
28
25
 
29
26
  const response = await fetch(
@@ -33,7 +30,7 @@ export class FetchWebDispatcher implements WebDispatcher {
33
30
 
34
31
  return await WebTestDispatchUtil.finalizeResponseBody(
35
32
  new WebResponse({
36
- body: Buffer.from(await response.arrayBuffer()),
33
+ body: await response.arrayBuffer(),
37
34
  context: { httpStatusCode: response.status },
38
35
  headers: response.headers
39
36
  })