plugin-connections
Version:
Connection management plugin for Twitter authentication and other services
1,306 lines (1,288 loc) • 222 kB
JavaScript
// ../../node_modules/twitter-api-v2/dist/esm/globals.js
var API_V2_PREFIX = "https://api.x.com/2/";
var API_V2_LABS_PREFIX = "https://api.x.com/labs/2/";
var API_V1_1_PREFIX = "https://api.x.com/1.1/";
var API_V1_1_UPLOAD_PREFIX = "https://upload.x.com/1.1/";
var API_V1_1_STREAM_PREFIX = "https://stream.x.com/1.1/";
var API_ADS_PREFIX = "https://ads-api.x.com/12/";
var API_ADS_SANDBOX_PREFIX = "https://ads-api-sandbox.twitter.com/12/";
// ../../node_modules/twitter-api-v2/dist/esm/paginators/TwitterPaginator.js
var TwitterPaginator = class {
// noinspection TypeScriptAbstractClassConstructorCanBeMadeProtected
constructor({ realData, rateLimit, instance, queryParams, sharedParams }) {
this._maxResultsWhenFetchLast = 100;
this._realData = realData;
this._rateLimit = rateLimit;
this._instance = instance;
this._queryParams = queryParams;
this._sharedParams = sharedParams;
}
get _isRateLimitOk() {
if (!this._rateLimit) {
return true;
}
const resetDate = this._rateLimit.reset * 1e3;
if (resetDate < Date.now()) {
return true;
}
return this._rateLimit.remaining > 0;
}
makeRequest(queryParams) {
return this._instance.get(this.getEndpoint(), queryParams, { fullResponse: true, params: this._sharedParams });
}
makeNewInstanceFromResult(result, queryParams) {
return new this.constructor({
realData: result.data,
rateLimit: result.rateLimit,
instance: this._instance,
queryParams,
sharedParams: this._sharedParams
});
}
getEndpoint() {
return this._endpoint;
}
injectQueryParams(maxResults) {
return {
...maxResults ? { max_results: maxResults } : {},
...this._queryParams
};
}
/* ---------------------- */
/* Real paginator methods */
/* ---------------------- */
/**
* Next page.
*/
async next(maxResults) {
const queryParams = this.getNextQueryParams(maxResults);
const result = await this.makeRequest(queryParams);
return this.makeNewInstanceFromResult(result, queryParams);
}
/**
* Next page, but store it in current instance.
*/
async fetchNext(maxResults) {
const queryParams = this.getNextQueryParams(maxResults);
const result = await this.makeRequest(queryParams);
await this.refreshInstanceFromResult(result, true);
return this;
}
/**
* Fetch up to {count} items after current page,
* as long as rate limit is not hit and Twitter has some results
*/
async fetchLast(count = Infinity) {
let queryParams = this.getNextQueryParams(this._maxResultsWhenFetchLast);
let resultCount = 0;
while (resultCount < count && this._isRateLimitOk) {
const response = await this.makeRequest(queryParams);
await this.refreshInstanceFromResult(response, true);
resultCount += this.getPageLengthFromRequest(response);
if (this.isFetchLastOver(response)) {
break;
}
queryParams = this.getNextQueryParams(this._maxResultsWhenFetchLast);
}
return this;
}
get rateLimit() {
var _a;
return { ...(_a = this._rateLimit) !== null && _a !== void 0 ? _a : {} };
}
/** Get raw data returned by Twitter API. */
get data() {
return this._realData;
}
get done() {
return !this.canFetchNextPage(this._realData);
}
/**
* Iterate over currently fetched items.
*/
*[Symbol.iterator]() {
yield* this.getItemArray();
}
/**
* Iterate over items "indefinitely" (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.
*/
async *[Symbol.asyncIterator]() {
yield* this.getItemArray();
let paginator = this;
let canFetchNextPage = this.canFetchNextPage(this._realData);
while (canFetchNextPage && this._isRateLimitOk && paginator.getItemArray().length > 0) {
const next = await paginator.next(this._maxResultsWhenFetchLast);
this.refreshInstanceFromResult({ data: next._realData, headers: {}, rateLimit: next._rateLimit }, true);
canFetchNextPage = this.canFetchNextPage(next._realData);
const items = next.getItemArray();
yield* items;
paginator = next;
}
}
/**
* Iterate over items "indefinitely" 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];
}
let paginator = this;
let canFetchNextPage = this.canFetchNextPage(this._realData);
while (canFetchNextPage && this._isRateLimitOk && paginator.getItemArray().length > 0) {
const next = await paginator.next(this._maxResultsWhenFetchLast);
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;
}
}
};
var PreviousableTwitterPaginator = class extends TwitterPaginator {
/**
* Previous page (new tweets)
*/
async previous(maxResults) {
const queryParams = this.getPreviousQueryParams(maxResults);
const result = await this.makeRequest(queryParams);
return this.makeNewInstanceFromResult(result, queryParams);
}
/**
* Previous page, but in current instance.
*/
async fetchPrevious(maxResults) {
const queryParams = this.getPreviousQueryParams(maxResults);
const result = await this.makeRequest(queryParams);
await this.refreshInstanceFromResult(result, false);
return this;
}
};
var TwitterPaginator_default = TwitterPaginator;
// ../../node_modules/twitter-api-v2/dist/esm/paginators/paginator.v1.js
var CursoredV1Paginator = class extends TwitterPaginator_default {
getNextQueryParams(maxResults) {
var _a;
return {
...this._queryParams,
cursor: (_a = this._realData.next_cursor_str) !== null && _a !== void 0 ? _a : this._realData.next_cursor,
...maxResults ? { count: maxResults } : {}
};
}
isFetchLastOver(result) {
return !this.canFetchNextPage(result.data);
}
canFetchNextPage(result) {
return !this.isNextCursorInvalid(result.next_cursor) || !this.isNextCursorInvalid(result.next_cursor_str);
}
isNextCursorInvalid(value) {
return value === void 0 || value === 0 || value === -1 || value === "0" || value === "-1";
}
};
// ../../node_modules/twitter-api-v2/dist/esm/paginators/dm.paginator.v1.js
var DmEventsV1Paginator = class extends CursoredV1Paginator {
constructor() {
super(...arguments);
this._endpoint = "direct_messages/events/list.json";
}
refreshInstanceFromResult(response, isNextPage) {
const result = response.data;
this._rateLimit = response.rateLimit;
if (isNextPage) {
this._realData.events.push(...result.events);
this._realData.next_cursor = result.next_cursor;
}
}
getPageLengthFromRequest(result) {
return result.data.events.length;
}
getItemArray() {
return this.events;
}
/**
* Events returned by paginator.
*/
get events() {
return this._realData.events;
}
};
var WelcomeDmV1Paginator = class extends CursoredV1Paginator {
constructor() {
super(...arguments);
this._endpoint = "direct_messages/welcome_messages/list.json";
}
refreshInstanceFromResult(response, isNextPage) {
const result = response.data;
this._rateLimit = response.rateLimit;
if (isNextPage) {
this._realData.welcome_messages.push(...result.welcome_messages);
this._realData.next_cursor = result.next_cursor;
}
}
getPageLengthFromRequest(result) {
return result.data.welcome_messages.length;
}
getItemArray() {
return this.welcomeMessages;
}
get welcomeMessages() {
return this._realData.welcome_messages;
}
};
// ../../node_modules/twitter-api-v2/dist/esm/types/v1/tweet.v1.types.js
var EUploadMimeType;
(function(EUploadMimeType2) {
EUploadMimeType2["Jpeg"] = "image/jpeg";
EUploadMimeType2["Mp4"] = "video/mp4";
EUploadMimeType2["Mov"] = "video/quicktime";
EUploadMimeType2["Gif"] = "image/gif";
EUploadMimeType2["Png"] = "image/png";
EUploadMimeType2["Srt"] = "text/plain";
EUploadMimeType2["Webp"] = "image/webp";
})(EUploadMimeType || (EUploadMimeType = {}));
// ../../node_modules/twitter-api-v2/dist/esm/types/v1/dm.v1.types.js
var EDirectMessageEventTypeV1;
(function(EDirectMessageEventTypeV12) {
EDirectMessageEventTypeV12["Create"] = "message_create";
EDirectMessageEventTypeV12["WelcomeCreate"] = "welcome_message";
})(EDirectMessageEventTypeV1 || (EDirectMessageEventTypeV1 = {}));
// ../../node_modules/twitter-api-v2/dist/esm/types/errors.types.js
var ETwitterApiError;
(function(ETwitterApiError2) {
ETwitterApiError2["Request"] = "request";
ETwitterApiError2["PartialResponse"] = "partial-response";
ETwitterApiError2["Response"] = "response";
})(ETwitterApiError || (ETwitterApiError = {}));
var ApiError = class extends Error {
constructor() {
super(...arguments);
this.error = true;
}
};
var ApiRequestError = class extends ApiError {
constructor(message, options) {
super(message);
this.type = ETwitterApiError.Request;
Error.captureStackTrace(this, this.constructor);
Object.defineProperty(this, "_options", { value: options });
}
get request() {
return this._options.request;
}
get requestError() {
return this._options.requestError;
}
toJSON() {
return {
type: this.type,
error: this.requestError
};
}
};
var ApiPartialResponseError = class extends ApiError {
constructor(message, options) {
super(message);
this.type = ETwitterApiError.PartialResponse;
Error.captureStackTrace(this, this.constructor);
Object.defineProperty(this, "_options", { value: options });
}
get request() {
return this._options.request;
}
get response() {
return this._options.response;
}
get responseError() {
return this._options.responseError;
}
get rawContent() {
return this._options.rawContent;
}
toJSON() {
return {
type: this.type,
error: this.responseError
};
}
};
var ApiResponseError = class extends ApiError {
constructor(message, options) {
super(message);
this.type = ETwitterApiError.Response;
Error.captureStackTrace(this, this.constructor);
Object.defineProperty(this, "_options", { value: options });
this.code = options.code;
this.headers = options.headers;
this.rateLimit = options.rateLimit;
if (options.data && typeof options.data === "object" && "error" in options.data && !options.data.errors) {
const data = { ...options.data };
data.errors = [{
code: EApiV1ErrorCode.InternalError,
message: data.error
}];
this.data = data;
} else {
this.data = options.data;
}
}
get request() {
return this._options.request;
}
get response() {
return this._options.response;
}
/** Check for presence of one of given v1/v2 error codes. */
hasErrorCode(...codes) {
const errors = this.errors;
if (!(errors === null || errors === void 0 ? void 0 : errors.length)) {
return false;
}
if ("code" in errors[0]) {
const v1errors = errors;
return v1errors.some((error) => codes.includes(error.code));
}
const v2error = this.data;
return codes.includes(v2error.type);
}
get errors() {
var _a;
return (_a = this.data) === null || _a === void 0 ? void 0 : _a.errors;
}
get rateLimitError() {
return this.code === 420 || this.code === 429;
}
get isAuthError() {
if (this.code === 401) {
return true;
}
return this.hasErrorCode(EApiV1ErrorCode.AuthTimestampInvalid, EApiV1ErrorCode.AuthenticationFail, EApiV1ErrorCode.BadAuthenticationData, EApiV1ErrorCode.InvalidOrExpiredToken);
}
toJSON() {
return {
type: this.type,
code: this.code,
error: this.data,
rateLimit: this.rateLimit,
headers: this.headers
};
}
};
var EApiV1ErrorCode;
(function(EApiV1ErrorCode2) {
EApiV1ErrorCode2[EApiV1ErrorCode2["InvalidCoordinates"] = 3] = "InvalidCoordinates";
EApiV1ErrorCode2[EApiV1ErrorCode2["NoLocationFound"] = 13] = "NoLocationFound";
EApiV1ErrorCode2[EApiV1ErrorCode2["AuthenticationFail"] = 32] = "AuthenticationFail";
EApiV1ErrorCode2[EApiV1ErrorCode2["InvalidOrExpiredToken"] = 89] = "InvalidOrExpiredToken";
EApiV1ErrorCode2[EApiV1ErrorCode2["UnableToVerifyCredentials"] = 99] = "UnableToVerifyCredentials";
EApiV1ErrorCode2[EApiV1ErrorCode2["AuthTimestampInvalid"] = 135] = "AuthTimestampInvalid";
EApiV1ErrorCode2[EApiV1ErrorCode2["BadAuthenticationData"] = 215] = "BadAuthenticationData";
EApiV1ErrorCode2[EApiV1ErrorCode2["NoUserMatch"] = 17] = "NoUserMatch";
EApiV1ErrorCode2[EApiV1ErrorCode2["UserNotFound"] = 50] = "UserNotFound";
EApiV1ErrorCode2[EApiV1ErrorCode2["ResourceNotFound"] = 34] = "ResourceNotFound";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetNotFound"] = 144] = "TweetNotFound";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetNotVisible"] = 179] = "TweetNotVisible";
EApiV1ErrorCode2[EApiV1ErrorCode2["NotAllowedResource"] = 220] = "NotAllowedResource";
EApiV1ErrorCode2[EApiV1ErrorCode2["MediaIdNotFound"] = 325] = "MediaIdNotFound";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetNoLongerAvailable"] = 421] = "TweetNoLongerAvailable";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetViolatedRules"] = 422] = "TweetViolatedRules";
EApiV1ErrorCode2[EApiV1ErrorCode2["TargetUserSuspended"] = 63] = "TargetUserSuspended";
EApiV1ErrorCode2[EApiV1ErrorCode2["YouAreSuspended"] = 64] = "YouAreSuspended";
EApiV1ErrorCode2[EApiV1ErrorCode2["AccountUpdateFailed"] = 120] = "AccountUpdateFailed";
EApiV1ErrorCode2[EApiV1ErrorCode2["NoSelfSpamReport"] = 36] = "NoSelfSpamReport";
EApiV1ErrorCode2[EApiV1ErrorCode2["NoSelfMute"] = 271] = "NoSelfMute";
EApiV1ErrorCode2[EApiV1ErrorCode2["AccountLocked"] = 326] = "AccountLocked";
EApiV1ErrorCode2[EApiV1ErrorCode2["RateLimitExceeded"] = 88] = "RateLimitExceeded";
EApiV1ErrorCode2[EApiV1ErrorCode2["NoDMRightForApp"] = 93] = "NoDMRightForApp";
EApiV1ErrorCode2[EApiV1ErrorCode2["OverCapacity"] = 130] = "OverCapacity";
EApiV1ErrorCode2[EApiV1ErrorCode2["InternalError"] = 131] = "InternalError";
EApiV1ErrorCode2[EApiV1ErrorCode2["TooManyFollowings"] = 161] = "TooManyFollowings";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetLimitExceeded"] = 185] = "TweetLimitExceeded";
EApiV1ErrorCode2[EApiV1ErrorCode2["DuplicatedTweet"] = 187] = "DuplicatedTweet";
EApiV1ErrorCode2[EApiV1ErrorCode2["TooManySpamReports"] = 205] = "TooManySpamReports";
EApiV1ErrorCode2[EApiV1ErrorCode2["RequestLooksLikeSpam"] = 226] = "RequestLooksLikeSpam";
EApiV1ErrorCode2[EApiV1ErrorCode2["NoWriteRightForApp"] = 261] = "NoWriteRightForApp";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetActionsDisabled"] = 425] = "TweetActionsDisabled";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetRepliesRestricted"] = 433] = "TweetRepliesRestricted";
EApiV1ErrorCode2[EApiV1ErrorCode2["NamedParameterMissing"] = 38] = "NamedParameterMissing";
EApiV1ErrorCode2[EApiV1ErrorCode2["InvalidAttachmentUrl"] = 44] = "InvalidAttachmentUrl";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetTextTooLong"] = 186] = "TweetTextTooLong";
EApiV1ErrorCode2[EApiV1ErrorCode2["MissingUrlParameter"] = 195] = "MissingUrlParameter";
EApiV1ErrorCode2[EApiV1ErrorCode2["NoMultipleGifs"] = 323] = "NoMultipleGifs";
EApiV1ErrorCode2[EApiV1ErrorCode2["InvalidMediaIds"] = 324] = "InvalidMediaIds";
EApiV1ErrorCode2[EApiV1ErrorCode2["InvalidUrl"] = 407] = "InvalidUrl";
EApiV1ErrorCode2[EApiV1ErrorCode2["TooManyTweetAttachments"] = 386] = "TooManyTweetAttachments";
EApiV1ErrorCode2[EApiV1ErrorCode2["StatusAlreadyFavorited"] = 139] = "StatusAlreadyFavorited";
EApiV1ErrorCode2[EApiV1ErrorCode2["FollowRequestAlreadySent"] = 160] = "FollowRequestAlreadySent";
EApiV1ErrorCode2[EApiV1ErrorCode2["CannotUnmuteANonMutedAccount"] = 272] = "CannotUnmuteANonMutedAccount";
EApiV1ErrorCode2[EApiV1ErrorCode2["TweetAlreadyRetweeted"] = 327] = "TweetAlreadyRetweeted";
EApiV1ErrorCode2[EApiV1ErrorCode2["ReplyToDeletedTweet"] = 385] = "ReplyToDeletedTweet";
EApiV1ErrorCode2[EApiV1ErrorCode2["DMReceiverNotFollowingYou"] = 150] = "DMReceiverNotFollowingYou";
EApiV1ErrorCode2[EApiV1ErrorCode2["UnableToSendDM"] = 151] = "UnableToSendDM";
EApiV1ErrorCode2[EApiV1ErrorCode2["MustAllowDMFromAnyone"] = 214] = "MustAllowDMFromAnyone";
EApiV1ErrorCode2[EApiV1ErrorCode2["CannotSendDMToThisUser"] = 349] = "CannotSendDMToThisUser";
EApiV1ErrorCode2[EApiV1ErrorCode2["DMTextTooLong"] = 354] = "DMTextTooLong";
EApiV1ErrorCode2[EApiV1ErrorCode2["SubscriptionAlreadyExists"] = 355] = "SubscriptionAlreadyExists";
EApiV1ErrorCode2[EApiV1ErrorCode2["CallbackUrlNotApproved"] = 415] = "CallbackUrlNotApproved";
EApiV1ErrorCode2[EApiV1ErrorCode2["SuspendedApplication"] = 416] = "SuspendedApplication";
EApiV1ErrorCode2[EApiV1ErrorCode2["OobOauthIsNotAllowed"] = 417] = "OobOauthIsNotAllowed";
})(EApiV1ErrorCode || (EApiV1ErrorCode = {}));
var EApiV2ErrorCode;
(function(EApiV2ErrorCode2) {
EApiV2ErrorCode2["InvalidRequest"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#invalid-request";
EApiV2ErrorCode2["ClientForbidden"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#client-forbidden";
EApiV2ErrorCode2["UnsupportedAuthentication"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#unsupported-authentication";
EApiV2ErrorCode2["InvalidRules"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#invalid-rules";
EApiV2ErrorCode2["TooManyRules"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#rule-cap";
EApiV2ErrorCode2["DuplicatedRules"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#duplicate-rules";
EApiV2ErrorCode2["RateLimitExceeded"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#usage-capped";
EApiV2ErrorCode2["ConnectionError"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#streaming-connection";
EApiV2ErrorCode2["ClientDisconnected"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#client-disconnected";
EApiV2ErrorCode2["TwitterDisconnectedYou"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#operational-disconnect";
EApiV2ErrorCode2["ResourceNotFound"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#resource-not-found";
EApiV2ErrorCode2["ResourceUnauthorized"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#not-authorized-for-resource";
EApiV2ErrorCode2["DisallowedResource"] = "https://developer.x.com/en/support/x-api/error-troubleshooting#disallowed-resource";
})(EApiV2ErrorCode || (EApiV2ErrorCode = {}));
// ../../node_modules/twitter-api-v2/dist/esm/types/client.types.js
var ETwitterStreamEvent;
(function(ETwitterStreamEvent2) {
ETwitterStreamEvent2["Connected"] = "connected";
ETwitterStreamEvent2["ConnectError"] = "connect error";
ETwitterStreamEvent2["ConnectionError"] = "connection error";
ETwitterStreamEvent2["ConnectionClosed"] = "connection closed";
ETwitterStreamEvent2["ConnectionLost"] = "connection lost";
ETwitterStreamEvent2["ReconnectAttempt"] = "reconnect attempt";
ETwitterStreamEvent2["Reconnected"] = "reconnected";
ETwitterStreamEvent2["ReconnectError"] = "reconnect error";
ETwitterStreamEvent2["ReconnectLimitExceeded"] = "reconnect limit exceeded";
ETwitterStreamEvent2["DataKeepAlive"] = "data keep-alive";
ETwitterStreamEvent2["Data"] = "data event content";
ETwitterStreamEvent2["DataError"] = "data twitter error";
ETwitterStreamEvent2["TweetParseError"] = "data tweet parse error";
ETwitterStreamEvent2["Error"] = "stream error";
})(ETwitterStreamEvent || (ETwitterStreamEvent = {}));
// ../../node_modules/twitter-api-v2/dist/esm/types/plugins/client.plugins.types.js
var TwitterApiPluginResponseOverride = class {
constructor(value) {
this.value = value;
}
};
// ../../node_modules/twitter-api-v2/dist/esm/v1/client.v1.write.js
import * as fs2 from "fs";
// ../../node_modules/twitter-api-v2/dist/esm/settings.js
var TwitterApiV2Settings = {
debug: false,
deprecationWarnings: true,
logger: { log: console.log.bind(console) }
};
// ../../node_modules/twitter-api-v2/dist/esm/helpers.js
function sharedPromise(getter) {
const sharedPromise2 = {
value: void 0,
promise: getter().then((val) => {
sharedPromise2.value = val;
return val;
})
};
return sharedPromise2;
}
function arrayWrap(value) {
if (Array.isArray(value)) {
return value;
}
return [value];
}
function trimUndefinedProperties(object) {
for (const parameter in object) {
if (object[parameter] === void 0)
delete object[parameter];
}
}
function isTweetStreamV2ErrorPayload(payload) {
return typeof payload === "object" && "errors" in payload && !("data" in payload);
}
function hasMultipleItems(item) {
if (Array.isArray(item) && item.length > 1) {
return true;
}
return item.toString().includes(",");
}
var deprecationWarningsCache = /* @__PURE__ */ new Set();
function safeDeprecationWarning(message) {
if (typeof console === "undefined" || !console.warn || !TwitterApiV2Settings.deprecationWarnings) {
return;
}
const hash = `${message.instance}-${message.method}-${message.problem}`;
if (deprecationWarningsCache.has(hash)) {
return;
}
const formattedMsg = `[twitter-api-v2] Deprecation warning: In ${message.instance}.${message.method}() call, ${message.problem}.
${message.resolution}.`;
console.warn(formattedMsg);
console.warn("To disable this message, import variable TwitterApiV2Settings from twitter-api-v2 and set TwitterApiV2Settings.deprecationWarnings to false.");
deprecationWarningsCache.add(hash);
}
// ../../node_modules/twitter-api-v2/dist/esm/stream/TweetStream.js
import { EventEmitter as EventEmitter4 } from "events";
// ../../node_modules/twitter-api-v2/dist/esm/client-mixins/request-handler.helper.js
import { request } from "https";
import * as zlib from "zlib";
import { EventEmitter } from "events";
var RequestHandlerHelper = class {
constructor(requestData) {
this.requestData = requestData;
this.requestErrorHandled = false;
this.responseData = [];
}
/* Request helpers */
get hrefPathname() {
const url = this.requestData.url;
return url.hostname + url.pathname;
}
isCompressionDisabled() {
return !this.requestData.compression || this.requestData.compression === "identity";
}
isFormEncodedEndpoint() {
return this.requestData.url.href.startsWith("https://api.x.com/oauth/");
}
/* Error helpers */
createRequestError(error) {
if (TwitterApiV2Settings.debug) {
TwitterApiV2Settings.logger.log("Request error:", error);
}
return new ApiRequestError("Request failed.", {
request: this.req,
error
});
}
createPartialResponseError(error, abortClose) {
const res = this.res;
let message = `Request failed with partial response with HTTP code ${res.statusCode}`;
if (abortClose) {
message += " (connection abruptly closed)";
} else {
message += " (parse error)";
}
return new ApiPartialResponseError(message, {
request: this.req,
response: this.res,
responseError: error,
rawContent: Buffer.concat(this.responseData).toString()
});
}
formatV1Errors(errors) {
return errors.map(({ code, message }) => `${message} (Twitter code ${code})`).join(", ");
}
formatV2Error(error) {
return `${error.title}: ${error.detail} (see ${error.type})`;
}
createResponseError({ res, data, rateLimit, code }) {
var _a;
if (TwitterApiV2Settings.debug) {
TwitterApiV2Settings.logger.log(`Request failed with code ${code}, data:`, data);
TwitterApiV2Settings.logger.log("Response headers:", res.headers);
}
let errorString = `Request failed with code ${code}`;
if ((_a = data === null || data === void 0 ? void 0 : data.errors) === null || _a === void 0 ? void 0 : _a.length) {
const errors = data.errors;
if (typeof errors[0] === "object" && "code" in errors[0]) {
errorString += " - " + this.formatV1Errors(errors);
} else {
errorString += " - " + this.formatV2Error(data);
}
}
return new ApiResponseError(errorString, {
code,
data,
headers: res.headers,
request: this.req,
response: res,
rateLimit
});
}
/* Response helpers */
getResponseDataStream(res) {
if (this.isCompressionDisabled()) {
return res;
}
const contentEncoding = (res.headers["content-encoding"] || "identity").trim().toLowerCase();
if (contentEncoding === "br") {
const brotli = zlib.createBrotliDecompress({
flush: zlib.constants.BROTLI_OPERATION_FLUSH,
finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH
});
res.pipe(brotli);
return brotli;
}
if (contentEncoding === "gzip") {
const gunzip = zlib.createGunzip({
flush: zlib.constants.Z_SYNC_FLUSH,
finishFlush: zlib.constants.Z_SYNC_FLUSH
});
res.pipe(gunzip);
return gunzip;
}
if (contentEncoding === "deflate") {
const inflate = zlib.createInflate({
flush: zlib.constants.Z_SYNC_FLUSH,
finishFlush: zlib.constants.Z_SYNC_FLUSH
});
res.pipe(inflate);
return inflate;
}
return res;
}
detectResponseType(res) {
var _a, _b;
if (((_a = res.headers["content-type"]) === null || _a === void 0 ? void 0 : _a.includes("application/json")) || ((_b = res.headers["content-type"]) === null || _b === void 0 ? void 0 : _b.includes("application/problem+json"))) {
return "json";
} else if (this.isFormEncodedEndpoint()) {
return "url";
}
return "text";
}
getParsedResponse(res) {
const data = this.responseData;
const mode = this.requestData.forceParseMode || this.detectResponseType(res);
if (mode === "buffer") {
return Buffer.concat(data);
} else if (mode === "text") {
return Buffer.concat(data).toString();
} else if (mode === "json") {
const asText = Buffer.concat(data).toString();
return asText.length ? JSON.parse(asText) : void 0;
} else if (mode === "url") {
const asText = Buffer.concat(data).toString();
const formEntries = {};
for (const [item, value] of new URLSearchParams(asText)) {
formEntries[item] = value;
}
return formEntries;
} else {
return void 0;
}
}
getRateLimitFromResponse(res) {
let rateLimit = void 0;
if (res.headers["x-rate-limit-limit"]) {
rateLimit = {
limit: Number(res.headers["x-rate-limit-limit"]),
remaining: Number(res.headers["x-rate-limit-remaining"]),
reset: Number(res.headers["x-rate-limit-reset"])
};
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) {
this.requestData.rateLimitSaver(rateLimit);
}
}
return rateLimit;
}
/* Request event handlers */
onSocketEventHandler(reject, cleanupListener, socket) {
const onClose = this.onSocketCloseHandler.bind(this, reject);
socket.on("close", onClose);
cleanupListener.on("complete", () => socket.off("close", onClose));
}
onSocketCloseHandler(reject) {
this.req.removeAllListeners("timeout");
const res = this.res;
if (res) {
return;
}
if (!this.requestErrorHandled) {
return reject(this.createRequestError(new Error("Socket closed without any information.")));
}
}
requestErrorHandler(reject, requestError) {
var _a, _b;
(_b = (_a = this.requestData).requestEventDebugHandler) === null || _b === void 0 ? void 0 : _b.call(_a, "request-error", { requestError });
this.requestErrorHandled = true;
reject(this.createRequestError(requestError));
}
timeoutErrorHandler() {
this.requestErrorHandled = true;
this.req.destroy(new Error("Request timeout."));
}
/* Response event handlers */
classicResponseHandler(resolve, reject, res) {
this.res = res;
const dataStream = this.getResponseDataStream(res);
dataStream.on("data", (chunk) => this.responseData.push(chunk));
dataStream.on("end", this.onResponseEndHandler.bind(this, resolve, reject));
dataStream.on("close", this.onResponseCloseHandler.bind(this, resolve, reject));
if (this.requestData.requestEventDebugHandler) {
this.requestData.requestEventDebugHandler("response", { res });
res.on("aborted", (error) => this.requestData.requestEventDebugHandler("response-aborted", { error }));
res.on("error", (error) => this.requestData.requestEventDebugHandler("response-error", { error }));
res.on("close", () => this.requestData.requestEventDebugHandler("response-close", { data: this.responseData }));
res.on("end", () => this.requestData.requestEventDebugHandler("response-end"));
}
}
onResponseEndHandler(resolve, reject) {
const rateLimit = this.getRateLimitFromResponse(this.res);
let data;
try {
data = this.getParsedResponse(this.res);
} catch (e) {
reject(this.createPartialResponseError(e, false));
return;
}
const code = this.res.statusCode;
if (code >= 400) {
reject(this.createResponseError({ data, res: this.res, rateLimit, code }));
return;
}
if (TwitterApiV2Settings.debug) {
TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${this.res.statusCode}`);
TwitterApiV2Settings.logger.log("Response body:", data);
}
resolve({
data,
headers: this.res.headers,
rateLimit
});
}
onResponseCloseHandler(resolve, reject) {
const res = this.res;
if (res.aborted) {
try {
this.getParsedResponse(this.res);
return this.onResponseEndHandler(resolve, reject);
} catch (e) {
return reject(this.createPartialResponseError(e, true));
}
}
if (!res.complete) {
return reject(this.createPartialResponseError(new Error("Response has been interrupted before response could be parsed."), true));
}
}
streamResponseHandler(resolve, reject, res) {
const code = res.statusCode;
if (code < 400) {
if (TwitterApiV2Settings.debug) {
TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]: Request succeeds with code ${res.statusCode} (starting stream)`);
}
const dataStream = this.getResponseDataStream(res);
resolve({ req: this.req, res: dataStream, originalResponse: res, requestData: this.requestData });
} else {
this.classicResponseHandler(() => void 0, reject, res);
}
}
/* Wrappers for request lifecycle */
debugRequest() {
const url = this.requestData.url;
TwitterApiV2Settings.logger.log(`[${this.requestData.options.method} ${this.hrefPathname}]`, this.requestData.options);
if (url.search) {
TwitterApiV2Settings.logger.log("Request parameters:", [...url.searchParams.entries()].map(([key, value]) => `${key}: ${value}`));
}
if (this.requestData.body) {
TwitterApiV2Settings.logger.log("Request body:", this.requestData.body);
}
}
buildRequest() {
var _a;
const url = this.requestData.url;
const auth = url.username ? `${url.username}:${url.password}` : void 0;
const headers = (_a = this.requestData.options.headers) !== null && _a !== void 0 ? _a : {};
if (this.requestData.compression === true || this.requestData.compression === "brotli") {
headers["accept-encoding"] = "br;q=1.0, gzip;q=0.8, deflate;q=0.5, *;q=0.1";
} else if (this.requestData.compression === "gzip") {
headers["accept-encoding"] = "gzip;q=1, deflate;q=0.5, *;q=0.1";
} else if (this.requestData.compression === "deflate") {
headers["accept-encoding"] = "deflate;q=1, *;q=0.1";
}
if (TwitterApiV2Settings.debug) {
this.debugRequest();
}
this.req = 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 || void 0,
path: url.pathname + url.search,
protocol: url.protocol,
auth,
headers
});
}
registerRequestEventDebugHandlers(req) {
req.on("close", () => this.requestData.requestEventDebugHandler("close"));
req.on("abort", () => this.requestData.requestEventDebugHandler("abort"));
req.on("socket", (socket) => {
this.requestData.requestEventDebugHandler("socket", { socket });
socket.on("error", (error) => this.requestData.requestEventDebugHandler("socket-error", { socket, error }));
socket.on("connect", () => this.requestData.requestEventDebugHandler("socket-connect", { socket }));
socket.on("close", (withError) => this.requestData.requestEventDebugHandler("socket-close", { socket, withError }));
socket.on("end", () => this.requestData.requestEventDebugHandler("socket-end", { socket }));
socket.on("lookup", (...data) => this.requestData.requestEventDebugHandler("socket-lookup", { socket, data }));
socket.on("timeout", () => this.requestData.requestEventDebugHandler("socket-timeout", { socket }));
});
}
makeRequest() {
this.buildRequest();
return new Promise((_resolve, _reject) => {
const resolve = (value) => {
cleanupListener.emit("complete");
_resolve(value);
};
const reject = (value) => {
cleanupListener.emit("complete");
_reject(value);
};
const cleanupListener = new EventEmitter();
const req = this.req;
req.on("error", this.requestErrorHandler.bind(this, reject));
req.on("socket", this.onSocketEventHandler.bind(this, reject, cleanupListener));
req.on("response", this.classicResponseHandler.bind(this, resolve, reject));
if (this.requestData.options.timeout) {
req.on("timeout", this.timeoutErrorHandler.bind(this));
}
if (this.requestData.requestEventDebugHandler) {
this.registerRequestEventDebugHandlers(req);
}
if (this.requestData.body) {
req.write(this.requestData.body);
}
req.end();
});
}
async makeRequestAsStream() {
const { req, res, requestData, originalResponse } = await this.makeRequestAndResolveWhenReady();
return new TweetStream_default(requestData, { req, res, originalResponse });
}
makeRequestAndResolveWhenReady() {
this.buildRequest();
return new Promise((resolve, reject) => {
const req = this.req;
req.on("error", this.requestErrorHandler.bind(this, reject));
req.on("response", this.streamResponseHandler.bind(this, resolve, reject));
if (this.requestData.body) {
req.write(this.requestData.body);
}
req.end();
});
}
};
var request_handler_helper_default = RequestHandlerHelper;
// ../../node_modules/twitter-api-v2/dist/esm/stream/TweetStreamEventCombiner.js
import { EventEmitter as EventEmitter2 } from "events";
var TweetStreamEventCombiner = class extends EventEmitter2 {
constructor(stream) {
super();
this.stream = stream;
this.stack = [];
this.onStreamData = this.onStreamData.bind(this);
this.onStreamError = this.onStreamError.bind(this);
this.onceNewEvent = this.once.bind(this, "event");
stream.on(ETwitterStreamEvent.Data, this.onStreamData);
stream.on(ETwitterStreamEvent.ConnectionError, this.onStreamError);
stream.on(ETwitterStreamEvent.TweetParseError, this.onStreamError);
stream.on(ETwitterStreamEvent.ConnectionClosed, this.onStreamError);
}
/** Returns a new `Promise` that will `resolve` on next event (`data` or any sort of error). */
nextEvent() {
return new Promise(this.onceNewEvent);
}
/** Returns `true` if there's something in the stack. */
hasStack() {
return this.stack.length > 0;
}
/** Returns stacked data events, and clean the stack. */
popStack() {
const stack = this.stack;
this.stack = [];
return stack;
}
/** Cleanup all the listeners attached on stream. */
destroy() {
this.removeAllListeners();
this.stream.off(ETwitterStreamEvent.Data, this.onStreamData);
this.stream.off(ETwitterStreamEvent.ConnectionError, this.onStreamError);
this.stream.off(ETwitterStreamEvent.TweetParseError, this.onStreamError);
this.stream.off(ETwitterStreamEvent.ConnectionClosed, this.onStreamError);
}
emitEvent(type, payload) {
this.emit("event", { type, payload });
}
onStreamError(payload) {
this.emitEvent("error", payload);
}
onStreamData(payload) {
this.stack.push(payload);
this.emitEvent("data", payload);
}
};
var TweetStreamEventCombiner_default = TweetStreamEventCombiner;
// ../../node_modules/twitter-api-v2/dist/esm/stream/TweetStreamParser.js
import { EventEmitter as EventEmitter3 } from "events";
var TweetStreamParser = class extends EventEmitter3 {
constructor() {
super(...arguments);
this.currentMessage = "";
}
// Code partially belongs to twitter-stream-api for this
// https://github.com/trygve-lie/twitter-stream-api/blob/master/lib/parser.js
push(chunk) {
this.currentMessage += chunk;
chunk = this.currentMessage;
const size = chunk.length;
let start = 0;
let offset = 0;
while (offset < size) {
if (chunk.slice(offset, offset + 2) === "\r\n") {
const piece = chunk.slice(start, offset);
start = offset += 2;
if (!piece.length) {
continue;
}
try {
const payload = JSON.parse(piece);
if (payload) {
this.emit(EStreamParserEvent.ParsedData, payload);
continue;
}
} catch (error) {
this.emit(EStreamParserEvent.ParseError, error);
}
}
offset++;
}
this.currentMessage = chunk.slice(start, size);
}
/** Reset the currently stored message (f.e. on connection reset) */
reset() {
this.currentMessage = "";
}
};
var EStreamParserEvent;
(function(EStreamParserEvent2) {
EStreamParserEvent2["ParsedData"] = "parsed data";
EStreamParserEvent2["ParseError"] = "parse error";
})(EStreamParserEvent || (EStreamParserEvent = {}));
// ../../node_modules/twitter-api-v2/dist/esm/stream/TweetStream.js
var basicRetriesAttempt = [5, 15, 30, 60, 90, 120, 180, 300, 600, 900];
var basicReconnectRetry = (tryOccurrence) => tryOccurrence > basicRetriesAttempt.length ? 901e3 : basicRetriesAttempt[tryOccurrence - 1] * 1e3;
var TweetStream = class extends EventEmitter4 {
constructor(requestData, connection) {
super();
this.requestData = requestData;
this.autoReconnect = false;
this.autoReconnectRetries = 5;
this.keepAliveTimeoutMs = 1e3 * 120;
this.nextRetryTimeout = basicReconnectRetry;
this.parser = new TweetStreamParser();
this.connectionProcessRunning = false;
this.onKeepAliveTimeout = this.onKeepAliveTimeout.bind(this);
this.initEventsFromParser();
if (connection) {
this.req = connection.req;
this.res = connection.res;
this.originalResponse = connection.originalResponse;
this.initEventsFromRequest();
}
}
on(event, handler) {
return super.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) => {
this.emit(ETwitterStreamEvent.ConnectionError, err);
this.emit(ETwitterStreamEvent.Error, {
type: ETwitterStreamEvent.ConnectionError,
error: err,
message: "Connection lost or closed by Twitter."
});
this.onConnectionError();
};
this.req.on("error", errorHandler);
this.res.on("error", errorHandler);
this.res.on("close", () => errorHandler(new Error("Connection closed by Twitter.")));
this.res.on("data", (chunk) => {
this.resetKeepAliveTimeout();
if (chunk.toString() === "\r\n") {
return this.emit(ETwitterStreamEvent.DataKeepAlive);
}
this.parser.push(chunk.toString());
});
this.resetKeepAliveTimeout();
}
initEventsFromParser() {
const payloadIsError = this.requestData.payloadIsError;
this.parser.on(EStreamParserEvent.ParsedData, (eventData) => {
if (payloadIsError && payloadIsError(eventData)) {
this.emit(ETwitterStreamEvent.DataError, eventData);
this.emit(ETwitterStreamEvent.Error, {
type: ETwitterStreamEvent.DataError,
error: eventData,
message: "Twitter sent a payload that is detected as an error payload."
});
} else {
this.emit(ETwitterStreamEvent.Data, eventData);
}
});
this.parser.on(EStreamParserEvent.ParseError, (error) => {
this.emit(ETwitterStreamEvent.TweetParseError, error);
this.emit(ETwitterStreamEvent.Error, {
type: ETwitterStreamEvent.TweetParseError,
error,
message: "Failed to parse stream data."
});
});
}
resetKeepAliveTimeout() {
this.unbindKeepAliveTimeout();
if (this.keepAliveTimeoutMs !== Infinity) {
this.keepAliveTimeout = setTimeout(this.onKeepAliveTimeout, this.keepAliveTimeoutMs);
}
}
onKeepAliveTimeout() {
this.emit(ETwitterStreamEvent.ConnectionLost);
this.onConnectionError();
}
unbindTimeouts() {
this.unbindRetryTimeout();
this.unbindKeepAliveTimeout();
}
unbindKeepAliveTimeout() {
if (this.keepAliveTimeout) {
clearTimeout(this.keepAliveTimeout);
this.keepAliveTimeout = void 0;
}
}
unbindRetryTimeout() {
if (this.retryTimeout) {
clearTimeout(this.retryTimeout);
this.retryTimeout = void 0;
}
}
closeWithoutEmit() {
this.unbindTimeouts();
if (this.res) {
this.res.removeAllListeners();
this.res.destroy();
}
if (this.req) {
this.req.removeAllListeners();
this.req.destroy();
}
}
/** Terminate connection to Twitter. */
close() {
this.emit(ETwitterStreamEvent.ConnectionClosed);
this.closeWithoutEmit();
}
/** Unbind all listeners, and close connection. */
destroy() {
this.removeAllListeners();
this.close();
}
/**
* Make a new request that creates a new `TweetStream` instance with
* the same parameters, and bind current listeners to new stream.
*/
async clone() {
const newRequest = new request_handler_helper_default(this.requestData);
const newStream = await newRequest.makeRequestAsStream();
const listenerNames = this.eventNames();
for (const listener of listenerNames) {
const callbacks = this.listeners(listener);
for (const callback of callbacks) {
newStream.on(listener, callback);
}
}
return newStream;
}
/** 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;
}
this.unbindTimeouts();
try {
await this.reconnect();
} catch (e) {
this.emit(ETwitterStreamEvent.ConnectError, 0);
this.emit(ETwitterStreamEvent.Error, {
type: ETwitterStreamEvent.ConnectError,
error: e,
message: "Connect error - Initial connection just failed."
});
if (this.autoReconnect) {
this.makeAutoReconnectRetry(0, e);
} else {
throw e;
}
}
return this;
}
/** Make a new request to (re)connect to Twitter. */
async reconnect() {
if (this.connectionProcessRunning) {
throw new Error("Connection process is already running.");
}
this.connectionProcessRunning = true;
try {
let initialConnection = true;
if (this.req) {
initialConnection = false;
this.closeWithoutEmit();
}
const { req, res, originalResponse } = await new request_handler_helper_default(this.requestData).makeRequestAndResolveWhenReady();
this.req = req;
this.res = res;
this.originalResponse = originalResponse;
this.emit(initialConnection ? ETwitterStreamEvent.Connected : ETwitterStreamEvent.Reconnected);
this.parser.reset();
this.initEventsFromRequest();
} finally {
this.connectionProcessRunning = false;
}
}
async onConnectionError(retryOccurrence = 0) {
this.unbindTimeouts();
this.closeWithoutEmit();
if (!this.autoReconnect) {
this.emit(ETwitterStreamEvent.ConnectionClosed);
return;
}
if (retryOccurrence >= this.autoReconnectRetries) {
this.emit(ETwitterStreamEvent.ReconnectLimitExceeded);
this.emit(ETwitterStreamEvent.ConnectionClosed);
return;
}
try {
this.emit(ETwitterStreamEvent.ReconnectAttempt, retryOccurrence);
await this.reconnect();
} catch (e) {
this.emit(ETwitterStreamEvent.ReconnectError, retryOccurrence);
this.emit(ETwitterStreamEvent.Error, {
type: ETwitterStreamEvent.ReconnectError,
error: e,
message: `Reconnect error - ${retryOccurrence + 1} attempts made yet.`
});
this.makeAutoReconnectRetry(retryOccurrence, e);
}
}
makeAutoReconnectRetry(retryOccurrence, error) {
const nextRetry = this.nextRetryTimeout(retryOccurrence + 1, error);
this.retryTimeout = setTimeout(() => {
this.onConnectionError(retryOccurrence + 1);
}, nextRetry);
}
async *[Symbol.asyncIterator]() {
const eventCombiner = new TweetStreamEventCombiner_default(this);
try {
while (true) {
if (!this.req || this.req.aborted) {
throw new Error("Connection closed");
}
if (eventCombiner.hasStack()) {
yield* eventCombiner.popStack();
}
const { type, payload } = await eventCombiner.nextEvent();
if (type === "error") {
throw payload;
}
}
} finally {
eventCombiner.destroy();
}
}
};
var TweetStream_default = TweetStream;
// ../../node_modules/twitter-api-v2/dist/esm/plugins/helpers.js
function hasRequestErrorPlugins(client) {
var _a;
if (!((_a = client.clientSettings.plugins) === null || _a === void 0 ? void 0 : _a.length)) {
return false;
}
for (const plugin of client.clientSettings.plugins) {
if (plugin.onRequestError || plugin.onResponseError) {
return true;
}
}
return false;
}
async function applyResponseHooks(requestParams, computedParams, requestOptions, error) {
let override;
if (error instanceof ApiRequestError || error instanceof ApiPartialResponseError) {
override = await this.applyPluginMethod("onRequestError", {
client: this,
url: this.getUrlObjectFromUrlString(requestParams.url),
params: requestParams,
computedParams,
requestOptions,
error
});
} else if (error instanceof ApiResponseError) {
override = await this.applyPluginMethod("onResponseError", {
client: this,
url: this.getUrlObjectFromUrlString(requestParams.url),
params: requestParams,
computedParams,
requestOptions,
error
});
}
if (override && override instanceof TwitterApiPluginResponseOverride) {
return override.value;
}
return Promise.reject(error);
}
// ../../node_modules/twitter-api-v2/dist/esm/client-mixins/oauth1.helper.js
import * as crypto from "crypto";
var OAuth1Helper = class _OAuth1Helper {
constructor(options) {
this.nonceLength = 32;
this.consumerKeys = options.consumerKeys;
}
static percentEncode(str) {
return encodeURIComponent(str).replace(/!/g, "%21").replace(/\*/g, "%2A").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29");
}
hash(base, key) {
return crypto.createHmac("sha1", key).update(base).digest("base64");
}
authorize(request2, accessTokens = {}) {
const oauthInfo = {
oauth_consumer_key: this.consumerKeys.key,
oauth_nonce: this.getNonce(),
oauth_signature_method: "HMAC-SHA1",
oauth_timestamp: this.getTimestamp(),
oauth_version: "1.0"
};
if (accessTokens.key !== void 0) {
oauthInfo.oauth_token = accessTokens.key;
}
if (!request2.data) {
request2.data = {};
}
oauthInfo.oauth_signature = this.getSignature(request2, accessTokens.secret, oauthInfo);
return oauthInfo;
}
toHeader(oauthInfo) {
const sorted = sortObject(oauthInfo);
let heade