fix(medium): Fix various bugs and improve async handling.

This commit is contained in:
2024-07-01 23:55:47 +02:00
parent 93e8ffcc95
commit 6b557ba71c
8 changed files with 128 additions and 168 deletions

View File

@@ -9,11 +9,9 @@ export interface IMediumAccountData {
}
/**
*
* Represents a Medium account with various functionalities to interact with Medium's API.
*/
export class MediumAccount implements IMediumAccountData {
// STATIC
// INSTANCE
private accessToken: string;
public readyDeferred = plugins.smartpromise.defer();
@@ -24,43 +22,104 @@ export class MediumAccount implements IMediumAccountData {
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) => {
Object.assign(this, dataArg);
this.readyDeferred.resolve();
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);
});
}
public async getAccountInfo(): Promise<IMediumAccountData> {
const result = await this.request('/me', 'GET');
const accountData = result.body.data;
return accountData;
/**
* Fetches the account information from Medium.
* @returns A promise that resolves to the account data.
*/
public async getAccountInfo(): Promise<IMediumAccountData | undefined> {
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<MediumPublication[]> {
return MediumPublication.getAllPublications(this);
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<MediumPublication[]> {
return MediumPublication.getOwnPublications(this);
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;
}
public async getPublicationByName(nameArg: string): Promise<MediumPublication> {
return MediumPublication.getPublicationByName(this, nameArg);
/**
* 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<MediumPublication | undefined> {
const publications = await this.getAllPublications();
return publications.find(publication => publication.name === nameArg);
}
public async request(routeArg: string, methodArg: 'POST' | 'GET', payloadArg?: any) {
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,
requestBody: payloadArg ? JSON.stringify(payloadArg) : null
});
return response;
/**
* 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<any> {
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;
}
}
}
}