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/README.md CHANGED
@@ -1,197 +1,296 @@
1
1
  # LinkedIn API Voyager
2
2
 
3
- Uma biblioteca TypeScript para interagir com a API interna do LinkedIn (Voyager) de forma simples e eficiente.
3
+ Biblioteca TypeScript para interagir com endpoints internos do LinkedIn (Voyager). Esta não é uma API oficial.
4
4
 
5
- ## 🚀 Instalação
5
+ ## Instalação
6
6
 
7
7
  ```bash
8
8
  npm install linkedin-api-voyager
9
- # ou
10
- yarn add linkedin-api-voyager
11
9
  ```
12
10
 
13
- ## 📋 Pré-requisitos
11
+ ## Autenticação (cookies)
14
12
 
15
- Você precisa ter cookies válidos do LinkedIn para usar esta biblioteca. Os cookies devem estar salvos em um arquivo `linkedin_cookies.json` na raiz do seu projeto.
13
+ Para fazer requisições autenticadas, você precisa dos cookies `li_at` e `JSESSIONID` da sua sessão no LinkedIn.
16
14
 
17
- ### Formato dos cookies:
15
+ ### Onde pegar `li_at` e `JSESSIONID`
16
+
17
+ 1. Faça login no LinkedIn pelo navegador.
18
+ 2. Abra o DevTools do navegador.
19
+ 3. Vá em:
20
+ - Chrome/Edge: `Application` -> `Storage` -> `Cookies` -> `https://www.linkedin.com`
21
+ - Firefox: `Storage` -> `Cookies` -> `https://www.linkedin.com`
22
+ 4. Copie os valores dos cookies:
23
+ - `li_at`: copie o valor inteiro.
24
+ - `JSESSIONID`: o valor costuma vir no formato `"ajax:123456789"`.
25
+ - Remova as aspas.
26
+ - Use apenas os números após `ajax:` (ex.: `123456789`).
27
+
28
+ ### Salvando cookies em `linkedin_cookies.json`
29
+
30
+ Por padrão, a lib procura o arquivo `linkedin_cookies.json` na raiz do seu projeto.
31
+
32
+ Formato esperado:
18
33
 
19
34
  ```json
20
35
  {
21
- "JSESSIONID": "seu_token_aqui",
22
- "li_at": "seu_token_aqui",
23
- "timestamp": "1234567890"
36
+ "JSESSIONID": "123456789",
37
+ "li_at": "AQEDAR...",
38
+ "timestamp": 1730000000000
24
39
  }
25
40
  ```
26
41
 
27
- ## 🔧 Uso
42
+ Observações:
28
43
 
29
- ### Configuração inicial
44
+ - O arquivo `linkedin_cookies.json` já está no `.gitignore`.
45
+ - Não compartilhe esses cookies e não comite esse arquivo.
30
46
 
31
- ```typescript
47
+ ## Uso rápido
48
+
49
+ ```ts
32
50
  import {
33
- getProfile,
51
+ getUserMiniProfile,
34
52
  getProfissionalExperiences,
35
53
  getCompany,
36
- search,
54
+ searchPeople,
55
+ getCommentsByPostUrl,
37
56
  } from "linkedin-api-voyager";
57
+
58
+ const profile = await getUserMiniProfile("wesbush");
59
+ const experiences = await getProfissionalExperiences("wesbush");
60
+ const company = await getCompany("microsoft");
61
+ const people = await searchPeople("software engineer");
62
+ const comments = await getCommentsByPostUrl(
63
+ "https://www.linkedin.com/feed/update/urn:li:activity-1234567890/",
64
+ );
38
65
  ```
39
66
 
40
- ### 👤 Perfil de usuário
67
+ ## API (por arquivo em `src/`)
68
+
69
+ O pacote reexporta os módulos listados em `src/index.ts`: `user`, `company`, `posts`, `search`, `utils`, `config`.
70
+
71
+ ### `src/config.ts`
72
+
73
+ Constantes exportadas:
74
+
75
+ - `COOKIE_FILE_PATH`: caminho padrão do arquivo de cookies (`linkedin_cookies.json`).
76
+ - `API_BASE_URL`: base URL das chamadas Voyager (`https://www.linkedin.com/voyager/api`).
77
+ - `AUTH_BASE_URL`: base URL do LinkedIn (`https://www.linkedin.com`).
78
+
79
+ Funções exportadas:
80
+
81
+ - `saveCookies(JSESSIONID: string, li_at: string): Promise<void>`
82
+ - Salva os cookies no `COOKIE_FILE_PATH`.
83
+ - `loadCookies(): Promise<{ JSESSIONID: string; li_at: string; timestamp: number } | null>`
84
+ - Carrega e valida o arquivo de cookies.
85
+ - `Client(providedCookies?: { JSESSIONID: string; li_at: string }): Promise<AxiosInstance>`
86
+ - Cria um cliente HTTP com headers/cookies.
87
+ - Se existir `linkedin_cookies.json`, usa ele.
88
+ - Se não existir e `providedCookies` for passado, salva e usa.
89
+ - `fetchData(endpoint: string): Promise<any>`
90
+ - Faz um `GET` usando `Client()` e retorna `response.data`.
91
+
92
+ Exemplo (salvar cookies e criar cliente):
41
93
 
42
- ```typescript
43
- // Obter perfil completo
44
- const profile = await getProfile("username-do-linkedin");
94
+ ```ts
95
+ import { Client, saveCookies } from "linkedin-api-voyager";
45
96
 
46
- // Obter experiências profissionais (ordenadas do mais recente ao mais antigo)
47
- const experiences = await getProfissionalExperiences("username-do-linkedin");
97
+ await saveCookies("123456789", "AQEDAR...");
98
+ const api = await Client();
99
+
100
+ const me = await api.get("/me");
48
101
  ```
49
102
 
50
- ### 🏢 Informações de empresa
103
+ ### `src/user.ts`
104
+
105
+ Tipos exportados:
106
+
107
+ - `MiniUserProfileLinkedin`
108
+
109
+ Funções exportadas:
110
+
111
+ - `getUserMiniProfile(identifier: string): Promise<MiniUserProfileLinkedin>`
112
+ - Busca dados básicos do perfil (nome, headline, imagens) e também o `about`.
113
+ - `identifier` é o `publicIdentifier` (parte final da URL `linkedin.com/in/<identifier>`).
114
+
115
+ - `extractProfileIdLinkedin(profileUrl: string): Promise<string | null>`
116
+ - Extrai o `publicIdentifier` de uma URL `linkedin.com/in/...`.
117
+ - Se você passar apenas o identificador, ele tenta usar diretamente.
118
+ - Retorna o ID numérico interno (sem o prefixo `urn:li:fsd_profile:`) quando encontra.
119
+
120
+ - `getProfileSectionAbout(identifier: string): Promise<string | null>`
121
+ - Retorna o texto de “Sobre” (about) do perfil.
122
+
123
+ - `getProfissionalExperiences(identifier: string): Promise<Array<any>>`
124
+ - Retorna a lista de experiências profissionais.
125
+ - Para cada experiência, tenta enriquecer com dados de empresa via `getCompany`.
126
+
127
+ - `getContactInfo(identifier: string): Promise<{ ... }>`
128
+ - Retorna informações de contato quando disponíveis (email, telefones, sites etc.).
129
+
130
+ - `getLinkedinSkills(identifier: string): Promise<Array<string | null>>`
131
+ - Retorna as skills (habilidades) listadas no perfil.
132
+
133
+ - `getLinkedinEducation(identifier: string): Promise<Array<any>>`
134
+ - Retorna a educação (escola, degree, datas, skills relacionadas quando houver).
135
+
136
+ - `getLinkedinCertifications(identifier: string): Promise<Array<any>>`
137
+ - Retorna certificações.
138
+
139
+ Exemplo:
140
+
141
+ ```ts
142
+ import {
143
+ getUserMiniProfile,
144
+ getProfileSectionAbout,
145
+ getProfissionalExperiences,
146
+ getContactInfo,
147
+ getLinkedinSkills,
148
+ getLinkedinEducation,
149
+ getLinkedinCertifications,
150
+ } from "linkedin-api-voyager";
151
+
152
+ const identifier = "wesbush";
51
153
 
52
- ```typescript
53
- // Obter dados completos da empresa
54
- const company = await getCompany("nome-universal-da-empresa");
154
+ const mini = await getUserMiniProfile(identifier);
155
+ const about = await getProfileSectionAbout(identifier);
156
+ const experiences = await getProfissionalExperiences(identifier);
157
+ const contact = await getContactInfo(identifier);
158
+ const skills = await getLinkedinSkills(identifier);
159
+ const education = await getLinkedinEducation(identifier);
160
+ const certifications = await getLinkedinCertifications(identifier);
55
161
  ```
56
162
 
57
- ### 🔍 Busca
163
+ ### `src/company.ts`
58
164
 
59
- ```typescript
60
- // Busca geral
61
- const results = await search(
62
- {
63
- keywords: "desenvolvedor javascript",
64
- filters: "List(resultType->PEOPLE)",
65
- },
66
- { limit: 50 }
67
- );
165
+ Funções exportadas:
68
166
 
69
- // Busca com parâmetros personalizados
70
- const customSearch = await search({
71
- q: "all",
72
- keywords: "react developer",
73
- filters: "List(resultType->PEOPLE,locationFilter->br:0)",
74
- start: 0,
75
- count: "25",
76
- });
167
+ - `getCompany(identifier: string): Promise<any>`
168
+ - Busca dados de uma empresa pelo `universalName` (slug da página).
169
+ - Exemplo de slug: `https://www.linkedin.com/company/microsoft/` -> `microsoft`.
170
+
171
+ Exemplo:
172
+
173
+ ```ts
174
+ import { getCompany } from "linkedin-api-voyager";
175
+
176
+ const company = await getCompany("microsoft");
77
177
  ```
78
178
 
79
- ### 💬 Comentários de posts
179
+ ### `src/posts.ts`
180
+
181
+ Funções exportadas:
182
+
183
+ - `parseResponsePostLinkedin(response: any, key: string, accumulatedData: any): any`
184
+ - Helper para selecionar itens do `included` a partir de `*elements`.
185
+
186
+ - `getCommentsByPostUrl(url: string, start = 0, limit = 50, accumulatedComments: unknown[] = []): Promise<unknown[]>`
187
+ - Busca comentários de um post (paginando recursivamente até acabar).
188
+
189
+ - `getPosts(): Promise<unknown[]>`
190
+ - Atualmente retorna `[]` (placeholder).
191
+
192
+ - `getPostLinkedin(url: string, commentsCount = 10, likesCount = 10): Promise<any>`
193
+ - Busca um post pelo slug da URL e retorna os dados do post e do autor.
194
+
195
+ - `getUserPosts({ identifier, start = 0, count = 50, accumulatedPosts = [] }): Promise<any>`
196
+ - Busca posts do usuário por `identifier` (publicIdentifier).
197
+
198
+ - `helperGetPosts(response: any, key: string, accumulatedPosts?: any, addFields?: Record<string, string>): any`
199
+ - Helper para extrair posts e contagens (likes, comentários, shares).
200
+
201
+ - `helperGetImageUrl(item: any): string`
202
+ - Helper para montar a URL de imagem, priorizando o maior artifact.
203
+
204
+ Exemplo (comentários):
80
205
 
81
- ```typescript
206
+ ```ts
82
207
  import { getCommentsByPostUrl } from "linkedin-api-voyager";
83
208
 
84
- // Obter todos os comentários de um post
85
209
  const comments = await getCommentsByPostUrl(
86
210
  "https://www.linkedin.com/feed/update/urn:li:activity-1234567890/",
87
- 0, // início
88
- 50 // limite por página
89
211
  );
90
212
  ```
91
213
 
92
- ## 📊 Estrutura de dados
214
+ ### `src/search.ts`
93
215
 
94
- ### Perfil
216
+ Constantes internas:
95
217
 
96
- ```typescript
97
- {
98
- publicIdentifier: string;
99
- firstName: string;
100
- lastName: string;
101
- fullName: string;
102
- profilePicture: string;
103
- backgroundPicture: string;
104
- location: {
105
- country: string;
106
- city: string;
107
- }
108
- industry: string;
109
- headline: string;
110
- summary: string;
111
- // ... outros campos
112
- }
113
- ```
218
+ - `MAX_SEARCH_COUNT = 25` (limite máximo por chamada na busca geral)
114
219
 
115
- ### Experiências profissionais
116
-
117
- ```typescript
118
- [
119
- {
120
- id: string;
121
- title: string;
122
- companyName: string;
123
- companyUrn: string;
124
- universalName: string; // Nome universal da empresa
125
- description: string;
126
- location: string;
127
- startDate: { year: number; month: number };
128
- endDate: { year: number; month: number } | null; // null = ativo
129
- // ... outros campos
130
- }
131
- ]
132
- ```
220
+ Funções exportadas:
133
221
 
134
- ### Empresa
222
+ - `search(params: ISearchParams): Promise<SearchResponse>`
223
+ - Busca geral usando `query` e/ou `filters` (formato Voyager).
224
+ - Aceita paginação via `offset`.
135
225
 
136
- ```typescript
137
- {
138
- id: string;
139
- name: string;
140
- description: string;
141
- username: string;
142
- companyPageUrl: string;
143
- staffCount: number;
144
- url: string;
145
- location: string;
146
- followerCount: number;
147
- logo: object;
148
- // ... outros campos
149
- }
150
- ```
226
+ - `searchPeople(queryOrParams: string | ISearchPeopleParams): Promise<ISearchPeopleResponse>`
227
+ - Busca pessoas com helpers para montar filtros (networkDepth, regiões, empresas etc.).
228
+
229
+ Exemplo:
151
230
 
152
- ## 🛠️ Funcionalidades avançadas
231
+ ```ts
232
+ import { search, searchPeople } from "linkedin-api-voyager";
153
233
 
154
- ### Extração de campos personalizados
234
+ const res = await search({ query: "react developer" });
235
+ const people = await searchPeople({
236
+ query: "engenheiro de software",
237
+ regions: ["br:0"],
238
+ });
239
+ ```
155
240
 
156
- ```typescript
157
- import { extractFields, extractFieldsFromIncluded } from "linkedin-api-voyager";
241
+ ### `src/utils.ts`
242
+
243
+ Funções exportadas (helpers usados em parsing e normalização):
244
+
245
+ - `filterKeys(obj: any, keysToKeep: string[]): any`
246
+ - `filterOutKeys(obj: any, keysToIgnore: string[]): any`
247
+ - `getNestedValue(obj: any, path: string): any`
248
+ - `extractFields(data: any[], fieldsMap: Record<string, string>): any[]`
249
+ - `debugObjectStructure(obj: any, maxDepth = 3, currentDepth = 0): void`
250
+ - `resolveReferences(data: any, included: any[]): any`
251
+ - `extractDataWithReferences(elements: string[], included: any[], fieldsMap?: Record<string, string>): any[]`
252
+ - `debugResolvedStructure(elements: string[], included: any[], maxDepth = 2): void`
253
+ - `extractFieldsFromIncluded(included: any[], fields: string[]): Array<Record<string, any>>`
254
+ - `mergeExtraFields(mainData: any[], extraData: Array<Record<string, any>>, matchKey = "companyUrn"): any[]`
255
+ - `getDataIncludedForEntity(jsonData: Record<string, any>, entityUrn: string): any`
256
+ - `extractExperiences(jsonData: Record<string, any>): Array<{ role: string | null; idCompany: string | null; company: string | null; ... }>`
257
+ - `assert(value: unknown, message?: string | Error): asserts value`
258
+ - `getIdFromUrn(urn?: string): string | undefined`
259
+ - `getUrnFromRawUpdate(update?: string): string | undefined`
260
+ - `isLinkedInUrn(urn?: string): boolean`
261
+ - `parseExperienceItem(item: any, opts: { isGroupItem?: boolean; included: any[] }): ExperienceItem`
262
+ - `getGroupedItemId(item: any): string | undefined`
263
+ - `omit(inputObj: object, ...keys: string[]): object`
264
+ - `resolveImageUrl(vectorImage?: VectorImage): string | undefined`
265
+ - `resolveLinkedVectorImageUrl(linkedVectorImage?: LinkedVectorImage): string | undefined`
266
+ - `stringifyLinkedInDate(date?: LIDate): string | undefined`
267
+ - `normalizeRawOrganization(o?: RawOrganization): Organization`
268
+
269
+ Exemplo (mapear campos com path aninhado):
270
+
271
+ ```ts
272
+ import { extractFields } from "linkedin-api-voyager";
158
273
 
159
- // Mapear campos específicos
160
274
  const fieldsMap = {
161
275
  nome: "firstName",
162
- empresa: "company.name",
163
- cargo: "title",
276
+ headline: "headline",
277
+ foto: "profilePicture.displayImageReferenceResolutionResult.vectorImage.rootUrl",
164
278
  };
165
279
 
166
- const dadosMapeados = extractFields(dados, fieldsMap);
280
+ const mapped = extractFields([someObject], fieldsMap);
167
281
  ```
168
282
 
169
- ### Resolução automática de referências
170
-
171
- A biblioteca resolve automaticamente referências URN aninhadas, permitindo acesso direto a dados relacionados sem necessidade de mapeamento manual.
172
-
173
- ## ⚠️ Limitações e considerações
283
+ ### `src/types.ts`
174
284
 
175
- - Esta biblioteca usa a API interna do LinkedIn (Voyager)
176
- - Requer cookies válidos de uma sessão autenticada
177
- - Respeite os termos de uso do LinkedIn
178
- - Use com moderação para evitar bloqueios
179
- - Não é uma API oficial do LinkedIn
285
+ Este arquivo exporta tipos e interfaces TypeScript usados pela biblioteca (por exemplo: `ISearchParams`, `ISearchPeopleParams`, `SearchResponse`, `Organization`, `ExperienceItem`).
180
286
 
181
- ## 🔒 Segurança
287
+ ## Limitações e considerações
182
288
 
183
- - Mantenha seus cookies seguros
184
- - Não compartilhe o arquivo `linkedin_cookies.json`
185
- - O arquivo está incluído no `.gitignore`
289
+ - Usa endpoints internos do LinkedIn (Voyager), que podem mudar sem aviso.
290
+ - Requer cookies válidos de uma sessão autenticada.
291
+ - Use com moderação para reduzir risco de bloqueio.
292
+ - Respeite os termos de uso do LinkedIn.
186
293
 
187
- ## 📝 Licença
294
+ ## Licença
188
295
 
189
296
  MIT
190
-
191
- ## 🤝 Contribuição
192
-
193
- Contribuições são bem-vindas! Por favor, abra uma issue ou pull request.
194
-
195
- ## 📞 Suporte
196
-
197
- Para dúvidas ou problemas, abra uma issue no repositório.
@@ -0,0 +1 @@
1
+ export declare const getCompany: (identifier: string) => Promise<any>;
package/lib/company.js ADDED
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getCompany = void 0;
13
+ const config_1 = require("./config");
14
+ const utils_1 = require("./utils");
15
+ const getCompany = (identifier) => __awaiter(void 0, void 0, void 0, function* () {
16
+ const response = yield (0, config_1.fetchData)(`/organization/companies?decorationId=com.linkedin.voyager.deco.organization.web.WebFullCompanyMain-12&q=universalName&universalName=${identifier}`);
17
+ const data = (0, utils_1.extractDataWithReferences)(response.data["*elements"], response.included);
18
+ const fieldsMap = {
19
+ id: "entityUrn",
20
+ name: "name",
21
+ description: "description",
22
+ username: "universalName",
23
+ companyPageUrl: "companyPageUrl",
24
+ staffCount: "staffCount",
25
+ url: "url",
26
+ companyIndustries: "*companyIndustries[0].localizedName",
27
+ location: "locationName",
28
+ jobSearchPageUrl: "jobSearchPageUrl",
29
+ phone: "phone",
30
+ followerCount: "followingInfo.followerCount",
31
+ backgroundCoverImage: "backgroundCoverImage.image",
32
+ logo: "logo.image",
33
+ permissions: "permissions",
34
+ };
35
+ return (0, utils_1.extractFields)(data, fieldsMap).map((item) => {
36
+ var _a, _b, _c, _d, _e, _f, _g, _h;
37
+ return (Object.assign(Object.assign({}, item), { id: item.id.split(":")[3], backgroundCoverImage: `${(_a = item.backgroundCoverImage) === null || _a === void 0 ? void 0 : _a.rootUrl}${(_d = (_c = (_b = item.backgroundCoverImage) === null || _b === void 0 ? void 0 : _b.artifacts) === null || _c === void 0 ? void 0 : _c.at(-1)) === null || _d === void 0 ? void 0 : _d.fileIdentifyingUrlPathSegment}`, logo: `${(_e = item.logo) === null || _e === void 0 ? void 0 : _e.rootUrl}${(_h = (_g = (_f = item.logo) === null || _f === void 0 ? void 0 : _f.artifacts) === null || _g === void 0 ? void 0 : _g.at(-1)) === null || _h === void 0 ? void 0 : _h.fileIdentifyingUrlPathSegment}` }));
38
+ })[0];
39
+ });
40
+ exports.getCompany = getCompany;
@@ -0,0 +1,20 @@
1
+ export declare const COOKIE_FILE_PATH = "linkedin_cookies.json";
2
+ export declare const API_BASE_URL = "https://www.linkedin.com/voyager/api";
3
+ export declare const AUTH_BASE_URL = "https://www.linkedin.com";
4
+ interface LinkedInCookies {
5
+ JSESSIONID: string;
6
+ li_at: string;
7
+ timestamp: number;
8
+ }
9
+ export declare const saveCookies: (JSESSIONID: string, li_at: string) => Promise<void>;
10
+ export declare const loadCookies: () => Promise<LinkedInCookies | null>;
11
+ export declare const Client: (providedCookies?: {
12
+ JSESSIONID: string;
13
+ li_at: string;
14
+ }) => Promise<ReturnType<typeof api>>;
15
+ declare const api: ({ JSESSIONID, li_at }: {
16
+ li_at: string;
17
+ JSESSIONID: number;
18
+ }) => import("axios").AxiosInstance;
19
+ export declare const fetchData: (endpoint: string) => Promise<any>;
20
+ export {};
package/lib/config.js ADDED
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.fetchData = exports.Client = exports.loadCookies = exports.saveCookies = exports.AUTH_BASE_URL = exports.API_BASE_URL = exports.COOKIE_FILE_PATH = void 0;
13
+ const fs = require("fs-extra");
14
+ const axios_1 = require("axios");
15
+ exports.COOKIE_FILE_PATH = "linkedin_cookies.json";
16
+ exports.API_BASE_URL = "https://www.linkedin.com/voyager/api";
17
+ exports.AUTH_BASE_URL = "https://www.linkedin.com";
18
+ // Função para salvar cookies no arquivo JSON
19
+ const saveCookies = (JSESSIONID, li_at) => __awaiter(void 0, void 0, void 0, function* () {
20
+ try {
21
+ const cookies = {
22
+ JSESSIONID,
23
+ li_at,
24
+ timestamp: Date.now(),
25
+ };
26
+ yield fs.ensureFile(exports.COOKIE_FILE_PATH);
27
+ yield fs.writeJson(exports.COOKIE_FILE_PATH, cookies, { spaces: 2 });
28
+ }
29
+ catch (error) {
30
+ throw error;
31
+ }
32
+ });
33
+ exports.saveCookies = saveCookies;
34
+ // Função para carregar cookies do arquivo JSON
35
+ const loadCookies = () => __awaiter(void 0, void 0, void 0, function* () {
36
+ try {
37
+ const exists = yield fs.pathExists(exports.COOKIE_FILE_PATH);
38
+ if (!exists) {
39
+ throw new Error("Arquivo de cookies não encontrado");
40
+ }
41
+ const cookies = yield fs.readJson(exports.COOKIE_FILE_PATH);
42
+ // Verificar se os cookies têm a estrutura esperada
43
+ if (!cookies.JSESSIONID || !cookies.li_at) {
44
+ throw new Error("Cookies inválidos encontrados no arquivo");
45
+ }
46
+ return cookies;
47
+ }
48
+ catch (error) {
49
+ throw error;
50
+ }
51
+ });
52
+ exports.loadCookies = loadCookies;
53
+ // Função para criar cliente com cookies automáticos
54
+ const Client = (providedCookies) => __awaiter(void 0, void 0, void 0, function* () {
55
+ let cookiesToUse;
56
+ const savedCookies = yield (0, exports.loadCookies)();
57
+ if (savedCookies) {
58
+ cookiesToUse = {
59
+ JSESSIONID: savedCookies.JSESSIONID,
60
+ li_at: savedCookies.li_at,
61
+ };
62
+ }
63
+ else {
64
+ if (providedCookies) {
65
+ yield (0, exports.saveCookies)(providedCookies.JSESSIONID, providedCookies.li_at);
66
+ cookiesToUse = providedCookies;
67
+ }
68
+ else {
69
+ throw new Error("Nenhum cookie válido fornecido");
70
+ }
71
+ }
72
+ return api({
73
+ JSESSIONID: parseInt(cookiesToUse.JSESSIONID),
74
+ li_at: cookiesToUse.li_at,
75
+ });
76
+ });
77
+ exports.Client = Client;
78
+ const api = ({ JSESSIONID, li_at }) => {
79
+ return axios_1.default.create({
80
+ baseURL: exports.API_BASE_URL,
81
+ headers: {
82
+ "accept-language": "pt-BR,pt;q=0.9,fr-FR;q=0.8,fr;q=0.7,en-US;q=0.6,en;q=0.5",
83
+ accept: "application/vnd.linkedin.normalized+json+2.1",
84
+ cookie: `li_at=${li_at}; JSESSIONID="ajax:${JSESSIONID}"`,
85
+ "csrf-token": `ajax:${JSESSIONID}`,
86
+ },
87
+ });
88
+ };
89
+ const fetchData = (endpoint) => __awaiter(void 0, void 0, void 0, function* () {
90
+ const api = yield (0, exports.Client)();
91
+ const response = yield api.get(endpoint);
92
+ return response.data;
93
+ });
94
+ exports.fetchData = fetchData;
@@ -1,4 +1,4 @@
1
- export * from "./account";
1
+ export * from "./user";
2
2
  export * from "./company";
3
3
  export * from "./posts";
4
4
  export * from "./search";
package/lib/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./user"), exports);
18
+ __exportStar(require("./company"), exports);
19
+ __exportStar(require("./posts"), exports);
20
+ __exportStar(require("./search"), exports);
21
+ __exportStar(require("./utils"), exports);
22
+ __exportStar(require("./config"), exports);
package/lib/posts.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export declare const parseResponsePostLinkedin: (response: any, key: string, accumulatedData: any) => any;
2
+ export declare const getCommentsByPostUrl: (url: string, start?: number, limit?: number, accumulatedComments?: unknown[]) => Promise<unknown[]>;
3
+ export declare const getPosts: () => Promise<never[]>;
4
+ export declare const getPostLinkedin: (url: string, commentsCount?: number, likesCount?: number) => Promise<any>;
5
+ export declare const getUserPosts: ({ identifier, start, count, accumulatedPosts, }: {
6
+ identifier: string;
7
+ start?: number;
8
+ count?: number;
9
+ accumulatedPosts?: unknown[];
10
+ }) => Promise<any[]>;
11
+ export declare const helperGetPosts: (response: any, key: string, accumulatedPosts?: any, addFields?: Record<string, string>) => any[];
12
+ export declare const helperGetImageUrl: (item: any) => any;