bb-fca 2.0.8 → 2.0.9

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.
@@ -88,30 +88,8 @@ export interface PostComment {
88
88
  }
89
89
 
90
90
  export interface GetPostCommentsOptions {
91
- /** Numeric story_fbid (used with id to construct permalink.php URL) */
92
- story_fbid?: string;
93
- /** Facebook user/page ID (used with story_fbid) */
91
+ story_fbid: string;
94
92
  id?: string;
95
- /** Direct Facebook post URL (e.g. https://www.facebook.com/user/posts/pfbid...) */
96
- url?: string;
97
- /** Cursor for fetching next page of comments (from page_info.end_cursor) */
98
- after?: string;
99
- /** GraphQL feedback ID for pagination (from page_info.feedback_id) */
100
- feedback_id?: string;
101
- }
102
-
103
- export interface PageInfo {
104
- end_cursor: string | null;
105
- has_next_page: boolean;
106
- has_previous_page?: boolean;
107
- start_cursor?: string | null;
108
- /** GraphQL feedback ID needed for pagination queries */
109
- feedback_id?: string;
110
- }
111
-
112
- export interface GetPostCommentsResult {
113
- comments: PostComment[];
114
- page_info: PageInfo | null;
115
93
  }
116
94
 
117
95
  export interface ShareResult {
@@ -681,9 +659,8 @@ export interface API {
681
659
  ): Promise<DeletePostResult>;
682
660
  getComments(
683
661
  postID: string | GetPostCommentsOptions,
684
- optionsOrCallback?: GetPostCommentsOptions | Callback<GetPostCommentsResult>,
685
- callback?: Callback<GetPostCommentsResult>,
686
- ): Promise<GetPostCommentsResult>;
662
+ callback?: Callback<PostComment[]>,
663
+ ): Promise<PostComment[]>;
687
664
  uploadPhoto(
688
665
  photoPath: string,
689
666
  callback?: Callback<UploadPhotoResult>,
@@ -794,14 +771,16 @@ export interface API {
794
771
  searchCity(
795
772
  query: string,
796
773
  searchCategory?: string,
797
- ): Promise<Array<{
798
- fbid: string;
799
- title: string;
800
- value: string;
801
- photoUri: string;
802
- subtitle: string;
803
- secondSubtitle: string;
804
- }>>;
774
+ ): Promise<
775
+ Array<{
776
+ fbid: string;
777
+ title: string;
778
+ value: string;
779
+ photoUri: string;
780
+ subtitle: string;
781
+ secondSubtitle: string;
782
+ }>
783
+ >;
805
784
 
806
785
  /**
807
786
  * Searches for companies/workplaces matching the given query string.
@@ -810,14 +789,16 @@ export interface API {
810
789
  */
811
790
  searchCompany(
812
791
  query: string,
813
- ): Promise<Array<{
814
- fbid: string;
815
- title: string;
816
- value: string;
817
- photoUri: string;
818
- subtitle: string;
819
- secondSubtitle: string;
820
- }>>;
792
+ ): Promise<
793
+ Array<{
794
+ fbid: string;
795
+ title: string;
796
+ value: string;
797
+ photoUri: string;
798
+ subtitle: string;
799
+ secondSubtitle: string;
800
+ }>
801
+ >;
821
802
 
822
803
  /**
823
804
  * Searches for job titles/positions matching the given query string.
@@ -826,14 +807,16 @@ export interface API {
826
807
  */
827
808
  searchJobTitle(
828
809
  query: string,
829
- ): Promise<Array<{
830
- fbid: string;
831
- title: string;
832
- value: string;
833
- photoUri: string;
834
- subtitle: string;
835
- secondSubtitle: string;
836
- }>>;
810
+ ): Promise<
811
+ Array<{
812
+ fbid: string;
813
+ title: string;
814
+ value: string;
815
+ photoUri: string;
816
+ subtitle: string;
817
+ secondSubtitle: string;
818
+ }>
819
+ >;
837
820
 
838
821
  /**
839
822
  * Fetches the friend list of a given user with pagination support.
@@ -884,10 +867,7 @@ export interface API {
884
867
  * @param cityId The Facebook ID of the city (from searchCity's fbid field).
885
868
  * @param privacy Privacy setting: 'EVERYONE', 'FRIENDS', or 'SELF' (default: 'EVERYONE').
886
869
  */
887
- updateCity(
888
- cityId: string,
889
- privacy?: string,
890
- ): Promise<any>;
870
+ updateCity(cityId: string, privacy?: string): Promise<any>;
891
871
 
892
872
  /**
893
873
  * Updates the hometown on the profile.
@@ -895,10 +875,7 @@ export interface API {
895
875
  * @param cityId The Facebook ID of the city (from searchCity's fbid field).
896
876
  * @param privacy Privacy setting: 'EVERYONE', 'FRIENDS', or 'SELF' (default: 'EVERYONE').
897
877
  */
898
- updateHometown(
899
- cityId: string,
900
- privacy?: string,
901
- ): Promise<any>;
878
+ updateHometown(cityId: string, privacy?: string): Promise<any>;
902
879
 
903
880
  /**
904
881
  * Changes the Facebook account display name (two-step: preview then confirm).
@@ -3,9 +3,14 @@ const gradient = require('gradient-string');
3
3
  const echaceb = gradient(['#0061ff', '#681297']);
4
4
  const ws = echaceb('bb-fca');
5
5
 
6
- let h;
7
- const i = {};
8
- const j = {
6
+ /**
7
+ * Presence compression token map.
8
+ * Keys are single uppercase letters used as compact tokens;
9
+ * values are the URL-encoded JSON substrings they replace.
10
+ * This map is used by presenceEncode/presenceDecode to compress
11
+ * presence payloads before sending to Facebook's EdgeChat API.
12
+ */
13
+ const PRESENCE_TOKEN_MAP: Record<string, string> = {
9
14
  _: '%',
10
15
  A: '%2',
11
16
  B: '000',
@@ -36,17 +41,27 @@ const j = {
36
41
  Z:
37
42
  '%2c%22sb%22%3a1%2c%22t%22%3a%5b%5d%2c%22f%22%3anull%2c%22uct%22%3a0%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a',
38
43
  };
39
- (function() {
40
- const l = [];
41
- for (const m in j) {
42
- i[j[m]] = m;
43
- l.push(j[m]);
44
+
45
+ /** Reverse map: encoded substring → token letter. Built from PRESENCE_TOKEN_MAP. */
46
+ const presenceDecodeMap: Record<string, string> = {};
47
+
48
+ /** RegExp that matches any encodedsubstring in PRESENCE_TOKEN_MAP (longest first). */
49
+ let presenceEncodeRegex: RegExp;
50
+
51
+ (function buildPresenceMaps(): void {
52
+ const encodedValues: string[] = [];
53
+ for (const token in PRESENCE_TOKEN_MAP) {
54
+ presenceDecodeMap[PRESENCE_TOKEN_MAP[token]] = token;
55
+ encodedValues.push(PRESENCE_TOKEN_MAP[token]);
44
56
  }
45
- l.reverse();
46
- h = new RegExp(l.join('|'), 'g');
57
+ // Sort longest first so greedy matching works correctly
58
+ encodedValues.reverse();
59
+ presenceEncodeRegex = new RegExp(encodedValues.join('|'), 'g');
47
60
  })();
48
61
 
49
- const NUM_TO_MONTH = [
62
+ // ─── Calendar helpers ───────────────────────────────────────────────────────
63
+
64
+ const NUM_TO_MONTH: string[] = [
50
65
  'Jan',
51
66
  'Feb',
52
67
  'Mar',
@@ -60,26 +75,27 @@ const NUM_TO_MONTH = [
60
75
  'Nov',
61
76
  'Dec',
62
77
  ];
63
- const NUM_TO_DAY = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
78
+ const NUM_TO_DAY: string[] = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
79
+
80
+ // ─── Utility functions ───────────────────────────────────────────────────────
64
81
 
65
- function getRandom(arr) {
82
+ function getRandom<T>(arr: T[]): T {
66
83
  return arr[Math.floor(Math.random() * arr.length)];
67
84
  }
68
85
 
69
- function padZeros(val, len = 2) {
70
- val = String(val);
71
- while (val.length < len) val = '0' + val;
72
- return val;
86
+ function padZeros(val: string | number, len: number = 2): string {
87
+ let s = String(val);
88
+ while (s.length < len) s = '0' + s;
89
+ return s;
73
90
  }
74
91
 
75
- function generateThreadingID(clientID) {
76
- const k = Date.now();
77
- const l = Math.floor(Math.random() * 4294967295);
78
- const m = clientID;
79
- return '<' + k + ':' + l + '-' + m + '@mail.projektitan.com>';
92
+ function generateThreadingID(clientID: string): string {
93
+ const timestamp = Date.now();
94
+ const rand = Math.floor(Math.random() * 4294967295);
95
+ return '<' + timestamp + ':' + rand + '-' + clientID + '@mail.projektitan.com>';
80
96
  }
81
97
 
82
- function binaryToDecimal(data) {
98
+ function binaryToDecimal(data: string): string {
83
99
  let ret = '';
84
100
  while (data !== '0') {
85
101
  let end = 0;
@@ -100,7 +116,7 @@ function binaryToDecimal(data) {
100
116
  return ret;
101
117
  }
102
118
 
103
- function generateOfflineThreadingID() {
119
+ function generateOfflineThreadingID(): string {
104
120
  const ret = Date.now();
105
121
  const value = Math.floor(Math.random() * 4294967295);
106
122
  const str = ('0000000000000000000000' + value.toString(2)).slice(-22);
@@ -108,26 +124,33 @@ function generateOfflineThreadingID() {
108
124
  return binaryToDecimal(msgs);
109
125
  }
110
126
 
111
- function presenceEncode(str) {
127
+ /**
128
+ * Compresses a presence JSON string using PRESENCE_TOKEN_MAP shortcuts.
129
+ * Reduces payload size when communicating with Facebook's EdgeChat API.
130
+ */
131
+ function presenceEncode(str: string): string {
112
132
  return encodeURIComponent(str)
113
- .replace(/([_A-Z])|%../g, function(m, n) {
133
+ .replace(/([_A-Z])|%../g, function(m: string, n: string): string {
114
134
  return n ? '%' + n.charCodeAt(0).toString(16) : m;
115
135
  })
116
136
  .toLowerCase()
117
- .replace(h, function(m) {
118
- return i[m];
137
+ .replace(presenceEncodeRegex, function(m: string): string {
138
+ return presenceDecodeMap[m];
119
139
  });
120
140
  }
121
141
 
122
- function presenceDecode(str) {
142
+ /**
143
+ * Decompresses a presence-encoded string back to its original form.
144
+ */
145
+ function presenceDecode(str: string): string {
123
146
  return decodeURIComponent(
124
- str.replace(/[_A-Z]/g, function(m) {
125
- return j[m];
147
+ str.replace(/[_A-Z]/g, function(m: string): string {
148
+ return PRESENCE_TOKEN_MAP[m];
126
149
  }),
127
150
  );
128
151
  }
129
152
 
130
- function generatePresence(userID) {
153
+ function generatePresence(userID: string): string {
131
154
  const time = Date.now();
132
155
  return (
133
156
  'E' +
@@ -153,7 +176,7 @@ function generatePresence(userID) {
153
176
  );
154
177
  }
155
178
 
156
- function generateAccessiblityCookie() {
179
+ function generateAccessiblityCookie(): string {
157
180
  const time = Date.now();
158
181
  return encodeURIComponent(
159
182
  JSON.stringify({
@@ -169,20 +192,19 @@ function generateAccessiblityCookie() {
169
192
  );
170
193
  }
171
194
 
172
- function getGUID() {
195
+ function getGUID(): string {
173
196
  let sectionLength = Date.now();
174
197
  const id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(
175
- c,
176
- ) {
198
+ c: string,
199
+ ): string {
177
200
  const r = Math.floor((sectionLength + Math.random() * 16) % 16);
178
201
  sectionLength = Math.floor(sectionLength / 16);
179
- const _guid = (c == 'x' ? r : (r & 7) | 8).toString(16);
180
- return _guid;
202
+ return (c == 'x' ? r : (r & 7) | 8).toString(16);
181
203
  });
182
204
  return id;
183
205
  }
184
206
 
185
- function getFrom(str, startToken, endToken) {
207
+ function getFrom(str: string, startToken: string, endToken: string): string {
186
208
  const start = str.indexOf(startToken) + startToken.length;
187
209
  if (start < startToken.length) return '';
188
210
 
@@ -196,7 +218,7 @@ function getFrom(str, startToken, endToken) {
196
218
  return lastHalf.substring(0, end);
197
219
  }
198
220
 
199
- function makeParsable(html) {
221
+ function makeParsable(html: string): string | string[] {
200
222
  const withoutForLoop = html.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, '');
201
223
  const maybeMultipleObjects = withoutForLoop.split(/\}\r\n *\{/);
202
224
  if (maybeMultipleObjects.length === 1) return maybeMultipleObjects;
@@ -204,52 +226,57 @@ function makeParsable(html) {
204
226
  return '[' + maybeMultipleObjects.join('},{') + ']';
205
227
  }
206
228
 
207
- function arrToForm(form) {
229
+ function arrToForm(form: Array<{ name: string; val: any }>): Record<string, any> {
208
230
  return arrayToObject(
209
231
  form,
210
- function(v) {
211
- return v.name;
212
- },
213
- function(v) {
214
- return v.val;
215
- },
232
+ function(v) { return v.name; },
233
+ function(v) { return v.val; },
216
234
  );
217
235
  }
218
236
 
219
- function arrayToObject(arr, getKey, getValue) {
220
- return arr.reduce(function(acc, val) {
237
+ function arrayToObject<T>(
238
+ arr: T[],
239
+ getKey: (v: T) => string,
240
+ getValue: (v: T) => any,
241
+ ): Record<string, any> {
242
+ return arr.reduce(function(acc: Record<string, any>, val: T) {
221
243
  acc[getKey(val)] = getValue(val);
222
244
  return acc;
223
245
  }, {});
224
246
  }
225
247
 
226
- function getSignatureID() {
248
+ function getSignatureID(): string {
227
249
  return Math.floor(Math.random() * 2147483648).toString(16);
228
250
  }
229
251
 
230
- function generateTimestampRelative() {
252
+ function generateTimestampRelative(): string {
231
253
  const d = new Date();
232
254
  return d.getHours() + ':' + padZeros(d.getMinutes());
233
255
  }
234
256
 
235
- function getType(obj) {
257
+ function getType(obj: unknown): string {
236
258
  return Object.prototype.toString.call(obj).slice(8, -1);
237
259
  }
238
260
 
239
- // Logs
261
+ // ─── Logging ─────────────────────────────────────────────────────────────────
262
+
240
263
  let logging = true;
241
- function logOptions(bool) {
264
+
265
+ function logOptions(bool: boolean): void {
242
266
  logging = bool;
243
267
  }
244
- function log(...args) {
268
+
269
+ function log(...args: unknown[]): void {
245
270
  if (logging === false) return;
246
271
  console.log(ws, chalk.green.bold('[LOG]'), ...args);
247
272
  }
248
- function error(...args) {
273
+
274
+ function error(...args: unknown[]): void {
249
275
  if (logging === false) return;
250
276
  console.error(ws, chalk.red.bold('[ERROR]'), ...args);
251
277
  }
252
- function warn(...args) {
278
+
279
+ function warn(...args: unknown[]): void {
253
280
  if (logging === false) return;
254
281
  console.warn(ws, chalk.yellow.bold('[WARNING]'), ...args);
255
282
  }