Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change JsonContent to return object rather than string #379

Merged
merged 4 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@
},
"types": "./lib/index.d.ts",
"version": "6.4.3"
}
}
6 changes: 3 additions & 3 deletions src/base_http_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ export class BaseHttpController {
return new StatusCodeResult(statusCode);
}

protected json(
content: unknown,
protected json<T extends Record<string, unknown>>(
content: T | T[],
statusCode: number = StatusCodes.OK
): JsonResult {
): JsonResult<T> {
return new JsonResult(content, statusCode);
}
}
4 changes: 3 additions & 1 deletion src/content/httpContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ export abstract class HttpContent {
return this._headers;
}

public abstract readAsStringAsync(): Promise<string>;
public abstract readAsync(): Promise<
string | Record<string, unknown> | Record<string, unknown>[]
>;
}
12 changes: 5 additions & 7 deletions src/content/jsonContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ import { HttpContent } from './httpContent';

const DEFAULT_MEDIA_TYPE = 'application/json';

export class JsonContent extends HttpContent {
private content: string;

constructor(content: unknown) {
export class JsonContent<
T extends Record<string, unknown>
> extends HttpContent {
constructor(private content: T | T[]) {
super();

this.content = JSON.stringify(content);

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

public readAsStringAsync(): Promise<string> {
public readAsync(): Promise<T | T[]> {
return Promise.resolve(this.content);
}
}
2 changes: 1 addition & 1 deletion src/content/stringContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class StringContent extends HttpContent {
this.headers['content-type'] = DEFAULT_MEDIA_TYPE;
}

public readAsStringAsync(): Promise<string> {
public readAsync(): Promise<string> {
return Promise.resolve(this.content);
}
}
10 changes: 6 additions & 4 deletions src/results/JsonResult.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { HttpResponseMessage } from '../httpResponseMessage';
import { JsonContent } from '../content/jsonContent';
import { HttpResponseMessage } from '../httpResponseMessage';
import type { IHttpActionResult } from '../interfaces';

export class JsonResult implements IHttpActionResult {
export class JsonResult<
T extends Record<string, unknown>
> implements IHttpActionResult {
constructor(
public readonly json: unknown,
public readonly json: T | T[],
public readonly statusCode: number
) { }

public async executeAsync(): Promise<HttpResponseMessage> {
const response = new HttpResponseMessage(this.statusCode);
response.content = new JsonContent(this.json);
response.content = new JsonContent<T>(this.json);
return Promise.resolve(response);
}
}
2 changes: 1 addition & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export class InversifyExpressServer {
res.status(message.statusCode)
// If the content is a number, ensure we change it to a string, else our content is
// treated as a statusCode rather than as the content of the Response
.send(await message.content.readAsStringAsync());
.send(await message.content.readAsync());
} else {
res.sendStatus(message.statusCode);
}
Expand Down
8 changes: 4 additions & 4 deletions test/action_result.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('ActionResults', () => {

expect(responseMessage.statusCode).toBe(StatusCodes.OK);
expect(
await responseMessage.content.readAsStringAsync(),
await responseMessage.content.readAsync(),
).toBe(JSON.stringify(content));
});
});
Expand All @@ -43,7 +43,7 @@ describe('ActionResults', () => {
const responseMessage = await actionResult.executeAsync();

expect(responseMessage.statusCode).toBe(StatusCodes.BAD_REQUEST);
expect(await responseMessage.content.readAsStringAsync()).toBe(message);
expect(await responseMessage.content.readAsync()).toBe(message);
});
});

Expand All @@ -68,7 +68,7 @@ describe('ActionResults', () => {

expect(responseMessage.statusCode).toBe(StatusCodes.CREATED);
expect(
await responseMessage.content.readAsStringAsync(),
await responseMessage.content.readAsync(),
).toBe(JSON.stringify(content));
expect(responseMessage.headers['location']).toBe(uri);
});
Expand All @@ -85,7 +85,7 @@ describe('ActionResults', () => {
.toBe(StatusCodes.INTERNAL_SERVER_ERROR);

expect(await responseMessage.content
.readAsStringAsync())
.readAsync())
.toBe('Error: foo');
});
});
Expand Down
6 changes: 3 additions & 3 deletions test/content/jsonContent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe('JsonContent', () => {
expect(content.headers['content-type']).toBe('application/json');
});

it('should respond with the stringified version of the object', done => {
it('should respond with the original object', done => {
const mockObject = {
count: 6,
success: true,
Expand All @@ -15,8 +15,8 @@ describe('JsonContent', () => {

const content = new JsonContent(mockObject);

void content.readAsStringAsync().then(value => {
expect(value).toBe(JSON.stringify(mockObject));
void content.readAsync().then(value => {
expect(value).toBe(mockObject);
done();
});
});
Expand Down