twitter-api-v2
Advanced tools
Comparing version 1.15.1 to 1.15.2
@@ -0,1 +1,7 @@ | ||
1.15.2 | ||
------ | ||
- fix: Cleanup socket listeners after a request is either rejected or resolved #455 | ||
- feat: Support 24-hour rate limit parsing #495 | ||
- fix: Correctly return error on media upload even if status stays to "in_progress" #483 | ||
1.15.1 | ||
@@ -2,0 +8,0 @@ ------ |
@@ -6,2 +6,3 @@ /// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import type { Socket } from 'net'; | ||
@@ -15,2 +16,3 @@ import type { IncomingMessage, ClientRequest } from 'http'; | ||
import { Readable } from 'stream'; | ||
import { EventEmitter } from 'events'; | ||
declare type TRequestReadyPayload = { | ||
@@ -51,3 +53,3 @@ req: ClientRequest; | ||
protected getRateLimitFromResponse(res: IncomingMessage): TwitterRateLimit | undefined; | ||
protected onSocketEventHandler(reject: TRequestRejecter, socket: Socket): void; | ||
protected onSocketEventHandler(reject: TRequestRejecter, cleanupListener: EventEmitter, socket: Socket): void; | ||
protected onSocketCloseHandler(reject: TRequestRejecter): void; | ||
@@ -54,0 +56,0 @@ protected requestErrorHandler(reject: TRequestRejecter, requestError: Error): void; |
@@ -35,2 +35,3 @@ "use strict"; | ||
const zlib = __importStar(require("zlib")); | ||
const events_1 = require("events"); | ||
class RequestHandlerHelper { | ||
@@ -191,2 +192,9 @@ constructor(requestData) { | ||
}; | ||
if (res.headers['x-app-limit-24hour-limit']) { | ||
rateLimit.day = { | ||
limit: Number(res.headers['x-app-limit-24hour-limit']), | ||
remaining: Number(res.headers['x-app-limit-24hour-remaining']), | ||
reset: Number(res.headers['x-app-limit-24hour-reset']), | ||
}; | ||
} | ||
if (this.requestData.rateLimitSaver) { | ||
@@ -199,4 +207,6 @@ this.requestData.rateLimitSaver(rateLimit); | ||
/* Request event handlers */ | ||
onSocketEventHandler(reject, socket) { | ||
socket.on('close', this.onSocketCloseHandler.bind(this, reject)); | ||
onSocketEventHandler(reject, cleanupListener, socket) { | ||
const onClose = this.onSocketCloseHandler.bind(this, reject); | ||
socket.on('close', onClose); | ||
cleanupListener.on('complete', () => socket.off('close', onClose)); | ||
} | ||
@@ -356,7 +366,17 @@ onSocketCloseHandler(reject) { | ||
this.buildRequest(); | ||
return new Promise((resolve, reject) => { | ||
return new Promise((_resolve, _reject) => { | ||
// Hooks to call when promise is fulfulled to cleanup the socket (shared between requests) | ||
const resolve = value => { | ||
cleanupListener.emit('complete'); | ||
_resolve(value); | ||
}; | ||
const reject = value => { | ||
cleanupListener.emit('complete'); | ||
_reject(value); | ||
}; | ||
const cleanupListener = new events_1.EventEmitter(); | ||
const req = this.req; | ||
// Handle request errors | ||
req.on('error', this.requestErrorHandler.bind(this, reject)); | ||
req.on('socket', this.onSocketEventHandler.bind(this, reject)); | ||
req.on('socket', this.onSocketEventHandler.bind(this, reject, cleanupListener)); | ||
req.on('response', this.classicResponseHandler.bind(this, resolve, reject)); | ||
@@ -363,0 +383,0 @@ if (this.requestData.options.timeout) { |
@@ -48,2 +48,3 @@ import { TwitterRateLimit, TwitterResponse } from '../types'; | ||
get rateLimit(): { | ||
day?: import("../types").SingleTwitterRateLimit | undefined; | ||
limit: number; | ||
@@ -50,0 +51,0 @@ reset: number; |
@@ -8,3 +8,3 @@ /// <reference types="node" /> | ||
} | ||
export interface TwitterRateLimit { | ||
export interface SingleTwitterRateLimit { | ||
limit: number; | ||
@@ -14,1 +14,4 @@ reset: number; | ||
} | ||
export interface TwitterRateLimit extends SingleTwitterRateLimit { | ||
day?: SingleTwitterRateLimit; | ||
} |
@@ -337,2 +337,3 @@ "use strict"; | ||
async awaitForMediaProcessingCompletion(fullMediaData) { | ||
var _a; | ||
// eslint-disable-next-line no-constant-condition | ||
@@ -346,7 +347,8 @@ while (true) { | ||
} | ||
if ((_a = processing_info.error) === null || _a === void 0 ? void 0 : _a.code) { | ||
const { name, message } = processing_info.error; | ||
throw new Error(`Failed to process media: ${name} - ${message}.`); | ||
} | ||
if (processing_info.state === 'failed') { | ||
if (processing_info.error) { | ||
const { name, message } = processing_info.error; | ||
throw new Error(`Failed to process media: ${name} - ${message}.`); | ||
} | ||
// No error data | ||
throw new Error('Failed to process the media.'); | ||
@@ -353,0 +355,0 @@ } |
@@ -6,2 +6,3 @@ /// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import type { Socket } from 'net'; | ||
@@ -15,2 +16,3 @@ import type { IncomingMessage, ClientRequest } from 'http'; | ||
import { Readable } from 'stream'; | ||
import { EventEmitter } from 'events'; | ||
declare type TRequestReadyPayload = { | ||
@@ -51,3 +53,3 @@ req: ClientRequest; | ||
protected getRateLimitFromResponse(res: IncomingMessage): TwitterRateLimit | undefined; | ||
protected onSocketEventHandler(reject: TRequestRejecter, socket: Socket): void; | ||
protected onSocketEventHandler(reject: TRequestRejecter, cleanupListener: EventEmitter, socket: Socket): void; | ||
protected onSocketCloseHandler(reject: TRequestRejecter): void; | ||
@@ -54,0 +56,0 @@ protected requestErrorHandler(reject: TRequestRejecter, requestError: Error): void; |
@@ -6,2 +6,3 @@ import { request } from 'https'; | ||
import * as zlib from 'zlib'; | ||
import { EventEmitter } from 'events'; | ||
export class RequestHandlerHelper { | ||
@@ -162,2 +163,9 @@ constructor(requestData) { | ||
}; | ||
if (res.headers['x-app-limit-24hour-limit']) { | ||
rateLimit.day = { | ||
limit: Number(res.headers['x-app-limit-24hour-limit']), | ||
remaining: Number(res.headers['x-app-limit-24hour-remaining']), | ||
reset: Number(res.headers['x-app-limit-24hour-reset']), | ||
}; | ||
} | ||
if (this.requestData.rateLimitSaver) { | ||
@@ -170,4 +178,6 @@ this.requestData.rateLimitSaver(rateLimit); | ||
/* Request event handlers */ | ||
onSocketEventHandler(reject, socket) { | ||
socket.on('close', this.onSocketCloseHandler.bind(this, reject)); | ||
onSocketEventHandler(reject, cleanupListener, socket) { | ||
const onClose = this.onSocketCloseHandler.bind(this, reject); | ||
socket.on('close', onClose); | ||
cleanupListener.on('complete', () => socket.off('close', onClose)); | ||
} | ||
@@ -327,7 +337,17 @@ onSocketCloseHandler(reject) { | ||
this.buildRequest(); | ||
return new Promise((resolve, reject) => { | ||
return new Promise((_resolve, _reject) => { | ||
// Hooks to call when promise is fulfulled to cleanup the socket (shared between requests) | ||
const resolve = value => { | ||
cleanupListener.emit('complete'); | ||
_resolve(value); | ||
}; | ||
const reject = value => { | ||
cleanupListener.emit('complete'); | ||
_reject(value); | ||
}; | ||
const cleanupListener = new EventEmitter(); | ||
const req = this.req; | ||
// Handle request errors | ||
req.on('error', this.requestErrorHandler.bind(this, reject)); | ||
req.on('socket', this.onSocketEventHandler.bind(this, reject)); | ||
req.on('socket', this.onSocketEventHandler.bind(this, reject, cleanupListener)); | ||
req.on('response', this.classicResponseHandler.bind(this, resolve, reject)); | ||
@@ -334,0 +354,0 @@ if (this.requestData.options.timeout) { |
@@ -48,2 +48,3 @@ import { TwitterRateLimit, TwitterResponse } from '../types'; | ||
get rateLimit(): { | ||
day?: import("../types").SingleTwitterRateLimit | undefined; | ||
limit: number; | ||
@@ -50,0 +51,0 @@ reset: number; |
@@ -8,3 +8,3 @@ /// <reference types="node" /> | ||
} | ||
export interface TwitterRateLimit { | ||
export interface SingleTwitterRateLimit { | ||
limit: number; | ||
@@ -14,1 +14,4 @@ reset: number; | ||
} | ||
export interface TwitterRateLimit extends SingleTwitterRateLimit { | ||
day?: SingleTwitterRateLimit; | ||
} |
@@ -309,2 +309,3 @@ import * as fs from 'fs'; | ||
async awaitForMediaProcessingCompletion(fullMediaData) { | ||
var _a; | ||
// eslint-disable-next-line no-constant-condition | ||
@@ -318,7 +319,8 @@ while (true) { | ||
} | ||
if ((_a = processing_info.error) === null || _a === void 0 ? void 0 : _a.code) { | ||
const { name, message } = processing_info.error; | ||
throw new Error(`Failed to process media: ${name} - ${message}.`); | ||
} | ||
if (processing_info.state === 'failed') { | ||
if (processing_info.error) { | ||
const { name, message } = processing_info.error; | ||
throw new Error(`Failed to process media: ${name} - ${message}.`); | ||
} | ||
// No error data | ||
throw new Error('Failed to process the media.'); | ||
@@ -325,0 +327,0 @@ } |
{ | ||
"name": "twitter-api-v2", | ||
"version": "1.15.1", | ||
"version": "1.15.2", | ||
"description": "Strongly typed, full-featured, light, versatile yet powerful Twitter API v1.1 and v2 client for Node.js.", | ||
@@ -5,0 +5,0 @@ "main": "dist/cjs/index.js", |
997690
22542