Skip to content

Commit

Permalink
refactor: add separate controls for MyUser
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `Client.users.fetchMe()` is now `Client.me.fetch()`.
  • Loading branch information
thislooksfun committed May 2, 2022
1 parent 5a1274b commit 57adf74
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 143 deletions.
2 changes: 1 addition & 1 deletion examples/oauth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ app.get("/auth", async (req, res) => {
);

// Get and display the user's information so we know it worked!
const user = await client.users.fetchMe();
const user = await client.me.fetch();
res.send(`Hello ${user.name}!`);
} catch (e) {
// If something goes wrong, log it.
Expand Down
6 changes: 5 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { makeDebug } from "./helper/debug";
import { CommentControls } from "./reddit/comment/controls";
import { PostControls } from "./reddit/post/controls";
import { SubredditControls } from "./reddit/subreddit/controls";
import { UserControls } from "./reddit/user/controls";
import { MyUserControls } from "./reddit/user/my-user/controls";
import { UserControls } from "./reddit/user/other-user/controls";

const debug = makeDebug("class:Client");

Expand Down Expand Up @@ -125,6 +126,8 @@ export interface ClientOptions {
export class Client {
/** Controls for interacting with comments. */
public readonly comments: CommentControls;
/** Controls for interacting with the currently authorized user. */
public readonly me: MyUserControls;
/** Controls for interacting with posts. */
public readonly posts: PostControls;
/** Controls for interacting with subreddits. */
Expand Down Expand Up @@ -182,6 +185,7 @@ export class Client {

// Set up controls after we have initialized the internal state.
this.comments = new CommentControls(this);
this.me = new MyUserControls(this);
this.posts = new PostControls(this);
this.subreddits = new SubredditControls(this);
this.users = new UserControls(this);
Expand Down
16 changes: 9 additions & 7 deletions src/reddit/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,21 @@ export type { SubredditData } from "./subreddit/object";
export { Subreddit } from "./subreddit/object";
export type { SubredditType } from "./subreddit/types";
export type { SearchSort, SearchSyntax, Size, TimeRange } from "./types";
export { UserControls } from "./user/controls";
export { BaseUserControls } from "./user/base/controls";
export type { UserData } from "./user/base/object";
export { User } from "./user/base/object";
export type { BannedUserData } from "./user/moderator-actioned/banned";
export { BannedUser } from "./user/moderator-actioned/banned";
export type { ModeratorActionedUserData } from "./user/moderator-actioned/base";
export { ModeratorActionedUser } from "./user/moderator-actioned/base";
export type { ModeratorData } from "./user/moderator-actioned/moderator";
export { Moderator } from "./user/moderator-actioned/moderator";
export type { UserData } from "./user/object/base-object";
export { User } from "./user/object/base-object";
export type { MyUserData } from "./user/object/my-user";
export { MyUser } from "./user/object/my-user";
export type { OtherUserData } from "./user/object/other-user";
export { OtherUser } from "./user/object/other-user";
export { MyUserControls } from "./user/my-user/controls";
export type { MyUserData } from "./user/my-user/object";
export { MyUser } from "./user/my-user/object";
export { UserControls } from "./user/other-user/controls";
export type { OtherUserData } from "./user/other-user/object";
export { OtherUser } from "./user/other-user/object";
export type { UserItemsSort } from "./user/types";
export { VoteableControls } from "./voteable/controls";
export type { Gildings, VoteableData } from "./voteable/object";
Expand Down
86 changes: 86 additions & 0 deletions src/reddit/user/base/controls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import type { Client } from "../../../client";
import type { Comment } from "../../comment/object";
import type { Listing } from "../../listing/listing";
import type { Post } from "../../post/object";
import type { PostSort } from "../../post/types";
import type { Subreddit } from "../../subreddit/object";
import type { RedditObject } from "../../types";
import type { MyUserData } from "../my-user/object";
import type { OtherUserData } from "../other-user/object";
import type { UserItemsSort } from "../types";
import type { User, UserData } from "./object";

import { BaseControls } from "../../base-controls";
import { CommentListing } from "../../comment/listing/listing";
import { fakeListingAfter } from "../../listing/util";
import { PostListing } from "../../post/listing";
import { assertKind, fromRedditData } from "../../util";
import { MyUser } from "../my-user/object";
import { OtherUser } from "../other-user/object";

/**
* The base controls for interacting with users.
*
* @category Controls
*/
export class BaseUserControls extends BaseControls {
/** @internal */
constructor(client: Client) {
super(client, "u/");
}

/**
* Fetch a user's subreddit.
*
* @param username The user who's subreddit to fetch.
*
* @returns A promise that resolves to the user's subreddit.
*/
async fetchSubreddit(username: string): Promise<Subreddit> {
return this.client.subreddits.fetch(`u_${username}`);
}

/**
* Get a Listing of all the posts a user has made.
*
* @param username The user to get posts from.
* @param sort How to sort the posts.
*
* @returns A sorted Listing of posts.
*/
getPosts(username: string, sort: PostSort = "new"): Listing<Post> {
const request = { url: `user/${username}/submitted`, query: { sort } };
const context = { request, client: this.client };
return new PostListing(fakeListingAfter(""), context);
}

/**
* Get a Listing of all the comments a user has made.
*
* @param username The user to get comments from.
* @param sort How to sort the comments.
*
* @returns A sorted Listing of comments.
*/
getSortedComments(
username: string,
sort: UserItemsSort = "new"
): Listing<Comment> {
const request = { url: `user/${username}/comments`, query: { sort } };
const context = { request, client: this.client };
return new CommentListing(fakeListingAfter(""), context);
}

/** @internal */
fromRaw(raw: RedditObject): User {
assertKind("t2", raw);

const rDat = raw.data;
const data: UserData = fromRedditData(rDat);

// "coins" is only set in the personal user response.
return "coins" in rDat
? new MyUser(this.client.me, data as MyUserData)
: new OtherUser(this.client.users, data as OtherUserData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import type { Listing } from "../../listing/listing";
import type { Post } from "../../post/object";
import type { PostSort } from "../../post/types";
import type { Subreddit } from "../../subreddit/object";
import type { UserControls } from "../controls";
import type { UserItemsSort } from "../types";
import type { BaseUserControls } from "./controls";

import { Content } from "../../content";

Expand Down Expand Up @@ -44,7 +44,7 @@ export interface UserData extends ContentData {
* Whether or not this user is a friend of the authorized user.
*
* @note This is only provided if you use {@link UserControls.fetch}, *not* if
* you use {@link UserControls.fetchMe}.
* you use {@link MyUserControls.fetch}.
*/
isFriend?: boolean;

Expand Down Expand Up @@ -96,10 +96,10 @@ export abstract class User extends Content implements UserData {
totalKarma: number;
verified: boolean;

protected controls: UserControls;
protected controls: BaseUserControls;

/** @internal */
constructor(controls: UserControls, data: UserData) {
constructor(controls: BaseUserControls, data: UserData) {
super(data);
this.controls = controls;

Expand Down Expand Up @@ -127,9 +127,7 @@ export abstract class User extends Content implements UserData {
*
* @returns A promise that resolves to the newly fetched user.
*/
async refetch(): Promise<User> {
return this.controls.fetch(this.name);
}
abstract refetch(): Promise<User>;

/**
* Fetch the user subreddit for this user.
Expand Down
115 changes: 0 additions & 115 deletions src/reddit/user/controls.ts

This file was deleted.

24 changes: 24 additions & 0 deletions src/reddit/user/my-user/controls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { Data } from "../../../helper/types";
import type { RedditObject } from "../../types";
import type { MyUser } from "./object";

import { BaseUserControls } from "../base/controls";

/**
* Various methods to allow you to interact with the authorized user.
*
* @category Controls
*/
export class MyUserControls extends BaseUserControls {
/**
* Fetch the details of the authorized user.
*
* @returns The user.
*/
async fetch(): Promise<MyUser> {
const userData: Data = await this.gateway.get("api/v1/me");
// /me doesn't return a wrapped object, so we have to make it ourselves.
const raw: RedditObject = { kind: "t2", data: userData };
return this.client.users.fromRaw(raw) as MyUser;
}
}

0 comments on commit 57adf74

Please sign in to comment.