UNPKG

earningscall

Version:

The EarningsCall JavaScript library provides convenient access to the EarningsCall API. It includes a pre-defined set of classes for API resources that initialize themselves dynamically from API responses.

257 lines 19.9 kB
import { getTranscript, getEvents, getSp500CompaniesTxtFile, downloadAudioFile, isDemoAccount, } from './api'; import { camelCaseKeys } from './camel-case'; import { InsufficientApiAccessError, MissingApiKeyError, NotFoundError, } from './errors'; import { EXCHANGES_IN_ORDER, getSymbols } from './symbols'; export class Company { companyInfo; name; events_; constructor(companyInfo) { this.companyInfo = companyInfo; this.name = companyInfo.name; this.events_ = undefined; } toString() { return String(this.name); } /** * Get the events for the company. Useful for getting the earnings events for a company. * * @returns A promise that resolves to an array of EarningsEvent objects. */ async getEvents() { const rawResponse = await getEvents(this.companyInfo.exchange, this.companyInfo.symbol); const responseAsRecord = rawResponse; const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true }); const eventsResponse = camelCasedObject; this.events_ = eventsResponse.events; return this.events_; } async events() { return await this.getEvents(); } validateTranscriptOptions(options) { const { year, quarter } = options; if (year === undefined || quarter === undefined) { throw new Error('Must specify either event or year and quarter'); } if (year < 1990 || year > 2030) { throw new Error('Invalid year. Must be between 1990 and 2030'); } if (![1, 2, 3, 4].includes(quarter)) { throw new Error('Invalid quarter. Must be one of: {1,2,3,4}'); } } getOptions(options) { if (options.event !== undefined) { const event = options.event; const { year, quarter } = event; return { year, quarter }; } const { year, quarter } = options; return { year, quarter }; } /** * Retrieve a single transcript for this company. This is the basic transcript with no speaker groups. * * @param options - The options for getting a transcript. * @returns A promise that resolves to a Transcript object or undefined if not found. */ async getBasicTranscript(options) { const transcriptOptions = this.getOptions(options); this.validateTranscriptOptions(transcriptOptions); const { year, quarter } = transcriptOptions; try { const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 1); const responseAsRecord = response; const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true }); const transcript = camelCasedObject; return transcript; } catch (error) { if (error instanceof NotFoundError) { return undefined; // Transcript not found } throw error; } } handleEnhancedTranscriptDataError(error) { if (error instanceof InsufficientApiAccessError) { const planName = error.response.headers.get('X-Plan-Name'); throw new InsufficientApiAccessError(`Your plan (${planName}) does not include Enhanced Transcript Data. Upgrade your plan here: https://earningscall.biz/api-pricing`, error.response); } } /** * Retrieve a single transcript for this company with speaker groups. * * Requires an Enhanced Transcript Data plan. * * @param options - The options for getting a transcript. * @returns A promise that resolves to a Transcript object or undefined if not found. */ async getSpeakerGroups(options) { const transcriptOptions = this.getOptions(options); this.validateTranscriptOptions(transcriptOptions); const { year, quarter } = transcriptOptions; try { const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 2); const responseAsRecord = response; const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true }); const transcript = camelCasedObject; if (transcript.speakerNameMapV2) { for (const speaker of transcript.speakers) { const speakerLabel = speaker.speaker; if (transcript.speakerNameMapV2[speakerLabel]) { speaker.speakerInfo = transcript.speakerNameMapV2[speakerLabel]; } } } return transcript; } catch (error) { if (error instanceof NotFoundError) { return undefined; // Transcript not found } this.handleEnhancedTranscriptDataError(error); throw error; } } /** * Retrieve a single transcript for this company with word level timestamps. * * Requires an Enhanced Transcript Data plan. * * @param options - The options for getting a transcript. * @returns A promise that resolves to a TranscriptV3 object or undefined if not found. */ async getWordLevelTimestamps(options) { const transcriptOptions = this.getOptions(options); this.validateTranscriptOptions(transcriptOptions); const { year, quarter } = transcriptOptions; try { const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 3); const responseAsRecord = response; const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true }); const transcript = camelCasedObject; return transcript; } catch (error) { if (error instanceof NotFoundError) { return undefined; // Transcript not found } this.handleEnhancedTranscriptDataError(error); throw error; } } /** * Retrieve a single transcript for this company with question and answer transcripts. * * Requires an Enhanced Transcript Data plan. * * @param options - The options for getting a transcript. * @returns A promise that resolves to a TranscriptV4 object or undefined if not found. */ async getQuestionAndAnswerTranscript(options) { const transcriptOptions = this.getOptions(options); this.validateTranscriptOptions(transcriptOptions); const { year, quarter } = transcriptOptions; try { const response = await getTranscript(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, 4); const responseAsRecord = response; const camelCasedObject = camelCaseKeys(responseAsRecord, { deep: true }); const transcript = camelCasedObject; return transcript; } catch (error) { if (error instanceof NotFoundError) { return undefined; // Transcript not found } this.handleEnhancedTranscriptDataError(error); throw error; } } /** * Downloads a single audio file for this company to disk. * * @param options - The options for getting an audio file. * @returns A promise that resolves to a GetAudioFileResponse object. */ async downloadAudioFile(options) { const { year, quarter, outputFilePath } = options; try { const response = await downloadAudioFile(this.companyInfo.exchange, this.companyInfo.symbol, year, quarter, outputFilePath); return response; } catch (error) { if (error instanceof NotFoundError) { return undefined; } throw error; } } } /** * Get a company by symbol and optionally, exchange. * * @param options - The options for getting a company. * @returns A promise that resolves to a Company object. */ export async function getCompany(options) { const companyInfo = await lookupCompany(options); if (!companyInfo) { throw new Error(`Symbol not found: ${options.symbol}`); } return new Company(companyInfo); } export async function lookupCompany(options) { const { exchange, symbol } = options; const symbols = await getSymbols(); if (exchange) { return symbols.get(exchange.toUpperCase(), symbol.toUpperCase()); } for (const exchange of EXCHANGES_IN_ORDER) { const info = symbols.get(exchange, symbol.toUpperCase()); if (info) { return info; } } if (isDemoAccount()) { throw new MissingApiKeyError(`"${symbol}" requires an API Key for access. To get your API Key, ` + 'see: https://earningscall.biz/api-pricing'); } return undefined; } export async function getAllCompaniesInfos() { const symbols = await getSymbols(); return Array.from(symbols.getAll()); } /** * Get all companies. * * @returns A promise that resolves to an array of Company objects. */ export async function getAllCompanies() { const infos = await getAllCompaniesInfos(); return infos.map((info) => new Company(info)); } /** * Get all S&P 500 companies. * * @returns A promise that resolves to an array of Company objects. */ export async function getSP500Companies() { const sp500CompaniesTxtFile = await getSp500CompaniesTxtFile(); const symbols = sp500CompaniesTxtFile.split('\n').map((line) => line.trim()); const companyPromises = symbols.map(async (symbol) => { try { return await getCompany({ symbol }); } catch (error) { return null; } }); const results = await Promise.all(companyPromises); // Filter out null values and explicitly type as Company[] return results.filter((company) => company !== null); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGFueS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvY29tcGFueS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFlQSxPQUFPLEVBQ0wsYUFBYSxFQUNiLFNBQVMsRUFDVCx3QkFBd0IsRUFDeEIsaUJBQWlCLEVBQ2pCLGFBQWEsR0FDZCxNQUFNLE9BQU8sQ0FBQztBQUNmLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDN0MsT0FBTyxFQUNMLDBCQUEwQixFQUMxQixrQkFBa0IsRUFDbEIsYUFBYSxHQUNkLE1BQU0sVUFBVSxDQUFDO0FBRWxCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxVQUFVLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFM0QsTUFBTSxPQUFPLE9BQU87SUFDVCxXQUFXLENBQWM7SUFDekIsSUFBSSxDQUFVO0lBQ2YsT0FBTyxDQUFtQjtJQUVsQyxZQUFZLFdBQXdCO1FBQ2xDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztJQUMzQixDQUFDO0lBRUQsUUFBUTtRQUNOLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLEtBQUssQ0FBQyxTQUFTO1FBQ3JCLE1BQU0sV0FBVyxHQUFHLE1BQU0sU0FBUyxDQUNqQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFDekIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQ3hCLENBQUM7UUFDRixNQUFNLGdCQUFnQixHQUFHLFdBQXNDLENBQUM7UUFDaEUsTUFBTSxnQkFBZ0IsR0FBRyxhQUFhLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN6RSxNQUFN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