linkedin-api-voyager 1.1.0 → 1.3.1

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.
package/lib/utils.js CHANGED
@@ -1,4 +1,6 @@
1
1
  "use strict";
2
+ /* eslint-disable prefer-const */
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
4
  var __rest = (this && this.__rest) || function (s, e) {
3
5
  var t = {};
4
6
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -11,6 +13,7 @@ var __rest = (this && this.__rest) || function (s, e) {
11
13
  return t;
12
14
  };
13
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.omit = exports.getDataIncludedForEntity = void 0;
14
17
  exports.filterKeys = filterKeys;
15
18
  exports.filterOutKeys = filterOutKeys;
16
19
  exports.getNestedValue = getNestedValue;
@@ -21,6 +24,17 @@ exports.extractDataWithReferences = extractDataWithReferences;
21
24
  exports.debugResolvedStructure = debugResolvedStructure;
22
25
  exports.extractFieldsFromIncluded = extractFieldsFromIncluded;
23
26
  exports.mergeExtraFields = mergeExtraFields;
27
+ exports.extractExperiences = extractExperiences;
28
+ exports.assert = assert;
29
+ exports.getIdFromUrn = getIdFromUrn;
30
+ exports.getUrnFromRawUpdate = getUrnFromRawUpdate;
31
+ exports.isLinkedInUrn = isLinkedInUrn;
32
+ exports.parseExperienceItem = parseExperienceItem;
33
+ exports.getGroupedItemId = getGroupedItemId;
34
+ exports.resolveImageUrl = resolveImageUrl;
35
+ exports.resolveLinkedVectorImageUrl = resolveLinkedVectorImageUrl;
36
+ exports.stringifyLinkedInDate = stringifyLinkedInDate;
37
+ exports.normalizeRawOrganization = normalizeRawOrganization;
24
38
  function filterKeys(obj, keysToKeep) {
25
39
  const filteredObject = {};
26
40
  keysToKeep.forEach((key) => {
@@ -41,12 +55,12 @@ function filterOutKeys(obj, keysToIgnore) {
41
55
  }
42
56
  // Nova função para extrair valores de caminhos aninhados
43
57
  function getNestedValue(obj, path) {
44
- return path.split('.').reduce((current, key) => {
58
+ return path.split(".").reduce((current, key) => {
45
59
  var _a;
46
60
  // Lidar com arrays como attributes[0]
47
- if (key.includes('[') && key.includes(']')) {
48
- const [arrayKey, indexStr] = key.split('[');
49
- const index = parseInt(indexStr.replace(']', ''));
61
+ if (key.includes("[") && key.includes("]")) {
62
+ const [arrayKey, indexStr] = key.split("[");
63
+ const index = parseInt(indexStr.replace("]", ""));
50
64
  return (_a = current === null || current === void 0 ? void 0 : current[arrayKey]) === null || _a === void 0 ? void 0 : _a[index];
51
65
  }
52
66
  return current === null || current === void 0 ? void 0 : current[key];
@@ -54,7 +68,7 @@ function getNestedValue(obj, path) {
54
68
  }
55
69
  // Nova função melhorada para filtrar com caminhos aninhados
56
70
  function extractFields(data, fieldsMap) {
57
- return data.map(item => {
71
+ return data === null || data === void 0 ? void 0 : data.map((item) => {
58
72
  const extracted = {};
59
73
  Object.entries(fieldsMap).forEach(([newKey, path]) => {
60
74
  const value = getNestedValue(item, path);
@@ -69,7 +83,7 @@ function extractFields(data, fieldsMap) {
69
83
  function debugObjectStructure(obj, maxDepth = 3, currentDepth = 0) {
70
84
  if (currentDepth >= maxDepth)
71
85
  return;
72
- const indent = ' '.repeat(currentDepth);
86
+ const indent = " ".repeat(currentDepth);
73
87
  if (Array.isArray(obj)) {
74
88
  console.log(`${indent}Array[${obj.length}]:`);
75
89
  if (obj.length > 0) {
@@ -77,10 +91,12 @@ function debugObjectStructure(obj, maxDepth = 3, currentDepth = 0) {
77
91
  debugObjectStructure(obj[0], maxDepth, currentDepth + 2);
78
92
  }
79
93
  }
80
- else if (obj && typeof obj === 'object') {
81
- Object.keys(obj).slice(0, 10).forEach(key => {
94
+ else if (obj && typeof obj === "object") {
95
+ Object.keys(obj)
96
+ .slice(0, 10)
97
+ .forEach((key) => {
82
98
  const value = obj[key];
83
- if (typeof value === 'object' && value !== null) {
99
+ if (typeof value === "object" && value !== null) {
84
100
  console.log(`${indent}${key}:`);
85
101
  debugObjectStructure(value, maxDepth, currentDepth + 1);
86
102
  }
@@ -96,7 +112,7 @@ function resolveReferences(data, included) {
96
112
  return data;
97
113
  // Criar um mapa de URN para acesso rápido
98
114
  const urnMap = new Map();
99
- included.forEach(item => {
115
+ included.forEach((item) => {
100
116
  if (item.entityUrn) {
101
117
  urnMap.set(item.entityUrn, item);
102
118
  }
@@ -104,13 +120,13 @@ function resolveReferences(data, included) {
104
120
  // Função recursiva para resolver referências
105
121
  function resolveObject(obj) {
106
122
  if (Array.isArray(obj)) {
107
- return obj.map(item => resolveObject(item));
123
+ return obj.map((item) => resolveObject(item));
108
124
  }
109
- if (obj && typeof obj === 'object') {
125
+ if (obj && typeof obj === "object") {
110
126
  const resolved = {};
111
127
  Object.entries(obj).forEach(([key, value]) => {
112
128
  // Detectar chaves que começam com * (referências URN)
113
- if (key.startsWith('*') && typeof value === 'string') {
129
+ if (key.startsWith("*") && typeof value === "string") {
114
130
  const referencedData = urnMap.get(value);
115
131
  if (referencedData) {
116
132
  // Remover o * e usar como chave
@@ -122,15 +138,20 @@ function resolveReferences(data, included) {
122
138
  }
123
139
  }
124
140
  // Detectar arrays de URNs
125
- else if (Array.isArray(value) && value.length > 0 && typeof value[0] === 'string' && value[0].startsWith('urn:li:')) {
126
- const resolvedArray = value.map(urn => {
141
+ else if (Array.isArray(value) &&
142
+ value.length > 0 &&
143
+ typeof value[0] === "string" &&
144
+ value[0].startsWith("urn:li:")) {
145
+ const resolvedArray = value
146
+ .map((urn) => {
127
147
  const referencedData = urnMap.get(urn);
128
148
  return referencedData ? resolveObject(referencedData) : urn;
129
- }).filter(item => item !== null);
149
+ })
150
+ .filter((item) => item !== null);
130
151
  resolved[key] = resolvedArray;
131
152
  }
132
153
  // Recursão para objetos aninhados
133
- else if (value && typeof value === 'object') {
154
+ else if (value && typeof value === "object") {
134
155
  resolved[key] = resolveObject(value);
135
156
  }
136
157
  // Valores primitivos
@@ -147,9 +168,9 @@ function resolveReferences(data, included) {
147
168
  // Função para extrair dados com resolução automática de referências
148
169
  function extractDataWithReferences(elements, included, fieldsMap) {
149
170
  // Filtrar dados pelos elementos
150
- const filteredData = included.filter(item => elements.includes(item.entityUrn));
171
+ const filteredData = included.filter((item) => elements.includes(item.entityUrn));
151
172
  // Resolver todas as referências
152
- const resolvedData = filteredData.map(item => resolveReferences(item, included));
173
+ const resolvedData = filteredData.map((item) => resolveReferences(item, included));
153
174
  // Se há mapeamento de campos, aplicar
154
175
  if (fieldsMap) {
155
176
  return extractFields(resolvedData, fieldsMap);
@@ -158,21 +179,21 @@ function extractDataWithReferences(elements, included, fieldsMap) {
158
179
  }
159
180
  // Função para debug de estrutura com referências resolvidas
160
181
  function debugResolvedStructure(elements, included, maxDepth = 2) {
161
- console.log('🔍 Estrutura dos dados com referências resolvidas:');
182
+ console.log("🔍 Estrutura dos dados com referências resolvidas:");
162
183
  const resolved = extractDataWithReferences(elements, included);
163
184
  if (resolved.length > 0) {
164
185
  console.log(`📊 Total de itens: ${resolved.length}`);
165
- console.log('📋 Estrutura do primeiro item:');
186
+ console.log("📋 Estrutura do primeiro item:");
166
187
  debugObjectStructure(resolved[0], maxDepth);
167
188
  }
168
189
  }
169
190
  // Função para extrair campos específicos de todos os objetos no included
170
191
  function extractFieldsFromIncluded(included, fields) {
171
192
  return included
172
- .filter(item => fields.some(field => item[field] !== undefined))
173
- .map(item => {
193
+ .filter((item) => fields.some((field) => item[field] !== undefined))
194
+ .map((item) => {
174
195
  const extracted = { entityUrn: item.entityUrn };
175
- fields.forEach(field => {
196
+ fields.forEach((field) => {
176
197
  if (item[field] !== undefined) {
177
198
  extracted[field] = item[field];
178
199
  }
@@ -181,9 +202,9 @@ function extractFieldsFromIncluded(included, fields) {
181
202
  });
182
203
  }
183
204
  // Função para associar dados extras aos dados principais
184
- function mergeExtraFields(mainData, extraData, matchKey = 'companyUrn') {
185
- return mainData.map(item => {
186
- const extraItem = extraData.find(extra => item[matchKey] && extra.entityUrn === item[matchKey]);
205
+ function mergeExtraFields(mainData, extraData, matchKey = "companyUrn") {
206
+ return mainData.map((item) => {
207
+ const extraItem = extraData.find((extra) => item[matchKey] && extra.entityUrn === item[matchKey]);
187
208
  if (extraItem) {
188
209
  const { entityUrn } = extraItem, extraFields = __rest(extraItem, ["entityUrn"]);
189
210
  return Object.assign(Object.assign({}, item), extraFields);
@@ -191,3 +212,395 @@ function mergeExtraFields(mainData, extraData, matchKey = 'companyUrn') {
191
212
  return item;
192
213
  });
193
214
  }
215
+ const getDataIncludedForEntity = (jsonData, entityUrn) => {
216
+ const data = jsonData === null || jsonData === void 0 ? void 0 : jsonData.included;
217
+ if (data.length) {
218
+ const dataEntityUrn = data.find((item) => item.entityUrn.toLowerCase().includes(entityUrn.toLowerCase()));
219
+ return dataEntityUrn;
220
+ }
221
+ return [];
222
+ };
223
+ exports.getDataIncludedForEntity = getDataIncludedForEntity;
224
+ function extractExperiences(jsonData) {
225
+ var _a, _b, _c, _d, _e, _f;
226
+ const experiences = [];
227
+ try {
228
+ const included = (_a = jsonData === null || jsonData === void 0 ? void 0 : jsonData.included) !== null && _a !== void 0 ? _a : [];
229
+ if (!included.length) {
230
+ console.warn("[PROFILE] No 'included' array found");
231
+ return experiences;
232
+ }
233
+ // ===== PASS 1: Build component map by URN =====
234
+ console.info(`[PROFILE] Pass 1: Building component map from ${included.length} items`);
235
+ const componentMap = {};
236
+ for (const item of included) {
237
+ const urn = item === null || item === void 0 ? void 0 : item.entityUrn;
238
+ if (urn)
239
+ componentMap[urn] = item;
240
+ }
241
+ console.info(`[PROFILE] Pass 1: Indexed ${Object.keys(componentMap).length} components by URN`);
242
+ // ===== PASS 2: Find anchor and traverse =====
243
+ let mainExperienceUrn = null;
244
+ for (const urn of Object.keys(componentMap)) {
245
+ if (urn.includes("EXPERIENCE_VIEW_DETAILS") &&
246
+ urn.includes("fsd_profile:")) {
247
+ mainExperienceUrn = urn;
248
+ console.info(`[PROFILE] Pass 2: Found main experience anchor: ${urn}`);
249
+ break;
250
+ }
251
+ }
252
+ if (!mainExperienceUrn) {
253
+ console.warn("[PROFILE] Pass 2: No experience anchor found");
254
+ return experiences;
255
+ }
256
+ const mainList = componentMap[mainExperienceUrn];
257
+ if (!mainList) {
258
+ console.error("[PROFILE] Pass 2: Anchor URN not in map (shouldn't happen)");
259
+ return experiences;
260
+ }
261
+ let elements = (_d = (_b = mainList.elements) !== null && _b !== void 0 ? _b : (_c = mainList.components) === null || _c === void 0 ? void 0 : _c.elements) !== null && _d !== void 0 ? _d : [];
262
+ console.info(`[PROFILE] Pass 2: Found ${elements.length} experience blocks`);
263
+ const paging = (_e = mainList.paging) !== null && _e !== void 0 ? _e : (_f = mainList.components) === null || _f === void 0 ? void 0 : _f.paging;
264
+ if (paging) {
265
+ const { total = "unknown", count = "unknown", start = 0 } = paging;
266
+ console.warn(`[PROFILE] PAGINATION: ${count} of ${total} experiences (start: ${start})`);
267
+ }
268
+ if (!elements.length) {
269
+ console.warn("[PROFILE] Pass 2: No elements in main list");
270
+ return experiences;
271
+ }
272
+ // Step 4: Process each experience block
273
+ elements.forEach((elem, idx) => {
274
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
275
+ try {
276
+ if (typeof elem !== "object" || elem === null)
277
+ return;
278
+ const entity = (_a = elem === null || elem === void 0 ? void 0 : elem.components) === null || _a === void 0 ? void 0 : _a.entityComponent;
279
+ if (typeof entity !== "object" || !entity) {
280
+ console.debug(`[PROFILE] Element ${idx}: No entityComponent`);
281
+ return;
282
+ }
283
+ // Detect nested grouped roles (company with multiple positions)
284
+ let nestedUrn = null;
285
+ const subCompsWrapper = entity.subComponents;
286
+ if (typeof subCompsWrapper === "object" && subCompsWrapper) {
287
+ const subComponents = subCompsWrapper.components;
288
+ if (Array.isArray(subComponents) && subComponents.length > 0) {
289
+ const firstSub = subComponents[0];
290
+ const subComps = firstSub === null || firstSub === void 0 ? void 0 : firstSub.components;
291
+ if (typeof subComps === "object" && subComps) {
292
+ for (const key of ["*pagedListComponent", "pagedListComponent"]) {
293
+ const value = subComps[key];
294
+ if (value) {
295
+ nestedUrn =
296
+ typeof value === "string"
297
+ ? value
298
+ : ((_b = value === null || value === void 0 ? void 0 : value.entityUrn) !== null && _b !== void 0 ? _b : null);
299
+ if (nestedUrn)
300
+ break;
301
+ }
302
+ }
303
+ if (!nestedUrn) {
304
+ for (const [key, value] of Object.entries(subComps)) {
305
+ if (key.toLowerCase().includes("pagedlistcomponent") &&
306
+ value) {
307
+ nestedUrn =
308
+ typeof value === "string"
309
+ ? value
310
+ : ((_c = value === null || value === void 0 ? void 0 : value.entityUrn) !== null && _c !== void 0 ? _c : null);
311
+ if (nestedUrn)
312
+ break;
313
+ }
314
+ }
315
+ }
316
+ }
317
+ }
318
+ }
319
+ if (nestedUrn) {
320
+ // GROUPED ENTRY (company with multiple roles)
321
+ let companyName = "";
322
+ const titleV2 = entity.titleV2;
323
+ if (titleV2 && typeof titleV2 === "object") {
324
+ const textObj = titleV2.text;
325
+ companyName =
326
+ typeof textObj === "string" ? textObj : ((_d = textObj === null || textObj === void 0 ? void 0 : textObj.text) !== null && _d !== void 0 ? _d : "");
327
+ }
328
+ let totalDuration = "";
329
+ const subtitle = entity.subtitle;
330
+ if (subtitle && typeof subtitle === "object") {
331
+ const textObj = subtitle.text;
332
+ totalDuration =
333
+ typeof textObj === "string" ? textObj : ((_e = textObj === null || textObj === void 0 ? void 0 : textObj.text) !== null && _e !== void 0 ? _e : "");
334
+ }
335
+ console.info(`[PROFILE] Element ${idx}: Grouped company '${companyName}' (${totalDuration})`);
336
+ const nestedList = componentMap[nestedUrn];
337
+ if (nestedList) {
338
+ const nestedElements = (_h = (_f = nestedList.elements) !== null && _f !== void 0 ? _f : (_g = nestedList.components) === null || _g === void 0 ? void 0 : _g.elements) !== null && _h !== void 0 ? _h : [];
339
+ console.info(`[PROFILE] Found ${nestedElements.length} roles for '${companyName}'`);
340
+ for (const [roleIdx, roleElem] of nestedElements.entries()) {
341
+ const roleEntity = (_j = roleElem === null || roleElem === void 0 ? void 0 : roleElem.components) === null || _j === void 0 ? void 0 : _j.entityComponent;
342
+ if (roleEntity && typeof roleEntity === "object") {
343
+ const exp = extractOneExperience(roleEntity, companyName);
344
+ if (exp) {
345
+ console.debug(`[PROFILE] Extracted role ${roleIdx + 1}/${nestedElements.length}: ${exp.role} at ${companyName}`);
346
+ experiences.push(exp);
347
+ }
348
+ }
349
+ }
350
+ }
351
+ else {
352
+ console.warn(`[PROFILE] Nested URN not found in map: ${nestedUrn}`);
353
+ }
354
+ // Continue to next element without extracting parent
355
+ return;
356
+ }
357
+ // SINGLE ENTRY
358
+ const titleV2 = entity.titleV2;
359
+ const caption = entity.caption;
360
+ if (titleV2 && !caption) {
361
+ console.warn(`[PROFILE] Element ${idx}: Skipping potential parent block`);
362
+ return;
363
+ }
364
+ const exp = extractOneExperience(entity);
365
+ if (exp)
366
+ experiences.push(exp);
367
+ }
368
+ catch (err) {
369
+ console.warn(`[PROFILE] Error on element ${idx}: ${err.message}`);
370
+ }
371
+ });
372
+ console.info(`[PROFILE] Successfully extracted ${experiences.length} total experiences`);
373
+ }
374
+ catch (err) {
375
+ console.error(`[PROFILE] Fatal error: ${err.message}`);
376
+ }
377
+ return experiences;
378
+ }
379
+ // Helper function
380
+ function extractOneExperience(entity, companyOverride) {
381
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
382
+ if (!entity || typeof entity !== "object")
383
+ return null;
384
+ const safeGetText = (obj, ...keys) => {
385
+ var _a;
386
+ let current = obj;
387
+ for (const key of keys) {
388
+ if (typeof current !== "object" || current === null)
389
+ return "";
390
+ current = current[key];
391
+ if (current === undefined || current === null)
392
+ return "";
393
+ }
394
+ return typeof current === "string" ? current : ((_a = current === null || current === void 0 ? void 0 : current.text) !== null && _a !== void 0 ? _a : "");
395
+ };
396
+ const title = safeGetText(entity, "titleV2", "text", "text");
397
+ const idCompany = ((_b = (_a = safeGetText(entity, "textActionTarget")) === null || _a === void 0 ? void 0 : _a.match(/\/(\d+)\/?$/)) === null || _b === void 0 ? void 0 : _b[1]) || null;
398
+ if (!title)
399
+ return null;
400
+ let company = companyOverride !== null && companyOverride !== void 0 ? companyOverride : "";
401
+ if (!company) {
402
+ const subtitle = entity.subtitle;
403
+ if (subtitle && typeof subtitle === "object") {
404
+ company =
405
+ typeof subtitle.text === "string"
406
+ ? subtitle.text
407
+ : ((_d = (_c = subtitle.text) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : "");
408
+ }
409
+ }
410
+ let dates = "";
411
+ const caption = entity.caption;
412
+ if (caption && typeof caption === "object") {
413
+ dates =
414
+ typeof caption.text === "string"
415
+ ? caption.text
416
+ : ((_f = (_e = caption.text) === null || _e === void 0 ? void 0 : _e.text) !== null && _f !== void 0 ? _f : "");
417
+ }
418
+ let location = "";
419
+ const metadata = entity.metadata;
420
+ if (metadata && typeof metadata === "object") {
421
+ location =
422
+ typeof metadata.text === "string"
423
+ ? metadata.text
424
+ : ((_h = (_g = metadata.text) === null || _g === void 0 ? void 0 : _g.text) !== null && _h !== void 0 ? _h : "");
425
+ }
426
+ let description = "";
427
+ try {
428
+ const subcomps = entity.subComponents;
429
+ const components = subcomps === null || subcomps === void 0 ? void 0 : subcomps.components;
430
+ if (Array.isArray(components)) {
431
+ for (const sc of components) {
432
+ const scComps = sc === null || sc === void 0 ? void 0 : sc.components;
433
+ const fixed = scComps === null || scComps === void 0 ? void 0 : scComps.fixedListComponent;
434
+ const fixedComps = fixed === null || fixed === void 0 ? void 0 : fixed.components;
435
+ if (Array.isArray(fixedComps)) {
436
+ for (const fc of fixedComps) {
437
+ const txtComp = (_j = fc === null || fc === void 0 ? void 0 : fc.components) === null || _j === void 0 ? void 0 : _j.textComponent;
438
+ const txt = safeGetText(txtComp, "text", "text");
439
+ if (txt) {
440
+ description = txt;
441
+ break;
442
+ }
443
+ }
444
+ }
445
+ if (description)
446
+ break;
447
+ }
448
+ }
449
+ }
450
+ catch (err) {
451
+ console.debug(`[PROFILE] Error extracting description: ${err.message}`);
452
+ }
453
+ const result = {
454
+ role: title,
455
+ idCompany,
456
+ company: company || null,
457
+ time_duration: dates || "",
458
+ location: location || "",
459
+ description: description || null,
460
+ };
461
+ if (dates.includes("·")) {
462
+ const parts = dates.split("·");
463
+ result.time_period = parts[0].trim();
464
+ if (parts[1])
465
+ result.duration = parts[1].trim();
466
+ }
467
+ console.info(`[PROFILE] ✓ ${title} at ${company || null}`);
468
+ return result;
469
+ }
470
+ function assert(value, message) {
471
+ if (value) {
472
+ return;
473
+ }
474
+ if (!message) {
475
+ throw new Error("Assertion failed");
476
+ }
477
+ throw typeof message === "string" ? new Error(message) : message;
478
+ }
479
+ function getIdFromUrn(urn) {
480
+ return urn === null || urn === void 0 ? void 0 : urn.split(":").at(-1);
481
+ }
482
+ /**
483
+ * Return the URN of a raw group update
484
+ *
485
+ * Example: urn:li:fs_miniProfile:<id>
486
+ * Example: urn:li:fs_updateV2:(<urn>,GROUP_FEED,EMPTY,DEFAULT,false)
487
+ */
488
+ function getUrnFromRawUpdate(update) {
489
+ var _a, _b;
490
+ return (_b = (_a = update === null || update === void 0 ? void 0 : update.split("(")[1]) === null || _a === void 0 ? void 0 : _a.split(",").at(0)) === null || _b === void 0 ? void 0 : _b.trim();
491
+ }
492
+ function isLinkedInUrn(urn) {
493
+ return (urn === null || urn === void 0 ? void 0 : urn.startsWith("urn:li:")) && urn.split(":").length >= 4;
494
+ }
495
+ function parseExperienceItem(item, { isGroupItem = false, included }) {
496
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
497
+ const component = item.components.entityComponent;
498
+ const title = component.titleV2.text.text;
499
+ const subtitle = component.subtitle;
500
+ const subtitleParts = (_a = subtitle === null || subtitle === void 0 ? void 0 : subtitle.text) === null || _a === void 0 ? void 0 : _a.split(" · ");
501
+ const company = subtitleParts === null || subtitleParts === void 0 ? void 0 : subtitleParts[0];
502
+ const employmentType = subtitleParts === null || subtitleParts === void 0 ? void 0 : subtitleParts[1];
503
+ const companyId = (_e = getIdFromUrn((_d = (_c = (_b = component.image) === null || _b === void 0 ? void 0 : _b.attributes) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d["*companyLogo"])) !== null && _e !== void 0 ? _e : (_g = (_f = component.image) === null || _f === void 0 ? void 0 : _f.actionTarget) === null || _g === void 0 ? void 0 : _g.split("/").findLast(Boolean);
504
+ const companyUrn = companyId ? `urn:li:fsd_company:${companyId}` : undefined;
505
+ let companyImage;
506
+ if (companyId) {
507
+ const companyEntity = included.find((i) => { var _a; return (_a = i.entityUrn) === null || _a === void 0 ? void 0 : _a.endsWith(companyId); });
508
+ if (companyEntity) {
509
+ companyImage = resolveImageUrl((_h = companyEntity.logoResolutionResult) === null || _h === void 0 ? void 0 : _h.vectorImage);
510
+ }
511
+ }
512
+ const metadata = (component === null || component === void 0 ? void 0 : component.metadata) || {};
513
+ const location = metadata === null || metadata === void 0 ? void 0 : metadata.text;
514
+ const durationText = (_j = component.caption) === null || _j === void 0 ? void 0 : _j.text;
515
+ const durationParts = durationText === null || durationText === void 0 ? void 0 : durationText.split(" · ");
516
+ const dateParts = (_k = durationParts === null || durationParts === void 0 ? void 0 : durationParts[0]) === null || _k === void 0 ? void 0 : _k.split(" - ");
517
+ const duration = durationParts === null || durationParts === void 0 ? void 0 : durationParts[1];
518
+ const startDate = dateParts === null || dateParts === void 0 ? void 0 : dateParts[0];
519
+ const endDate = dateParts === null || dateParts === void 0 ? void 0 : dateParts[1];
520
+ const subComponents = component.subComponents;
521
+ const fixedListComponent = (_o = (_m = (_l = subComponents === null || subComponents === void 0 ? void 0 : subComponents.components) === null || _l === void 0 ? void 0 : _l[0]) === null || _m === void 0 ? void 0 : _m.components) === null || _o === void 0 ? void 0 : _o.fixedListComponent;
522
+ const fixedListTextComponent = (_r = (_q = (_p = fixedListComponent === null || fixedListComponent === void 0 ? void 0 : fixedListComponent.components) === null || _p === void 0 ? void 0 : _p[0]) === null || _q === void 0 ? void 0 : _q.components) === null || _r === void 0 ? void 0 : _r.textComponent;
523
+ const description = (_s = fixedListTextComponent === null || fixedListTextComponent === void 0 ? void 0 : fixedListTextComponent.text) === null || _s === void 0 ? void 0 : _s.text;
524
+ const parsedData = {
525
+ title,
526
+ companyName: !isGroupItem ? company : undefined,
527
+ employmentType: isGroupItem ? company : employmentType,
528
+ location,
529
+ duration,
530
+ startDate,
531
+ endDate,
532
+ description,
533
+ company: {
534
+ entityUrn: companyUrn,
535
+ id: companyId,
536
+ name: !isGroupItem ? company : undefined,
537
+ logo: companyImage,
538
+ },
539
+ };
540
+ return parsedData;
541
+ }
542
+ function getGroupedItemId(item) {
543
+ var _a, _b, _c, _d;
544
+ const subComponents = (_b = (_a = item.components) === null || _a === void 0 ? void 0 : _a.entityComponent) === null || _b === void 0 ? void 0 : _b.subComponents;
545
+ const subComponentsComponents = (_d = (_c = subComponents === null || subComponents === void 0 ? void 0 : subComponents.components) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.components;
546
+ const pagedListComponentId = subComponentsComponents === null || subComponentsComponents === void 0 ? void 0 : subComponentsComponents["*pagedListComponent"];
547
+ if (pagedListComponentId === null || pagedListComponentId === void 0 ? void 0 : pagedListComponentId.includes("fsd_profilePositionGroup")) {
548
+ const pattern = /urn:li:fsd_profilePositionGroup:\([\dA-z]+,[\dA-z]+\)/;
549
+ const match = pagedListComponentId.match(pattern);
550
+ return match === null || match === void 0 ? void 0 : match[0];
551
+ }
552
+ return undefined;
553
+ }
554
+ const omit = (inputObj, ...keys) => {
555
+ const keysSet = new Set(keys);
556
+ return Object.fromEntries(Object.entries(inputObj).filter(([k]) => !keysSet.has(k)));
557
+ };
558
+ exports.omit = omit;
559
+ function resolveImageUrl(vectorImage) {
560
+ var _a, _b;
561
+ if (!(vectorImage === null || vectorImage === void 0 ? void 0 : vectorImage.rootUrl))
562
+ return;
563
+ if (!((_a = vectorImage.artifacts) === null || _a === void 0 ? void 0 : _a.length))
564
+ return;
565
+ const largestArtifact = vectorImage.artifacts.reduce((a, b) => {
566
+ if (b.width > a.width)
567
+ return b;
568
+ return a;
569
+ }, (_b = vectorImage.artifacts[0]) !== null && _b !== void 0 ? _b : { width: 0, height: 0 });
570
+ if (!(largestArtifact === null || largestArtifact === void 0 ? void 0 : largestArtifact.fileIdentifyingUrlPathSegment))
571
+ return;
572
+ return `${vectorImage.rootUrl}${largestArtifact.fileIdentifyingUrlPathSegment}`;
573
+ }
574
+ function resolveLinkedVectorImageUrl(linkedVectorImage) {
575
+ return resolveImageUrl(linkedVectorImage === null || linkedVectorImage === void 0 ? void 0 : linkedVectorImage["com.linkedin.common.VectorImage"]);
576
+ }
577
+ function stringifyLinkedInDate(date) {
578
+ if (!date)
579
+ return undefined;
580
+ if (date.year === undefined)
581
+ return undefined;
582
+ return [date.year, date.month].filter(Boolean).join("-");
583
+ }
584
+ function normalizeRawOrganization(o) {
585
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
586
+ assert(o, "Missing organization");
587
+ assert(o.entityUrn, "Invalid organization: missing entityUrn");
588
+ const id = getIdFromUrn(o.entityUrn);
589
+ assert(id, `Invalid organization ID: ${o.entityUrn}`);
590
+ return Object.assign(Object.assign({}, (0, exports.omit)(o, "universalName", "logo", "backgroundCoverImage", "coverPhoto", "overviewPhoto", "$recipeType", "callToAction", "phone", "permissions", "followingInfo", "adsRule", "autoGenerated", "lcpTreatment", "staffingCompany", "showcase", "paidCompany", "claimable", "claimableByViewer", "viewerPendingAdministrator", "viewerConnectedToAdministrator", "viewerFollowingJobsUpdates", "viewerEmployee", "associatedHashtags", "associatedHashtagsResolutionResults", "affiliatedCompaniesResolutionResults", "groupsResolutionResults", "showcasePagesResolutionResults")), { id, publicIdentifier: o.universalName, logo: resolveLinkedVectorImageUrl((_a = o.logo) === null || _a === void 0 ? void 0 : _a.image), backgroundCoverImage: resolveLinkedVectorImageUrl((_b = o.backgroundCoverImage) === null || _b === void 0 ? void 0 : _b.image), coverPhoto: (_d = (_c = o.coverPhoto) === null || _c === void 0 ? void 0 : _c["com.linkedin.voyager.common.MediaProcessorImage"]) === null || _d === void 0 ? void 0 : _d.id, overviewPhoto: (_f = (_e = o.overviewPhoto) === null || _e === void 0 ? void 0 : _e["com.linkedin.voyager.common.MediaProcessorImage"]) === null || _f === void 0 ? void 0 : _f.id, callToActionUrl: (_g = o.callToAction) === null || _g === void 0 ? void 0 : _g.url, phone: (_h = o.phone) === null || _h === void 0 ? void 0 : _h.number, numFollowers: (_j = o.followingInfo) === null || _j === void 0 ? void 0 : _j.followerCount, affiliatedCompaniesResolutionResults: Object.fromEntries(Object.entries((_k = o.affiliatedCompaniesResolutionResults) !== null && _k !== void 0 ? _k : {}).map(([k, v]) => {
591
+ var _a, _b;
592
+ return [
593
+ k,
594
+ Object.assign(Object.assign({}, (0, exports.omit)(v, "universalName", "logo", "$recipeType", "followingInfo", "showcase", "paidCompany")), { id: getIdFromUrn(v.entityUrn), publicIdentifier: v.universalName, numFollowers: (_a = v.followingInfo) === null || _a === void 0 ? void 0 : _a.followerCount, logo: resolveLinkedVectorImageUrl((_b = v.logo) === null || _b === void 0 ? void 0 : _b.image) }),
595
+ ];
596
+ })), groupsResolutionResults: Object.fromEntries(Object.entries((_l = o.groupsResolutionResults) !== null && _l !== void 0 ? _l : {}).map(([k, v]) => [
597
+ k,
598
+ Object.assign(Object.assign({}, (0, exports.omit)(v, "logo", "$recipeType")), { id: getIdFromUrn(v.entityUrn), logo: resolveLinkedVectorImageUrl(v.logo) }),
599
+ ])), showcasePagesResolutionResults: Object.fromEntries(Object.entries((_m = o.showcasePagesResolutionResults) !== null && _m !== void 0 ? _m : {}).map(([k, v]) => {
600
+ var _a, _b;
601
+ return [
602
+ k,
603
+ Object.assign(Object.assign({}, (0, exports.omit)(v, "universalName", "logo", "$recipeType", "followingInfo", "showcase", "paidCompany")), { id: getIdFromUrn(v.entityUrn), publicIdentifier: v.universalName, numFollowers: (_a = v.followingInfo) === null || _a === void 0 ? void 0 : _a.followerCount, logo: resolveLinkedVectorImageUrl((_b = v.logo) === null || _b === void 0 ? void 0 : _b.image) }),
604
+ ];
605
+ })) });
606
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "linkedin-api-voyager",
3
- "version": "1.1.0",
3
+ "version": "1.3.1",
4
4
  "description": "Uma biblioteca TypeScript para interagir com a API interna do LinkedIn (Voyager)",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -11,7 +11,7 @@
11
11
  "scripts": {
12
12
  "build": "tsc",
13
13
  "prepare": "npm run build",
14
- "dev": "nodemon src/index.ts",
14
+ "dev": "nodemon src/teste.ts",
15
15
  "prepublishOnly": "npm run build"
16
16
  },
17
17
  "devDependencies": {
@@ -23,6 +23,7 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "axios": "^1.11.0",
26
- "fs-extra": "^11.3.1"
26
+ "fs-extra": "^11.3.1",
27
+ "path": "^0.12.7"
27
28
  }
28
29
  }
package/lib/account.d.ts DELETED
@@ -1,18 +0,0 @@
1
- export declare const getProfile: (identifier: string) => Promise<{
2
- publicIdentifier: any;
3
- firstName: any;
4
- lastName: any;
5
- fullName: string;
6
- birthDate: string | null;
7
- profilePicture: string | null;
8
- backgroundPicture: string | null;
9
- location: {
10
- country: any;
11
- city: any;
12
- };
13
- address: any;
14
- industry: any;
15
- headline: any;
16
- summary: any;
17
- }>;
18
- export declare const getProfissionalExperiences: (identifier: string) => Promise<any[]>;