Skip to content

Commit

Permalink
Update some outdated documentation and make some functions better
Browse files Browse the repository at this point in the history
  • Loading branch information
TTTaevas committed Mar 25, 2024
1 parent 8b2530d commit 3f8e51c
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 56 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
You are more than welcome to contribute to this package if you feel like it!! If you want to get started with developing this package, read below:
You are more than welcome to contribute to this package if you feel like it!! If you want to get started with developing this package, fork it, then read below:

```bash
git clone https://github.com/TTTaevas/osu-api-v2-js.git # Clone this package's repository
git clone https://github.com/<your_github>/osu-api-v2-js.git # Clone your fork of this package's repository
yarn install # Add its dependencies using Yarn Classic

# Duplicate the .env.example file and rename it .env, then fill it with the details of one of your clients
Expand Down
2 changes: 1 addition & 1 deletion lib/beatmap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export namespace Beatmap {

/**
* Get extensive beatmap data about whichever beatmap you want!
* @param beatmap An object with the id of the beatmap you're trying to get
* @param beatmap The beatmap or the id of the beatmap you're trying to get
*/
export async function getOne(this: API, beatmap: Beatmap["id"] | Beatmap): Promise<Extended.WithFailtimesBeatmapset> {
return await this.request("get", `beatmaps/${getId(beatmap)}`)
Expand Down
2 changes: 1 addition & 1 deletion lib/beatmapset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ export namespace Beatmapset {

/**
* Get extensive beatmapset data about whichever beatmapset you want!
* @param beatmapset An object with the id of the beatmapset you're trying to get
* @param beatmapset The beatmapset or the id of the beatmapset you're trying to get
*/
export async function getOne(this: API, beatmapset: Beatmapset["id"] | Beatmapset): Promise<Beatmapset.Extended.Plus> {
return await this.request("get", `beatmapsets/${getId(beatmapset)}`)
Expand Down
65 changes: 34 additions & 31 deletions lib/forum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export namespace Forum {
/**
* Edit a ForumPost! Note that it can be the initial one of a ForumTopic!
* @scope {@link Scope"forum.write"}
* @param post An object with the id of the post in question
* @param post The post or the id of the post in question
* @param new_text The new content of the post (replaces the old content)
* @returns The edited ForumPost
*/
Expand Down Expand Up @@ -94,7 +94,19 @@ export namespace Forum {
* @param poll If you want to make a poll, specify the parameters of that poll!
* @returns An object with the topic you've made, and its first initial post (which uses your `text`)
*/
export async function create(this: API, forum_id: number, title: string, text: string, poll?: PollConfig): Promise<{topic: Forum.Topic, post: Forum.Post}> {
export async function create(this: API, forum_id: number, title: string, text: string, poll?: {
title: string
/** The things the users can vote for */
options: string[]
/** Length of voting period in days, 0 means forever */
length_days: number
/** The maximum amount of votes per user! (defaults to **1**) */
max_options?: number
/** Do you allow users to change their vote? (defaults to **false**) */
vote_change?: boolean
/** Should the results of the poll be hidden while the voting period is still active? (defaults to **false**) */
hide_results?: boolean
}): Promise<{topic: Forum.Topic, post: Forum.Post}> {
const with_poll = poll !== undefined
const options = poll?.options !== undefined ? poll.options.toString().replace(/,/g, "\n") : undefined

Expand All @@ -109,21 +121,21 @@ export namespace Forum {
}

/**
* Make and send a ForumPost in a ForumTopic!
* Make and send a Forum.Post in a Forum.Topic!
* @scope {@link Scope"forum.write"}
* @param topic An object with the id of the topic you're making your reply in
* @param topic The topic or the id of the topic you're making your reply in
* @param text Your reply! Your message!
* @returns The reply you've made!
* @returns The reply you've made, as a Forum.Post!
*/
export async function reply(this: API, topic: Topic["id"] | Topic, text: string): Promise<Post> {
return await this.request("post", `forums/topics/${getId(topic)}/reply`, {body: text})
}

/**
* Edit the title of a ForumTopic!
* Edit the title of a Forum.Topic!
* @scope {@link Scope"forum.write"}
* @remarks Use `editForumPost` if you wanna edit the post at the top of the topic
* @param topic An object with the id of the topic in question
* @param topic The topic or the id of the topic in question
* @param new_title The new title of the topic
* @returns The edited ForumTopic
*/
Expand All @@ -136,30 +148,21 @@ export namespace Forum {
* Get a forum topic, as well as its main post (content) and the posts that were sent in it!
* @remarks The oldest post of a topic is the text of a topic
* @param topic An object with the id of the topic in question
* @param limit How many `posts` maximum, up to 50 (defaults to **20**)
* @param sort "id_asc" to have the oldest post at the beginning of the `posts` array, "id_desc" to have the newest instead (defaults to **id_asc**)
* @param first_post (ignored if `cursor_string`) An Object with the id of the first post to be returned in `posts`
* @param cursor_string Use a response's `cursor_string` with the same parameters to get the next "page" of results, so `posts` in this instance!
* @param config How many results maximum, how to sort them, etc...
*/
export async function getTopicAndPosts(this: API, topic: Topic["id"] | Topic, limit: number = 20, sort: "id_asc" | "id_desc" = "id_asc",
first_post?: Post["id"] | Post, cursor_string?: string): Promise<{posts: Post[], topic: Topic, cursor_string: string | null}> {
const start = sort === "id_asc" && first_post ? getId(first_post) : undefined
const end = sort === "id_desc" && first_post ? getId(first_post) : undefined
return await this.request("get", `forums/topics/${getId(topic)}`, {sort, limit, start, end, cursor_string})
export async function getTopicAndPosts(this: API, topic: Topic["id"] | Topic, config?: {
/** The id (or the post itself) of the first post to be returned in `posts` (irrelevant if using a `cursor_string`) */
first_post?: Post["id"] | Post
/** How many `posts` maximum, up to 50 */
limit?: number
/** "id_asc" to have the oldest post at the beginning of the `posts` array, "id_desc" to have the newest instead */
sort?: "id_asc" | "id_desc"
/** Use a response's `cursor_string` with the same parameters to get the next "page" of results, so `posts` in this instance! */
cursor_string?: string
}): Promise<{topic: Topic, posts: Post[], cursor_string: string | null}> {
const start = config?.sort === "id_asc" && config?.first_post ? getId(config.first_post) : undefined
const end = config?.sort === "id_desc" && config?.first_post ? getId(config.first_post) : undefined
return await this.request("get", `forums/topics/${getId(topic)}`,
{start, end, sort: config?.sort, limit: config?.limit, cursor_string: config?.cursor_string})
}
}

/** Feel free to use this interface to help you create polls with {@link API.createForumTopic}! */
export interface PollConfig {
title: string
/** The things the users can vote for */
options: string[]
/** Length of voting period in days, 0 means forever */
length_days: number
/** (defaults to 1) The maximum amount of votes per user! */
max_options?: number
/** defaults to false) Do you allow users to change their vote? */
vote_change?: boolean
/** (defaults to false) Should the results of the poll be hidden while the voting period is still active? */
hide_results?: boolean
}
2 changes: 1 addition & 1 deletion lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export { Ranking } from "./ranking.js"
export { Event } from "./event.js"

export { Changelog } from "./changelog.js"
export { Forum, PollConfig } from "./forum.js"
export { Forum } from "./forum.js"
export { WikiPage } from "./wiki.js"
export { NewsPost } from "./news.js"
export { Home } from "./home.js"
Expand Down
4 changes: 2 additions & 2 deletions lib/multiplayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export namespace Multiplayer {

/**
* Get data about a lazer multiplayer room (realtime or playlists)!
* @param room An object with the id of the room, is at the end of its URL (after `/multiplayer/rooms/`)
* @param room The room or the id of the room, can be found at the end of its URL (after `/multiplayer/rooms/`)
*/
export async function getOne(this: API, room: number | Multiplayer.Room): Promise<Multiplayer.Room> {
return await this.request("get", `rooms/${getId(room)}`)
Expand All @@ -123,7 +123,7 @@ export namespace Multiplayer {
/**
* Get the room stats of all the users of that room!
* @scope {@link Scope"public"}
* @param room An object with the id of the room in question
* @param room The room or the id of the room in question
*/
export async function getLeaderboard(this: API, room: number | Multiplayer.Room): Promise<Multiplayer.Room.Leader[]> {
const response = await this.request("get", `rooms/${getId(room)}/leaderboard`)
Expand Down
37 changes: 21 additions & 16 deletions lib/ranking.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Beatmapset } from "./beatmapset.js"
import { API } from "./index.js"
import { Spotlight as SpotlightInterface, Rulesets, getId } from "./misc.js"
import { User } from "./user.js"
import { API, Beatmapset, Rulesets, Spotlight as SpotlightInterface, User } from "./index.js"
import { getId } from "./misc.js"

interface RankingBare {
interface Ranking {
cursor: {
/** The number of the next page, is null if no more results are available */
page: number | null
Expand All @@ -14,12 +12,12 @@ interface RankingBare {

export namespace Ranking {
/** @obtainableFrom {@link API.getUserRanking} */
export interface User extends RankingBare {
export interface User extends Ranking {
ranking: User.Statistics.WithUser[]
}

/** @obtainableFrom {@link API.getCountryRanking} */
export interface Country extends RankingBare {
export interface Country extends Ranking {
ranking: {
/** Same as `country.code` */
code: string
Expand All @@ -46,14 +44,20 @@ export namespace Ranking {
* Get the top players of the game, with some filters!
* @param ruleset Self-explanatory, is also known as "Gamemode"
* @param type Rank players by their performance points or by their ranked score?
* @param page Imagine the array you get as a page, it can only have a maximum of 50 players, while 50 others may be on the next one (defaults to **1**)
* @param filter What kind of players do you want to see? Keep in mind `friends` has no effect if no authorized user (defaults to **all**)
* @param country Only get players from a specific country, using its ISO 3166-1 alpha-2 country code! (France would be `FR`, United States `US`)
* @param variant If `type` is `performance` and `ruleset` is mania, choose between 4k and 7k!
* @param config Specify which page, country, filter out non-friends...
*/
export async function getUser(this: API, ruleset: Rulesets, type: "performance" | "score", page: number = 1, filter: "all" | "friends" = "all",
country?: string, variant?: "4k" | "7k"): Promise<Ranking.User> {
return await this.request("get", `rankings/${Rulesets[ruleset]}/${type}`, {page, filter, country, variant})
export async function getUser(this: API, ruleset: Rulesets, type: "performance" | "score", config?: {
/** Imagine the array you get as a page, it can only have a maximum of 50 players, while 50 others may be on the next one */
page?: number,
/** What kind of players do you want to see? Keep in mind `friends` has no effect if no authorized user */
filter?: "all" | "friends",
/** Only get players from a specific country, using its ISO 3166-1 alpha-2 country code! (France would be `FR`, United States `US`) */
country?: string
/** If `type` is `performance` and `ruleset` is mania, choose between 4k and 7k! */
variant?: "4k" | "7k"
}): Promise<Ranking.User> {
return await this.request("get", `rankings/${Rulesets[ruleset]}/${type}`,
{page: config?.page, filter: config?.filter, country: config?.country, variant: config?.variant})
}

/**
Expand All @@ -68,7 +72,7 @@ export namespace Ranking {
/** Get the top 50 players who have the most total kudosu! */
export async function getKudosu(this: API): Promise<User.WithKudosu[]> {
const response = await this.request("get", "rankings/kudosu")
return response.ranking
return response.ranking // It's the only property
}

/**
Expand All @@ -77,7 +81,8 @@ export namespace Ranking {
* @param spotlight The spotlight in question
* @param filter What kind of players do you want to see? Keep in mind `friends` has no effect if no authorized user (defaults to **all**)
*/
export async function getSpotlight(this: API, ruleset: Rulesets, spotlight: SpotlightInterface["id"] | SpotlightInterface, filter: "all" | "friends" = "all"): Promise<Ranking.Spotlight> {
export async function getSpotlight(this: API, ruleset: Rulesets, spotlight: SpotlightInterface["id"] | SpotlightInterface, filter: "all" | "friends" = "all"):
Promise<Ranking.Spotlight> {
return await this.request("get", `rankings/${Rulesets[ruleset]}/charts`, {spotlight: getId(spotlight), filter})
}
}
4 changes: 2 additions & 2 deletions lib/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ const testEvent = async (): Promise<boolean> => {
const testForum = async (): Promise<boolean> => {
let okay = true
console.log("\n===> FORUM")
const a = await attempt(api.getForumTopicAndPosts, 1848236, 2)
const a = await attempt(api.getForumTopicAndPosts, 1848236, {limit: 2})
if (!isOk(a, !a || (a.topic.title === "survey" && validate(a.topic, "Forum.Topic") && validate(a.posts, "Forum.Post")))) okay = false
return okay
}
Expand Down Expand Up @@ -267,7 +267,7 @@ const testRanking = async (): Promise<boolean> => {

const a = await attempt(api.getKudosuRanking)
if (!isOk(a, !a || (a[0].kudosu.total > 10000 && validate(a, "User.WithKudosu")))) okay = false
const b = await attempt(api.getUserRanking, osu.Rulesets.osu, "score", 1, "all", "FR")
const b = await attempt(api.getUserRanking, osu.Rulesets.osu, "score", {country: "FR"})
if (!isOk(b, !b || (b.ranking[0].level.current > 106 && validate(b, "Ranking.User")), 2)) okay = false
const c = await attempt(api.getCountryRanking, osu.Rulesets.osu)
if (!isOk(c, !c || (c.ranking[0].code === "US" && validate(c, "Ranking.Country")))) okay = false
Expand Down

0 comments on commit 3f8e51c

Please sign in to comment.