@twurple/api-call
Advanced tools
+2
-3
@@ -1,2 +0,2 @@ | ||
| import { type Response } from '@d-fischer/cross-fetch'; | ||
| /// <reference types="node" /> | ||
| import type { TwitchApiCallFetchOptions, TwitchApiCallOptions } from './TwitchApiCallOptions'; | ||
@@ -15,5 +15,4 @@ /** | ||
| * @param fetchOptions Additional options to be passed to the `fetch` function. | ||
| * @param mockServerPort | ||
| */ | ||
| export declare function callTwitchApiRaw(options: TwitchApiCallOptions, clientId?: string, accessToken?: string, authorizationType?: string, fetchOptions?: TwitchApiCallFetchOptions, mockServerPort?: number): Promise<Response>; | ||
| export declare function callTwitchApiRaw(options: TwitchApiCallOptions, clientId?: string, accessToken?: string, authorizationType?: string, fetchOptions?: TwitchApiCallFetchOptions): Promise<Response>; | ||
| /** | ||
@@ -20,0 +19,0 @@ * Makes a call to the Twitch API using given credentials. |
+14
-22
@@ -1,8 +0,4 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.callTwitchApi = exports.callTwitchApiRaw = void 0; | ||
| const cross_fetch_1 = require("@d-fischer/cross-fetch"); | ||
| const qs_1 = require("@d-fischer/qs"); | ||
| const transform_1 = require("./helpers/transform"); | ||
| const url_1 = require("./helpers/url"); | ||
| import { stringify } from 'qs'; | ||
| import { handleTwitchApiResponseError, transformTwitchApiResponse } from './helpers/transform'; | ||
| import { getTwitchApiUrl } from './helpers/url'; | ||
| /** | ||
@@ -20,11 +16,9 @@ * Makes a call to the Twitch API using the given credentials, returning the raw Response object. | ||
| * @param fetchOptions Additional options to be passed to the `fetch` function. | ||
| * @param mockServerPort | ||
| */ | ||
| async function callTwitchApiRaw(options, clientId, accessToken, authorizationType, fetchOptions = {}, mockServerPort) { | ||
| var _a, _b; | ||
| const type = (_a = options.type) !== null && _a !== void 0 ? _a : 'helix'; | ||
| const url = (0, url_1.getTwitchApiUrl)(options.url, type, mockServerPort); | ||
| const params = (0, qs_1.stringify)(options.query, { arrayFormat: 'repeat', addQueryPrefix: true }); | ||
| export async function callTwitchApiRaw(options, clientId, accessToken, authorizationType, fetchOptions = {}) { | ||
| const type = options.type ?? 'helix'; | ||
| const url = getTwitchApiUrl(options.url, type); | ||
| const params = stringify(options.query, { arrayFormat: 'repeat', addQueryPrefix: true }); | ||
| // eslint-disable-next-line @typescript-eslint/naming-convention | ||
| const headers = new cross_fetch_1.Headers({ Accept: 'application/json' }); | ||
| const headers = new Headers({ Accept: 'application/json' }); | ||
| let body = undefined; | ||
@@ -39,13 +33,12 @@ if (options.jsonBody) { | ||
| if (accessToken) { | ||
| headers.append('Authorization', `${type === 'helix' ? authorizationType !== null && authorizationType !== void 0 ? authorizationType : 'Bearer' : 'OAuth'} ${accessToken}`); | ||
| headers.append('Authorization', `${type === 'helix' ? authorizationType ?? 'Bearer' : 'OAuth'} ${accessToken}`); | ||
| } | ||
| const requestOptions = { | ||
| ...fetchOptions, | ||
| method: (_b = options.method) !== null && _b !== void 0 ? _b : 'GET', | ||
| method: options.method ?? 'GET', | ||
| headers, | ||
| body, | ||
| }; | ||
| return await (0, cross_fetch_1.default)(`${url}${params}`, requestOptions); | ||
| return await fetch(`${url}${params}`, requestOptions); | ||
| } | ||
| exports.callTwitchApiRaw = callTwitchApiRaw; | ||
| /** | ||
@@ -64,7 +57,6 @@ * Makes a call to the Twitch API using given credentials. | ||
| */ | ||
| async function callTwitchApi(options, clientId, accessToken, authorizationType, fetchOptions = {}) { | ||
| export async function callTwitchApi(options, clientId, accessToken, authorizationType, fetchOptions = {}) { | ||
| const response = await callTwitchApiRaw(options, clientId, accessToken, authorizationType, fetchOptions); | ||
| await (0, transform_1.handleTwitchApiResponseError)(response, options); | ||
| return await (0, transform_1.transformTwitchApiResponse)(response); | ||
| await handleTwitchApiResponseError(response, options); | ||
| return await transformTwitchApiResponse(response); | ||
| } | ||
| exports.callTwitchApi = callTwitchApi; |
@@ -1,9 +0,10 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.HttpStatusCodeError = void 0; | ||
| const common_1 = require("@twurple/common"); | ||
| import { CustomError } from '@twurple/common'; | ||
| /** | ||
| * Thrown whenever a HTTP error occurs. Some HTTP errors are handled in the library when they're expected. | ||
| */ | ||
| class HttpStatusCodeError extends common_1.CustomError { | ||
| export class HttpStatusCodeError extends CustomError { | ||
| _statusCode; | ||
| _url; | ||
| _method; | ||
| _body; | ||
| /** @private */ | ||
@@ -42,2 +43,1 @@ constructor(_statusCode, statusText, _url, _method, _body, isJson) { | ||
| } | ||
| exports.HttpStatusCodeError = HttpStatusCodeError; |
@@ -1,2 +0,1 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| export {}; |
@@ -1,10 +0,6 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.createBroadcasterQuery = void 0; | ||
| const common_1 = require("@twurple/common"); | ||
| function createBroadcasterQuery(user) { | ||
| import { extractUserId } from '@twurple/common'; | ||
| export function createBroadcasterQuery(user) { | ||
| return { | ||
| broadcaster_id: (0, common_1.extractUserId)(user), | ||
| broadcaster_id: extractUserId(user), | ||
| }; | ||
| } | ||
| exports.createBroadcasterQuery = createBroadcasterQuery; |
@@ -1,2 +0,2 @@ | ||
| import { type Response } from '@d-fischer/cross-fetch'; | ||
| /// <reference types="node" /> | ||
| import type { TwitchApiCallOptions } from '../TwitchApiCallOptions'; | ||
@@ -3,0 +3,0 @@ /** @private */ |
@@ -1,20 +0,15 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.transformTwitchApiResponse = exports.handleTwitchApiResponseError = void 0; | ||
| const qs_1 = require("@d-fischer/qs"); | ||
| const HttpStatusCodeError_1 = require("../errors/HttpStatusCodeError"); | ||
| import { stringify } from 'qs'; | ||
| import { HttpStatusCodeError } from '../errors/HttpStatusCodeError'; | ||
| /** @private */ | ||
| async function handleTwitchApiResponseError(response, options) { | ||
| var _a; | ||
| export async function handleTwitchApiResponseError(response, options) { | ||
| if (!response.ok) { | ||
| const isJson = response.headers.get('Content-Type') === 'application/json'; | ||
| const text = isJson ? JSON.stringify(await response.json(), null, 2) : await response.text(); | ||
| const params = (0, qs_1.stringify)(options.query, { arrayFormat: 'repeat', addQueryPrefix: true }); | ||
| const params = stringify(options.query, { arrayFormat: 'repeat', addQueryPrefix: true }); | ||
| const fullUrl = `${options.url}${params}`; | ||
| throw new HttpStatusCodeError_1.HttpStatusCodeError(response.status, response.statusText, fullUrl, (_a = options.method) !== null && _a !== void 0 ? _a : 'GET', text, isJson); | ||
| throw new HttpStatusCodeError(response.status, response.statusText, fullUrl, options.method ?? 'GET', text, isJson); | ||
| } | ||
| } | ||
| exports.handleTwitchApiResponseError = handleTwitchApiResponseError; | ||
| /** @private */ | ||
| async function transformTwitchApiResponse(response) { | ||
| export async function transformTwitchApiResponse(response) { | ||
| if (response.status === 204) { | ||
@@ -29,2 +24,1 @@ return undefined; // oof | ||
| } | ||
| exports.transformTwitchApiResponse = transformTwitchApiResponse; |
+14
-14
@@ -1,19 +0,20 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.getTwitchApiUrl = void 0; | ||
| import { getMockApiPort } from '@twurple/common'; | ||
| /** @internal */ | ||
| function getTwitchApiUrl(url, type, mockServerPort) { | ||
| export function getTwitchApiUrl(url, type) { | ||
| const mockServerPort = getMockApiPort(); | ||
| switch (type) { | ||
| case 'helix': { | ||
| const unprefixedUrl = url.replace(/^\//, ''); | ||
| if (mockServerPort) { | ||
| if (unprefixedUrl === 'eventsub/subscriptions') { | ||
| return `http://localhost:${mockServerPort}/${unprefixedUrl}`; | ||
| } | ||
| return `http://localhost:${mockServerPort}/mock/${unprefixedUrl}`; | ||
| } | ||
| return `https://api.twitch.tv/helix/${unprefixedUrl}`; | ||
| return mockServerPort | ||
| ? unprefixedUrl === 'eventsub/subscriptions' | ||
| ? `http://localhost:${mockServerPort}/${unprefixedUrl}` | ||
| : `http://localhost:${mockServerPort}/mock/${unprefixedUrl}` | ||
| : `https://api.twitch.tv/helix/${unprefixedUrl}`; | ||
| } | ||
| case 'auth': | ||
| return `https://id.twitch.tv/oauth2/${url.replace(/^\//, '')}`; | ||
| case 'auth': { | ||
| const unprefixedUrl = url.replace(/^\//, ''); | ||
| return mockServerPort | ||
| ? `http://localhost:${mockServerPort}/auth/${unprefixedUrl}` | ||
| : `https://id.twitch.tv/oauth2/${unprefixedUrl}`; | ||
| } | ||
| case 'custom': | ||
@@ -25,2 +26,1 @@ return url; | ||
| } | ||
| exports.getTwitchApiUrl = getTwitchApiUrl; |
+4
-13
@@ -1,13 +0,4 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.HttpStatusCodeError = exports.transformTwitchApiResponse = exports.handleTwitchApiResponseError = exports.createBroadcasterQuery = exports.callTwitchApiRaw = exports.callTwitchApi = void 0; | ||
| var apiCall_1 = require("./apiCall"); | ||
| Object.defineProperty(exports, "callTwitchApi", { enumerable: true, get: function () { return apiCall_1.callTwitchApi; } }); | ||
| Object.defineProperty(exports, "callTwitchApiRaw", { enumerable: true, get: function () { return apiCall_1.callTwitchApiRaw; } }); | ||
| var queries_external_1 = require("./helpers/queries.external"); | ||
| Object.defineProperty(exports, "createBroadcasterQuery", { enumerable: true, get: function () { return queries_external_1.createBroadcasterQuery; } }); | ||
| var transform_1 = require("./helpers/transform"); | ||
| Object.defineProperty(exports, "handleTwitchApiResponseError", { enumerable: true, get: function () { return transform_1.handleTwitchApiResponseError; } }); | ||
| Object.defineProperty(exports, "transformTwitchApiResponse", { enumerable: true, get: function () { return transform_1.transformTwitchApiResponse; } }); | ||
| var HttpStatusCodeError_1 = require("./errors/HttpStatusCodeError"); | ||
| Object.defineProperty(exports, "HttpStatusCodeError", { enumerable: true, get: function () { return HttpStatusCodeError_1.HttpStatusCodeError; } }); | ||
| export { callTwitchApi, callTwitchApiRaw } from './apiCall'; | ||
| export { createBroadcasterQuery } from './helpers/queries.external'; | ||
| export { handleTwitchApiResponseError, transformTwitchApiResponse } from './helpers/transform'; | ||
| export { HttpStatusCodeError } from './errors/HttpStatusCodeError'; |
@@ -1,2 +0,1 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| export {}; |
+6
-10
| { | ||
| "name": "@twurple/api-call", | ||
| "version": "7.4.0", | ||
| "version": "8.0.0", | ||
| "publishConfig": { | ||
@@ -15,2 +15,3 @@ "access": "public" | ||
| "sideEffects": false, | ||
| "type": "module", | ||
| "main": "lib", | ||
@@ -21,4 +22,3 @@ "types": "lib", | ||
| "types": "./lib/index.d.ts", | ||
| "require": "./lib/index.js", | ||
| "import": "./es/index.mjs" | ||
| "import": "./lib/index.js" | ||
| } | ||
@@ -36,6 +36,5 @@ }, | ||
| "dependencies": { | ||
| "@d-fischer/cross-fetch": "^5.0.1", | ||
| "@d-fischer/qs": "^7.0.2", | ||
| "@d-fischer/shared-utils": "^3.6.1", | ||
| "@twurple/common": "7.4.0", | ||
| "@twurple/common": "8.0.0", | ||
| "qs": "^6.14.0", | ||
| "tslib": "^2.0.3" | ||
@@ -47,7 +46,4 @@ }, | ||
| "lib", | ||
| "!lib/**/*.d.ts.map", | ||
| "es", | ||
| "!es/**/*.d.ts", | ||
| "!es/**/*.d.ts.map" | ||
| "!lib/**/*.d.ts.map" | ||
| ] | ||
| } |
| import fetch, { Headers } from '@d-fischer/cross-fetch'; | ||
| import { stringify } from '@d-fischer/qs'; | ||
| import { handleTwitchApiResponseError, transformTwitchApiResponse } from "./helpers/transform.mjs"; | ||
| import { getTwitchApiUrl } from "./helpers/url.mjs"; | ||
| /** | ||
| * Makes a call to the Twitch API using the given credentials, returning the raw Response object. | ||
| * | ||
| * @param options The configuration of the call. | ||
| * @param clientId The client ID of your application. | ||
| * @param accessToken The access token to call the API with. | ||
| * | ||
| * You need to obtain one using one of the [Twitch OAuth flows](https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/). | ||
| * @param authorizationType The type of Authorization header to send. | ||
| * | ||
| * Defaults to "Bearer" for Helix and "OAuth" for everything else. | ||
| * @param fetchOptions Additional options to be passed to the `fetch` function. | ||
| * @param mockServerPort | ||
| */ | ||
| export async function callTwitchApiRaw(options, clientId, accessToken, authorizationType, fetchOptions = {}, mockServerPort) { | ||
| var _a, _b; | ||
| const type = (_a = options.type) !== null && _a !== void 0 ? _a : 'helix'; | ||
| const url = getTwitchApiUrl(options.url, type, mockServerPort); | ||
| const params = stringify(options.query, { arrayFormat: 'repeat', addQueryPrefix: true }); | ||
| // eslint-disable-next-line @typescript-eslint/naming-convention | ||
| const headers = new Headers({ Accept: 'application/json' }); | ||
| let body = undefined; | ||
| if (options.jsonBody) { | ||
| body = JSON.stringify(options.jsonBody); | ||
| headers.append('Content-Type', 'application/json'); | ||
| } | ||
| if (clientId && type !== 'auth') { | ||
| headers.append('Client-ID', clientId); | ||
| } | ||
| if (accessToken) { | ||
| headers.append('Authorization', `${type === 'helix' ? authorizationType !== null && authorizationType !== void 0 ? authorizationType : 'Bearer' : 'OAuth'} ${accessToken}`); | ||
| } | ||
| const requestOptions = { | ||
| ...fetchOptions, | ||
| method: (_b = options.method) !== null && _b !== void 0 ? _b : 'GET', | ||
| headers, | ||
| body, | ||
| }; | ||
| return await fetch(`${url}${params}`, requestOptions); | ||
| } | ||
| /** | ||
| * Makes a call to the Twitch API using given credentials. | ||
| * | ||
| * @param options The configuration of the call. | ||
| * @param clientId The client ID of your application. | ||
| * @param accessToken The access token to call the API with. | ||
| * | ||
| * You need to obtain one using one of the [Twitch OAuth flows](https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/). | ||
| * @param authorizationType The type of Authorization header to send. | ||
| * | ||
| * Defaults to "Bearer" for Helix and "OAuth" for everything else. | ||
| * @param fetchOptions Additional options to be passed to the `fetch` function. | ||
| */ | ||
| export async function callTwitchApi(options, clientId, accessToken, authorizationType, fetchOptions = {}) { | ||
| const response = await callTwitchApiRaw(options, clientId, accessToken, authorizationType, fetchOptions); | ||
| await handleTwitchApiResponseError(response, options); | ||
| return await transformTwitchApiResponse(response); | ||
| } |
| import { CustomError } from '@twurple/common'; | ||
| /** | ||
| * Thrown whenever a HTTP error occurs. Some HTTP errors are handled in the library when they're expected. | ||
| */ | ||
| export class HttpStatusCodeError extends CustomError { | ||
| /** @private */ | ||
| constructor(_statusCode, statusText, _url, _method, _body, isJson) { | ||
| super(`Encountered HTTP status code ${_statusCode}: ${statusText}\n\nURL: ${_url}\nMethod: ${_method}\nBody:\n${!isJson && _body.length > 150 ? `${_body.slice(0, 147)}...` : _body}`); | ||
| this._statusCode = _statusCode; | ||
| this._url = _url; | ||
| this._method = _method; | ||
| this._body = _body; | ||
| } | ||
| /** | ||
| * The HTTP status code of the error. | ||
| */ | ||
| get statusCode() { | ||
| return this._statusCode; | ||
| } | ||
| /** | ||
| * The URL that was requested. | ||
| */ | ||
| get url() { | ||
| return this._url; | ||
| } | ||
| /** | ||
| * The HTTP method that was used for the request. | ||
| */ | ||
| get method() { | ||
| return this._method; | ||
| } | ||
| /** | ||
| * The body that was used for the request, as a string. | ||
| */ | ||
| get body() { | ||
| return this._body; | ||
| } | ||
| } |
| export {}; |
| import { extractUserId } from '@twurple/common'; | ||
| export function createBroadcasterQuery(user) { | ||
| return { | ||
| broadcaster_id: extractUserId(user), | ||
| }; | ||
| } |
| import { stringify } from '@d-fischer/qs'; | ||
| import { HttpStatusCodeError } from "../errors/HttpStatusCodeError.mjs"; | ||
| /** @private */ | ||
| export async function handleTwitchApiResponseError(response, options) { | ||
| var _a; | ||
| if (!response.ok) { | ||
| const isJson = response.headers.get('Content-Type') === 'application/json'; | ||
| const text = isJson ? JSON.stringify(await response.json(), null, 2) : await response.text(); | ||
| const params = stringify(options.query, { arrayFormat: 'repeat', addQueryPrefix: true }); | ||
| const fullUrl = `${options.url}${params}`; | ||
| throw new HttpStatusCodeError(response.status, response.statusText, fullUrl, (_a = options.method) !== null && _a !== void 0 ? _a : 'GET', text, isJson); | ||
| } | ||
| } | ||
| /** @private */ | ||
| export async function transformTwitchApiResponse(response) { | ||
| if (response.status === 204) { | ||
| return undefined; // oof | ||
| } | ||
| const text = await response.text(); | ||
| if (!text) { | ||
| return undefined; // mega oof - Twitch doesn't return a response when it should | ||
| } | ||
| return JSON.parse(text); | ||
| } |
| /** @internal */ | ||
| export function getTwitchApiUrl(url, type, mockServerPort) { | ||
| switch (type) { | ||
| case 'helix': { | ||
| const unprefixedUrl = url.replace(/^\//, ''); | ||
| if (mockServerPort) { | ||
| if (unprefixedUrl === 'eventsub/subscriptions') { | ||
| return `http://localhost:${mockServerPort}/${unprefixedUrl}`; | ||
| } | ||
| return `http://localhost:${mockServerPort}/mock/${unprefixedUrl}`; | ||
| } | ||
| return `https://api.twitch.tv/helix/${unprefixedUrl}`; | ||
| } | ||
| case 'auth': | ||
| return `https://id.twitch.tv/oauth2/${url.replace(/^\//, '')}`; | ||
| case 'custom': | ||
| return url; | ||
| default: | ||
| return url; // wat | ||
| } | ||
| } |
| export { callTwitchApi, callTwitchApiRaw } from "./apiCall.mjs"; | ||
| export { createBroadcasterQuery } from "./helpers/queries.external.mjs"; | ||
| export { handleTwitchApiResponseError, transformTwitchApiResponse } from "./helpers/transform.mjs"; | ||
| export { HttpStatusCodeError } from "./errors/HttpStatusCodeError.mjs"; |
| export {}; |
4
-20%1
-50%Yes
NaN15184
-37.27%19
-29.63%321
-36.81%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated