1 | 'use strict';
|
2 |
|
3 | var xml2js = require('xml2js');
|
4 | var _ = require('lodash');
|
5 | var ApiParseError = require('./errors').ApiParseError;
|
6 | var ApiError = require('./errors').ApiError;
|
7 | var OAuthError = require('./errors').OAuthError;
|
8 | var cleaners = require('./response-cleaners');
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | function parse(response, opts, callback) {
|
18 | var parser, jsonParseError, result;
|
19 |
|
20 | if (opts.format.toUpperCase() === 'XML') {
|
21 | callback(null, response);
|
22 | return;
|
23 | }
|
24 |
|
25 | if (opts.contentType && opts.contentType.indexOf('json') >= 0) {
|
26 | try {
|
27 | result = JSON.parse(response);
|
28 | } catch (e) {
|
29 | jsonParseError = e;
|
30 | }
|
31 | return validateAndCleanResponse(jsonParseError, { response: result });
|
32 | }
|
33 |
|
34 | parser = new xml2js.Parser({
|
35 | mergeAttrs: true,
|
36 | explicitArray: false
|
37 | });
|
38 |
|
39 | parser.parseString(response, validateAndCleanResponse);
|
40 | function validateAndCleanResponse(err, result) {
|
41 | var cleanedResult;
|
42 | var clean, error, apiError;
|
43 |
|
44 | function makeParseErr(msg) {
|
45 | return new ApiParseError(msg + ' from: ' + opts.url, response);
|
46 | }
|
47 |
|
48 |
|
49 | if (err) {
|
50 | return callback(makeParseErr('Unparsable api response'));
|
51 | }
|
52 | if (!result) {
|
53 | return callback(makeParseErr('Empty response'));
|
54 | }
|
55 | if (!result.response) {
|
56 | return callback(makeParseErr('Missing response node'));
|
57 | }
|
58 |
|
59 |
|
60 | if (result.response.status === 'error') {
|
61 | error = result.response.error;
|
62 | if (/oauth/i.test(error.errorMessage)) {
|
63 | return callback(new OAuthError(error,
|
64 | error.errorMessage + ': ' + opts.url));
|
65 | }
|
66 |
|
67 | apiError = new ApiError(error, error.errorMessage + ': '
|
68 | + opts.url);
|
69 | apiError.params = opts.params;
|
70 |
|
71 | return callback(apiError);
|
72 | } else if (result.response.status !== 'ok') {
|
73 | return callback(new ApiParseError(
|
74 | 'Unexpected response status from: ' + opts.url, response));
|
75 | }
|
76 |
|
77 | clean = _.compose(
|
78 | cleaners.renameCardTypes,
|
79 | cleaners.ensureCollections.bind(null, cleaners.collectionPaths),
|
80 | cleaners.removeXmlNamespaceKeys,
|
81 | cleaners.nullifyNils);
|
82 |
|
83 | cleanedResult = clean(result.response);
|
84 | return callback(null, cleanedResult);
|
85 | }
|
86 | }
|
87 |
|
88 | module.exports.parse = parse;
|