Skip to content

Commit 067152e

Browse files
committed
renames and context.http.location
1 parent b1ff9e2 commit 067152e

File tree

8 files changed

+76
-63
lines changed

8 files changed

+76
-63
lines changed

packages/express/src/rest.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,10 @@ const serviceMiddleware = (): RequestHandler => {
3939
const context = await (service as any)[method](...args, contextBase);
4040
res.hook = context;
4141

42-
const result = http.getData(context);
43-
const statusCode = http.getStatusCode(context, result);
44-
const responseHeaders = http.getResponseHeaders(context);
45-
46-
res.data = result;
47-
res.statusCode = statusCode;
48-
res.set(responseHeaders);
42+
const response = http.getResponse(context);
43+
res.statusCode = response.status;
44+
res.set(response.headers);
45+
res.data = response.body;
4946

5047
return next();
5148
});

packages/express/test/rest.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ describe('@feathersjs/express/rest provider', () => {
197197

198198
app.service('hook-status').hooks({
199199
after (hook: HookContext) {
200-
hook.http!.statusCode = 206;
200+
hook.http!.status = 206;
201201
}
202202
});
203203

@@ -215,7 +215,7 @@ describe('@feathersjs/express/rest provider', () => {
215215

216216
app.service('hook-headers').hooks({
217217
after (hook: HookContext) {
218-
hook.http!.responseHeaders = { foo: 'first', bar: ['second', 'third'] };
218+
hook.http!.headers = { foo: 'first', bar: ['second', 'third'] };
219219
}
220220
});
221221

packages/feathers/src/declarations.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,17 @@ export interface Params {
242242

243243
export interface Http {
244244
/**
245-
* A writeable, optional property that allows to override the standard HTTP status
246-
* code that should be returned.
245+
* A writeable, optional property with status code override.
247246
*/
248-
statusCode?: number;
247+
status?: number;
248+
/**
249+
* A writeable, optional property with headers.
250+
*/
251+
headers?: { [key: string]: string | string[] };
249252
/**
250-
* A writeable, optional property that allows to provide HTTP response headers.
253+
* A writeable, optional property with `Location` header's value.
251254
*/
252-
responseHeaders?: { [key: string]: string | string[] };
255+
location?: string;
253256
}
254257

255258
export interface HookContext<A = Application, S = any> extends BaseHookContext<ServiceGenericType<S>> {
@@ -323,11 +326,11 @@ export interface HookContext<A = Application, S = any> extends BaseHookContext<S
323326
* A writeable, optional property that allows to override the standard HTTP status
324327
* code that should be returned.
325328
*
326-
* @deprecated Use `http.statusCode` instead.
329+
* @deprecated Use `http.status` instead.
327330
*/
328331
statusCode?: number;
329332
/**
330-
* A writeable, optional property that contains options specific to HTTP transports.
333+
* A writeable, optional property with options specific to HTTP transports.
331334
*/
332335
http?: Http;
333336
/**

packages/feathers/src/hooks/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ export function hookMixin<A> (
8282
event: null,
8383
type: null,
8484
get statusCode () {
85-
return this.http?.statusCode;
85+
return this.http?.status;
8686
},
8787
set statusCode (value: number) {
88-
(this.http ||= {}).statusCode = value;
88+
(this.http ||= {}).status = value;
8989
}
9090
});
9191

packages/koa/src/rest.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,10 @@ const serviceMiddleware = (): Middleware => {
3535
const context = await (service as any)[method](...args, contextBase);
3636
ctx.hook = context;
3737

38-
const result = http.getData(context);
39-
const statusCode = http.getStatusCode(context, result);
40-
const responseHeaders = http.getResponseHeaders(context);
41-
42-
ctx.body = result;
43-
ctx.status = statusCode;
44-
ctx.set(responseHeaders);
38+
const response = http.getResponse(context);
39+
ctx.status = response.status;
40+
ctx.set(response.headers);
41+
ctx.body = response.body;
4542

4643
return next();
4744
};

packages/transport-commons/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@
5555
"@feathersjs/commons": "^5.0.0-pre.16",
5656
"@feathersjs/errors": "^5.0.0-pre.16",
5757
"@feathersjs/feathers": "^5.0.0-pre.16",
58+
"encodeurl": "^1.0.2",
5859
"lodash": "^4.17.21"
5960
},
6061
"devDependencies": {
62+
"@types/encodeurl": "^1.0.0",
6163
"@types/lodash": "^4.14.178",
6264
"@types/mocha": "^9.0.0",
6365
"@types/node": "^17.0.5",

packages/transport-commons/src/http.ts

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { MethodNotAllowed } from '@feathersjs/errors/lib';
22
import { HookContext, NullableId, Params } from '@feathersjs/feathers';
3+
import encodeUrl from 'encodeurl';
34

45
export const METHOD_HEADER = 'x-service-method';
56

@@ -13,7 +14,8 @@ export const statusCodes = {
1314
created: 201,
1415
noContent: 204,
1516
methodNotAllowed: 405,
16-
success: 200
17+
success: 200,
18+
seeOther: 303
1719
};
1820

1921
export const knownMethods: { [key: string]: string } = {
@@ -53,28 +55,32 @@ export const argumentsFor = {
5355
default: ({ data, params }: ServiceParams) => [ data, params ]
5456
}
5557

56-
export function getData (context: HookContext) {
57-
return context.dispatch !== undefined
58-
? context.dispatch
59-
: context.result;
60-
}
58+
export function getResponse (context: HookContext) {
59+
const http = context.http || {};
6160

62-
export function getStatusCode (context: HookContext, data?: any) {
63-
if (context.http?.statusCode) {
64-
return context.http.statusCode;
65-
}
61+
let status = statusCodes.success;
62+
let headers = http.headers || {};
63+
let location = headers[ 'Location' ];
64+
let body = context.result;
6665

67-
if (context.method === 'create') {
68-
return statusCodes.created;
66+
if (context.dispatch !== undefined) {
67+
body = context.dispatch;
6968
}
7069

71-
if (!data) {
72-
return statusCodes.noContent;
70+
if (http.location !== undefined) {
71+
location = encodeUrl(http.location);
72+
headers = { ...headers, Location: location };
7373
}
7474

75-
return statusCodes.success;
76-
}
75+
if (http.status) {
76+
status = http.status;
77+
} else if (context.method === 'create') {
78+
status = statusCodes.created;
79+
} else if (location !== undefined) {
80+
status = statusCodes.seeOther;
81+
} else if (!body) {
82+
status = statusCodes.noContent;
83+
}
7784

78-
export function getResponseHeaders (context: HookContext) {
79-
return context.http?.responseHeaders ?? {};
85+
return { status, headers, body };
8086
}

packages/transport-commons/test/http.test.ts

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { HookContext } from '@feathersjs/feathers';
33
import { http } from '../src';
44

55
describe('@feathersjs/transport-commons HTTP helpers', () => {
6-
it('getData', () => {
6+
it('getResponse body', () => {
77
const plainData = { message: 'hi' };
88
const dispatch = { message: 'from dispatch' };
99
const resultContext = {
@@ -13,22 +13,41 @@ describe('@feathersjs/transport-commons HTTP helpers', () => {
1313
dispatch
1414
};
1515

16-
assert.strictEqual(http.getData(resultContext as HookContext), plainData);
17-
assert.strictEqual(http.getData(dispatchContext as HookContext), dispatch);
16+
assert.strictEqual(http.getResponse(resultContext as HookContext).body, plainData);
17+
assert.strictEqual(http.getResponse(dispatchContext as HookContext).body, dispatch);
1818
});
1919

20-
it('getStatusCode', () => {
20+
it('getResponse status', () => {
2121
const statusContext = {
22-
http: { statusCode: 202 }
22+
http: { status: 202 }
2323
};
2424
const createContext = {
2525
method: 'create'
2626
};
27+
const redirectContext = {
28+
http: { location: '/' }
29+
};
30+
31+
assert.strictEqual(http.getResponse(statusContext as HookContext).status, 202);
32+
assert.strictEqual(http.getResponse(createContext as HookContext).status, http.statusCodes.created);
33+
assert.strictEqual(http.getResponse(redirectContext as HookContext).status, http.statusCodes.seeOther);
34+
assert.strictEqual(http.getResponse({} as HookContext).status, http.statusCodes.noContent);
35+
assert.strictEqual(http.getResponse({result: true} as HookContext).status, http.statusCodes.success);
36+
});
37+
38+
it('getResponse headers', () => {
39+
const headers = { key: 'value' } as any;
40+
const headersContext = {
41+
http: { headers }
42+
};
43+
const locationContext = {
44+
http: { location: '/' }
45+
};
2746

28-
assert.strictEqual(http.getStatusCode(statusContext as HookContext, {}), 202);
29-
assert.strictEqual(http.getStatusCode(createContext as HookContext, {}), http.statusCodes.created);
30-
assert.strictEqual(http.getStatusCode({} as HookContext), http.statusCodes.noContent);
31-
assert.strictEqual(http.getStatusCode({} as HookContext, {}), http.statusCodes.success);
47+
assert.deepStrictEqual(http.getResponse({} as HookContext).headers, {});
48+
assert.deepStrictEqual(http.getResponse({http: {}} as HookContext).headers, {});
49+
assert.strictEqual(http.getResponse(headersContext as HookContext).headers, headers);
50+
assert.deepStrictEqual(http.getResponse(locationContext as HookContext).headers, { Location: '/' });
3251
});
3352

3453
it('getServiceMethod', () => {
@@ -39,15 +58,4 @@ describe('@feathersjs/transport-commons HTTP helpers', () => {
3958
assert.strictEqual(http.getServiceMethod('delete', null), 'remove');
4059
assert.throws(() => http.getServiceMethod('nonsense', null));
4160
});
42-
43-
it('getResponseHeaders', () => {
44-
const responseHeaders = { key: 'value' };
45-
const headersContext = {
46-
http: { responseHeaders }
47-
};
48-
49-
assert.deepStrictEqual(http.getResponseHeaders({} as HookContext), {});
50-
assert.deepStrictEqual(http.getResponseHeaders({http: {}} as HookContext), {});
51-
assert.strictEqual(http.getResponseHeaders(headersContext as any as HookContext), responseHeaders);
52-
});
5361
});

0 commit comments

Comments
 (0)