UNPKG

@chez14/mal-api-lite

Version:
1 lines 12.5 kB
{"version":3,"sources":["../src/constants.ts","../src/client.ts"],"names":["got","randomBytes","URL"],"mappings":"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","file":"client.cjs","sourcesContent":["export const PKG_VERSION = process.env.PKG_VERSION || '-dev';\n","import { randomBytes } from 'node:crypto';\nimport got, { Got as GotInstance, Options as GotOptions } from 'got';\nimport { URL } from 'url';\nimport { PKG_VERSION } from './constants.js';\nimport { BaseRequester, PaginatableRequestParam, RequestParam, TokenResponse } from './types.js';\n\nexport interface Options {\n clientId?: string;\n clientSecret?: string;\n accessToken?: string;\n refreshToken?: string;\n gotOptions?: GotOptions;\n gotOAuthOptions?: GotOptions;\n autoRefreshAccessToken?: boolean;\n}\n\nexport class MALClient implements BaseRequester {\n\n public clientId?: string;\n\n public clientSecret?: string;\n\n public accessToken?: string;\n\n public refreshToken?: string;\n\n public got: GotInstance;\n\n public gotOAuth: GotInstance;\n\n public PKCEChallangeGenerateSize = 32;\n\n public userAgent = '@chez14/mal-api-lite';\n\n public malApiBaseUrl = 'https://api.myanimelist.net/v2/';\n\n public malOAuthUrl = 'https://myanimelist.net/v1/oauth2/';\n\n /**\n * Create MAL API Client\n *\n * @param param0 Your trusty configuration\n */\n public constructor({ clientId, clientSecret, accessToken, refreshToken, gotOptions, gotOAuthOptions }: Options) {\n if ((!clientSecret || !clientId) && !(accessToken || refreshToken)) {\n // if either ( clientSecret or clientId ) not preset, AND accessToken or\n // refreshToken is provided...\n throw new Error(\n 'You need to provide both (`clientSecret` and `clientId`) OR one of (`accessToken` or `refreshToken`)',\n );\n }\n\n this.clientId = clientId;\n this.clientSecret = clientSecret;\n this.accessToken = accessToken;\n this.refreshToken = refreshToken;\n\n this.userAgent += ` v${PKG_VERSION}`;\n\n this.got = got.extend({\n prefixUrl: this.malApiBaseUrl,\n responseType: 'json',\n headers: { 'user-agent': this.userAgent },\n hooks: {\n beforeRequest: [\n (options) => {\n if (this.accessToken) {\n options.headers.authorization = `Bearer ${this.accessToken}`;\n } else {\n options.headers['X-MAL-CLIENT-ID'] = this.clientId;\n }\n }\n ]\n },\n ...gotOptions,\n });\n this.gotOAuth = got.extend({\n prefixUrl: this.malOAuthUrl,\n headers: { 'user-agent': this.userAgent },\n responseType: 'json',\n ...gotOAuthOptions,\n });\n }\n\n\n\n /**\n * Get Access Token & Refresh Token from given Authorization Code.\n *\n * @param authCode Authorization code\n * @param codeVerifier PKCE Code Challenge\n * @param redirectUri Redirect url, specified on on previous step\n */\n public async resolveAuthCode(authCode: string, codeVerifier: string, redirectUri?: string): Promise<TokenResponse> {\n if (!this.clientSecret || !this.clientId) {\n throw new Error('clientSecret and clientId must be filled to use this function!');\n }\n\n const resp = await this.gotOAuth.post<TokenResponse>('token', {\n form: {\n client_id: this.clientId,\n client_secret: this.clientSecret,\n grant_type: 'authorization_code',\n code: authCode,\n redirect_uri: redirectUri,\n code_verifier: codeVerifier,\n },\n });\n const { access_token, refresh_token } = resp.body;\n this.accessToken = access_token;\n this.refreshToken = refresh_token;\n return resp.body;\n }\n\n /**\n * Generate OAuth URL to gain access to user account on MyAnimeList platform.\n * Will require clientId and clientSecret from custructor.\n *\n * @param codeChallenge PKCE Code Challenge\n * @param redirectUri If you have more than one Redirect URL, please specify\n * the url you use.\n * @param state Your app state\n * @param codeChallengeMethod Only accept \"plain\". Don't change unless you\n * know what you're doing!\n */\n public getOAuthURL(\n redirectUri?: string,\n codeChallenge?: string,\n state?: string,\n ): { url: string; codeChallenge: string; state?: string } {\n if (!this.clientId) {\n throw new Error('clientId must be filled to use this function!');\n }\n\n if (!codeChallenge) {\n codeChallenge = randomBytes(this.PKCEChallangeGenerateSize).toString('base64url');\n }\n\n const query: Record<string, string | undefined> = {\n response_type: 'code',\n client_id: this.clientId,\n state,\n redirect_uri: redirectUri,\n code_challenge: codeChallenge,\n code_challenge_method: 'plain',\n };\n\n const urlBuilder = new URL('authorize', this.gotOAuth.defaults.options.prefixUrl);\n Object.keys(query).forEach((key) => {\n if (query[key]) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n urlBuilder.searchParams.append(key, query[key]!);\n }\n });\n\n return { url: urlBuilder.toString(), codeChallenge, state };\n }\n\n\n\n /**\n * Refresh your access token with refresh token.\n *\n * @param refreshToken Custom refresh token\n */\n public async resolveRefreshToken(refreshToken?: string): Promise<TokenResponse> {\n if (!refreshToken) {\n refreshToken = this.refreshToken;\n }\n\n if (!refreshToken) {\n throw Error('No refreshToken provided.');\n }\n\n const resp = await this.gotOAuth.post<TokenResponse>('token', {\n form: {\n client_id: this.clientId,\n client_secret: this.clientSecret,\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n },\n });\n const { access_token, refresh_token } = resp.body;\n this.accessToken = access_token;\n this.refreshToken = refresh_token;\n return resp.body;\n }\n\n\n protected preprocessParam(param?: RequestParam): RequestParam | undefined {\n if (param?.fields && Array.isArray(param.fields)) {\n param.fields = param.fields.join(',');\n }\n\n return param;\n }\n\n\n /**\n * Do HTTP GET stuffs.\n *\n * @param resource Url to call\n * @param param Parameter body\n */\n public async get<T = any>(resource: string, param?: RequestParam | PaginatableRequestParam): Promise<T> { // eslint-disable-line @typescript-eslint/no-explicit-any\n param = this.preprocessParam(param);\n\n const response = await this.got.get<T>(resource, {\n searchParams: param,\n });\n\n return response.body;\n }\n\n /**\n * Do HTTP POST stuffs.\n *\n * @param resource Url to call\n * @param param Parameter body\n */\n public async post<T = any>(resource: string, param?: RequestParam): Promise<T> { // eslint-disable-line @typescript-eslint/no-explicit-any\n param = this.preprocessParam(param);\n\n const response = await this.got.post<T>(resource, {\n form: param,\n });\n return response.body;\n }\n\n\n\n /**\n * Do HTTP PATCH stuffs.\n *\n * @param resource Url to call\n * @param param Parameter body\n */\n public async patch<T = any>(resource: string, param?: RequestParam): Promise<T> { // eslint-disable-line @typescript-eslint/no-explicit-any\n param = this.preprocessParam(param);\n\n const response = await this.got.patch<T>(resource, {\n form: param,\n });\n return response.body;\n }\n\n /**\n * Do HTTP DELETE stuffs.\n *\n * @param resource Url to call\n * @param param Parameter body (discouraged)\n */\n public async delete<T = any>(resource: string): Promise<T> { // eslint-disable-line @typescript-eslint/no-explicit-any\n const response = await this.got.delete<T>(resource);\n return response.body;\n }\n}\n"]}