Skip to content

Commit

Permalink
revokeToken() returns void, schedule testing
Browse files Browse the repository at this point in the history
  • Loading branch information
TTTaevas committed Oct 28, 2024
1 parent 31eb8de commit 00eb8d9
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 53 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'

- run: yarn
- run: yarn publish
- run: npm install
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ on:
pull_request:
branches:
- "**"
schedule:
- cron: "45 10 12 * *"

jobs:
build:
Expand Down
2 changes: 1 addition & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
lib/
docs/
tests/
yarn.lock
package-lock.json
tsconfig.json
CONTRIBUTING.md
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ You are more than welcome to contribute to this package if you feel like it!! If

```bash
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
npm install # Add its dependencies using npm

# Duplicate the .env.example file and rename it .env, then fill it with the details of one of your clients
# Note: the env variables starting with DEV are only used in test_authorized if the server used isn't osu.ppy.sh (and is for example a development server)
# As a reminder, you may find and create your clients at https://osu.ppy.sh/home/account/edit#oauth

yarn run test # Check that everything seems to be in order
npm run test # Check that everything seems to be in order
```

From this point onwards, you can work on debugging and adding features by customizing the lib/tests/test.ts or lib/tests/test_authorized.ts file!

```bash
yarn run test # Run the lib/tests/test.ts file
yarn run test-authorized # Run the lib/tests/test_authorized.ts file
npm run test # Run the lib/tests/guest.ts file
npm run test-authenticated # Run the lib/tests/authenticated.ts file
```
18 changes: 10 additions & 8 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,19 +302,21 @@ export class API {
return api
}

/** Revoke your current token! Revokes the refresh token as well */
public async revokeToken(): Promise<true> {
/**
* Revoke your current token! This revokes the refresh token as well
* @remarks Uses {@link API.route_api} instead of {@link API.route_token}, as normally expected by the server
*/
public async revokeToken(): Promise<void> {
// Note that unlike when getting a token, we actually need to use the normal route to revoke a token for some reason
await this.request("delete", "oauth/tokens/current")
return true
return await this.request("delete", "oauth/tokens/current")
}


// REFRESH TOKEN STUFF

private _refresh_token?: string
/**
* Valid for an unknown amount of time, allows you to get a new token without going through the Authorization Code Grant again!
* Valid for an unknown amount of time, it allows you to get a new token without going through the Authorization Code Grant again!
* Use {@link API.refreshToken} to do that
*/
get refresh_token() {return this._refresh_token}
Expand Down Expand Up @@ -432,7 +434,7 @@ export class API {
* @returns A Promise with the API's response
*/
public async request(method: "get" | "post" | "put" | "delete", endpoint: string, parameters: {[k: string]: any} = {},
settings?: ChildAPI["additional_fetch_settings"],info: {number_try: number, just_refreshed: boolean} = {number_try: 1, just_refreshed: false}):
settings?: ChildAPI["additional_fetch_settings"], info: {number_try: number, just_refreshed: boolean} = {number_try: 1, just_refreshed: false}):
Promise<any> {
let to_retry = false
let error_object: Error | undefined
Expand Down Expand Up @@ -467,7 +469,7 @@ export class API {
"Content-Type": "application/json",
"User-Agent": "osu-api-v2-js (https://github.com/TTTaevas/osu-api-v2-js)",
"Authorization": `${this.token_type} ${this.access_token}`,
"x-api-version": "20241027",
"x-api-version": "20241028",
...settings?.headers // written that way, custom headers with (for example) only a user-agent would only overwrite the default user-agent
},
body: method !== "get" ? JSON.stringify(parameters) : undefined, // parameters are here if request is NOT GET
Expand Down Expand Up @@ -812,7 +814,7 @@ export class API {
}

/**
* Created with {@link API.withSettings}, this special version of the {@link API} specifies additional settings to every request!
* Created with {@link API.withSettings}, this special version of the {@link API} specifies additional fetch settings to every request!
* @remarks This **is not** to be used for any purpose other than calling methods; The original {@link ChildAPI.original} handles tokens & configuration
*/
export class ChildAPI extends API {
Expand Down
22 changes: 3 additions & 19 deletions lib/tests/authenticated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import ajv from "ajv"

import { exec } from "child_process"
import http from "http"
import { AR, fixDate, getCurrentDateString } from "./exports.js"


if (process.env.REDIRECT_URI === undefined) {throw new Error("❌ The SECRET has not been defined in the environment variables!")}
const generator = tsj.createGenerator({path: "lib/index.ts", additionalProperties: true})
Expand Down Expand Up @@ -69,23 +71,6 @@ async function attempt<T extends (...args: any[]) => any>(fun: T, ...args: Param
}
}

// ajv will not work properly if type is not changed from string to object where format is date-time
function fixDate(x: any) {
if (typeof x === "object" && x !== null) {
if (x["format"] && x["format"] === "date-time" && x["type"] && x["type"] === "string") {
x["type"] = "object"
}

const k = Object.keys(x)
const v = Object.values(x)
for (let i = 0; i < k.length; i++) {
x[k[i]] = fixDate(v[i])
}
}

return x
}

function validate(object: unknown, schemaName: string): boolean {
try {
const schema = fixDate(generator.createSchema(schemaName))
Expand Down Expand Up @@ -130,8 +115,6 @@ function validate(object: unknown, schemaName: string): boolean {
}
}

type AR<T extends (...args: any) => any> = Awaited<ReturnType<T>>;

class Test<
F extends (...args: any[]) => Promise<T>,
T,
Expand Down Expand Up @@ -312,6 +295,7 @@ const test = async (): Promise<void> => {
const url = osu.generateAuthorizationURL(id, redirect_uri, scopes, server)
const code = await getCode(url)
api = await osu.API.createAsync(id, secret, {code, redirect_uri}, {verbose: "all", timeout: 30, server, retry_on_timeout: true})
// api = api.withSettings({headers: {"x-api-version": getCurrentDateString()}})

const tests = [
testChat,
Expand Down
30 changes: 30 additions & 0 deletions lib/tests/exports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export type AR<T extends (...args: any) => any> = Awaited<ReturnType<T>>;

/** ajv will not work properly if type is not changed from string to object where format is date-time */
export function fixDate(arg: any) {
if (typeof arg === "object" && arg !== null) {
if (arg["format"] && arg["format"] === "date-time" && arg["type"] && arg["type"] === "string") {
arg["type"] = "object"
}

const keys = Object.keys(arg)
const value = Object.values(arg)
for (let i = 0; i < keys.length; i++) {
arg[keys[i]] = fixDate(value[i])
}
}

return arg
}

/** cool for automatically coming up with the latest x-api-verison */
export function getCurrentDateString(): string {
const today = new Date()
const year = today.getFullYear()
const month = String(today.getMonth() + 1).padStart(2, "0") // Months are zero-based
const day = String(today.getDate()).padStart(2, "0")

const str = `${year}${month}${day}`
console.log("Using the following x-api-version:", str)
return str
}
21 changes: 2 additions & 19 deletions lib/tests/guest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import util from "util"
// A basic example would be WikiPage's available_locales, which could've been WikiPage["locale"]
import tsj from "ts-json-schema-generator"
import ajv from "ajv"
import { AR, fixDate, getCurrentDateString } from "./exports.js"


let api: osu.API
Expand All @@ -28,23 +29,6 @@ async function attempt<T extends (...args: any[]) => any>(fun: T, ...args: Param
}
}

// ajv will not work properly if type is not changed from string to object where format is date-time
function fixDate(arg: any) {
if (typeof arg === "object" && arg !== null) {
if (arg["format"] && arg["format"] === "date-time" && arg["type"] && arg["type"] === "string") {
arg["type"] = "object"
}

const keys = Object.keys(arg)
const value = Object.values(arg)
for (let i = 0; i < keys.length; i++) {
arg[keys[i]] = fixDate(value[i])
}
}

return arg
}

function validate(object: unknown, schemaName: string): boolean {
try {
const schema = fixDate(generator.createSchema(schemaName))
Expand Down Expand Up @@ -72,8 +56,6 @@ function validate(object: unknown, schemaName: string): boolean {
}
}

type AR<T extends (...args: any) => any> = Awaited<ReturnType<T>>;

class Test<
F extends (...args: any[]) => Promise<T>,
T,
Expand Down Expand Up @@ -353,6 +335,7 @@ const testOther = () => [

const test = async (id: number, secret: string): Promise<void> => {
api = await osu.API.createAsync(id, secret, undefined, {verbose: "all", timeout: 30, retry_on_timeout: true})
// api = api.withSettings({headers: {"x-api-version": getCurrentDateString()}})

const tests = [
testBeatmapPack,
Expand Down

0 comments on commit 00eb8d9

Please sign in to comment.