format
This commit is contained in:
parent
af1d873de0
commit
a451755d2b
8 changed files with 333 additions and 273 deletions
2
proxy/.prettierignore
Normal file
2
proxy/.prettierignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
**/*.md
|
||||||
|
pnpm-lock.yaml
|
6
proxy/.prettierrc.yaml
Normal file
6
proxy/.prettierrc.yaml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
proseWrap: always
|
||||||
|
semi: false
|
||||||
|
singleQuote: true
|
||||||
|
printWidth: 80
|
||||||
|
trailingComma: none
|
||||||
|
htmlWhitespaceSensitivity: ignore
|
|
@ -4,6 +4,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rm -rf build",
|
"clean": "rm -rf build",
|
||||||
"prebuild": "npm run clean",
|
"prebuild": "npm run clean",
|
||||||
|
"format": "prettier -w --cache --check .",
|
||||||
"build": "tsc --build"
|
"build": "tsc --build"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.12.12",
|
"@types/node": "^20.12.12",
|
||||||
"dotenv": "^16.4.4"
|
"dotenv": "^16.4.4",
|
||||||
|
"prettier": "^3.2.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ importers:
|
||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^16.4.4
|
specifier: ^16.4.4
|
||||||
version: 16.4.4
|
version: 16.4.4
|
||||||
|
prettier:
|
||||||
|
specifier: ^3.2.5
|
||||||
|
version: 3.2.5
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
@ -292,6 +295,11 @@ packages:
|
||||||
resolution: {integrity: sha512-Mz/gKiRyuXu4HnpHgi1YWdHQCoWMufapzooisvFn78zl4dZciAxS+YeRkUxXl1ee/SzU80YCz1zpECCh4oC6Aw==}
|
resolution: {integrity: sha512-Mz/gKiRyuXu4HnpHgi1YWdHQCoWMufapzooisvFn78zl4dZciAxS+YeRkUxXl1ee/SzU80YCz1zpECCh4oC6Aw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
prettier@3.2.5:
|
||||||
|
resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==}
|
||||||
|
engines: {node: '>=14'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
process-warning@2.3.2:
|
process-warning@2.3.2:
|
||||||
resolution: {integrity: sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==}
|
resolution: {integrity: sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==}
|
||||||
|
|
||||||
|
@ -668,6 +676,8 @@ snapshots:
|
||||||
sonic-boom: 3.8.0
|
sonic-boom: 3.8.0
|
||||||
thread-stream: 2.4.1
|
thread-stream: 2.4.1
|
||||||
|
|
||||||
|
prettier@3.2.5: {}
|
||||||
|
|
||||||
process-warning@2.3.2: {}
|
process-warning@2.3.2: {}
|
||||||
|
|
||||||
process-warning@3.0.0: {}
|
process-warning@3.0.0: {}
|
||||||
|
|
|
@ -1,89 +1,116 @@
|
||||||
|
|
||||||
import fastify, {
|
import fastify, {
|
||||||
FastifyInstance,
|
FastifyInstance,
|
||||||
FastifyListenOptions,
|
FastifyListenOptions,
|
||||||
FastifyReply,
|
FastifyReply,
|
||||||
FastifyRequest,
|
FastifyRequest
|
||||||
} from "fastify"
|
} from 'fastify'
|
||||||
import { PinoLoggerOptions } from "fastify/types/logger"
|
import { PinoLoggerOptions } from 'fastify/types/logger'
|
||||||
import { Proxy } from "./proxy"
|
import { Proxy } from './proxy'
|
||||||
import { Logger } from "pino"
|
import { Logger } from 'pino'
|
||||||
import 'dotenv/config'
|
import 'dotenv/config'
|
||||||
|
|
||||||
const host = process.env.HOST
|
const host = process.env.HOST
|
||||||
const port = parseInt(process.env.PORT ?? "8080", 10)
|
const port = parseInt(process.env.PORT ?? '8080', 10)
|
||||||
const baseUrl = process.env.NITTER_BASE_URL
|
const baseUrl = process.env.NITTER_BASE_URL
|
||||||
const concurrency = parseInt(process.env.CONCURRENCY ?? "1", 10)
|
const concurrency = parseInt(process.env.CONCURRENCY ?? '1', 10)
|
||||||
const retryAfterMillis = process.env.RETRY_AFTER_MILLIS ? parseInt(process.env.RETRY_AFTER_MILLIS, 10) : null
|
const retryAfterMillis = process.env.RETRY_AFTER_MILLIS
|
||||||
const maxCacheSize = parseInt(process.env.MAX_CACHE_SIZE ?? "100000", 10)
|
? parseInt(process.env.RETRY_AFTER_MILLIS, 10)
|
||||||
const logLevel = process.env.LOG_LEVEL ?? "debug"
|
: null
|
||||||
|
const maxCacheSize = parseInt(process.env.MAX_CACHE_SIZE ?? '100000', 10)
|
||||||
|
const logLevel = process.env.LOG_LEVEL ?? 'debug'
|
||||||
|
|
||||||
const server = fastify({
|
const server = fastify({
|
||||||
logger: {
|
logger: {
|
||||||
name: "app",
|
name: 'app',
|
||||||
level: logLevel,
|
level: logLevel,
|
||||||
...( logLevel == "trace" ? { transport: { target: 'pino-pretty' } } : {})
|
...(logLevel == 'trace' ? { transport: { target: 'pino-pretty' } } : {})
|
||||||
} as PinoLoggerOptions
|
} as PinoLoggerOptions
|
||||||
})
|
})
|
||||||
|
|
||||||
const log = server.log as Logger
|
const log = server.log as Logger
|
||||||
const proxy = new Proxy(log, baseUrl, concurrency, retryAfterMillis, maxCacheSize)
|
const proxy = new Proxy(
|
||||||
|
log,
|
||||||
|
baseUrl,
|
||||||
|
concurrency,
|
||||||
|
retryAfterMillis,
|
||||||
|
maxCacheSize
|
||||||
|
)
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
server.register(
|
||||||
server.register((fastify: FastifyInstance, opts, done) => {
|
(fastify: FastifyInstance, opts, done) => {
|
||||||
|
fastify.get(
|
||||||
fastify.get(`/user/:username`, {},
|
`/user/:username`,
|
||||||
|
{},
|
||||||
async (request: FastifyRequest, reply: FastifyReply) => {
|
async (request: FastifyRequest, reply: FastifyReply) => {
|
||||||
log.debug({
|
log.debug(
|
||||||
|
{
|
||||||
headers: request.headers,
|
headers: request.headers,
|
||||||
reqId: request.id,
|
reqId: request.id,
|
||||||
params: request.params }, 'incoming request /user/:username')
|
params: request.params
|
||||||
|
},
|
||||||
|
'incoming request /user/:username'
|
||||||
|
)
|
||||||
const { username } = request.params as any
|
const { username } = request.params as any
|
||||||
const { status, data } = await proxy.getUser(username, { reqId: request.id })
|
const { status, data } = await proxy.getUser(username, {
|
||||||
|
reqId: request.id
|
||||||
|
})
|
||||||
reply.status(status).send(data)
|
reply.status(status).send(data)
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
|
||||||
fastify.get(`/user/:userId/tweets`, {},
|
fastify.get(
|
||||||
|
`/user/:userId/tweets`,
|
||||||
|
{},
|
||||||
async (request: FastifyRequest, reply: FastifyReply) => {
|
async (request: FastifyRequest, reply: FastifyReply) => {
|
||||||
const { userId } = request.params as any
|
const { userId } = request.params as any
|
||||||
const { cursor } = request.query as any
|
const { cursor } = request.query as any
|
||||||
const { status, data } = await proxy.getUserTweets(userId, cursor, { reqId: request.id })
|
const { status, data } = await proxy.getUserTweets(userId, cursor, {
|
||||||
|
reqId: request.id
|
||||||
|
})
|
||||||
reply.status(status).send(data)
|
reply.status(status).send(data)
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
|
||||||
fastify.get(`/tweet/:id`, {},
|
fastify.get(
|
||||||
|
`/tweet/:id`,
|
||||||
|
{},
|
||||||
async (request: FastifyRequest, reply: FastifyReply) => {
|
async (request: FastifyRequest, reply: FastifyReply) => {
|
||||||
const { id } = request.params as any
|
const { id } = request.params as any
|
||||||
const { status, data } = await proxy.getTweetById(id, { reqId: request.id })
|
const { status, data } = await proxy.getTweetById(id, {
|
||||||
|
reqId: request.id
|
||||||
|
})
|
||||||
reply.status(status).send(data)
|
reply.status(status).send(data)
|
||||||
});
|
}
|
||||||
|
)
|
||||||
|
|
||||||
done()
|
done()
|
||||||
|
},
|
||||||
}, { prefix: '/api' })
|
{ prefix: '/api' }
|
||||||
|
)
|
||||||
|
|
||||||
server.setNotFoundHandler((request: FastifyRequest, reply: FastifyReply) => {
|
server.setNotFoundHandler((request: FastifyRequest, reply: FastifyReply) => {
|
||||||
reply.status(404)
|
reply.status(404).send({ message: `Method not found` })
|
||||||
.send({ message: `Method not found` })
|
|
||||||
})
|
})
|
||||||
|
|
||||||
server.setErrorHandler((err: Error, request: FastifyRequest, reply: FastifyReply) => {
|
server.setErrorHandler(
|
||||||
|
(err: Error, request: FastifyRequest, reply: FastifyReply) => {
|
||||||
const { log } = request
|
const { log } = request
|
||||||
log.error(err)
|
log.error(err)
|
||||||
// Send error response
|
// Send error response
|
||||||
reply.status(500).send({ message: `Internal server error` })
|
reply.status(500).send({ message: `Internal server error` })
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// await server.register(import('@fastify/rate-limit'), {
|
// await server.register(import('@fastify/rate-limit'), {
|
||||||
// max: 100,
|
// max: 100,
|
||||||
// timeWindow: '1 minute'
|
// timeWindow: '1 minute'
|
||||||
// })
|
// })
|
||||||
|
|
||||||
await server.listen({ port, host } as FastifyListenOptions);
|
await server.listen({ port, host } as FastifyListenOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch(err => {
|
main().catch((err) => {
|
||||||
log.fatal(err)
|
log.fatal(err)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
// noinspection TypeScriptUnresolvedReference
|
// noinspection TypeScriptUnresolvedReference
|
||||||
|
|
||||||
import axios from "axios"
|
import axios from 'axios'
|
||||||
import { AxiosInstance, AxiosRequestConfig } from "axios"
|
import { AxiosInstance, AxiosRequestConfig } from 'axios'
|
||||||
import fastq from "fastq"
|
import fastq from 'fastq'
|
||||||
import { Logger } from "pino"
|
import { Logger } from 'pino'
|
||||||
import retry from "axios-retry-after"
|
import retry from 'axios-retry-after'
|
||||||
import { LRUCache } from 'lru-cache'
|
import { LRUCache } from 'lru-cache'
|
||||||
|
|
||||||
const GET_USER_POSITIVE_TTL_MS = process.env.GET_USER_POSITIVE_TTL
|
const GET_USER_POSITIVE_TTL_MS = process.env.GET_USER_POSITIVE_TTL
|
||||||
|
@ -33,12 +33,11 @@ export interface Job {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JobResponse {
|
export interface JobResponse {
|
||||||
status: number,
|
status: number
|
||||||
data: any
|
data: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Proxy {
|
export class Proxy {
|
||||||
|
|
||||||
private readonly cache: LRUCache<string, JobResponse>
|
private readonly cache: LRUCache<string, JobResponse>
|
||||||
private readonly client: AxiosInstance
|
private readonly client: AxiosInstance
|
||||||
private readonly queue: fastq.queueAsPromised<Job, JobResponse>
|
private readonly queue: fastq.queueAsPromised<Job, JobResponse>
|
||||||
|
@ -64,11 +63,19 @@ export class Proxy {
|
||||||
this.counter.requests = 0
|
this.counter.requests = 0
|
||||||
}, this.timeWindowMillis)
|
}, this.timeWindowMillis)
|
||||||
|
|
||||||
if ( retryAfterMillis ) {
|
if (retryAfterMillis) {
|
||||||
this.client.interceptors.response.use(null, retry(this.client, {
|
this.client.interceptors.response.use(
|
||||||
|
null,
|
||||||
|
retry(this.client, {
|
||||||
// Determine when we should attempt to retry
|
// Determine when we should attempt to retry
|
||||||
isRetryable (error) {
|
isRetryable(error) {
|
||||||
log.debug({ status: error.response?.status, headers: error.response?.headers }, 'checking retryable')
|
log.debug(
|
||||||
|
{
|
||||||
|
status: error.response?.status,
|
||||||
|
headers: error.response?.headers
|
||||||
|
},
|
||||||
|
'checking retryable'
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
error.response && error.response.status === 429
|
error.response && error.response.status === 429
|
||||||
// Use X-Retry-After rather than Retry-After, and cap retry delay at 60 seconds
|
// Use X-Retry-After rather than Retry-After, and cap retry delay at 60 seconds
|
||||||
|
@ -76,57 +83,68 @@ export class Proxy {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
// Customize the wait behavior
|
// Customize the wait behavior
|
||||||
wait (error) {
|
wait(error) {
|
||||||
log.debug({ status: error.response?.status, headers: error.response?.headers }, 'waiting for retry')
|
log.debug(
|
||||||
|
{
|
||||||
|
status: error.response?.status,
|
||||||
|
headers: error.response?.headers
|
||||||
|
},
|
||||||
|
'waiting for retry'
|
||||||
|
)
|
||||||
return new Promise(
|
return new Promise(
|
||||||
// Use X-Retry-After rather than Retry-After
|
// Use X-Retry-After rather than Retry-After
|
||||||
// resolve => setTimeout(resolve, error.response.headers['x-retry-after'])
|
// resolve => setTimeout(resolve, error.response.headers['x-retry-after'])
|
||||||
resolve => setTimeout(resolve, retryAfterMillis)
|
(resolve) => setTimeout(resolve, retryAfterMillis)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}))
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUser(username: string, options?: { reqId?: string }) {
|
async getUser(username: string, options?: { reqId?: string }) {
|
||||||
const key = `usernames:${username}`
|
const key = `usernames:${username}`
|
||||||
|
|
||||||
if ( this.cache.has(key)) {
|
if (this.cache.has(key)) {
|
||||||
return this.cache.get(key)
|
return this.cache.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.queue.push({
|
const result = await this.queue.push({
|
||||||
url: `/api/user/${ username }`,
|
url: `/api/user/${username}`,
|
||||||
reqId: options?.reqId
|
reqId: options?.reqId
|
||||||
})
|
})
|
||||||
|
|
||||||
if ( result.status === 200 ) {
|
if (result.status === 200) {
|
||||||
this.cache.set(key, result, { ttl: GET_USER_POSITIVE_TTL_MS })
|
this.cache.set(key, result, { ttl: GET_USER_POSITIVE_TTL_MS })
|
||||||
}
|
}
|
||||||
if ( result.status === 404 ) {
|
if (result.status === 404) {
|
||||||
this.cache.set(key, result, { ttl: GET_USER_NEGATIVE_TTL_MS })
|
this.cache.set(key, result, { ttl: GET_USER_NEGATIVE_TTL_MS })
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserTweets(userId: string, cursor?: string, options?: { reqId?: string }) {
|
async getUserTweets(
|
||||||
|
userId: string,
|
||||||
|
cursor?: string,
|
||||||
|
options?: { reqId?: string }
|
||||||
|
) {
|
||||||
const key = `users:${userId}:tweets:${cursor ?? 'last'}`
|
const key = `users:${userId}:tweets:${cursor ?? 'last'}`
|
||||||
|
|
||||||
if ( this.cache.has(key) ) {
|
if (this.cache.has(key)) {
|
||||||
return this.cache.get(key)
|
return this.cache.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.queue.push({
|
const result = await this.queue.push({
|
||||||
url: `/api/user/${ userId }/tweets`,
|
url: `/api/user/${userId}/tweets`,
|
||||||
params: { cursor },
|
params: { cursor },
|
||||||
reqId: options?.reqId
|
reqId: options?.reqId
|
||||||
})
|
})
|
||||||
|
|
||||||
if ( result.status === 200 ) {
|
if (result.status === 200) {
|
||||||
this.cache.set(key, result, { ttl: GET_TWEETS_POSITIVE_TTL_MS })
|
this.cache.set(key, result, { ttl: GET_TWEETS_POSITIVE_TTL_MS })
|
||||||
}
|
}
|
||||||
if ( result.status === 404 ) {
|
if (result.status === 404) {
|
||||||
this.cache.set(key, result, { ttl: GET_TWEETS_NEGATIVE_TTL_MS })
|
this.cache.set(key, result, { ttl: GET_TWEETS_NEGATIVE_TTL_MS })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,19 +154,19 @@ export class Proxy {
|
||||||
async getTweetById(tweetId: string, options?: { reqId?: string }) {
|
async getTweetById(tweetId: string, options?: { reqId?: string }) {
|
||||||
const key = `tweets:${tweetId}`
|
const key = `tweets:${tweetId}`
|
||||||
|
|
||||||
if ( this.cache.has(key) ) {
|
if (this.cache.has(key)) {
|
||||||
return this.cache.get(key)
|
return this.cache.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.queue.push({
|
const result = await this.queue.push({
|
||||||
url: `/api/tweet/${ tweetId }`,
|
url: `/api/tweet/${tweetId}`,
|
||||||
reqId: options?.reqId
|
reqId: options?.reqId
|
||||||
})
|
})
|
||||||
|
|
||||||
if ( result.status === 200 ) {
|
if (result.status === 200) {
|
||||||
this.cache.set(key, result, { ttl: GET_TWEET_POSITIVE_TTL_MS })
|
this.cache.set(key, result, { ttl: GET_TWEET_POSITIVE_TTL_MS })
|
||||||
}
|
}
|
||||||
if ( result.status === 404 ) {
|
if (result.status === 404) {
|
||||||
this.cache.set(key, result, { ttl: GET_TWEET_NEGATIVE_TTL_MS })
|
this.cache.set(key, result, { ttl: GET_TWEET_NEGATIVE_TTL_MS })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,10 +174,9 @@ export class Proxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async sendRequest(job: Job): Promise<any> {
|
private async sendRequest(job: Job): Promise<any> {
|
||||||
|
|
||||||
const { reqId, url, params } = job
|
const { reqId, url, params } = job
|
||||||
|
|
||||||
if ( this.counter.requests > this.concurrency * this.maxRequestsPerAccount ) {
|
if (this.counter.requests > this.concurrency * this.maxRequestsPerAccount) {
|
||||||
return {
|
return {
|
||||||
status: 429
|
status: 429
|
||||||
}
|
}
|
||||||
|
@ -167,9 +184,9 @@ export class Proxy {
|
||||||
|
|
||||||
let config = {
|
let config = {
|
||||||
url,
|
url,
|
||||||
method: "get",
|
method: 'get',
|
||||||
baseURL: this.baseUrl,
|
baseURL: this.baseUrl,
|
||||||
params,
|
params
|
||||||
} as AxiosRequestConfig
|
} as AxiosRequestConfig
|
||||||
|
|
||||||
this.log.trace({ config, reqId: reqId }, 'sending request to nitter')
|
this.log.trace({ config, reqId: reqId }, 'sending request to nitter')
|
||||||
|
@ -177,23 +194,23 @@ export class Proxy {
|
||||||
try {
|
try {
|
||||||
const response = await this.client.request(config)
|
const response = await this.client.request(config)
|
||||||
|
|
||||||
this.log.trace({
|
this.log.trace(
|
||||||
|
{
|
||||||
status: response.status,
|
status: response.status,
|
||||||
data: response.data,
|
data: response.data,
|
||||||
reqId: reqId
|
reqId: reqId
|
||||||
}, 'nitter response')
|
},
|
||||||
|
'nitter response'
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: response.status,
|
status: response.status,
|
||||||
data: response.data,
|
data: response.data
|
||||||
} as JobResponse
|
} as JobResponse
|
||||||
|
} catch (err) {
|
||||||
} catch(err) {
|
|
||||||
|
|
||||||
this.log.warn({ err, reqId }, 'nitter error')
|
this.log.warn({ err, reqId }, 'nitter error')
|
||||||
|
|
||||||
if ( err.name === "AxiosError" ) {
|
if (err.name === 'AxiosError') {
|
||||||
|
|
||||||
this.counter.requests = Number.MAX_SAFE_INTEGER
|
this.counter.requests = Number.MAX_SAFE_INTEGER
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
14
proxy/src/types.d.ts
vendored
14
proxy/src/types.d.ts
vendored
|
@ -1,16 +1,15 @@
|
||||||
declare module 'axios-retry-after' {
|
declare module 'axios-retry-after' {
|
||||||
|
import { AxiosError, AxiosInstance } from 'axios'
|
||||||
import { AxiosError, AxiosInstance } from "axios";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to enhance Axios instance with retry-after functionality.
|
* Function to enhance Axios instance with retry-after functionality.
|
||||||
* @param axios Axios instance to be enhanced.
|
* @param axios Axios instance to be enhanced.
|
||||||
* @param options Configuration options for retry behavior.
|
* @param options Configuration options for retry behavior.
|
||||||
*/
|
*/
|
||||||
export default function(
|
export default function (
|
||||||
axios: AxiosInstance,
|
axios: AxiosInstance,
|
||||||
options?: AxiosRetryAfterOptions
|
options?: AxiosRetryAfterOptions
|
||||||
): (error: AxiosError) => Promise<void>;
|
): (error: AxiosError) => Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration options for axios-retry-after.
|
* Configuration options for axios-retry-after.
|
||||||
|
@ -20,20 +19,19 @@ declare module 'axios-retry-after' {
|
||||||
* Function to determine if an error response is retryable.
|
* Function to determine if an error response is retryable.
|
||||||
* @param error The Axios error to evaluate.
|
* @param error The Axios error to evaluate.
|
||||||
*/
|
*/
|
||||||
isRetryable?: (error: AxiosError) => boolean;
|
isRetryable?: (error: AxiosError) => boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to wait for a specified amount of time.
|
* Function to wait for a specified amount of time.
|
||||||
* @param error The Axios error that contains retry-after header.
|
* @param error The Axios error that contains retry-after header.
|
||||||
*/
|
*/
|
||||||
wait?: (error: AxiosError) => Promise<void>;
|
wait?: (error: AxiosError) => Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to retry the original request.
|
* Function to retry the original request.
|
||||||
* @param axios The Axios instance used for retrying the request.
|
* @param axios The Axios instance used for retrying the request.
|
||||||
* @param error The Axios error to retry.
|
* @param error The Axios error to retry.
|
||||||
*/
|
*/
|
||||||
retry?: (axios: AxiosInstance, error: AxiosError) => Promise<any>;
|
retry?: (axios: AxiosInstance, error: AxiosError) => Promise<any>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,5 @@
|
||||||
"outDir": "./build"
|
"outDir": "./build"
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"],
|
"include": ["src/**/*"],
|
||||||
"exclude": [
|
"exclude": ["node_modules"]
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue