added npm files

This commit is contained in:
2024-05-09 08:10:20 -07:00
parent 9f0b036391
commit c58dab1807
11 changed files with 937 additions and 1 deletions
+70
View File
@@ -0,0 +1,70 @@
import { LinkedInProfile } from "./Profile.js";
export class Company {
/** @type {import('../index.js').linkedInAPIClass} */
#APIRef;
/**
* gets the employees of a company
* @param {Number} [limit=Infinity] to make things simpler I used increments of 50, so the limit is essentially ceiled to the nearest multiple of 50
* @param {Boolean} [raw=false] whether or not you want the raw JSON returned
* @returns {Promise<JSON[] | LinkedInProfile[]>}
* @note This function skips over any employees who's profile is marked as private
*/
async getEmployees(limit = Infinity, raw = false) {
const employeesInit = await this.#APIRef._makeReq(`variables=(start:0,origin:FACETED_SEARCH,query:(flagshipSearchIntent:ORGANIZATIONS_PEOPLE_ALUMNI,queryParameters:List((key:currentCompany,value:List(${this.urn})),(key:resultType,value:List(ORGANIZATION_ALUMNI))),includeFiltersInResponse:true),count:1)`)
const numEmp = employeesInit.data.data.searchDashClustersByAll.paging.total,
empAll = []
// since the max cap is 50, we need to iterate until it's over 50
for (let i = 0; i < numEmp; i += 50) {
if (empAll.length >= limit) break;
const c = (i + 50 >= limit) ? limit - i : 50;
const employeeRes = await this.#APIRef._makeReq(`variables=(start:${i},origin:FACETED_SEARCH,query:(flagshipSearchIntent:ORGANIZATIONS_PEOPLE_ALUMNI,queryParameters:List((key:currentCompany,value:List(${this.urn})),(key:resultType,value:List(ORGANIZATION_ALUMNI))),includeFiltersInResponse:true),count:${c})`);
const employees = employeeRes.included;
const empParsed = employees.filter(e => (e.$type === "com.linkedin.voyager.dash.search.EntityResultViewModel"))
.filter(o => o.title.text !== "LinkedIn Member");
if (empParsed.length) empAll.push(...empParsed);
await this.#APIRef.evade();
}
return (raw) ? empAll : empAll.map(eRaw => new LinkedInProfile(eRaw, this.#APIRef));
}
/**
* @returns {Promise<JSON[] | LinkedInProfile[]>}
* @param {string} name
* @param {boolean} raw
*/
getEmployees = (name, limit=1000, raw=false) => this.#APIRef.searchEmployees(name, limit, !raw, [this.urn]);
async getInfo() {
const toAdd = `q=universalName&universalName=${this.urn}`;
return await this.#APIRef._makeReq(toAdd);
}
checkIfCompleted = () => !!(this.name && this.url && this.urn && this.#APIRef);
/**
* @param {{title: {text: String}, entityUrn: String, navigationUrl: String}} data
* @param {import('../index.js').linkedInAPIClass} APIRef
*/
constructor(data, APIRef) {
this.#APIRef = APIRef;
// this.entityUrn = entityUrn?.replace("urn:li:fsd_company:", "");
this.name = data.title.text;
this.urn = data.entityUrn;
this.url = data.navigationUrl;
if (!this.checkIfCompleted()) throw "NOT ALL NEEDED PARAMS FOUND!";
}
}
+47
View File
@@ -0,0 +1,47 @@
import { linkedInAPIClass } from "../index.js";
export class LinkedInProfile {
/** @type {linkedInAPIClass} */
#APIRef;
/**
* Attempts to get the contact info for the person
* @returns {Promise<{websites: [{label:string, category:string, url:string}], emailAddress:string, phoneNumbers:[string],weChatContactInfo:any,twitterHandles:[string], instantMessengers:[]}>}
*/
async getContactInfo() {
const r = await this.#APIRef._makeReq(`includeWebMetadata=true&variables=(memberIdentity:${this.entityNameJoined})`, true);
if (r?.data?.errors) return console.error(JSON.stringify(r.data.errors));
const uObj = r.included.find(o => o.publicIdentifier === this.entityNameJoined);
if (!uObj) return;
let { phoneNumbers, emailAddress, websites, weChatContactInfo, twitterHandles, instantMessengers } = uObj;
if (websites) websites = websites.map(w => ({ label: w.label, category: w.category, url: w.url }));
return { phoneNumbers, emailAddress, websites, weChatContactInfo, twitterHandles, instantMessengers };
}
// Parse specific services offered, contained in the 'simpleInsight' section of 'insightsResolutionResults'
parseServices(insights) {
for (let insight of insights) {
if (insight.simpleInsight && insight.simpleInsight.title && insight.simpleInsight.title.text) {
return insight.simpleInsight.title.text;
}
}
return '';
}
constructor(jsonData, apiRef) {
this.#APIRef = apiRef;
this.name = jsonData.title ? jsonData.title.text : '';
this.entityNameJoined = jsonData.navigationUrl?.split("/in/")[1]?.split("?")[0];
this.profileUrl = jsonData.navigationUrl || '';
this.trackingUrn = jsonData.trackingUrn || '';
const match = jsonData.entityUrn?.match(/urn:li:fsd_profile:(.*?),/);
this.entityUrn = match ? match[1] : '';
this.jobServices = jsonData.insightsResolutionResults ? this.parseServices(jsonData.insightsResolutionResults) : '';
this.primarySubtitle = jsonData.primarySubtitle ? jsonData.primarySubtitle.text : '';
this.secondarySubtitle = jsonData.secondarySubtitle ? jsonData.secondarySubtitle.text : '';
this.bserpEntityNavigationalUrl = jsonData.bserpEntityNavigationalUrl || '';
}
}
+7
View File
@@ -0,0 +1,7 @@
import linkedInAPIClass from "../index.js";
import { LinkedInProfile } from "./Profile.js";
import { Company } from "./Company.js";
import { GenericEntity, Group, ReactionTypeCount, SocialActivityCounts } from './misc.js'
export { linkedInAPIClass, LinkedInProfile, Company, GenericEntity, Group, ReactionTypeCount, SocialActivityCounts };
+30
View File
@@ -0,0 +1,30 @@
export class ReactionTypeCount {
constructor({ count, reactionType }) {
this.count = count;
this.reactionType = reactionType;
}
}
export class SocialActivityCounts {
constructor({ entityUrn, numComments, numLikes, reactionTypeCounts, liked, preDashEntityUrn }) {
this.entityUrn = entityUrn;
this.numComments = numComments;
this.numLikes = numLikes;
this.reactionTypeCounts = reactionTypeCounts.map(count => new ReactionTypeCount(count));
this.liked = liked;
this.preDashEntityUrn = preDashEntityUrn;
}
}
export class Group {
constructor({ entityUrn }) {
this.entityUrn = entityUrn;
}
}
// Placeholder class for any other types
export class GenericEntity {
constructor(data) {
Object.assign(this, data);
}
}