import { MediumPublication } from './medium.classes.publication.js'; import * as plugins from './medium.plugins.js'; export interface IMediumAccountData { id: string; username: string; url: string; imageUrl: string; } /** * Represents a Medium account with various functionalities to interact with Medium's API. */ export class MediumAccount implements IMediumAccountData { // INSTANCE private accessToken: string; public readyDeferred = plugins.smartpromise.defer(); public baseApiDomain = 'https://api.medium.com/v1'; id: string; username: string; url: string; imageUrl: string; /** * Initializes a new instance of the MediumAccount class. * @param accessTokenArg - The access token for the Medium API. */ constructor(accessTokenArg: string) { this.accessToken = accessTokenArg; this.getAccountInfo().then((dataArg) => { if (dataArg) { Object.assign(this, dataArg); this.readyDeferred.resolve(); } else { this.readyDeferred.reject('Failed to fetch account info.'); } }).catch(error => { console.error('Error fetching account info:', error); this.readyDeferred.reject(error); }); } /** * Fetches the account information from Medium. * @returns A promise that resolves to the account data. */ public async getAccountInfo(): Promise { try { const result = await this.request('/me', 'GET'); console.log(result.statusCode); const accountData: IMediumAccountData = result.body.data; return accountData; } catch (error) { console.error('Error in getAccountInfo:', error); return undefined; } } /** * Fetches all publications associated with this account. * @returns A promise that resolves to an array of MediumPublication objects. */ public async getAllPublications(): Promise { const result = await this.request(`/users/${this.id}/publications`, 'GET'); return result.data.map((pub: any) => new MediumPublication(this, pub)); } /** * Fetches all publications authored by this account. * @returns A promise that resolves to an array of MediumPublication objects. */ public async getOwnPublications(): Promise { const allPublications = await this.getAllPublications(); const ownPublications: MediumPublication[] = []; for (const publication of allPublications) { const response = await this.request(`/publications/${publication.id}/contributors`, 'GET'); const contributors: { publicationId: string; userId: string; role: string; }[] = response.data; if (contributors.some(contributor => contributor.userId === this.id)) { ownPublications.push(publication); } } return ownPublications; } /** * Fetches a publication by its name. * @param nameArg - The name of the publication. * @returns A promise that resolves to the MediumPublication object. */ public async getPublicationByName(nameArg: string): Promise { const publications = await this.getAllPublications(); return publications.find(publication => publication.name === nameArg); } /** * Makes an authenticated request to the Medium API. * @param routeArg - The API route to request. * @param methodArg - The HTTP method to use for the request. * @param payloadArg - Optional payload for POST requests. * @returns A promise that resolves to the API response. */ public async request(routeArg: string, methodArg: 'POST' | 'GET', payloadArg?: any): Promise { try { const response = await plugins.smartrequest.request(`${this.baseApiDomain}${routeArg}`, { headers: { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json', Accept: 'application/json', 'Accept-Charset': 'utf-8', }, method: methodArg, keepAlive: false, requestBody: payloadArg ? JSON.stringify(payloadArg) : null }); return response; } catch (error) { console.error('Error in request:', error); throw error; } } }