Skip to content

Commit f0eb0de

Browse files
authored
Fix BaseController.ok on non string content (#423)
* refactor: update JsonResult with no generic * fix: update OkNegotiatedContentResult update OkNegotiatedContentResult to rely on JsonContent when non string content is provided
1 parent 800f041 commit f0eb0de

File tree

11 files changed

+84
-45
lines changed

11 files changed

+84
-45
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
### Changed
1313
- Updated `BaseMiddleware.handler` to allow async handlers.
1414
- Updated `Middleware` to allow include any `ServiceIdentifier`.
15+
- Updated `JsonContent` with no generic.
1516

1617
### Fixed
18+
- Updated `BaseController.ok` to no longer return `text/plain` responses when non string content is passed.
1719

1820
## [6.4.10]
1921

package-lock.json

Lines changed: 5 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"@types/supertest": "6.0.2",
5353
"@typescript-eslint/eslint-plugin": "8.20.0",
5454
"@typescript-eslint/parser": "8.20.0",
55+
"body-parser": "1.20.3",
5556
"cookie-parser": "1.4.7",
5657
"eslint": "9.18.0",
5758
"eslint-config-prettier": "10.0.1",

src/base_http_controller.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ export class BaseHttpController {
7979
return new StatusCodeResult(statusCode);
8080
}
8181

82-
protected json<T extends Record<string, unknown>>(
83-
content: T | T[],
82+
protected json(
83+
content: unknown,
8484
statusCode: number = StatusCodes.OK,
85-
): JsonResult<T> {
85+
): JsonResult {
8686
return new JsonResult(content, statusCode);
8787
}
8888

src/content/httpContent.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { OutgoingHttpHeaders } from 'node:http';
2-
import type { Readable } from 'node:stream';
32

43
export abstract class HttpContent {
54
private readonly _headers: OutgoingHttpHeaders = {};
@@ -8,7 +7,5 @@ export abstract class HttpContent {
87
return this._headers;
98
}
109

11-
public abstract readAsync(): Promise<
12-
string | Record<string, unknown> | Record<string, unknown>[] | Readable
13-
>;
10+
public abstract readAsync(): Promise<unknown>;
1411
}

src/content/jsonContent.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@ import { HttpContent } from './httpContent';
22

33
const DEFAULT_MEDIA_TYPE: string = 'application/json';
44

5-
export class JsonContent<
6-
T extends Record<string, unknown>,
7-
> extends HttpContent {
8-
constructor(private readonly content: T | T[]) {
5+
export class JsonContent extends HttpContent {
6+
constructor(private readonly content: unknown) {
97
super();
108

119
this.headers['content-type'] = DEFAULT_MEDIA_TYPE;
1210
}
1311

14-
public async readAsync(): Promise<T | T[]> {
12+
public async readAsync(): Promise<unknown> {
1513
return this.content;
1614
}
1715
}

src/results/JsonResult.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,17 @@ import { JsonContent } from '../content/jsonContent';
22
import { HttpResponseMessage } from '../httpResponseMessage';
33
import type { IHttpActionResult } from '../interfaces';
44

5-
export class JsonResult<T extends Record<string, unknown>>
6-
implements IHttpActionResult
7-
{
5+
export class JsonResult implements IHttpActionResult {
86
constructor(
9-
public readonly json: T | T[],
7+
public readonly json: unknown,
108
public readonly statusCode: number,
119
) {}
1210

1311
public async executeAsync(): Promise<HttpResponseMessage> {
1412
const response: HttpResponseMessage = new HttpResponseMessage(
1513
this.statusCode,
1614
);
17-
response.content = new JsonContent<T>(this.json);
15+
response.content = new JsonContent(this.json);
1816

1917
return response;
2018
}

src/results/OkNegotiatedContentResult.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { StatusCodes } from 'http-status-codes';
22

3+
import { JsonContent } from '../content/jsonContent';
34
import { StringContent } from '../content/stringContent';
45
import { HttpResponseMessage } from '../httpResponseMessage';
56
import type { IHttpActionResult } from '../interfaces';
@@ -11,7 +12,12 @@ export class OkNegotiatedContentResult<T> implements IHttpActionResult {
1112
const response: HttpResponseMessage = new HttpResponseMessage(
1213
StatusCodes.OK,
1314
);
14-
response.content = new StringContent(JSON.stringify(this.content));
15+
16+
if (typeof this.content === 'string') {
17+
response.content = new StringContent(this.content);
18+
} else {
19+
response.content = new JsonContent(this.content);
20+
}
1521

1622
return response;
1723
}

src/test/action_result.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ describe('ActionResults', () => {
4141
await actionResult.executeAsync();
4242

4343
expect(responseMessage.statusCode).toBe(StatusCodes.OK);
44-
expect(await responseMessage.content.readAsync()).toBe(
45-
JSON.stringify(content),
46-
);
44+
expect(await responseMessage.content.readAsync()).toStrictEqual(content);
4745
});
4846
});
4947

src/test/content/jsonContent.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { JsonContent } from '../../content/jsonContent';
44

55
describe('JsonContent', () => {
66
it('should have application/json as the default media type', () => {
7-
const content: JsonContent<Record<string, unknown>> = new JsonContent({});
7+
const content: JsonContent = new JsonContent({});
88
expect(content.headers['content-type']).toBe('application/json');
99
});
1010

0 commit comments

Comments
 (0)