@dongdev/fca-unofficial 2.0.6 → 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +6 -1
  2. package/func/checkUpdate.js +9 -9
  3. package/func/logger.js +40 -104
  4. package/module/login.js +4 -4
  5. package/module/loginHelper.js +3 -3
  6. package/module/options.js +5 -9
  7. package/package.json +6 -6
  8. package/src/api/action/addExternalModule.js +5 -5
  9. package/src/api/action/changeAvatar.js +11 -10
  10. package/src/api/action/changeBio.js +7 -8
  11. package/src/api/action/getCurrentUserID.js +1 -1
  12. package/src/api/action/handleFriendRequest.js +5 -5
  13. package/src/api/action/logout.js +9 -8
  14. package/src/api/action/refreshFb_dtsg.js +17 -12
  15. package/src/api/action/setPostReaction.js +10 -11
  16. package/src/api/action/unfriend.js +3 -4
  17. package/src/api/http/httpGet.js +7 -8
  18. package/src/api/http/httpPost.js +7 -8
  19. package/src/api/http/postFormData.js +6 -5
  20. package/src/api/messaging/addUserToGroup.js +0 -1
  21. package/src/api/messaging/changeAdminStatus.js +108 -89
  22. package/src/api/messaging/changeArchivedStatus.js +6 -6
  23. package/src/api/messaging/changeBlockedStatus.js +3 -4
  24. package/src/api/messaging/changeGroupImage.js +72 -117
  25. package/src/api/messaging/changeNickname.js +59 -48
  26. package/src/api/messaging/changeThreadColor.js +61 -47
  27. package/src/api/messaging/changeThreadEmoji.js +106 -0
  28. package/src/api/messaging/createNewGroup.js +5 -5
  29. package/src/api/messaging/createPoll.js +36 -63
  30. package/src/api/messaging/deleteMessage.js +4 -4
  31. package/src/api/messaging/deleteThread.js +4 -4
  32. package/src/api/messaging/forwardAttachment.js +38 -47
  33. package/src/api/messaging/getFriendsList.js +5 -6
  34. package/src/api/messaging/getMessage.js +4 -9
  35. package/src/api/messaging/handleMessageRequest.js +5 -5
  36. package/src/api/messaging/markAsDelivered.js +5 -5
  37. package/src/api/messaging/markAsRead.js +7 -7
  38. package/src/api/messaging/markAsReadAll.js +3 -4
  39. package/src/api/messaging/markAsSeen.js +7 -7
  40. package/src/api/messaging/muteThread.js +3 -4
  41. package/src/api/messaging/removeUserFromGroup.js +82 -56
  42. package/src/api/messaging/resolvePhotoUrl.js +2 -3
  43. package/src/api/messaging/searchForThread.js +2 -3
  44. package/src/api/messaging/sendMessage.js +171 -101
  45. package/src/api/messaging/sendMessageMqtt.js +14 -12
  46. package/src/api/messaging/sendTypingIndicator.js +11 -11
  47. package/src/api/messaging/setMessageReaction.js +68 -82
  48. package/src/api/messaging/setTitle.js +77 -48
  49. package/src/api/messaging/shareContact.js +2 -4
  50. package/src/api/messaging/threadColors.js +0 -3
  51. package/src/api/messaging/unsendMessage.js +74 -37
  52. package/src/api/messaging/uploadAttachment.js +11 -9
  53. package/src/api/socket/core/connectMqtt.js +180 -0
  54. package/src/api/socket/core/getSeqID.js +25 -0
  55. package/src/api/socket/core/getTaskResponseData.js +22 -0
  56. package/src/api/socket/core/markDelivery.js +12 -0
  57. package/src/api/socket/core/parseDelta.js +351 -0
  58. package/src/api/socket/detail/buildStream.js +176 -68
  59. package/src/api/socket/detail/constants.js +24 -0
  60. package/src/api/socket/listenMqtt.js +80 -1005
  61. package/src/api/{messaging → threads}/getThreadHistory.js +5 -22
  62. package/src/api/threads/getThreadInfo.js +35 -248
  63. package/src/api/threads/getThreadList.js +20 -20
  64. package/src/api/threads/getThreadPictures.js +3 -4
  65. package/src/api/users/getUserID.js +5 -6
  66. package/src/api/users/getUserInfo.js +305 -73
  67. package/src/api/users/getUserInfoV2.js +134 -0
  68. package/src/database/models/user.js +32 -0
  69. package/src/database/userData.js +89 -0
  70. package/src/utils/constants.js +12 -2
  71. package/src/utils/format.js +1051 -0
  72. package/src/utils/request.js +75 -7
  73. package/src/api/threads/changeThreadEmoji.js +0 -55
  74. package/src/utils/index.js +0 -1497
@@ -1,70 +1,43 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
- const log = require("npmlog");
5
-
6
- module.exports = function(defaultFuncs, api, ctx) {
7
- return function createPoll(title, threadID, options, callback) {
8
- let resolveFunc = function() {};
9
- let rejectFunc = function() {};
10
- const returnPromise = new Promise(function(resolve, reject) {
11
- resolveFunc = resolve;
12
- rejectFunc = reject;
13
- });
14
-
15
- if (!callback) {
16
- if (utils.getType(options) == "Function") {
17
- callback = options;
18
- options = null;
19
- } else {
20
- callback = function(err) {
21
- if (err) {
22
- return rejectFunc(err);
3
+ const { generateOfflineThreadingID } = require("../../utils/format");
4
+
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return async function createPoll(threadID, questionText, options) {
7
+ let count_req = 0
8
+ return new Promise((resolve, reject) => {
9
+ const payload = {
10
+ epoch_id: generateOfflineThreadingID(),
11
+ tasks: [
12
+ {
13
+ failure_count: null,
14
+ label: "163",
15
+ payload: JSON.stringify({
16
+ question_text: questionText,
17
+ thread_key: threadID,
18
+ options: options,
19
+ sync_group: 1
20
+ }),
21
+ queue_name: "poll_creation",
22
+ task_id: Math.floor(Math.random() * 1001)
23
23
  }
24
- resolveFunc();
25
- };
26
- }
27
- }
28
- if (!options) {
29
- options = {};
30
- }
31
-
32
- const form = {
33
- target_id: threadID,
34
- question_text: title
35
- };
36
-
37
- // Set fields for options (and whether they are selected initially by the posting user)
38
- let ind = 0;
39
- for (const opt in options) {
40
- if (options.hasOwnProperty(opt)) {
41
- form["option_text_array[" + ind + "]"] = opt;
42
- form["option_is_selected_array[" + ind + "]"] = options[opt]
43
- ? "1"
44
- : "0";
45
- ind++;
46
- }
47
- }
48
-
49
- defaultFuncs
50
- .post(
51
- "https://www.facebook.com/messaging/group_polling/create_poll/?dpr=1",
52
- ctx.jar,
53
- form
54
- )
55
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
56
- .then(function(resData) {
57
- if (resData.payload.status != "success") {
58
- throw resData;
59
- }
60
-
61
- return callback();
62
- })
63
- .catch(function(err) {
64
- log.error("createPoll", err);
65
- return callback(err);
24
+ ],
25
+ version_id: "8768858626531631"
26
+ };
27
+
28
+ const form = JSON.stringify({
29
+ app_id: "772021112871879",
30
+ payload: JSON.stringify(payload),
31
+ request_id: ++count_req,
32
+ type: 3
66
33
  });
67
34
 
68
- return returnPromise;
35
+ try {
36
+ mqttClient.publish("/ls_req", form);
37
+ resolve();
38
+ } catch (err) {
39
+ reject(err);
40
+ }
41
+ });
69
42
  };
70
43
  };
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin } = require("../../utils/client");
5
+ const { getType } = require("../../utils/format");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function deleteMessage(messageOrMessages, callback) {
8
8
  let resolveFunc = function() {};
@@ -24,7 +24,7 @@ module.exports = function(defaultFuncs, api, ctx) {
24
24
  client: "mercury"
25
25
  };
26
26
 
27
- if (utils.getType(messageOrMessages) !== "Array") {
27
+ if (getType(messageOrMessages) !== "Array") {
28
28
  messageOrMessages = [messageOrMessages];
29
29
  }
30
30
 
@@ -38,7 +38,7 @@ module.exports = function(defaultFuncs, api, ctx) {
38
38
  ctx.jar,
39
39
  form
40
40
  )
41
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
41
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
42
42
  .then(function(resData) {
43
43
  if (resData.error) {
44
44
  throw resData;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin } = require("../../utils/client");
5
+ const { getType } = require("../../utils/format");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function deleteThread(threadOrThreads, callback) {
8
8
  let resolveFunc = function() {};
@@ -24,7 +24,7 @@ module.exports = function(defaultFuncs, api, ctx) {
24
24
  client: "mercury"
25
25
  };
26
26
 
27
- if (utils.getType(threadOrThreads) !== "Array") {
27
+ if (getType(threadOrThreads) !== "Array") {
28
28
  threadOrThreads = [threadOrThreads];
29
29
  }
30
30
 
@@ -38,7 +38,7 @@ module.exports = function(defaultFuncs, api, ctx) {
38
38
  ctx.jar,
39
39
  form
40
40
  )
41
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
41
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
42
42
  .then(function(resData) {
43
43
  if (resData.error) {
44
44
  throw resData;
@@ -1,60 +1,51 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
- const log = require("npmlog");
3
+ const { generateOfflineThreadingID } = require("../../utils/format");
5
4
 
6
- module.exports = function(defaultFuncs, api, ctx) {
7
- return function forwardAttachment(attachmentID, userOrUsers, callback) {
8
- let resolveFunc = function() {};
9
- let rejectFunc = function() {};
10
- const returnPromise = new Promise(function(resolve, reject) {
5
+ module.exports = function (defaultFuncs, api, ctx) {
6
+ return async function forwardMessage(threadID, forwardedMsgID, callback) {
7
+ let resolveFunc, rejectFunc;
8
+ const returnPromise = new Promise((resolve, reject) => {
11
9
  resolveFunc = resolve;
12
10
  rejectFunc = reject;
13
11
  });
14
12
  if (!callback) {
15
- callback = function(err) {
16
- if (err) {
17
- return rejectFunc(err);
18
- }
19
- resolveFunc();
13
+ callback = (err, data) => {
14
+ if (err) return rejectFunc(err);
15
+ resolveFunc(data);
20
16
  };
21
17
  }
22
-
23
- const form = {
24
- attachment_id: attachmentID
25
- };
26
-
27
- if (utils.getType(userOrUsers) !== "Array") {
28
- userOrUsers = [userOrUsers];
29
- }
30
-
31
- const timestamp = Math.floor(Date.now() / 1000);
32
-
33
- for (let i = 0; i < userOrUsers.length; i++) {
34
- //That's good, the key of the array is really timestmap in seconds + index
35
- //Probably time when the attachment will be sent?
36
- form["recipient_map[" + (timestamp + i) + "]"] = userOrUsers[i];
37
- }
38
-
39
- defaultFuncs
40
- .post(
41
- "https://www.facebook.com/mercury/attachments/forward/",
42
- ctx.jar,
43
- form
44
- )
45
- .then(utils.parseAndCheckLogin(ctx.jar, defaultFuncs))
46
- .then(function(resData) {
47
- if (resData.error) {
48
- throw resData;
18
+ let count_req = 0
19
+ const payload = {
20
+ epoch_id: generateOfflineThreadingID(),
21
+ tasks: [
22
+ {
23
+ failure_count: null,
24
+ label: "46",
25
+ payload: JSON.stringify({
26
+ thread_id: threadID,
27
+ otid: generateOfflineThreadingID(),
28
+ source: 65544,
29
+ send_type: 5,
30
+ sync_group: 1,
31
+ mark_thread_read: 0,
32
+ forwarded_msg_id: forwardedMsgID,
33
+ strip_forwarded_msg_caption: 0,
34
+ initiating_source: 1
35
+ }),
36
+ queue_name: threadID,
37
+ task_id: Math.floor(Math.random() * 1001)
49
38
  }
50
-
51
- return callback();
52
- })
53
- .catch(function(err) {
54
- log.error("forwardAttachment", err);
55
- return callback(err);
56
- });
57
-
39
+ ],
40
+ version_id: "8768858626531631"
41
+ };
42
+ const form = JSON.stringify({
43
+ app_id: "772021112871879",
44
+ payload: JSON.stringify(payload),
45
+ "request_id": ++count_req,
46
+ "type": 3
47
+ });
48
+ mqttClient.publish("/ls_req", form);
58
49
  return returnPromise;
59
50
  };
60
51
  };
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
3
+ const { formatID } = require("../../utils/format");
4
4
  const log = require("npmlog");
5
-
6
- // [almost] copy pasted from one of FB's minified file (GenderConst)
5
+ const { parseAndCheckLogin } = require("../../utils/client");
7
6
  const GENDERS = {
8
7
  0: "unknown",
9
8
  1: "female_singular",
@@ -26,7 +25,7 @@ function formatData(obj) {
26
25
  alternateName: user.alternateName,
27
26
  firstName: user.firstName,
28
27
  gender: GENDERS[user.gender],
29
- userID: utils.formatID(user.id.toString()),
28
+ userID: formatID(user.id.toString()),
30
29
  isFriend: user.is_friend != null && user.is_friend ? true : false,
31
30
  fullName: user.name,
32
31
  profilePicture: user.thumbSrc,
@@ -61,9 +60,9 @@ module.exports = function(defaultFuncs, api, ctx) {
61
60
  "https://www.facebook.com/chat/user_info_all",
62
61
  ctx.jar,
63
62
  {},
64
- { viewer: ctx.i_userID || ctx.userID }
63
+ { viewer: ctx.userID }
65
64
  )
66
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
65
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
67
66
  .then(function(resData) {
68
67
  if (!resData) {
69
68
  throw { error: "getFriendsList returned empty object." };
@@ -1,13 +1,8 @@
1
1
  "use strict";
2
2
 
3
- // Original
4
- /**
5
- * @author https://github.com/Schmavery/facebook-chat-api/pull/865
6
- */
7
-
8
- const utils = require("../../utils");
9
3
  const log = require("npmlog");
10
-
4
+ const { _formatAttachment } = require("../../utils/format");
5
+ const { parseAndCheckLogin } = require("../../utils/client");
11
6
  function formatMessage(threadID, data) {
12
7
  switch (data.__typename) {
13
8
  case "ThreadNameMessage":
@@ -151,7 +146,7 @@ function formatMessage(threadID, data) {
151
146
  ? data.blob_attachments.length.map(att => {
152
147
  let x;
153
148
  try {
154
- x = utils._formatAttachment(att);
149
+ x = _formatAttachment(att);
155
150
  } catch (ex) {
156
151
  x = att;
157
152
  x.error = ex;
@@ -272,7 +267,7 @@ module.exports = function(defaultFuncs, api, ctx) {
272
267
 
273
268
  defaultFuncs
274
269
  .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
275
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
270
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
276
271
  .then(resData => {
277
272
  if (resData[resData.length - 1].error_results > 0) {
278
273
  throw resData[0].o0.errors;
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin } = require("../../utils/client");
5
+ const { getType } = require("../../utils/format");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function handleMessageRequest(threadID, accept, callback) {
8
- if (utils.getType(accept) !== "Boolean") {
8
+ if (getType(accept) !== "Boolean") {
9
9
  throw {
10
10
  error: "Please pass a boolean as a second argument."
11
11
  };
@@ -31,7 +31,7 @@ module.exports = function(defaultFuncs, api, ctx) {
31
31
  client: "mercury"
32
32
  };
33
33
 
34
- if (utils.getType(threadID) !== "Array") {
34
+ if (getType(threadID) !== "Array") {
35
35
  threadID = [threadID];
36
36
  }
37
37
 
@@ -47,7 +47,7 @@ module.exports = function(defaultFuncs, api, ctx) {
47
47
  ctx.jar,
48
48
  form
49
49
  )
50
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
50
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
51
51
  .then(function(resData) {
52
52
  if (resData.error) {
53
53
  throw resData;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- const utils = require("../../utils");
3
2
  const log = require("npmlog");
4
-
3
+ const { parseAndCheckLogin, saveCookies } = require("../../utils/client");
4
+ const { getType } = require("../../utils/format");
5
5
  module.exports = function(defaultFuncs, api, ctx) {
6
6
  return function markAsDelivered(threadID, messageID, callback) {
7
7
  let resolveFunc = function() {};
@@ -35,8 +35,8 @@ module.exports = function(defaultFuncs, api, ctx) {
35
35
  ctx.jar,
36
36
  form
37
37
  )
38
- .then(utils.saveCookies(ctx.jar))
39
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
38
+ .then(saveCookies(ctx.jar))
39
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
40
40
  .then(function(resData) {
41
41
  if (resData.error) {
42
42
  throw resData;
@@ -46,7 +46,7 @@ module.exports = function(defaultFuncs, api, ctx) {
46
46
  })
47
47
  .catch(function(err) {
48
48
  log.error("markAsDelivered", err);
49
- if (utils.getType(err) == "Object" && err.error === "Not logged in.") {
49
+ if (getType(err) == "Object" && err.error === "Not logged in.") {
50
50
  ctx.loggedIn = false;
51
51
  }
52
52
  return callback(err);
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin, saveCookies } = require("../../utils/client");
5
+ const { getType } = require("../../utils/format");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return async function markAsRead(threadID, read, callback) {
8
8
  if (
9
- utils.getType(read) === "Function" ||
10
- utils.getType(read) === "AsyncFunction"
9
+ getType(read) === "Function" ||
10
+ getType(read) === "AsyncFunction"
11
11
  ) {
12
12
  callback = read;
13
13
  read = true;
@@ -39,8 +39,8 @@ module.exports = function(defaultFuncs, api, ctx) {
39
39
  ctx.jar,
40
40
  form
41
41
  )
42
- .then(utils.saveCookies(ctx.jar))
43
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs));
42
+ .then(saveCookies(ctx.jar))
43
+ .then(parseAndCheckLogin(ctx, defaultFuncs));
44
44
  } catch (e) {
45
45
  callback(e);
46
46
  return e;
@@ -49,7 +49,7 @@ module.exports = function(defaultFuncs, api, ctx) {
49
49
  if (resData.error) {
50
50
  const err = resData.error;
51
51
  log.error("markAsRead", err);
52
- if (utils.getType(err) == "Object" && err.error === "Not logged in.") {
52
+ if (getType(err) == "Object" && err.error === "Not logged in.") {
53
53
  ctx.loggedIn = false;
54
54
  }
55
55
  callback(err);
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin, saveCookies } = require("../../utils/client");
6
5
  module.exports = function(defaultFuncs, api, ctx) {
7
6
  return function markAsReadAll(callback) {
8
7
  let resolveFunc = function() {};
@@ -31,8 +30,8 @@ module.exports = function(defaultFuncs, api, ctx) {
31
30
  ctx.jar,
32
31
  form
33
32
  )
34
- .then(utils.saveCookies(ctx.jar))
35
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
33
+ .then(saveCookies(ctx.jar))
34
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
36
35
  .then(function(resData) {
37
36
  if (resData.error) {
38
37
  throw resData;
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
 
3
- const utils = require("../../utils");
4
3
  const log = require("npmlog");
5
-
4
+ const { parseAndCheckLogin, saveCookies } = require("../../utils/client");
5
+ const { getType } = require("../../utils/format");
6
6
  module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function markAsRead(seen_timestamp, callback) {
8
8
  if (
9
- utils.getType(seen_timestamp) == "Function" ||
10
- utils.getType(seen_timestamp) == "AsyncFunction"
9
+ getType(seen_timestamp) == "Function" ||
10
+ getType(seen_timestamp) == "AsyncFunction"
11
11
  ) {
12
12
  callback = seen_timestamp;
13
13
  seen_timestamp = Date.now();
@@ -39,8 +39,8 @@ module.exports = function(defaultFuncs, api, ctx) {
39
39
  ctx.jar,
40
40
  form
41
41
  )
42
- .then(utils.saveCookies(ctx.jar))
43
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
42
+ .then(saveCookies(ctx.jar))
43
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
44
44
  .then(function(resData) {
45
45
  if (resData.error) {
46
46
  throw resData;
@@ -50,7 +50,7 @@ module.exports = function(defaultFuncs, api, ctx) {
50
50
  })
51
51
  .catch(function(err) {
52
52
  log.error("markAsSeen", err);
53
- if (utils.getType(err) == "Object" && err.error === "Not logged in.") {
53
+ if (getType(err) == "Object" && err.error === "Not logged in.") {
54
54
  ctx.loggedIn = false;
55
55
  }
56
56
  return callback(err);
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
- const utils = require("../../utils");
3
2
  const log = require("npmlog");
4
-
3
+ const { parseAndCheckLogin, saveCookies } = require("../../utils/client");
5
4
  module.exports = function(defaultFuncs, api, ctx) {
6
5
  // muteSecond: -1=permanent mute, 0=unmute, 60=one minute, 3600=one hour, etc.
7
6
  return function muteThread(threadID, muteSeconds, callback) {
@@ -32,8 +31,8 @@ module.exports = function(defaultFuncs, api, ctx) {
32
31
  ctx.jar,
33
32
  form
34
33
  )
35
- .then(utils.saveCookies(ctx.jar))
36
- .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
34
+ .then(saveCookies(ctx.jar))
35
+ .then(parseAndCheckLogin(ctx, defaultFuncs))
37
36
  .then(function(resData) {
38
37
  if (resData.error) {
39
38
  throw resData;