Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

twitter-api-v2

Package Overview
Dependencies
Maintainers
1
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

twitter-api-v2 - npm Package Compare versions

Comparing version 1.6.0 to 1.6.1

7

changelog.md

@@ -0,1 +1,8 @@

1.6.1
-----
- Feat: New option for creating streams, `autoConnect` that is `true` by default. Setting the value to `false` will cause the `TweetStream` object to be returned immediately (not in a `Promise`), because connection isn't awaited. #92
- Fix: `autoReconnectRetries`: Setting this params to `Infinity` no longer causes the stream reconnection attempts to be delayed to next event loop turn. #92
- Fix: Use `https.request(options)` instead of `https.request(url, options)`, because some people has outdated dependencies that overwrite native Node's exported function and break its signature. #94 #96
- Feat: Next retry timeout computation can be customized by using `.nextRetryTimeout` property of `TweetStream` instance, that is function taking a `tryOccurence` and returning the number of milliseconds to wait before trying to reconnect.
1.6.0

@@ -2,0 +9,0 @@ -----

9

dist/client-mixins/request-handler.helper.d.ts

@@ -24,7 +24,5 @@ /// <reference types="node" />

protected requestData: TRequestFullData | TRequestFullStreamData;
protected static readonly FORM_ENCODED_ENDPOINTS = "https://api.twitter.com/oauth/";
protected req: ClientRequest;
protected responseData: string;
constructor(requestData: TRequestFullData | TRequestFullStreamData);
get href(): string;
get hrefPathname(): string;

@@ -38,5 +36,6 @@ protected isFormEncodedEndpoint(): boolean;

protected getParsedResponse(res: IncomingMessage): any;
protected registerRequestErrorHandler(reject: TRequestRejecter): (requestError: Error) => void;
protected registerResponseHandler(resolve: TResponseResolver<T>, reject: TResponseRejecter): (res: IncomingMessage) => void;
protected registerStreamResponseHandler(resolve: TReadyRequestResolver, reject: TResponseRejecter): (res: IncomingMessage) => void;
protected requestErrorHandler(reject: TRequestRejecter, requestError: Error): void;
protected classicResponseHandler(resolve: TResponseResolver<T>, reject: TResponseRejecter, res: IncomingMessage): void;
protected onResponseEndHandler(resolve: TResponseResolver<T>, reject: TResponseRejecter, res: IncomingMessage): void;
protected streamResponseHandler(resolve: TReadyRequestResolver, reject: TResponseRejecter, res: IncomingMessage): void;
protected debugRequest(): void;

@@ -43,0 +42,0 @@ protected buildRequest(): void;

@@ -16,11 +16,8 @@ "use strict";

}
get href() {
return this.requestData.url;
}
get hrefPathname() {
const url = new URL(this.requestData.url);
const url = this.requestData.url;
return url.hostname + url.pathname;
}
isFormEncodedEndpoint() {
return this.href.startsWith(RequestHandlerHelper.FORM_ENCODED_ENDPOINTS);
return this.requestData.url.href.startsWith('https://api.twitter.com/oauth/');
}

@@ -100,49 +97,44 @@ getRateLimitFromResponse(res) {

}
registerRequestErrorHandler(reject) {
return (requestError) => {
reject(this.createRequestError(requestError));
};
requestErrorHandler(reject, requestError) {
reject(this.createRequestError(requestError));
}
registerResponseHandler(resolve, reject) {
return (res) => {
const rateLimit = this.getRateLimitFromResponse(res);
// Register the response data
res.on('data', chunk => this.responseData += chunk);
res.on('end', () => {
const data = this.getParsedResponse(res);
// Handle bad error codes
const code = res.statusCode;
if (code >= 400) {
reject(this.createResponseError({ data, res, rateLimit, code }));
}
if (settings_1.TwitterApiV2Settings.debug) {
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode}`);
console.log('Response body:', data);
}
resolve({
data,
headers: res.headers,
rateLimit,
});
});
};
classicResponseHandler(resolve, reject, res) {
// Register the response data
res.on('data', chunk => this.responseData += chunk);
res.on('end', this.onResponseEndHandler.bind(this, resolve, reject, res));
}
registerStreamResponseHandler(resolve, reject) {
return (res) => {
const code = res.statusCode;
if (code < 400) {
if (settings_1.TwitterApiV2Settings.debug) {
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode} (starting stream)`);
}
// HTTP code ok, consume stream
resolve({ req: this.req, res, requestData: this.requestData });
onResponseEndHandler(resolve, reject, res) {
const rateLimit = this.getRateLimitFromResponse(res);
const data = this.getParsedResponse(res);
// Handle bad error codes
const code = res.statusCode;
if (code >= 400) {
reject(this.createResponseError({ data, res, rateLimit, code }));
}
if (settings_1.TwitterApiV2Settings.debug) {
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode}`);
console.log('Response body:', data);
}
resolve({
data,
headers: res.headers,
rateLimit,
});
}
streamResponseHandler(resolve, reject, res) {
const code = res.statusCode;
if (code < 400) {
if (settings_1.TwitterApiV2Settings.debug) {
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode} (starting stream)`);
}
else {
// Handle response normally, can only rejects
this.registerResponseHandler(() => undefined, reject)(res);
}
};
// HTTP code ok, consume stream
resolve({ req: this.req, res, requestData: this.requestData });
}
else {
// Handle response normally, can only rejects
this.classicResponseHandler(() => undefined, reject, res);
}
}
debugRequest() {
const url = new URL(this.requestData.url);
const url = this.requestData.url;
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]`, this.requestData.options);

@@ -160,3 +152,13 @@ if (url.search) {

}
this.req = https_1.request(this.requestData.url, this.requestData.options);
const url = this.requestData.url;
const auth = url.username ? `${url.username}:${url.password}` : undefined;
this.req = https_1.request({
...this.requestData.options,
// Define URL params manually, addresses dependencies error https://github.com/PLhery/node-twitter-api-v2/issues/94
host: url.hostname,
port: url.port || undefined,
path: url.pathname + url.search,
protocol: url.protocol,
auth,
});
}

@@ -168,4 +170,4 @@ makeRequest() {

// Handle request errors
req.on('error', this.registerRequestErrorHandler(reject));
req.on('response', this.registerResponseHandler(resolve, reject));
req.on('error', this.requestErrorHandler.bind(this, reject));
req.on('response', this.classicResponseHandler.bind(this, resolve, reject));
if (this.requestData.body) {

@@ -179,3 +181,3 @@ req.write(this.requestData.body);

const { req, res, requestData } = await this.makeRequestAndResolveWhenReady();
return new TweetStream_1.default(req, res, requestData);
return new TweetStream_1.default(requestData, req, res);
}

@@ -187,4 +189,4 @@ makeRequestAndResolveWhenReady() {

// Handle request errors
req.on('error', this.registerRequestErrorHandler(reject));
req.on('response', this.registerStreamResponseHandler(resolve, reject));
req.on('error', this.requestErrorHandler.bind(this, reject));
req.on('response', this.streamResponseHandler.bind(this, resolve, reject));
if (this.requestData.body) {

@@ -198,3 +200,2 @@ req.write(this.requestData.body);

exports.RequestHandlerHelper = RequestHandlerHelper;
RequestHandlerHelper.FORM_ENCODED_ENDPOINTS = 'https://api.twitter.com/oauth/';
exports.default = RequestHandlerHelper;

@@ -7,3 +7,3 @@ /// <reference types="node" />

export declare type TRequestFullData = {
url: string;
url: URL;
options: RequestOptions;

@@ -42,3 +42,12 @@ body?: any;

payloadIsError?: (data: any) => boolean;
autoConnect?: boolean;
}
interface IGetStreamRequestArgsAsync {
payloadIsError?: (data: any) => boolean;
autoConnect?: true;
}
interface IGetStreamRequestArgsSync {
payloadIsError?: (data: any) => boolean;
autoConnect: false;
}
export declare type TCustomizableRequestArgs = Pick<IGetHttpRequestArgs, 'headers' | 'params' | 'forceBodyMode' | 'enableAuth' | 'enableRateLimitSave'>;

@@ -59,16 +68,13 @@ export declare abstract class ClientRequestMaker {

protected saveRateLimit(originalUrl: string, rateLimit: TwitterRateLimit): void;
/**
* Send a new request and returns a wrapped `Promise<TwitterResponse<T>`.
*
* The request URL should not contains a query string, prefers using `parameters` for GET request.
* If you need to pass a body AND query string parameter, duplicate parameters in the body.
*/
/** Send a new request and returns a wrapped `Promise<TwitterResponse<T>`. */
send<T = any>(requestParams: IGetHttpRequestArgs): Promise<TwitterResponse<T>>;
/**
* Send a new request, then creates a stream from its as a `Promise<TwitterStream>`.
* Create a new request, then creates a stream from it as a `TweetStream`.
*
* The request URL should not contains a query string, prefers using `parameters` for GET request.
* If you need to pass a body AND query string parameter, duplicate parameters in the body.
* Request will be sent only if `autoConnect` is not set or `true`: return type will be `Promise<TweetStream>`.
* If `autoConnect` is `false`, a `TweetStream` is directly returned and you should call `stream.connect()` by yourself.
*/
sendStream<T = any>(requestParams: IGetHttpRequestArgs & IGetStreamRequestArgs): Promise<TweetStream<T>>;
sendStream<T = any>(requestParams: IGetHttpRequestArgs & IGetStreamRequestArgsSync): TweetStream<T>;
sendStream<T = any>(requestParams: IGetHttpRequestArgs & IGetStreamRequestArgsAsync): Promise<TweetStream<T>>;
sendStream<T = any>(requestParams: IGetHttpRequestArgs & IGetStreamRequestArgs): Promise<TweetStream<T>> | TweetStream<T>;
protected buildOAuth(): OAuth1Helper;

@@ -82,3 +88,3 @@ protected getOAuthAccessTokens(): {

rawUrl: string;
url: string;
url: URL;
method: string;

@@ -85,0 +91,0 @@ headers: Record<string, string>;

@@ -7,2 +7,3 @@ "use strict";

exports.ClientRequestMaker = void 0;
const TweetStream_1 = __importDefault(require("../stream/TweetStream"));
const helpers_1 = require("../helpers");

@@ -19,8 +20,3 @@ const oauth1_helper_1 = __importDefault(require("./oauth1.helper"));

}
/**
* Send a new request and returns a wrapped `Promise<TwitterResponse<T>`.
*
* The request URL should not contains a query string, prefers using `parameters` for GET request.
* If you need to pass a body AND query string parameter, duplicate parameters in the body.
*/
/** Send a new request and returns a wrapped `Promise<TwitterResponse<T>`. */
send(requestParams) {

@@ -41,8 +37,2 @@ const args = this.getHttpRequestArgs(requestParams);

}
/**
* Send a new request, then creates a stream from its as a `Promise<TwitterStream>`.
*
* The request URL should not contains a query string, prefers using `parameters` for GET request.
* If you need to pass a body AND query string parameter, duplicate parameters in the body.
*/
sendStream(requestParams) {

@@ -52,6 +42,7 @@ const args = this.getHttpRequestArgs(requestParams);

const enableRateLimitSave = requestParams.enableRateLimitSave !== false;
const enableAutoConnect = requestParams.autoConnect !== false;
if (args.body) {
request_param_helper_1.default.setBodyLengthHeader(options, args.body);
}
return new request_handler_helper_1.default({
const requestData = {
url: args.url,

@@ -62,4 +53,8 @@ options,

payloadIsError: requestParams.payloadIsError,
})
.makeRequestAsStream();
};
const stream = new TweetStream_1.default(requestData);
if (!enableAutoConnect) {
return stream;
}
return stream.connect();
}

@@ -145,3 +140,3 @@ /* Token helpers */

rawUrl,
url: urlObject.toString(),
url: urlObject,
method,

@@ -148,0 +143,0 @@ headers,

@@ -29,3 +29,16 @@ import { TClientTokens, TwitterApiBasicAuth, TwitterApiOAuth2Init, TwitterApiTokens, TwitterRateLimit, TwitterResponse, UserV1 } from './types';

payloadIsError?: (data: any) => boolean;
/**
* Choose to make or not initial connection.
* Method `.connect` must be called on returned `TweetStream` object
* to start stream if `autoConnect` is set to `false`.
* Defaults to `true`.
*/
autoConnect?: boolean;
};
export declare type TStreamClientRequestArgsWithAutoConnect = TStreamClientRequestArgs & {
autoConnect?: true;
};
export declare type TStreamClientRequestArgsWithoutAutoConnect = TStreamClientRequestArgs & {
autoConnect: false;
};
/**

@@ -92,8 +105,9 @@ * Base class for Twitter instances

/** Stream request helpers */
getStream<T = any>(url: string, query?: TRequestQuery, { prefix }?: TStreamClientRequestArgs): Promise<TweetStream<T>>;
deleteStream<T = any>(url: string, query?: TRequestQuery, { prefix }?: TStreamClientRequestArgs): Promise<TweetStream<T>>;
postStream<T = any>(url: string, body?: TRequestBody, { prefix, ...rest }?: TStreamClientRequestArgs): Promise<TweetStream<T>>;
putStream<T = any>(url: string, body?: TRequestBody, { prefix, ...rest }?: TStreamClientRequestArgs): Promise<TweetStream<T>>;
patchStream<T = any>(url: string, body?: TRequestBody, { prefix, ...rest }?: TStreamClientRequestArgs): Promise<TweetStream<T>>;
getStream<T = any>(url: string, query: TRequestQuery | undefined, options: TStreamClientRequestArgsWithoutAutoConnect): TweetStream<T>;
getStream<T = any>(url: string, query?: TRequestQuery, options?: TStreamClientRequestArgsWithAutoConnect): Promise<TweetStream<T>>;
getStream<T = any>(url: string, query?: TRequestQuery, options?: TStreamClientRequestArgs): Promise<TweetStream<T>> | TweetStream<T>;
postStream<T = any>(url: string, body: TRequestBody | undefined, options: TStreamClientRequestArgsWithoutAutoConnect): TweetStream<T>;
postStream<T = any>(url: string, body?: TRequestBody, options?: TStreamClientRequestArgsWithAutoConnect): Promise<TweetStream<T>>;
postStream<T = any>(url: string, body?: TRequestBody, options?: TStreamClientRequestArgs): Promise<TweetStream<T>> | TweetStream<T>;
}
export {};

@@ -24,2 +24,3 @@ "use strict";

this._clientId = token._clientId;
this._rateLimits = token._rateLimits;
}

@@ -173,26 +174,13 @@ else if (typeof token === 'object' && 'appKey' in token) {

}
/** Stream request helpers */
async getStream(url, query, { prefix = this._prefix } = {}) {
if (prefix)
url = prefix + url;
getStream(url, query, { prefix = this._prefix, ...rest } = {}) {
return this.sendStream({
url,
url: prefix ? prefix + url : url,
method: 'GET',
query,
...rest,
});
}
async deleteStream(url, query, { prefix = this._prefix } = {}) {
if (prefix)
url = prefix + url;
postStream(url, body, { prefix = this._prefix, ...rest } = {}) {
return this.sendStream({
url,
method: 'DELETE',
query,
});
}
async postStream(url, body, { prefix = this._prefix, ...rest } = {}) {
if (prefix)
url = prefix + url;
return this.sendStream({
url,
url: prefix ? prefix + url : url,
method: 'POST',

@@ -203,23 +191,3 @@ body,

}
async putStream(url, body, { prefix = this._prefix, ...rest } = {}) {
if (prefix)
url = prefix + url;
return this.sendStream({
url,
method: 'PUT',
body,
...rest,
});
}
async patchStream(url, body, { prefix = this._prefix, ...rest } = {}) {
if (prefix)
url = prefix + url;
return this.sendStream({
url,
method: 'PATCH',
body,
...rest,
});
}
}
exports.default = TwitterApiBase;

@@ -11,5 +11,12 @@ /// <reference types="node" />

}
export interface IConnectTweetStreamParams {
autoReconnect: boolean;
autoReconnectRetries: number | 'unlimited';
/** Check for 'lost connection' status every `keepAliveTimeout` milliseconds. Defaults to 2 minutes (`120000`). */
keepAliveTimeout: number | 'disable';
nextRetryTimeout?: TStreamConnectRetryFn;
}
/** Returns a number of milliseconds to wait for {tryOccurence} (starting from 1) */
export declare type TStreamConnectRetryFn = (tryOccurence: number) => number;
export declare class TweetStream<T = any> extends EventEmitter {
protected req: ClientRequest;
protected res: IncomingMessage;
protected requestData: TRequestFullStreamData;

@@ -19,9 +26,13 @@ autoReconnect: boolean;

keepAliveTimeoutMs: number;
nextRetryTimeout: TStreamConnectRetryFn;
protected retryTimeout?: NodeJS.Timeout;
protected keepAliveTimeout?: NodeJS.Timeout;
protected parser: TweetStreamParser;
constructor(req: ClientRequest, res: IncomingMessage, requestData: TRequestFullStreamData);
protected req?: ClientRequest;
protected res?: IncomingMessage;
constructor(requestData: TRequestFullStreamData, req?: ClientRequest, res?: IncomingMessage);
on(event: ETwitterStreamEvent.Data, handler: (data: T) => any): this;
on(event: ETwitterStreamEvent.DataError, handler: (error: any) => any): this;
on(event: ETwitterStreamEvent.Error, handler: (errorPayload: ITweetStreamError) => any): this;
on(event: ETwitterStreamEvent.Connected, handler: () => any): this;
on(event: ETwitterStreamEvent.ConnectionLost, handler: () => any): this;

@@ -53,9 +64,11 @@ on(event: ETwitterStreamEvent.ConnectionError, handler: (error: Error) => any): this;

*/
clone(): Promise<TweetStream<unknown>>;
/** Make a new request to reconnect to Twitter. */
clone(): Promise<TweetStream<T>>;
/** Start initial stream connection, setup options on current instance and returns itself. */
connect(options?: Partial<IConnectTweetStreamParams>): Promise<this>;
/** Make a new request to (re)connect to Twitter. */
reconnect(): Promise<void>;
protected onConnectionError(retries?: number): Promise<void>;
protected makeAutoReconnectRetry(retries: number): void;
protected onConnectionError(retryOccurence?: number): Promise<void>;
protected makeAutoReconnectRetry(retryOccurence: number): void;
[Symbol.asyncIterator](): AsyncGenerator<T, void, undefined>;
}
export default TweetStream;

@@ -31,7 +31,6 @@ "use strict";

const TweetStreamParser_1 = __importStar(require("./TweetStreamParser"));
const basicReconnectRetry = tryOccurence => Math.min((tryOccurence ** 2) * 1000, 25000);
class TweetStream extends events_1.EventEmitter {
constructor(req, res, requestData) {
constructor(requestData, req, res) {
super();
this.req = req;
this.res = res;
this.requestData = requestData;

@@ -42,6 +41,11 @@ this.autoReconnect = false;

this.keepAliveTimeoutMs = 1000 * 120;
this.nextRetryTimeout = basicReconnectRetry;
this.parser = new TweetStreamParser_1.default();
this.onKeepAliveTimeout = this.onKeepAliveTimeout.bind(this);
this.initEventsFromParser();
this.initEventsFromRequest();
if (req && res) {
this.req = req;
this.res = res;
this.initEventsFromRequest();
}
}

@@ -52,2 +56,5 @@ on(event, handler) {

initEventsFromRequest() {
if (!this.req || !this.res) {
throw new Error('TweetStream error: You cannot init TweetStream without a request and response object.');
}
const errorHandler = (err) => {

@@ -122,6 +129,10 @@ this.emit(types_1.ETwitterStreamEvent.ConnectionError, err);

this.unbindTimeouts();
this.req.removeAllListeners();
this.res.removeAllListeners();
// Close connection silentely
this.req.destroy();
if (this.res) {
this.res.removeAllListeners();
}
if (this.req) {
this.req.removeAllListeners();
// Close connection silentely
this.req.destroy();
}
}

@@ -155,6 +166,31 @@ /** Terminate connection to Twitter. */

}
/** Make a new request to reconnect to Twitter. */
/** Start initial stream connection, setup options on current instance and returns itself. */
async connect(options = {}) {
if (typeof options.autoReconnect !== 'undefined') {
this.autoReconnect = options.autoReconnect;
}
if (typeof options.autoReconnectRetries !== 'undefined') {
this.autoReconnectRetries = options.autoReconnectRetries === 'unlimited'
? Infinity
: options.autoReconnectRetries;
}
if (typeof options.keepAliveTimeout !== 'undefined') {
this.keepAliveTimeoutMs = options.keepAliveTimeout === 'disable'
? Infinity
: options.keepAliveTimeout;
}
if (typeof options.nextRetryTimeout !== 'undefined') {
this.nextRetryTimeout = options.nextRetryTimeout;
}
await this.reconnect();
return this;
}
/** Make a new request to (re)connect to Twitter. */
async reconnect() {
if (!this.req.destroyed) {
this.closeWithoutEmit();
let initialConnection = true;
if (this.req) {
initialConnection = false;
if (!this.req.destroyed) {
this.closeWithoutEmit();
}
}

@@ -164,10 +200,10 @@ const { req, res } = await new request_handler_helper_1.default(this.requestData).makeRequestAndResolveWhenReady();

this.res = res;
this.emit(types_1.ETwitterStreamEvent.Reconnected);
this.emit(initialConnection ? types_1.ETwitterStreamEvent.Connected : types_1.ETwitterStreamEvent.Reconnected);
this.parser.reset();
this.initEventsFromRequest();
}
async onConnectionError(retries = this.autoReconnectRetries) {
async onConnectionError(retryOccurence = 0) {
this.unbindTimeouts();
// Close the request if necessary
if (!this.req.destroyed) {
if (this.req && !this.req.destroyed) {
this.closeWithoutEmit();

@@ -180,3 +216,3 @@ }

}
if (retries <= 0) {
if (retryOccurence >= this.autoReconnectRetries) {
this.emit(types_1.ETwitterStreamEvent.ReconnectLimitExceeded);

@@ -188,19 +224,18 @@ this.emit(types_1.ETwitterStreamEvent.ConnectionClosed);

try {
this.emit(types_1.ETwitterStreamEvent.ReconnectAttempt, this.autoReconnectRetries - retries);
this.emit(types_1.ETwitterStreamEvent.ReconnectAttempt, retryOccurence);
await this.reconnect();
}
catch (e) {
this.emit(types_1.ETwitterStreamEvent.ReconnectError, this.autoReconnectRetries - retries);
this.emit(types_1.ETwitterStreamEvent.ReconnectError, retryOccurence);
this.emit(types_1.ETwitterStreamEvent.Error, {
type: types_1.ETwitterStreamEvent.ReconnectError,
error: new Error(`Reconnect error - ${this.autoReconnectRetries - retries} attempts made yet.`),
error: new Error(`Reconnect error - ${retryOccurence + 1} attempts made yet.`),
});
this.makeAutoReconnectRetry(retries);
this.makeAutoReconnectRetry(retryOccurence);
}
}
makeAutoReconnectRetry(retries) {
const tryOccurence = (this.autoReconnectRetries - retries) + 1;
const nextRetry = Math.min((tryOccurence ** 2) * 1000, 25000);
makeAutoReconnectRetry(retryOccurence) {
const nextRetry = this.nextRetryTimeout(retryOccurence + 1);
this.retryTimeout = setTimeout(() => {
this.onConnectionError(retries - 1);
this.onConnectionError(retryOccurence + 1);
}, nextRetry);

@@ -212,3 +247,3 @@ }

while (true) {
if (this.req.aborted) {
if (!this.req || this.req.aborted) {
throw new Error('Connection closed');

@@ -215,0 +250,0 @@ }

export declare enum ETwitterStreamEvent {
Connected = "connected",
ConnectionError = "connection error",

@@ -3,0 +4,0 @@ ConnectionClosed = "connection closed",

@@ -6,2 +6,3 @@ "use strict";

(function (ETwitterStreamEvent) {
ETwitterStreamEvent["Connected"] = "connected";
ETwitterStreamEvent["ConnectionError"] = "connection error";

@@ -8,0 +9,0 @@ ETwitterStreamEvent["ConnectionClosed"] = "connection closed";

export declare type NumberString = number | string;
export declare type BooleanString = boolean | string;
export declare type TypeOrArrayOf<T> = T | T[];
export declare type PromiseOrType<T> = T | Promise<T>;

@@ -7,2 +7,4 @@ import TwitterApiSubClient from '../client.subclient';

import { ListMembershipsV1Paginator, ListMembersV1Paginator, ListOwnershipsV1Paginator, ListSubscribersV1Paginator, ListSubscriptionsV1Paginator } from '../paginators/list.paginator.v1';
import TweetStream from '../stream/TweetStream';
import { PromiseOrType } from '../types/shared.types';
/**

@@ -188,3 +190,11 @@ * Base Twitter v1 client with only read right.

*/
filterStream(params?: Partial<FilterStreamV1Params>): Promise<import("..").TweetStream<TweetV1>>;
filterStream(params?: Partial<FilterStreamV1Params> & {
autoConnect?: true;
}): Promise<TweetStream<TweetV1>>;
filterStream(params: Partial<FilterStreamV1Params> & {
autoConnect: false;
}): TweetStream<TweetV1>;
filterStream(params?: Partial<FilterStreamV1Params> & {
autoConnect?: boolean;
}): PromiseOrType<TweetStream<TweetV1>>;
/**

@@ -195,3 +205,11 @@ * Returns a small random sample of all public statuses.

*/
sampleStream(params?: Partial<SampleStreamV1Params>): Promise<import("..").TweetStream<TweetV1>>;
sampleStream(params?: Partial<SampleStreamV1Params> & {
autoConnect?: true;
}): Promise<TweetStream<TweetV1>>;
sampleStream(params: Partial<SampleStreamV1Params> & {
autoConnect: false;
}): TweetStream<TweetV1>;
sampleStream(params?: Partial<SampleStreamV1Params> & {
autoConnect?: boolean;
}): PromiseOrType<TweetStream<TweetV1>>;
/**

@@ -198,0 +216,0 @@ * Create a client that is prefixed with `https//stream.twitter.com` instead of classic API URL.

@@ -416,9 +416,3 @@ "use strict";

}
/* Streaming API */
/**
* Returns public statuses that match one or more filter predicates.
* Multiple parameters may be specified which allows most clients to use a single connection to the Streaming API.
* https://developer.twitter.com/en/docs/twitter-api/v1/tweets/filter-realtime/api-reference/post-statuses-filter
*/
filterStream(params = {}) {
filterStream({ autoConnect, ...params } = {}) {
const parameters = {};

@@ -438,12 +432,7 @@ for (const [key, value] of Object.entries(params)) {

const streamClient = this.stream;
return streamClient.postStream('statuses/filter.json', parameters);
return streamClient.postStream('statuses/filter.json', parameters, { autoConnect });
}
/**
* Returns a small random sample of all public statuses.
* The Tweets returned by the default access level are the same, so if two different clients connect to this endpoint, they will see the same Tweets.
* https://developer.twitter.com/en/docs/twitter-api/v1/tweets/sample-realtime/api-reference/get-statuses-sample
*/
sampleStream(params = {}) {
sampleStream({ autoConnect, ...params } = {}) {
const streamClient = this.stream;
return streamClient.getStream('statuses/sample.json', params);
return streamClient.getStream('statuses/sample.json', params, { autoConnect });
}

@@ -450,0 +439,0 @@ /**

@@ -402,3 +402,3 @@ "use strict";

// Await for first promise to be finished
await Promise.race([...currentUploads]);
await Promise.race(currentUploads);
}

@@ -405,0 +405,0 @@ [readBuffer, nread] = await media_helpers_v1_1.readNextPartOf(fileHandle, chunkLength, offset, buffer);

@@ -6,2 +6,4 @@ import TwitterApiSubClient from '../client.subclient';

import { UserBlockingUsersV2Paginator, UserFollowersV2Paginator, UserFollowingV2Paginator, UserMutingUsersV2Paginator } from '../paginators/user.paginator.v2';
import TweetStream from '../stream/TweetStream';
import { PromiseOrType } from '../types/shared.types';
/**

@@ -164,3 +166,11 @@ * Base Twitter v2 client with only read right.

*/
searchStream(options?: Partial<TweetSearchV2StreamParams>): Promise<import("..").TweetStream<TweetV2SingleStreamResult>>;
searchStream(options?: Partial<TweetSearchV2StreamParams> & {
autoConnect?: true;
}): Promise<TweetStream<TweetV2SingleStreamResult>>;
searchStream(options: Partial<TweetSearchV2StreamParams> & {
autoConnect: false;
}): TweetStream<TweetV2SingleStreamResult>;
searchStream(options?: Partial<TweetSearchV2StreamParams> & {
autoConnect?: boolean;
}): PromiseOrType<TweetStream<TweetV2SingleStreamResult>>;
/**

@@ -183,3 +193,11 @@ * Return a list of rules currently active on the streaming endpoint, either as a list or individually.

*/
sampleStream(options?: Partial<Tweetv2FieldsParams>): Promise<import("..").TweetStream<TweetV2SingleResult>>;
sampleStream(options?: Partial<Tweetv2FieldsParams> & {
autoConnect?: true;
}): Promise<TweetStream<TweetV2SingleResult>>;
sampleStream(options: Partial<Tweetv2FieldsParams> & {
autoConnect: false;
}): TweetStream<TweetV2SingleResult>;
sampleStream(options?: Partial<Tweetv2FieldsParams> & {
autoConnect?: boolean;
}): PromiseOrType<TweetStream<TweetV2SingleResult>>;
/**

@@ -186,0 +204,0 @@ * Returns a list of recent compliance jobs.

@@ -294,9 +294,4 @@ "use strict";

}
/* Streaming API */
/**
* Streams Tweets in real-time based on a specific set of filter rules.
* https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream
*/
searchStream(options = {}) {
return this.getStream('tweets/search/stream', options, { payloadIsError: helpers_1.isTweetStreamV2ErrorPayload });
searchStream({ autoConnect, ...options } = {}) {
return this.getStream('tweets/search/stream', options, { payloadIsError: helpers_1.isTweetStreamV2ErrorPayload, autoConnect });
}

@@ -313,8 +308,4 @@ /**

}
/**
* Streams about 1% of all Tweets in real-time.
* https://developer.twitter.com/en/docs/twitter-api/tweets/sampled-stream/api-reference/get-tweets-sample-stream
*/
sampleStream(options = {}) {
return this.getStream('tweets/sample/stream', options, { payloadIsError: helpers_1.isTweetStreamV2ErrorPayload });
sampleStream({ autoConnect, ...options } = {}) {
return this.getStream('tweets/sample/stream', options, { payloadIsError: helpers_1.isTweetStreamV2ErrorPayload, autoConnect });
}

@@ -321,0 +312,0 @@ /* Batch compliance */

{
"name": "twitter-api-v2",
"version": "1.6.0",
"version": "1.6.1",
"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/index.js",

@@ -15,3 +15,3 @@ # Twitter API v2

✅ **Light: No dependencies, 16kb minified+gzipped**
✅ **Light: No dependencies, 17kb minified+gzipped**

@@ -39,3 +39,3 @@ ✅ **Bundled types for request parameters and responses**

| -------------- | -------------- | ---------------- | ------------- | ---------- | --------------- | -------------:| -------------:|
| twitter-api-v2 | v1.1, v2, labs | ✅ | ✅ | ✅ | 0 | ~16 kB | [![twitter-api-v2 install size badge](https://badgen.net/packagephobia/install/twitter-api-v2)](https://packagephobia.com/result?p=twitter-api-v2) |
| twitter-api-v2 | v1.1, v2, labs | ✅ | ✅ | ✅ | 0 | ~17 kB | [![twitter-api-v2 install size badge](https://badgen.net/packagephobia/install/twitter-api-v2)](https://packagephobia.com/result?p=twitter-api-v2) |
| twit | v1.1 | ❌ | ✅ | ❌ | 51 | ~214.5 kB | [![twit install size badge](https://badgen.net/packagephobia/install/twit)](https://packagephobia.com/result?p=twit) |

@@ -42,0 +42,0 @@ | twitter | v1.1 | ❌ | ❌ | ❌ | 50 | ~182.1 kB | [![twitter install size badge](https://badgen.net/packagephobia/install/twitter)](https://packagephobia.com/result?p=twitter) |

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc