Skip to content
This repository was archived by the owner on May 28, 2024. It is now read-only.

Commit 6c48653

Browse files
committed
Split code into several files for readability
1 parent 758bfdf commit 6c48653

File tree

5 files changed

+105
-86
lines changed

5 files changed

+105
-86
lines changed

.eslintrc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,5 @@
22
"extends": "eslint-config-hapi",
33
"parserOptions": {
44
"ecmaVersion": 9
5-
},
6-
"rules": {
7-
"prefer-arrow-callback": [ "error", { "allowNamedFunctions": true } ]
85
}
96
}

lib/IsJsonApiRequest.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
const IsJsonApiRequest = function (request) {
4+
5+
if (!request.headers.accept) {
6+
return false;
7+
}
8+
9+
if (request.headers.accept.indexOf('application/vnd.api+json') === -1) {
10+
return false;
11+
}
12+
13+
return true;
14+
};
15+
16+
module.exports = IsJsonApiRequest;

lib/PreHandler.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
const Boom = require('boom');
4+
const MediaType = require('media-type');
5+
const IsJsonApiRequest = require('./IsJsonApiRequest');
6+
7+
const validateMediaType = function (contentType) {
8+
9+
const contentMedia = MediaType.fromString(contentType);
10+
11+
// Ignore charset=UTF-8 media type parameter
12+
// https://github.com/json-api/json-api/issues/837
13+
if (contentMedia.parameters.charset === 'UTF-8') {
14+
delete contentMedia.parameters.charset;
15+
}
16+
17+
// Hapi does not allow application/* w/o json suffix so we don't need to test for it
18+
if (contentMedia.type !== 'application' || contentMedia.subtype !== 'vnd.api' || Object.keys(contentMedia.parameters).length > 0) {
19+
20+
throw Boom.unsupportedMediaType('Only `application/vnd.api+json` content-type supported');
21+
}
22+
};
23+
24+
const validateAcceptAndContentTypeHeaders = function (request, respToolkit) {
25+
26+
if (!IsJsonApiRequest(request)) {
27+
return respToolkit.continue;
28+
}
29+
30+
const contentType = request.headers['content-type'];
31+
if (contentType) {
32+
validateMediaType(contentType);
33+
}
34+
35+
return respToolkit.continue;
36+
};
37+
38+
module.exports = validateAcceptAndContentTypeHeaders;

lib/PreResponse.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
const IsJsonApiRequest = require('./IsJsonApiRequest');
4+
5+
const prepareOutput = function (request, meta) {
6+
7+
const { response } = request;
8+
const { output } = response;
9+
10+
if (request.response.isBoom) {
11+
const error = {
12+
title: output.payload.error,
13+
status: output.statusCode,
14+
detail: output.payload.message
15+
};
16+
output.payload = {
17+
errors: [error],
18+
meta: { id: request.info.id, ...meta }
19+
};
20+
output.headers['content-type'] = 'application/vnd.api+json';
21+
}
22+
else {
23+
if (response.source) {
24+
response.source.meta = { id: request.info.id, ...meta };
25+
}
26+
response.headers['content-type'] = 'application/vnd.api+json';
27+
}
28+
};
29+
30+
const PreResponse = function (meta) {
31+
32+
return function convertBoomErrorsToJsonApiFormat(request, respToolkit) {
33+
34+
// Skip for OPTIONS requests and requests that don't accept application/vnd.api+json
35+
if (request.method === 'options' || !IsJsonApiRequest(request)) {
36+
return respToolkit.continue;
37+
}
38+
39+
// Prepare output with correct headers and format
40+
prepareOutput(request, meta);
41+
42+
return respToolkit.continue;
43+
};
44+
};
45+
46+
module.exports = PreResponse;

lib/index.js

Lines changed: 5 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,15 @@
11
'use strict';
22

3-
// Load modules
4-
const Boom = require('boom');
5-
const MediaType = require('media-type');
6-
7-
8-
const isntJsonApiRequest = function isntJsonApiRequest(request) {
9-
10-
if (!request.headers.accept) {
11-
return true;
12-
}
13-
14-
if (request.headers.accept.indexOf('application/vnd.api+json') === -1) {
15-
return true;
16-
}
17-
18-
return false;
19-
};
3+
const PreHandler = require('./PreHandler');
4+
const PreResponse = require('./PreResponse');
205

216
module.exports = {
227
pkg: require('../package.json'),
23-
register: (server, options) => {
8+
register: (server, options = {}) => {
249

2510
const meta = options.meta || {};
2611

27-
server.ext('onPreHandler', function validateAcceptAndContentTypeHeaders(request, respToolkit) {
28-
29-
if (isntJsonApiRequest(request)) {
30-
return respToolkit.continue;
31-
}
32-
33-
const contentType = request.headers['content-type'];
34-
35-
if (contentType) {
36-
const contentMedia = MediaType.fromString(contentType);
37-
38-
// Ignore charset=UTF-8 media type parameter
39-
// https://github.com/json-api/json-api/issues/837
40-
if (contentMedia.parameters.charset === 'UTF-8') {
41-
delete contentMedia.parameters.charset;
42-
}
43-
44-
//Hapi does not allow application/* w/o json suffix so we don't need to test for it
45-
if (contentMedia.type !== 'application' || contentMedia.subtype !== 'vnd.api' || Object.keys(contentMedia.parameters).length > 0) {
46-
47-
throw Boom.unsupportedMediaType('Only `application/vnd.api+json` content-type supported');
48-
}
49-
}
50-
return respToolkit.continue;
51-
});
52-
53-
server.ext('onPreResponse', function convertBoomErrorsToJsonApiFormat(request, respToolkit) {
54-
55-
const response = request.response;
56-
57-
if (request.method === 'options') {
58-
return respToolkit.continue;
59-
}
60-
61-
if (isntJsonApiRequest(request)) {
62-
return respToolkit.continue;
63-
}
64-
65-
if (response.isBoom) {
66-
const error = {
67-
title: response.output.payload.error,
68-
status: response.output.statusCode,
69-
detail: response.output.payload.message
70-
};
71-
response.output.payload = {
72-
errors: [error],
73-
meta: { ...{ id: request.info.id }, ...meta }
74-
};
75-
response.output.headers['content-type'] = 'application/vnd.api+json';
76-
}
77-
else {
78-
if (response.source) {
79-
response.source.meta = { ...{ id: request.info.id }, ...meta };
80-
}
81-
response.headers['content-type'] = 'application/vnd.api+json';
82-
}
83-
return respToolkit.continue;
84-
});
85-
12+
server.ext('onPreHandler', PreHandler);
13+
server.ext('onPreResponse', PreResponse(meta));
8614
}
8715
};
88-
89-
90-
91-
92-
93-

0 commit comments

Comments
 (0)