File size: 4,287 Bytes
fbad01d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
import { clsx, type ClassValue } from 'clsx'
import { customAlphabet } from 'nanoid'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
export const nanoid = customAlphabet(
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
7
) // 7-character random string
export function createChunkDecoder() {
const decoder = new TextDecoder()
return function (chunk: Uint8Array | undefined): string {
if (!chunk) return ''
return decoder.decode(chunk, { stream: true })
}
}
export function random (start: number, end: number) {
return start + Math.ceil(Math.random() * (end - start))
}
export function randomIP() {
return `11.${random(104, 107)}.${random(1, 255)}.${random(1, 255)}`
}
export function parseHeadersFromCurl(content: string) {
const re = /-H '([^:]+):\s*([^']+)/mg
const headers: HeadersInit = {}
content = content.replaceAll('-H "', '-H \'').replaceAll('" ^', '\'\\').replaceAll('^\\^"', '"') // 将 cmd curl 转成 bash curl
content.replace(re, (_: string, key: string, value: string) => {
headers[key] = value
return ''
})
return headers
}
export const ChunkKeys = ['BING_HEADER', 'BING_HEADER1', 'BING_HEADER2']
export function encodeHeadersToCookie(content: string) {
const base64Content = btoa(content)
const contentChunks = base64Content.match(/.{1,4000}/g) || []
return ChunkKeys.map((key, index) => `${key}=${contentChunks[index] ?? ''}`)
}
export function extraCurlFromCookie(cookies: Partial<{ [key: string]: string }>) {
let base64Content = ''
ChunkKeys.forEach((key) => {
base64Content += (cookies[key] || '')
})
try {
return atob(base64Content)
} catch(e) {
return ''
}
}
export function extraHeadersFromCookie(cookies: Partial<{ [key: string]: string }>) {
return parseHeadersFromCurl(extraCurlFromCookie(cookies))
}
export function formatDate(input: string | number | Date): string {
const date = new Date(input)
return date.toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric'
})
}
export function parseCookie(cookie: string, cookieName: string) {
const targetCookie = new RegExp(`(?:[; ]|^)${cookieName}=([^;]*)`).test(cookie) ? RegExp.$1 : cookie
return targetCookie ? decodeURIComponent(targetCookie).trim() : cookie.indexOf('=') === -1 ? cookie.trim() : ''
}
export function parseCookies(cookie: string, cookieNames: string[]) {
const cookies: { [key: string]: string } = {}
cookieNames.forEach(cookieName => {
cookies[cookieName] = parseCookie(cookie, cookieName)
})
return cookies
}
export const DEFAULT_UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.0.0'
export const DEFAULT_IP = process.env.BING_IP || randomIP()
export function parseUA(ua?: string, default_ua = DEFAULT_UA) {
return / EDGE?/i.test(decodeURIComponent(ua || '')) ? decodeURIComponent(ua!.trim()) : default_ua
}
export function createHeaders(cookies: Partial<{ [key: string]: string }>, defaultHeaders?: Partial<{ [key: string]: string }>) {
let {
BING_COOKIE = process.env.BING_COOKIE,
BING_UA = process.env.BING_UA,
BING_IP = process.env.BING_IP,
BING_HEADER = process.env.BING_HEADER,
} = cookies
if (BING_HEADER) {
return extraHeadersFromCookie({
BING_HEADER,
...cookies,
})
}
const ua = parseUA(BING_UA)
if (!BING_COOKIE) {
BING_COOKIE = defaultHeaders?.IMAGE_BING_COOKIE || 'xxx' // hf 暂时不用 Cookie 也可以正常使用
}
const parsedCookie = parseCookie(BING_COOKIE, '_U')
if (!parsedCookie) {
throw new Error('Invalid Cookie')
}
return {
'x-forwarded-for': BING_IP || DEFAULT_IP,
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'User-Agent': ua!,
'x-ms-useragent': 'azsdk-js-api-client-factory/1.0.0-beta.1 core-rest-pipeline/1.10.0 OS/Win32',
cookie: `_U=${parsedCookie}` || '',
}
}
export class WatchDog {
private tid = 0
watch(fn: Function, timeout = 2000) {
clearTimeout(this.tid)
this.tid = setTimeout(fn, timeout + Math.random() * 1000)
}
reset() {
clearTimeout(this.tid)
}
}
|