linkedin-api-voyager 1.3.0 → 1.3.2

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 ADDED
@@ -0,0 +1,606 @@
1
+ "use strict";
2
+ /* eslint-disable prefer-const */
3
+ /* eslint-disable @typescript-eslint/no-explicit-any */
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.omit = exports.getDataIncludedForEntity = void 0;
17
+ exports.filterKeys = filterKeys;
18
+ exports.filterOutKeys = filterOutKeys;
19
+ exports.getNestedValue = getNestedValue;
20
+ exports.extractFields = extractFields;
21
+ exports.debugObjectStructure = debugObjectStructure;
22
+ exports.resolveReferences = resolveReferences;
23
+ exports.extractDataWithReferences = extractDataWithReferences;
24
+ exports.debugResolvedStructure = debugResolvedStructure;
25
+ exports.extractFieldsFromIncluded = extractFieldsFromIncluded;
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;
38
+ function filterKeys(obj, keysToKeep) {
39
+ const filteredObject = {};
40
+ keysToKeep.forEach((key) => {
41
+ if (obj.hasOwnProperty(key)) {
42
+ filteredObject[key] = obj[key];
43
+ }
44
+ });
45
+ return filteredObject;
46
+ }
47
+ function filterOutKeys(obj, keysToIgnore) {
48
+ const filteredObject = {};
49
+ Object.keys(obj).forEach((key) => {
50
+ if (!keysToIgnore.includes(key)) {
51
+ filteredObject[key] = obj[key];
52
+ }
53
+ });
54
+ return filteredObject;
55
+ }
56
+ // Nova função para extrair valores de caminhos aninhados
57
+ function getNestedValue(obj, path) {
58
+ return path.split(".").reduce((current, key) => {
59
+ var _a;
60
+ // Lidar com arrays como attributes[0]
61
+ if (key.includes("[") && key.includes("]")) {
62
+ const [arrayKey, indexStr] = key.split("[");
63
+ const index = parseInt(indexStr.replace("]", ""));
64
+ return (_a = current === null || current === void 0 ? void 0 : current[arrayKey]) === null || _a === void 0 ? void 0 : _a[index];
65
+ }
66
+ return current === null || current === void 0 ? void 0 : current[key];
67
+ }, obj);
68
+ }
69
+ // Nova função melhorada para filtrar com caminhos aninhados
70
+ function extractFields(data, fieldsMap) {
71
+ return data === null || data === void 0 ? void 0 : data.map((item) => {
72
+ const extracted = {};
73
+ Object.entries(fieldsMap).forEach(([newKey, path]) => {
74
+ const value = getNestedValue(item, path);
75
+ if (value !== undefined) {
76
+ extracted[newKey] = value;
77
+ }
78
+ });
79
+ return extracted;
80
+ });
81
+ }
82
+ // Função para debug - mostra a estrutura do objeto
83
+ function debugObjectStructure(obj, maxDepth = 3, currentDepth = 0) {
84
+ if (currentDepth >= maxDepth)
85
+ return;
86
+ const indent = " ".repeat(currentDepth);
87
+ if (Array.isArray(obj)) {
88
+ console.log(`${indent}Array[${obj.length}]:`);
89
+ if (obj.length > 0) {
90
+ console.log(`${indent} [0]:`);
91
+ debugObjectStructure(obj[0], maxDepth, currentDepth + 2);
92
+ }
93
+ }
94
+ else if (obj && typeof obj === "object") {
95
+ Object.keys(obj)
96
+ .slice(0, 10)
97
+ .forEach((key) => {
98
+ const value = obj[key];
99
+ if (typeof value === "object" && value !== null) {
100
+ console.log(`${indent}${key}:`);
101
+ debugObjectStructure(value, maxDepth, currentDepth + 1);
102
+ }
103
+ else {
104
+ console.log(`${indent}${key}: ${typeof value} = ${String(value).slice(0, 50)}...`);
105
+ }
106
+ });
107
+ }
108
+ }
109
+ // Função para resolver referências URN dinamicamente
110
+ function resolveReferences(data, included) {
111
+ if (!data || !included)
112
+ return data;
113
+ // Criar um mapa de URN para acesso rápido
114
+ const urnMap = new Map();
115
+ included.forEach((item) => {
116
+ if (item.entityUrn) {
117
+ urnMap.set(item.entityUrn, item);
118
+ }
119
+ });
120
+ // Função recursiva para resolver referências
121
+ function resolveObject(obj) {
122
+ if (Array.isArray(obj)) {
123
+ return obj.map((item) => resolveObject(item));
124
+ }
125
+ if (obj && typeof obj === "object") {
126
+ const resolved = {};
127
+ Object.entries(obj).forEach(([key, value]) => {
128
+ // Detectar chaves que começam com * (referências URN)
129
+ if (key.startsWith("*") && typeof value === "string") {
130
+ const referencedData = urnMap.get(value);
131
+ if (referencedData) {
132
+ // Remover o * e usar como chave
133
+ const cleanKey = key.substring(1);
134
+ resolved[cleanKey] = resolveObject(referencedData);
135
+ }
136
+ else {
137
+ resolved[key] = value; // Manter original se não encontrar
138
+ }
139
+ }
140
+ // Detectar arrays de URNs
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) => {
147
+ const referencedData = urnMap.get(urn);
148
+ return referencedData ? resolveObject(referencedData) : urn;
149
+ })
150
+ .filter((item) => item !== null);
151
+ resolved[key] = resolvedArray;
152
+ }
153
+ // Recursão para objetos aninhados
154
+ else if (value && typeof value === "object") {
155
+ resolved[key] = resolveObject(value);
156
+ }
157
+ // Valores primitivos
158
+ else {
159
+ resolved[key] = value;
160
+ }
161
+ });
162
+ return resolved;
163
+ }
164
+ return obj;
165
+ }
166
+ return resolveObject(data);
167
+ }
168
+ // Função para extrair dados com resolução automática de referências
169
+ function extractDataWithReferences(elements, included, fieldsMap) {
170
+ // Filtrar dados pelos elementos
171
+ const filteredData = included.filter((item) => elements.includes(item.entityUrn));
172
+ // Resolver todas as referências
173
+ const resolvedData = filteredData.map((item) => resolveReferences(item, included));
174
+ // Se há mapeamento de campos, aplicar
175
+ if (fieldsMap) {
176
+ return extractFields(resolvedData, fieldsMap);
177
+ }
178
+ return resolvedData;
179
+ }
180
+ // Função para debug de estrutura com referências resolvidas
181
+ function debugResolvedStructure(elements, included, maxDepth = 2) {
182
+ console.log("🔍 Estrutura dos dados com referências resolvidas:");
183
+ const resolved = extractDataWithReferences(elements, included);
184
+ if (resolved.length > 0) {
185
+ console.log(`📊 Total de itens: ${resolved.length}`);
186
+ console.log("📋 Estrutura do primeiro item:");
187
+ debugObjectStructure(resolved[0], maxDepth);
188
+ }
189
+ }
190
+ // Função para extrair campos específicos de todos os objetos no included
191
+ function extractFieldsFromIncluded(included, fields) {
192
+ return included
193
+ .filter((item) => fields.some((field) => item[field] !== undefined))
194
+ .map((item) => {
195
+ const extracted = { entityUrn: item.entityUrn };
196
+ fields.forEach((field) => {
197
+ if (item[field] !== undefined) {
198
+ extracted[field] = item[field];
199
+ }
200
+ });
201
+ return extracted;
202
+ });
203
+ }
204
+ // Função para associar dados extras aos dados principais
205
+ function mergeExtraFields(mainData, extraData, matchKey = "companyUrn") {
206
+ return mainData.map((item) => {
207
+ const extraItem = extraData.find((extra) => item[matchKey] && extra.entityUrn === item[matchKey]);
208
+ if (extraItem) {
209
+ const { entityUrn } = extraItem, extraFields = __rest(extraItem, ["entityUrn"]);
210
+ return Object.assign(Object.assign({}, item), extraFields);
211
+ }
212
+ return item;
213
+ });
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,12 +1,18 @@
1
1
  {
2
2
  "name": "linkedin-api-voyager",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
+ "description": "Uma biblioteca TypeScript para interagir com a API interna do LinkedIn (Voyager)",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
4
7
  "license": "MIT",
8
+ "files": [
9
+ "lib/**/*"
10
+ ],
5
11
  "scripts": {
6
12
  "build": "tsc",
7
13
  "prepare": "npm run build",
8
- "dev": "nodemon src/index.ts",
9
- "publish": "yarn build && npm publish"
14
+ "dev": "nodemon src/teste.ts",
15
+ "prepublishOnly": "npm run build"
10
16
  },
11
17
  "devDependencies": {
12
18
  "@types/fs-extra": "^11.0.4",
@@ -17,6 +23,7 @@
17
23
  },
18
24
  "dependencies": {
19
25
  "axios": "^1.11.0",
20
- "fs-extra": "^11.3.1"
26
+ "fs-extra": "^11.3.1",
27
+ "path": "^0.12.7"
21
28
  }
22
29
  }