@crawlee/utils 3.0.0-alpha.2 → 3.0.0-alpha.5

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.
@@ -0,0 +1,661 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DISCORD_REGEX_GLOBAL = exports.DISCORD_REGEX = exports.PINTEREST_REGEX_GLOBAL = exports.PINTEREST_REGEX = exports.TIKTOK_REGEX_GLOBAL = exports.TIKTOK_REGEX = exports.YOUTUBE_REGEX_GLOBAL = exports.YOUTUBE_REGEX = exports.FACEBOOK_REGEX_GLOBAL = exports.FACEBOOK_REGEX = exports.TWITTER_REGEX_GLOBAL = exports.TWITTER_REGEX = exports.INSTAGRAM_REGEX_GLOBAL = exports.INSTAGRAM_REGEX = exports.LINKEDIN_REGEX_GLOBAL = exports.LINKEDIN_REGEX = exports.parseHandlesFromHtml = exports.phonesFromUrls = exports.phonesFromText = exports.emailsFromUrls = exports.emailsFromText = exports.EMAIL_REGEX_GLOBAL = exports.EMAIL_REGEX = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const cheerio_1 = tslib_1.__importDefault(require("cheerio"));
6
+ const cheerio_2 = require("./cheerio");
7
+ // Regex inspired by https://zapier.com/blog/extract-links-email-phone-regex/
8
+ // eslint-disable-next-line max-len
9
+ const EMAIL_REGEX_STRING = '(?:[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])';
10
+ /**
11
+ * Regular expression to exactly match a single email address.
12
+ * It has the following form: `/^...$/i`.
13
+ */
14
+ exports.EMAIL_REGEX = new RegExp(`^${EMAIL_REGEX_STRING}$`, 'i');
15
+ /**
16
+ * Regular expression to find multiple email addresses in a text.
17
+ * It has the following form: `/.../ig`.
18
+ */
19
+ exports.EMAIL_REGEX_GLOBAL = new RegExp(EMAIL_REGEX_STRING, 'ig');
20
+ const EMAIL_URL_PREFIX_REGEX = /^mailto:/i;
21
+ /**
22
+ * The function extracts email addresses from a plain text.
23
+ * Note that the function preserves the order of emails and keep duplicates.
24
+ * @param text Text to search in.
25
+ * @return Array of emails addresses found.
26
+ * If no emails are found, the function returns an empty array.
27
+ */
28
+ function emailsFromText(text) {
29
+ if (typeof text !== 'string')
30
+ return [];
31
+ return text.match(exports.EMAIL_REGEX_GLOBAL) || [];
32
+ }
33
+ exports.emailsFromText = emailsFromText;
34
+ /**
35
+ * The function extracts email addresses from a list of URLs.
36
+ * Basically it looks for all `mailto:` URLs and returns valid email addresses from them.
37
+ * Note that the function preserves the order of emails and keep duplicates.
38
+ * @param urls Array of URLs.
39
+ * @return Array of emails addresses found.
40
+ * If no emails are found, the function returns an empty array.
41
+ */
42
+ function emailsFromUrls(urls) {
43
+ if (!Array.isArray(urls))
44
+ throw new Error('The "urls" parameter must be an array');
45
+ const emails = [];
46
+ for (const url of urls) {
47
+ if (!url)
48
+ continue;
49
+ if (!EMAIL_URL_PREFIX_REGEX.test(url))
50
+ continue;
51
+ const email = url.replace(EMAIL_URL_PREFIX_REGEX, '').trim();
52
+ if (exports.EMAIL_REGEX.test(email))
53
+ emails.push(email);
54
+ }
55
+ return emails;
56
+ }
57
+ exports.emailsFromUrls = emailsFromUrls;
58
+ // Supports URLs starting with `tel://`, `tel:/` and `tel:`, and similarly `phone`, `telephone` and `callto`
59
+ const PHONE_URL_PREFIX_REGEX = /^(tel|phone|telephone|callto):(\/)?(\/)?/i;
60
+ // It's pretty much impossible (and unmaintainable) to have just one large regular expression for all possible phone numbers.
61
+ // So here we define various regular expression for typical phone number patterns, which are then used to compile
62
+ // a single large regular expressions. Add more patterns as needed.
63
+ // NOTE: The patterns are tested in the order as written below, so the longer ones should be before the shorter ones!
64
+ const PHONE_REGEXS_STRINGS = [
65
+ // 775123456
66
+ '[0-9]{6,15}',
67
+ // 1(413)555-2378 or 1(413)555.2378 or 1 (413) 555-2378 or 1 (413) 555 2378 or (303) 494-2320
68
+ '([0-9]{1,4}( )?)?\\([0-9]{2,4}\\)( )?[0-9]{2,4}(( )?(-|.))?( )?[0-9]{2,6}',
69
+ // (51) 5667-9987 or (19)94138-9398
70
+ '\\([0-9]{2}\\)( )?[0-9]{4,5}-[0-9]{4}',
71
+ // 1(262) 955-95-79 or 1(262)955.95.79
72
+ '([0-9]{1,4}( )?)?\\([0-9]{2,4}\\)( )?[0-9]{2,4}(( )?(-|.))?( )?[0-9]{2,6}',
73
+ // 413-577-1234-564
74
+ '[0-9]{2,4}-[0-9]{2,4}-[0-9]{2,4}-[0-9]{2,6}',
75
+ // 413-577-1234
76
+ '[0-9]{2,4}-[0-9]{2,4}-[0-9]{2,6}',
77
+ // 413-577
78
+ '[0-9]{2,4}-[0-9]{2,6}',
79
+ // 413.577.1234.564
80
+ '[0-9]{2,4}\\.[0-9]{2,4}\\.[0-9]{2,4}\\.[0-9]{2,6}',
81
+ // 413.577.1234
82
+ '[0-9]{2,4}\\.[0-9]{2,4}\\.[0-9]{2,6}',
83
+ // 413.577
84
+ '[0-9]{2,4}\\.[0-9]{2,6}',
85
+ // 413 577 1234 564
86
+ '[0-9]{2,4} [0-9]{2,4} [0-9]{2,4} [0-9]{2,6}',
87
+ // 413 577 1234
88
+ '[0-9]{2,4} [0-9]{2,4} [0-9]{2,6}',
89
+ // 123 4567
90
+ '[0-9]{2,4} [0-9]{3,8}',
91
+ // All phones might be prefixed with '+' or '00'
92
+ ].map((regex) => `(00|\\+)?${regex}`);
93
+ // The minimum number of digits a phone number can contain.
94
+ // That's because the PHONE_REGEXS_STRINGS patterns are quite wide and report a lot of false positives.
95
+ const PHONE_MIN_DIGITS = 7;
96
+ // These are patterns that might be matched by PHONE_REGEXS_STRINGS,
97
+ // but which are most likely not phone numbers. Add more patterns as needed.
98
+ const SKIP_PHONE_REGEXS = [
99
+ // 2018-11-10
100
+ '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
101
+ ];
102
+ const PHONE_REGEX_GLOBAL = new RegExp(`(${PHONE_REGEXS_STRINGS.join('|')})`, 'ig');
103
+ const PHONE_REGEX = new RegExp(`^(${PHONE_REGEXS_STRINGS.join('|')})$`, 'i');
104
+ const SKIP_PHONE_REGEX = new RegExp(`^(${SKIP_PHONE_REGEXS.join('|')})$`, 'i');
105
+ /**
106
+ * The function attempts to extract phone numbers from a text. Please note that
107
+ * the results might not be accurate, since phone numbers appear in a large variety of formats and conventions.
108
+ * If you encounter some problems, please [file an issue](https://github.com/apify/apify-js/issues).
109
+ * @param text Text to search the phone numbers in.
110
+ * @return Array of phone numbers found.
111
+ * If no phone numbers are found, the function returns an empty array.
112
+ */
113
+ function phonesFromText(text) {
114
+ if (typeof text !== 'string')
115
+ return [];
116
+ let phones = text.match(PHONE_REGEX_GLOBAL) || [];
117
+ phones = phones.filter((phone) => {
118
+ if (!phone)
119
+ return false;
120
+ // Skip too short phones, they are most likely incorrect
121
+ if (phone.match(/[0-9]/g).length < PHONE_MIN_DIGITS)
122
+ return false;
123
+ // Skip phone numbers matching specific patterns
124
+ if (SKIP_PHONE_REGEX.test(phone))
125
+ return false;
126
+ return true;
127
+ });
128
+ return phones;
129
+ }
130
+ exports.phonesFromText = phonesFromText;
131
+ /**
132
+ * Finds phone number links in an array of URLs and extracts the phone numbers from them.
133
+ * Note that the phone number links look like `tel://123456789`, `tel:/123456789` or `tel:123456789`.
134
+ * @param urls Array of URLs.
135
+ * @return Array of phone numbers found.
136
+ * If no phone numbers are found, the function returns an empty array.
137
+ */
138
+ function phonesFromUrls(urls) {
139
+ if (!Array.isArray(urls))
140
+ throw new Error('The "urls" parameter must be an array');
141
+ const phones = [];
142
+ for (const url of urls) {
143
+ if (!url)
144
+ continue;
145
+ if (!PHONE_URL_PREFIX_REGEX.test(url))
146
+ continue;
147
+ const phone = url.replace(PHONE_URL_PREFIX_REGEX, '').trim();
148
+ if (PHONE_REGEX.test(phone))
149
+ phones.push(phone);
150
+ }
151
+ return phones;
152
+ }
153
+ exports.phonesFromUrls = phonesFromUrls;
154
+ // NOTEs about the regular expressions
155
+ // - They have just a single matching group for the profile username, all other groups are non-matching
156
+ // - They use a negative lookbehind and lookahead assertions, which are only supported in Node 8+.
157
+ // They are used to prevent matching URLs in strings like "blahttps://www.example.com"
158
+ // eslint-disable-next-line max-len
159
+ const LINKEDIN_REGEX_STRING = '(?<!\\w)(?:(?:http(?:s)?:\\/\\/)?(?:(?:(?:[a-z]+\\.)?linkedin\\.com\\/(?:in|company)\\/)([a-z0-9\\-_%=]{2,60})(?![a-z0-9\\-_%=])))(?:\\/)?';
160
+ // eslint-disable-next-line max-len
161
+ const INSTAGRAM_REGEX_STRING = '(?<!\\w)(?:http(?:s)?:\\/\\/)?(?:(?:www\\.)?(?:instagram\\.com|instagr\\.am)\\/)(?!explore|_n|_u)([a-z0-9_.]{2,30})(?![a-z0-9_.])(?:/)?';
162
+ const TWITTER_RESERVED_PATHS = 'oauth|account|tos|privacy|signup|home|hashtag|search|login|widgets|i|settings|start|share|intent|oct';
163
+ // eslint-disable-next-line max-len
164
+ const TWITTER_REGEX_STRING = `(?<!\\w)(?:http(?:s)?:\\/\\/)?(?:www.)?(?:twitter.com)\\/(?!(?:${TWITTER_RESERVED_PATHS})(?:[\\'\\"\\?\\.\\/]|$))([a-z0-9_]{1,15})(?![a-z0-9_])(?:/)?`;
165
+ // eslint-disable-next-line max-len
166
+ const FACEBOOK_RESERVED_PATHS = 'rsrc\\.php|apps|groups|events|l\\.php|friends|images|photo.php|chat|ajax|dyi|common|policies|login|recover|reg|help|security|messages|marketplace|pages|live|bookmarks|games|fundraisers|saved|gaming|salesgroups|jobs|people|ads|ad_campaign|weather|offers|recommendations|crisisresponse|onthisday|developers|settings|connect|business|plugins|intern|sharer';
167
+ // eslint-disable-next-line max-len
168
+ const FACEBOOK_REGEX_STRING = `(?<!\\w)(?:http(?:s)?:\\/\\/)?(?:www.)?(?:facebook.com|fb.com)\\/(?!(?:${FACEBOOK_RESERVED_PATHS})(?:[\\'\\"\\?\\.\\/]|$))(profile\\.php\\?id\\=[0-9]{3,20}|(?!profile\\.php)[a-z0-9\\.]{5,51})(?![a-z0-9\\.])(?:/)?`;
169
+ // eslint-disable-next-line max-len
170
+ // eslint-disable-next-line max-len, quotes
171
+ const YOUTUBE_REGEX_STRING = '(?<!\\w)(?:https?:\\/\\/)?(?:youtu\\.be\\/|(?:www\\.|m\\.)?youtube\\.com(?:\\/(?:watch|v|embed|user|c(?:hannel)?)(?:\\.php)?)?(?:\\?[^ ]*v=|\\/))([a-zA-Z0-9\\-_]{2,100})';
172
+ // eslint-disable-next-line max-len, quotes
173
+ const TIKTOK_REGEX_STRING = '(?<!\\w)(?:http(?:s)?:\\/\\/)?(?:(?:www|m)\\.)?(?:tiktok\\.com)\\/(((?:(?:v|embed|trending)(?:\\?shareId=|\\/))[0-9]{2,50}(?![0-9]))|(?:@)[a-z0-9\\-_\\.]+((?:\\/video\\/)[0-9]{2,50}(?![0-9]))?)(?:\\/)?';
174
+ // eslint-disable-next-line max-len, quotes
175
+ const PINTEREST_REGEX_STRING = '(?<!\\w)(?:http(?:s)?:\\/\\/)?(?:(?:(?:(?:www\\.)?pinterest(?:\\.com|(?:\\.[a-z]{2}){1,2}))|(?:[a-z]{2})\\.pinterest\\.com)(?:\\/))((pin\\/[0-9]{2,50})|((?!pin)[a-z0-9\\-_\\.]+(\\/[a-z0-9\\-_\\.]+)?))(?:\\/)?';
176
+ // eslint-disable-next-line max-len, quotes
177
+ const DISCORD_REGEX_STRING = '(?<!\\w)(?:https?:\\/\\/)?(?:www\\.)?((?:(?:(?:canary|ptb).)?(?:discord|discordapp)\\.com\\/channels(?:\\/)[0-9]{2,50}(\\/[0-9]{2,50})*)|(?:(?:(?:canary|ptb).)?(?:discord\\.(?:com|me|li|gg|io)|discordapp\\.com)(?:\\/invite)?)\\/(?!channels)[a-z0-9\\-_]{2,50})(?:\\/)?';
178
+ /**
179
+ * The function attempts to extract emails, phone numbers and social profile URLs from a HTML document,
180
+ * specifically LinkedIn, Twitter, Instagram and Facebook profile URLs.
181
+ * The function removes duplicates from the resulting arrays and sorts the items alphabetically.
182
+ *
183
+ * Note that the `phones` field contains phone numbers extracted from the special phone links
184
+ * such as `[call us](tel:+1234556789)` (see {@link phonesFromUrls})
185
+ * and potentially other sources with high certainty, while `phonesUncertain` contains phone numbers
186
+ * extracted from the plain text, which might be very inaccurate.
187
+ *
188
+ * **Example usage:**
189
+ * ```typescript
190
+ * import { launchPuppeteer } from '@crawlee/puppeteer';
191
+ * import { social } from '@crawlee/utils';
192
+ *
193
+ * const browser = await launchPuppeteer();
194
+ * const page = await browser.newPage();
195
+ * await page.goto('http://www.example.com');
196
+ * const html = await page.content();
197
+ *
198
+ * const result = social.parseHandlesFromHtml(html);
199
+ * console.log('Social handles:');
200
+ * console.dir(result);
201
+ * ```
202
+ *
203
+ * @param html HTML text
204
+ * @param [data] Optional object which will receive the `text` and `$` properties
205
+ * that contain text content of the HTML and `cheerio` object, respectively. This is an optimization
206
+ * so that the caller doesn't need to parse the HTML document again, if needed.
207
+ * @return An object with the social handles.
208
+ */
209
+ function parseHandlesFromHtml(html, data = null) {
210
+ const result = {
211
+ emails: [],
212
+ phones: [],
213
+ phonesUncertain: [],
214
+ linkedIns: [],
215
+ twitters: [],
216
+ instagrams: [],
217
+ facebooks: [],
218
+ youtubes: [],
219
+ tiktoks: [],
220
+ pinterests: [],
221
+ discords: [],
222
+ };
223
+ // TODO: maybe extract phone numbers from JSON+LD
224
+ if (typeof html !== 'string')
225
+ return result;
226
+ const $ = cheerio_1.default.load(html, { decodeEntities: true });
227
+ if (data)
228
+ data.$ = $;
229
+ const text = (0, cheerio_2.htmlToText)($);
230
+ if (data)
231
+ data.text = text;
232
+ // Find all <a> links with href tag
233
+ const linkUrls = [];
234
+ $('a[href]').each((_index, elem) => {
235
+ if (elem)
236
+ linkUrls.push($(elem).attr('href'));
237
+ });
238
+ result.emails = emailsFromUrls(linkUrls).concat(emailsFromText(text));
239
+ result.phones = phonesFromUrls(linkUrls);
240
+ result.phonesUncertain = phonesFromText(text);
241
+ // Note that these regexps extract just the base profile path. For example for
242
+ // https://www.linkedin.com/in/carl-newman-123456a/detail/recent-activity/
243
+ // they match just:
244
+ // https://www.linkedin.com/in/carl-newman-123456a
245
+ result.linkedIns = html.match(exports.LINKEDIN_REGEX_GLOBAL) || [];
246
+ result.twitters = html.match(exports.TWITTER_REGEX_GLOBAL) || [];
247
+ result.instagrams = html.match(exports.INSTAGRAM_REGEX_GLOBAL) || [];
248
+ result.facebooks = html.match(exports.FACEBOOK_REGEX_GLOBAL) || [];
249
+ result.youtubes = html.match(exports.YOUTUBE_REGEX_GLOBAL) || [];
250
+ result.tiktoks = html.match(exports.TIKTOK_REGEX_GLOBAL) || [];
251
+ result.pinterests = html.match(exports.PINTEREST_REGEX_GLOBAL) || [];
252
+ result.discords = html.match(exports.DISCORD_REGEX_GLOBAL) || [];
253
+ // Sort and deduplicate handles
254
+ for (const key of Object.keys(result)) {
255
+ result[key].sort();
256
+ result[key] = [...new Set(result[key])].sort();
257
+ }
258
+ return result;
259
+ }
260
+ exports.parseHandlesFromHtml = parseHandlesFromHtml;
261
+ /**
262
+ * Regular expression to exactly match a single LinkedIn profile URL.
263
+ * It has the following form: `/^...$/i` and matches URLs such as:
264
+ * ```
265
+ * https://www.linkedin.com/in/alan-turing
266
+ * en.linkedin.com/in/alan-turing
267
+ * linkedin.com/in/alan-turing
268
+ * https://www.linkedin.com/company/linkedin/
269
+ * ```
270
+ *
271
+ * The regular expression does NOT match URLs with additional
272
+ * subdirectories or query parameters, such as:
273
+ * ```
274
+ * https://www.linkedin.com/in/linus-torvalds/latest-activity
275
+ * ```
276
+ *
277
+ * Example usage:
278
+ * ```
279
+ * import { social } from '@crawlee/utils';
280
+ *
281
+ * if (social.LINKEDIN_REGEX.test('https://www.linkedin.com/in/alan-turing')) {
282
+ * console.log('Match!');
283
+ * }
284
+ * ```
285
+ */
286
+ exports.LINKEDIN_REGEX = new RegExp(`^${LINKEDIN_REGEX_STRING}$`, 'i');
287
+ /**
288
+ * Regular expression to find multiple LinkedIn profile URLs in a text or HTML.
289
+ * It has the following form: `/.../ig` and matches URLs such as:
290
+ * ```
291
+ * https://www.linkedin.com/in/alan-turing
292
+ * en.linkedin.com/in/alan-turing
293
+ * linkedin.com/in/alan-turing
294
+ * https://www.linkedin.com/company/linkedin/
295
+ * ```
296
+ *
297
+ * If the profile URL contains subdirectories or query parameters, the regular expression
298
+ * extracts just the base part of the profile URL. For example, from text such as:
299
+ * ```
300
+ * https://www.linkedin.com/in/linus-torvalds/latest-activity
301
+ * ```
302
+ * the expression extracts just the following base URL:
303
+ * ```
304
+ * https://www.linkedin.com/in/linus-torvalds
305
+ * ```
306
+ *
307
+ * Example usage:
308
+ * ```
309
+ * import { social } from '@crawlee/utils';
310
+ *
311
+ * const matches = text.match(social.LINKEDIN_REGEX_GLOBAL);
312
+ * if (matches) console.log(`${matches.length} LinkedIn profiles found!`);
313
+ * ```
314
+ */
315
+ exports.LINKEDIN_REGEX_GLOBAL = new RegExp(LINKEDIN_REGEX_STRING, 'ig');
316
+ /**
317
+ * Regular expression to exactly match a single Instagram profile URL.
318
+ * It has the following form: `/^...$/i` and matches URLs such as:
319
+ * ```
320
+ * https://www.instagram.com/old_prague
321
+ * www.instagram.com/old_prague/
322
+ * instagr.am/old_prague
323
+ * ```
324
+ *
325
+ * The regular expression does NOT match URLs with additional
326
+ * subdirectories or query parameters, such as:
327
+ * ```
328
+ * https://www.instagram.com/cristiano/followers
329
+ * ```
330
+ *
331
+ * It also does NOT match the following URLs:
332
+ * ```
333
+ * https://www.instagram.com/explore/
334
+ * https://www.instagram.com/_n/
335
+ * https://www.instagram.com/_u/
336
+ *
337
+ * Example usage:
338
+ * ```
339
+ * import { social } from '@crawlee/utils';
340
+ *
341
+ * if (social.INSTAGRAM_REGEX.test('https://www.instagram.com/old_prague')) {
342
+ * console.log('Match!');
343
+ * }
344
+ * ```
345
+ */
346
+ exports.INSTAGRAM_REGEX = new RegExp(`^${INSTAGRAM_REGEX_STRING}$`, 'i');
347
+ /**
348
+ * Regular expression to find multiple Instagram profile URLs in a text or HTML.
349
+ * It has the following form: `/.../ig` and matches URLs such as:
350
+ * ```
351
+ * https://www.instagram.com/old_prague
352
+ * www.instagram.com/old_prague/
353
+ * instagr.am/old_prague
354
+ * ```
355
+ *
356
+ * If the profile URL contains subdirectories or query parameters, the regular expression
357
+ * extracts just the base part of the profile URL. For example, from text such as:
358
+ * ```
359
+ * https://www.instagram.com/cristiano/followers
360
+ * ```
361
+ * the expression extracts just the following base URL:
362
+ * ```
363
+ * https://www.instagram.com/cristiano
364
+ * ```
365
+ *
366
+ * The regular expression does NOT match the following URLs:
367
+ * ```
368
+ * https://www.instagram.com/explore/
369
+ * https://www.instagram.com/_n/
370
+ * https://www.instagram.com/_u/
371
+ * ```
372
+ *
373
+ * Example usage:
374
+ * ```
375
+ * import { social } from '@crawlee/utils';
376
+ *
377
+ * const matches = text.match(social.INSTAGRAM_REGEX_GLOBAL);
378
+ * if (matches) console.log(`${matches.length} Instagram profiles found!`);
379
+ * ```
380
+ */
381
+ exports.INSTAGRAM_REGEX_GLOBAL = new RegExp(INSTAGRAM_REGEX_STRING, 'ig');
382
+ /**
383
+ * Regular expression to exactly match a single Twitter profile URL.
384
+ * It has the following form: `/^...$/i` and matches URLs such as:
385
+ * ```
386
+ * https://www.twitter.com/apify
387
+ * twitter.com/apify
388
+ * ```
389
+ *
390
+ * The regular expression does NOT match URLs with additional
391
+ * subdirectories or query parameters, such as:
392
+ * ```
393
+ * https://www.twitter.com/realdonaldtrump/following
394
+ * ```
395
+ *
396
+ * Example usage:
397
+ * ```
398
+ * import { social } from '@crawlee/utils';
399
+ *
400
+ * if (social.TWITTER_REGEX.test('https://www.twitter.com/apify')) {
401
+ * console.log('Match!');
402
+ * }
403
+ * ```
404
+ */
405
+ exports.TWITTER_REGEX = new RegExp(`^${TWITTER_REGEX_STRING}$`, 'i');
406
+ /**
407
+ * Regular expression to find multiple Twitter profile URLs in a text or HTML.
408
+ * It has the following form: `/.../ig` and matches URLs such as:
409
+ * ```
410
+ * https://www.twitter.com/apify
411
+ * twitter.com/apify
412
+ * ```
413
+ *
414
+ * If the profile URL contains subdirectories or query parameters, the regular expression
415
+ * extracts just the base part of the profile URL. For example, from text such as:
416
+ * ```
417
+ * https://www.twitter.com/realdonaldtrump/following
418
+ * ```
419
+ * the expression extracts only the following base URL:
420
+ * ```
421
+ * https://www.twitter.com/realdonaldtrump
422
+ * ```
423
+ *
424
+ * Example usage:
425
+ * ```
426
+ * import { social } from '@crawlee/utils';
427
+ *
428
+ * const matches = text.match(social.TWITTER_REGEX_STRING);
429
+ * if (matches) console.log(`${matches.length} Twitter profiles found!`);
430
+ * ```
431
+ */
432
+ exports.TWITTER_REGEX_GLOBAL = new RegExp(TWITTER_REGEX_STRING, 'ig');
433
+ /**
434
+ * Regular expression to exactly match a single Facebook profile URL.
435
+ * It has the following form: `/^...$/i` and matches URLs such as:
436
+ * ```
437
+ * https://www.facebook.com/apifytech
438
+ * facebook.com/apifytech
439
+ * fb.com/apifytech
440
+ * https://www.facebook.com/profile.php?id=123456789
441
+ * ```
442
+ *
443
+ * The regular expression does NOT match URLs with additional
444
+ * subdirectories or query parameters, such as:
445
+ * ```
446
+ * https://www.facebook.com/apifytech/photos
447
+ * ```
448
+ *
449
+ * Example usage:
450
+ * ```
451
+ * import { social } from '@crawlee/utils';
452
+ *
453
+ * if (social.FACEBOOK_REGEX.test('https://www.facebook.com/apifytech')) {
454
+ * console.log('Match!');
455
+ * }
456
+ * ```
457
+ */
458
+ exports.FACEBOOK_REGEX = new RegExp(`^${FACEBOOK_REGEX_STRING}$`, 'i');
459
+ /**
460
+ * Regular expression to find multiple Facebook profile URLs in a text or HTML.
461
+ * It has the following form: `/.../ig` and matches URLs such as:
462
+ * ```
463
+ * https://www.facebook.com/apifytech
464
+ * facebook.com/apifytech
465
+ * fb.com/apifytech
466
+ * ```
467
+ *
468
+ * If the profile URL contains subdirectories or query parameters, the regular expression
469
+ * extracts just the base part of the profile URL. For example, from text such as:
470
+ * ```
471
+ * https://www.facebook.com/apifytech/photos
472
+ * ```
473
+ * the expression extracts only the following base URL:
474
+ * ```
475
+ * https://www.facebook.com/apifytech
476
+ * ```
477
+ *
478
+ * Example usage:
479
+ * ```
480
+ * import { social } from '@crawlee/utils';
481
+ *
482
+ * const matches = text.match(social.FACEBOOK_REGEX_GLOBAL);
483
+ * if (matches) console.log(`${matches.length} Facebook profiles found!`);
484
+ * ```
485
+ */
486
+ exports.FACEBOOK_REGEX_GLOBAL = new RegExp(FACEBOOK_REGEX_STRING, 'ig');
487
+ /**
488
+ * Regular expression to exactly match a single Youtube channel, user or video URL.
489
+ * It has the following form: `/^...$/i` and matches URLs such as:
490
+ * ```
491
+ * https://www.youtube.com/watch?v=kM7YfhfkiEE
492
+ * https://youtu.be/kM7YfhfkiEE
493
+ * https://www.youtube.com/c/TrapNation
494
+ * https://www.youtube.com/channel/UCklie6BM0fhFvzWYqQVoCTA
495
+ * https://www.youtube.com/user/pewdiepie
496
+ * ```
497
+ *
498
+ * Please note that this won't match URLs like https://www.youtube.com/pewdiepie that redirect to /user or /channel.
499
+ *
500
+ * Example usage:
501
+ * ```
502
+ * import { social } from '@crawlee/utils';
503
+ *
504
+ * if (social.YOUTUBE_REGEX.test('https://www.youtube.com/watch?v=kM7YfhfkiEE')) {
505
+ * console.log('Match!');
506
+ * }
507
+ * ```
508
+ */
509
+ exports.YOUTUBE_REGEX = new RegExp(`^${YOUTUBE_REGEX_STRING}$`, 'i');
510
+ /**
511
+ * Regular expression to find multiple Youtube channel, user or video URLs in a text or HTML.
512
+ * It has the following form: `/.../ig` and matches URLs such as:
513
+ * ```
514
+ * https://www.youtube.com/watch?v=kM7YfhfkiEE
515
+ * https://youtu.be/kM7YfhfkiEE
516
+ * https://www.youtube.com/c/TrapNation
517
+ * https://www.youtube.com/channel/UCklie6BM0fhFvzWYqQVoCTA
518
+ * https://www.youtube.com/user/pewdiepie
519
+ * ```
520
+ *
521
+ * Please note that this won't match URLs like https://www.youtube.com/pewdiepie that redirect to /user or /channel.
522
+ *
523
+ * Example usage:
524
+ * ```
525
+ * import { social } from '@crawlee/utils';
526
+ *
527
+ * const matches = text.match(social.YOUTUBE_REGEX_GLOBAL);
528
+ * if (matches) console.log(`${matches.length} Youtube videos found!`);
529
+ * ```
530
+ */
531
+ exports.YOUTUBE_REGEX_GLOBAL = new RegExp(YOUTUBE_REGEX_STRING, 'ig');
532
+ /**
533
+ * Regular expression to exactly match a Tiktok video or user account.
534
+ * It has the following form: `/^...$/i` and matches URLs such as:
535
+ * ```
536
+ * https://www.tiktok.com/trending?shareId=123456789
537
+ * https://www.tiktok.com/embed/123456789
538
+ * https://m.tiktok.com/v/123456789
539
+ * https://www.tiktok.com/@user
540
+ * https://www.tiktok.com/@user-account.pro
541
+ * https://www.tiktok.com/@user/video/123456789
542
+ * ```
543
+ *
544
+ * Example usage:
545
+ * ```
546
+ * import { social } from '@crawlee/utils';
547
+ *
548
+ * if (social.TIKTOK_REGEX.test('https://www.tiktok.com/trending?shareId=123456789')) {
549
+ * console.log('Match!');
550
+ * }
551
+ * ```
552
+ */
553
+ exports.TIKTOK_REGEX = new RegExp(`^${TIKTOK_REGEX_STRING}$`, 'i');
554
+ /**
555
+ * Regular expression to find multiple Tiktok videos or user accounts in a text or HTML.
556
+ * It has the following form: `/.../ig` and matches URLs such as:
557
+ * ```
558
+ * https://www.tiktok.com/trending?shareId=123456789
559
+ * https://www.tiktok.com/embed/123456789
560
+ * https://m.tiktok.com/v/123456789
561
+ * https://www.tiktok.com/@user
562
+ * https://www.tiktok.com/@user-account.pro
563
+ * https://www.tiktok.com/@user/video/123456789
564
+ * ```
565
+ *
566
+ * Example usage:
567
+ * ```
568
+ * import { social } from '@crawlee/utils';
569
+ *
570
+ * const matches = text.match(social.TIKTOK_REGEX_GLOBAL);
571
+ * if (matches) console.log(`${matches.length} Tiktok profiles/videos found!`);
572
+ * ```
573
+ */
574
+ exports.TIKTOK_REGEX_GLOBAL = new RegExp(TIKTOK_REGEX_STRING, 'ig');
575
+ /**
576
+ * Regular expression to exactly match a Pinterest pin, user or user's board.
577
+ * It has the following form: `/^...$/i` and matches URLs such as:
578
+ * ```
579
+ * https://pinterest.com/pin/123456789
580
+ * https://www.pinterest.cz/pin/123456789
581
+ * https://www.pinterest.com/user
582
+ * https://uk.pinterest.com/user
583
+ * https://www.pinterest.co.uk/user
584
+ * pinterest.com/user_name.gold
585
+ * https://cz.pinterest.com/user/board
586
+ * ```
587
+ *
588
+ * Example usage:
589
+ * ```
590
+ * import { social } from '@crawlee/utils';
591
+ *
592
+ * if (social.PINTEREST_REGEX.test('https://pinterest.com/pin/123456789')) {
593
+ * console.log('Match!');
594
+ * }
595
+ * ```
596
+ */
597
+ exports.PINTEREST_REGEX = new RegExp(`^${PINTEREST_REGEX_STRING}$`, 'i');
598
+ /**
599
+ * Regular expression to find multiple Pinterest pins, users or boards in a text or HTML.
600
+ * It has the following form: `/.../ig` and matches URLs such as:
601
+ * ```
602
+ * https://pinterest.com/pin/123456789
603
+ * https://www.pinterest.cz/pin/123456789
604
+ * https://www.pinterest.com/user
605
+ * https://uk.pinterest.com/user
606
+ * https://www.pinterest.co.uk/user
607
+ * pinterest.com/user_name.gold
608
+ * https://cz.pinterest.com/user/board
609
+ * ```
610
+ *
611
+ * Example usage:
612
+ * ```
613
+ * import { social } from '@crawlee/utils';
614
+ *
615
+ * const matches = text.match(social.PINTEREST_REGEX_GLOBAL);
616
+ * if (matches) console.log(`${matches.length} Pinterest pins found!`);
617
+ * ```
618
+ */
619
+ exports.PINTEREST_REGEX_GLOBAL = new RegExp(PINTEREST_REGEX_STRING, 'ig');
620
+ /**
621
+ * Regular expression to exactly match a Discord invite or channel.
622
+ * It has the following form: `/^...$/i` and matches URLs such as:
623
+ * ```
624
+ * https://discord.gg/discord-developers
625
+ * https://discord.com/invite/jyEM2PRvMU
626
+ * https://discordapp.com/channels/1234
627
+ * https://discord.com/channels/1234/1234
628
+ * discord.gg/discord-developers
629
+ * ```
630
+ *
631
+ * Example usage:
632
+ * ```
633
+ * import { social } from '@crawlee/utils';
634
+ *
635
+ * if (social.DISCORD_REGEX.test('https://discord.gg/discord-developers')) {
636
+ * console.log('Match!');
637
+ * }
638
+ * ```
639
+ */
640
+ exports.DISCORD_REGEX = new RegExp(`^${DISCORD_REGEX_STRING}$`, 'i');
641
+ /**
642
+ * Regular expression to find multiple Discord channels or invites in a text or HTML.
643
+ * It has the following form: `/.../ig` and matches URLs such as:
644
+ * ```
645
+ * https://discord.gg/discord-developers
646
+ * https://discord.com/invite/jyEM2PRvMU
647
+ * https://discordapp.com/channels/1234
648
+ * https://discord.com/channels/1234/1234
649
+ * discord.gg/discord-developers
650
+ * ```
651
+ *
652
+ * Example usage:
653
+ * ```
654
+ * import { social } from '@crawlee/utils';
655
+ *
656
+ * const matches = text.match(social.DISCORD_REGEX_GLOBAL);
657
+ * if (matches) console.log(`${matches.length} Discord channels found!`);
658
+ * ```
659
+ */
660
+ exports.DISCORD_REGEX_GLOBAL = new RegExp(DISCORD_REGEX_STRING, 'ig');
661
+ //# sourceMappingURL=social.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"social.js","sourceRoot":"","sources":["../../src/internals/social.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /** @ignore */
2
+ export declare type Dictionary<T = unknown> = Record<PropertyKey, T>;
3
+ /** @ignore */
4
+ export declare type Constructor<T = unknown> = new (...args: any[]) => T;
5
+ /** @ignore */
6
+ export declare type Awaitable<T> = T | PromiseLike<T>;
7
+ /** @ignore */
8
+ export declare function entries<T extends {}>(obj: T): [keyof T, T[keyof T]][];
9
+ /** @ignore */
10
+ export declare function keys<T extends {}>(obj: T): (keyof T)[];
11
+ //# sourceMappingURL=typedefs.d.ts.map