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.8.1 to 1.9.0

dist/v2/includes.v2.helper.d.ts

9

changelog.md

@@ -0,1 +1,10 @@

1.9.0
-----
- Feat: Helpers for v2 includes
- Feat: Support for custom debug loggers
- Fix: Errors accessor to get API errors in paginators #145
- Fix: Correctly update .includes/.meta/.errors in paginators when using async iterator #142
- Fix: Incorrect HTTP method for GET lists #147 #148
- Doc: Better doc & examples for OAuth 2.0 user-context
1.8.1

@@ -2,0 +11,0 @@ -----

1

dist/client-mixins/oauth2.helper.js

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

return Buffer.from(key).toString('base64');
;
}

@@ -40,0 +39,0 @@ static generateRandomString(length) {

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

if (settings_1.TwitterApiV2Settings.debug) {
console.log('Request network error:', error);
settings_1.TwitterApiV2Settings.logger.log('Request network error:', error);
}

@@ -58,3 +58,4 @@ return new types_1.ApiRequestError('Request failed.', {

if (settings_1.TwitterApiV2Settings.debug) {
console.log('Request failed with code', code, ', data:', data, 'response headers:', res.headers);
settings_1.TwitterApiV2Settings.logger.log(`Request failed with code ${code}, data:`, data);
settings_1.TwitterApiV2Settings.logger.log('Response headers:', res.headers);
}

@@ -115,4 +116,4 @@ // Errors formatting.

if (settings_1.TwitterApiV2Settings.debug) {
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode}`);
console.log('Response body:', data);
settings_1.TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode}`);
settings_1.TwitterApiV2Settings.logger.log('Response body:', data);
}

@@ -129,3 +130,3 @@ resolve({

if (settings_1.TwitterApiV2Settings.debug) {
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode} (starting stream)`);
settings_1.TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode} (starting stream)`);
}

@@ -142,8 +143,8 @@ // HTTP code ok, consume stream

const url = this.requestData.url;
console.log(`[${this.requestData.options.method} ${this.hrefPathname}]`, this.requestData.options);
settings_1.TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]`, this.requestData.options);
if (url.search) {
console.log('Request parameters:', [...url.searchParams.entries()].map(([key, value]) => `${key}: ${value}`));
settings_1.TwitterApiV2Settings.logger.log('Request parameters:', [...url.searchParams.entries()].map(([key, value]) => `${key}: ${value}`));
}
if (this.requestData.body) {
console.log('Request body:', this.requestData.body);
settings_1.TwitterApiV2Settings.logger.log('Request body:', this.requestData.body);
}

@@ -150,0 +151,0 @@ }

@@ -5,2 +5,3 @@ export { default as default } from './client';

export * from './v2/client.v2';
export * from './v2/includes.v2.helper';
export * from './v2-labs/client.v2.labs';

@@ -7,0 +8,0 @@ export * from './types';

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

__exportStar(require("./v2/client.v2"), exports);
__exportStar(require("./v2/includes.v2.helper"), exports);
__exportStar(require("./v2-labs/client.v2.labs"), exports);

@@ -24,0 +25,0 @@ __exportStar(require("./types"), exports);

@@ -1,23 +0,5 @@

import { PreviousableTwitterPaginator } from './TwitterPaginator';
import { Tweetv2SearchParams, Tweetv2SearchResult, TwitterResponse, TweetV2, Tweetv2TimelineResult, TweetV2TimelineParams, TweetV2UserTimelineResult, TweetV2UserTimelineParams, ApiV2Includes, Tweetv2ListResult, TweetV2PaginableListParams, Tweetv2FieldsParams } from '../types';
/** A generic PreviousableTwitterPaginator able to consume TweetV2[]. */
declare abstract class TweetsV2Paginator<TResult extends Tweetv2ListResult, TParams extends Partial<Tweetv2FieldsParams>, TShared = any> extends PreviousableTwitterPaginator<TResult, TParams, TweetV2, TShared> {
protected updateIncludes(data: TResult): void;
protected getPageLengthFromRequest(result: TwitterResponse<TResult>): number;
protected isFetchLastOver(result: TwitterResponse<TResult>): boolean;
protected canFetchNextPage(result: TResult): boolean;
protected getItemArray(): TweetV2[];
/**
* Tweets returned by paginator.
*/
get tweets(): TweetV2[];
get meta(): {
result_count: number;
next_token?: string | undefined;
previous_token?: string | undefined;
};
get includes(): ApiV2Includes;
}
import { Tweetv2SearchParams, Tweetv2SearchResult, TwitterResponse, TweetV2, Tweetv2TimelineResult, TweetV2TimelineParams, TweetV2UserTimelineResult, TweetV2UserTimelineParams, Tweetv2ListResult, TweetV2PaginableListParams } from '../types';
import { TimelineV2Paginator, TwitterV2Paginator } from './v2.paginator';
/** A generic PreviousableTwitterPaginator able to consume TweetV2 timelines. */
declare abstract class TweetTimelineV2Paginator<TResult extends Tweetv2TimelineResult, TParams extends TweetV2TimelineParams, TShared = any> extends TweetsV2Paginator<TResult, TParams, TShared> {
declare abstract class TweetTimelineV2Paginator<TResult extends Tweetv2TimelineResult, TParams extends TweetV2TimelineParams, TShared = any> extends TwitterV2Paginator<TResult, TParams, TweetV2, TShared> {
protected refreshInstanceFromResult(response: TwitterResponse<TResult>, isNextPage: boolean): void;

@@ -34,2 +16,10 @@ protected getNextQueryParams(maxResults?: number): {

};
protected getPageLengthFromRequest(result: TwitterResponse<TResult>): number;
protected isFetchLastOver(result: TwitterResponse<TResult>): boolean;
protected canFetchNextPage(result: TResult): boolean;
protected getItemArray(): TweetV2[];
/**
* Tweets returned by paginator.
*/
get tweets(): TweetV2[];
}

@@ -52,14 +42,8 @@ export declare class TweetSearchRecentV2Paginator extends TweetTimelineV2Paginator<Tweetv2SearchResult, Tweetv2SearchParams> {

/** A generic TwitterPaginator able to consume TweetV2 timelines. */
declare abstract class TweetListV2Paginator<TResult extends Tweetv2ListResult, TParams extends TweetV2PaginableListParams, TShared = any> extends TweetsV2Paginator<TResult, TParams, TShared> {
protected refreshInstanceFromResult(response: TwitterResponse<TResult>, isNextPage: boolean): void;
protected getNextQueryParams(maxResults?: number): {
max_results?: number | undefined;
} & Partial<TParams> & {
pagination_token: string | undefined;
};
protected getPreviousQueryParams(maxResults?: number): {
max_results?: number | undefined;
} & Partial<TParams> & {
pagination_token: string | undefined;
};
declare abstract class TweetListV2Paginator<TResult extends Tweetv2ListResult, TParams extends TweetV2PaginableListParams, TShared = any> extends TimelineV2Paginator<TResult, TParams, TweetV2, TShared> {
/**
* Tweets returned by paginator.
*/
get tweets(): TweetV2[];
protected getItemArray(): TweetV2[];
}

@@ -66,0 +50,0 @@ export declare class TweetV2UserLikedTweetsPaginator extends TweetListV2Paginator<Tweetv2ListResult, TweetV2PaginableListParams, TUserTimelinePaginatorShared> {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TweetV2ListTweetsPaginator = exports.TweetV2UserLikedTweetsPaginator = exports.TweetUserMentionTimelineV2Paginator = exports.TweetUserTimelineV2Paginator = exports.TweetSearchAllV2Paginator = exports.TweetSearchRecentV2Paginator = void 0;
const TwitterPaginator_1 = require("./TwitterPaginator");
/** A generic PreviousableTwitterPaginator able to consume TweetV2[]. */
class TweetsV2Paginator extends TwitterPaginator_1.PreviousableTwitterPaginator {
updateIncludes(data) {
if (!data.includes) {
return;
}
if (!this._realData.includes) {
this._realData.includes = {};
}
const includesRealData = this._realData.includes;
for (const [includeKey, includeArray] of Object.entries(data.includes)) {
if (!includesRealData[includeKey]) {
includesRealData[includeKey] = [];
}
includesRealData[includeKey] = [
...includesRealData[includeKey],
...includeArray,
];
}
}
getPageLengthFromRequest(result) {
var _a, _b;
return (_b = (_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
}
isFetchLastOver(result) {
var _a;
return !((_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) || !this.canFetchNextPage(result.data);
}
canFetchNextPage(result) {
return !!result.meta.next_token;
}
getItemArray() {
return this.tweets;
}
/**
* Tweets returned by paginator.
*/
get tweets() {
var _a;
return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
}
get meta() {
return this._realData.meta;
}
get includes() {
var _a;
return (_a = this._realData.includes) !== null && _a !== void 0 ? _a : {};
}
}
const v2_paginator_1 = require("./v2.paginator");
/** A generic PreviousableTwitterPaginator able to consume TweetV2 timelines. */
class TweetTimelineV2Paginator extends TweetsV2Paginator {
class TweetTimelineV2Paginator extends v2_paginator_1.TwitterV2Paginator {
refreshInstanceFromResult(response, isNextPage) {

@@ -78,2 +29,3 @@ var _a;

getNextQueryParams(maxResults) {
this.assertUsable();
return {

@@ -85,2 +37,3 @@ ...this.injectQueryParams(maxResults),

getPreviousQueryParams(maxResults) {
this.assertUsable();
return {

@@ -91,2 +44,23 @@ ...this.injectQueryParams(maxResults),

}
getPageLengthFromRequest(result) {
var _a, _b;
return (_b = (_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
}
isFetchLastOver(result) {
var _a;
return !((_a = result.data.data) === null || _a === void 0 ? void 0 : _a.length) || !this.canFetchNextPage(result.data);
}
canFetchNextPage(result) {
return !!result.meta.next_token;
}
getItemArray() {
return this.tweets;
}
/**
* Tweets returned by paginator.
*/
get tweets() {
var _a;
return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
}
}

@@ -128,35 +102,13 @@ // ----------------

/** A generic TwitterPaginator able to consume TweetV2 timelines. */
class TweetListV2Paginator extends TweetsV2Paginator {
refreshInstanceFromResult(response, isNextPage) {
class TweetListV2Paginator extends v2_paginator_1.TimelineV2Paginator {
/**
* Tweets returned by paginator.
*/
get tweets() {
var _a;
const result = response.data;
const resultData = (_a = result.data) !== null && _a !== void 0 ? _a : [];
this._rateLimit = response.rateLimit;
if (!this._realData.data) {
this._realData.data = [];
}
if (isNextPage) {
this._realData.meta.result_count += result.meta.result_count;
this._realData.meta.next_token = result.meta.next_token;
this._realData.data.push(...resultData);
}
else {
this._realData.meta.result_count += result.meta.result_count;
this._realData.meta.previous_token = result.meta.previous_token;
this._realData.data.unshift(...resultData);
}
this.updateIncludes(result);
return (_a = this._realData.data) !== null && _a !== void 0 ? _a : [];
}
getNextQueryParams(maxResults) {
return {
...this.injectQueryParams(maxResults),
pagination_token: this._realData.meta.next_token,
};
getItemArray() {
return this.tweets;
}
getPreviousQueryParams(maxResults) {
return {
...this.injectQueryParams(maxResults),
pagination_token: this._realData.meta.previous_token,
};
}
}

@@ -163,0 +115,0 @@ class TweetV2UserLikedTweetsPaginator extends TweetListV2Paginator {

@@ -60,5 +60,15 @@ import { TwitterRateLimit, TwitterResponse } from '../types';

/**
* Iterate over items "undefinitely" (until rate limit is hit / they're no more tweets available)
* Iterate over items "undefinitely" (until rate limit is hit / they're no more items available)
* This will **mutate the current instance** and fill data, metas, etc. inside this instance.
*
* If you need to handle concurrent requests, or you need to rely on immutability, please use `.fetchAndIterate()` instead.
*/
[Symbol.asyncIterator](): AsyncGenerator<TItem, void, undefined>;
/**
* Iterate over items "undefinitely" without modifying the current instance (until rate limit is hit / they're no more items available)
*
* This will **NOT** mutate the current instance, meaning that current instance will not inherit from `includes` and `meta` (v2 API only).
* Use `Symbol.asyncIterator` (`for-await of`) to directly access items with current instance mutation.
*/
fetchAndIterate(): AsyncGenerator<[TItem, this], void, undefined>;
}

@@ -65,0 +75,0 @@ /** PreviousableTwitterPaginator: a TwitterPaginator able to get consume data from both side, next and previous. */

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

/**
* Iterate over items "undefinitely" (until rate limit is hit / they're no more tweets available)
* Iterate over items "undefinitely" (until rate limit is hit / they're no more items available)
* This will **mutate the current instance** and fill data, metas, etc. inside this instance.
*
* If you need to handle concurrent requests, or you need to rely on immutability, please use `.fetchAndIterate()` instead.
*/

@@ -111,4 +114,5 @@ async *[Symbol.asyncIterator]() {

const next = await paginator.next(this._maxResultsWhenFetchLast);
// Store data into current instance [needed to access includes and meta]
this.refreshInstanceFromResult({ data: next._realData, headers: {}, rateLimit: next._rateLimit }, true);
canFetchNextPage = this.canFetchNextPage(next._realData);
this._rateLimit = next._rateLimit;
const items = next.getItemArray();

@@ -119,2 +123,27 @@ yield* items;

}
/**
* Iterate over items "undefinitely" without modifying the current instance (until rate limit is hit / they're no more items available)
*
* This will **NOT** mutate the current instance, meaning that current instance will not inherit from `includes` and `meta` (v2 API only).
* Use `Symbol.asyncIterator` (`for-await of`) to directly access items with current instance mutation.
*/
async *fetchAndIterate() {
for (const item of this.getItemArray()) {
yield [item, this];
}
// eslint-disable-next-line @typescript-eslint/no-this-alias
let paginator = this;
let canFetchNextPage = this.canFetchNextPage(this._realData);
while (canFetchNextPage && this._isRateLimitOk && paginator.getItemArray().length > 0) {
const next = await paginator.next(this._maxResultsWhenFetchLast);
// Store data into current instance [needed to access includes and meta]
this.refreshInstanceFromResult({ data: next._realData, headers: {}, rateLimit: next._rateLimit }, true);
canFetchNextPage = this.canFetchNextPage(next._realData);
for (const item of next.getItemArray()) {
yield [item, next];
}
this._rateLimit = next._rateLimit;
paginator = next;
}
}
}

@@ -121,0 +150,0 @@ exports.TwitterPaginator = TwitterPaginator;

import type { TwitterResponse } from '../types';
import type { DataMetaAndIncludeV2 } from '../types/v2/shared.v2.types';
import { TwitterV2IncludesHelper } from '../v2/includes.v2.helper';
import { PreviousableTwitterPaginator } from './TwitterPaginator';
/** A generic PreviousableTwitterPaginator able to consume v2 timelines that use max_results and pagination tokens. */
/** A generic PreviousableTwitterPaginator with common v2 helper methods. */
export declare abstract class TwitterV2Paginator<TResult extends DataMetaAndIncludeV2<any, any, any>, TParams extends object, TItem, TShared = any> extends PreviousableTwitterPaginator<TResult, TParams, TItem, TShared> {
protected _includesInstance?: TwitterV2IncludesHelper;
protected updateIncludes(data: TResult): void;
/** Throw if the current paginator is not usable. */
protected assertUsable(): void;
get meta(): any;
get includes(): TwitterV2IncludesHelper;
get errors(): import("../types").InlineErrorV2[];
/** `true` if this paginator only contains error payload and no metadata found to consume data. */
get unusable(): boolean;
}
/** A generic TwitterV2Paginator able to consume v2 timelines that use max_results and pagination tokens. */
export declare abstract class TimelineV2Paginator<TResult extends DataMetaAndIncludeV2<any, any, any>, TParams extends {
max_results?: number;
pagination_token?: string;
}, TItem, TShared = any> extends PreviousableTwitterPaginator<TResult, TParams, TItem, TShared> {
}, TItem, TShared = any> extends TwitterV2Paginator<TResult, TParams, TItem, TShared> {
protected refreshInstanceFromResult(response: TwitterResponse<TResult>, isNextPage: boolean): void;
protected updateIncludes(data: TResult): void;
protected getNextQueryParams(maxResults?: number): {

@@ -24,4 +36,2 @@ max_results?: number | undefined;

protected canFetchNextPage(result: TResult): boolean;
get meta(): any;
get includes(): any;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimelineV2Paginator = void 0;
exports.TimelineV2Paginator = exports.TwitterV2Paginator = void 0;
const includes_v2_helper_1 = require("../v2/includes.v2.helper");
const TwitterPaginator_1 = require("./TwitterPaginator");
/** A generic PreviousableTwitterPaginator able to consume v2 timelines that use max_results and pagination tokens. */
class TimelineV2Paginator extends TwitterPaginator_1.PreviousableTwitterPaginator {
/** A generic PreviousableTwitterPaginator with common v2 helper methods. */
class TwitterV2Paginator extends TwitterPaginator_1.PreviousableTwitterPaginator {
updateIncludes(data) {
// Update errors
if (data.errors) {
if (!this._realData.errors) {
this._realData.errors = [];
}
this._realData.errors = [...this._realData.errors, ...data.errors];
}
// Update includes
if (!data.includes) {
return;
}
if (!this._realData.includes) {
this._realData.includes = {};
}
const includesRealData = this._realData.includes;
for (const [includeKey, includeArray] of Object.entries(data.includes)) {
if (!includesRealData[includeKey]) {
includesRealData[includeKey] = [];
}
includesRealData[includeKey] = [
...includesRealData[includeKey],
...includeArray,
];
}
}
/** Throw if the current paginator is not usable. */
assertUsable() {
if (this.unusable) {
throw new Error('Unable to use this paginator to fetch more data, as it does not contain any metadata.' +
' Check .errors property for more details.');
}
}
get meta() {
return this._realData.meta;
}
get includes() {
var _a;
if (!((_a = this._realData) === null || _a === void 0 ? void 0 : _a.includes)) {
return new includes_v2_helper_1.TwitterV2IncludesHelper(this._realData);
}
if (this._includesInstance) {
return this._includesInstance;
}
return this._includesInstance = new includes_v2_helper_1.TwitterV2IncludesHelper(this._realData);
}
get errors() {
var _a;
return (_a = this._realData.errors) !== null && _a !== void 0 ? _a : [];
}
/** `true` if this paginator only contains error payload and no metadata found to consume data. */
get unusable() {
return this.errors.length > 0 && !this._realData.meta && !this._realData.data;
}
}
exports.TwitterV2Paginator = TwitterV2Paginator;
/** A generic TwitterV2Paginator able to consume v2 timelines that use max_results and pagination tokens. */
class TimelineV2Paginator extends TwitterV2Paginator {
refreshInstanceFromResult(response, isNextPage) {

@@ -27,21 +86,4 @@ var _a;

}
updateIncludes(data) {
if (!data.includes) {
return;
}
if (!this._realData.includes) {
this._realData.includes = {};
}
const includesRealData = this._realData.includes;
for (const [includeKey, includeArray] of Object.entries(data.includes)) {
if (!includesRealData[includeKey]) {
includesRealData[includeKey] = [];
}
includesRealData[includeKey] = [
...includesRealData[includeKey],
...includeArray,
];
}
}
getNextQueryParams(maxResults) {
this.assertUsable();
return {

@@ -53,2 +95,3 @@ ...this.injectQueryParams(maxResults),

getPreviousQueryParams(maxResults) {
this.assertUsable();
return {

@@ -70,10 +113,3 @@ ...this.injectQueryParams(maxResults),

}
get meta() {
return this._realData.meta;
}
get includes() {
var _a;
return (_a = this._realData.includes) !== null && _a !== void 0 ? _a : {};
}
}
exports.TimelineV2Paginator = TimelineV2Paginator;

@@ -1,4 +0,9 @@

export declare const TwitterApiV2Settings: {
export interface ITwitterApiV2Settings {
debug: boolean;
deprecationWarnings: boolean;
};
logger: ITwitterApiV2SettingsLogger;
}
export interface ITwitterApiV2SettingsLogger {
log(message: string, payload?: any): void;
}
export declare const TwitterApiV2Settings: ITwitterApiV2Settings;

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

deprecationWarnings: true,
logger: { log: console.log.bind(console) },
};

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

pagination_token?: string;
max_results?: number | string;
max_results?: number;
}

@@ -28,0 +28,0 @@ export interface TweetV2UserTimelineParams extends TweetV2PaginableTimelineParams {

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

list(id, options = {}) {
return this.post('lists/:id', options, { params: { id } });
return this.get('lists/:id', options, { params: { id } });
}

@@ -276,0 +276,0 @@ /**

{
"name": "twitter-api-v2",
"version": "1.8.1",
"version": "1.9.0",
"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",

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