chore: update built-in ip query function
Signed-off-by: Innei <i@innei.in>
This commit is contained in:
@@ -1,104 +1,7 @@
|
||||
import type { BuiltInFunctionObject } from '../../function.types'
|
||||
|
||||
const interfaceCode = `
|
||||
interface IPResponseData {
|
||||
code: number
|
||||
success: boolean
|
||||
message: string
|
||||
data: Data
|
||||
location: string
|
||||
myip: string
|
||||
time: string
|
||||
}
|
||||
interface Data {
|
||||
ip: string
|
||||
dec: string
|
||||
country: string
|
||||
countryCode: string
|
||||
province: string
|
||||
city: string
|
||||
districts: string
|
||||
idc: string
|
||||
isp: string
|
||||
net: string
|
||||
protocol: string
|
||||
begin: string
|
||||
end: string
|
||||
}
|
||||
`
|
||||
|
||||
const ipQueryFnCode = `${`
|
||||
import { isIPv4, isIPv6 } from 'net'
|
||||
import { URLSearchParams } from 'url'
|
||||
|
||||
const TIMEOUT = 5000
|
||||
|
||||
export default async function handler(ctx: Context, timeout = TIMEOUT) {
|
||||
const { ip } = ctx.query
|
||||
if (!ip) { ctx.throws(422, 'ip is empty') }
|
||||
const cache = ctx.storage.cache
|
||||
const hasCatch = await cache.get(ip)
|
||||
if (hasCatch) return JSON.parse(hasCatch)
|
||||
|
||||
const result = await getIp(ctx, ip);
|
||||
await cache.set(ip, result)
|
||||
return result
|
||||
}
|
||||
|
||||
async function getIp(ctx: Context, ip: string, timeout = TIMEOUT) {
|
||||
const isV4 = isIPv4(ip)
|
||||
const isV6 = isIPv6(ip)
|
||||
const { axios } = await (ctx.getService('http'))
|
||||
if (!isV4 && !isV6) {
|
||||
ctx.throws(422, 'Invalid IP')
|
||||
}
|
||||
try {
|
||||
// const getIpQueryEndpoint = (ip, type: 'v4' | 'v6') =>
|
||||
// \`https://ip$\{type}.ip.mir6.com/api_json.php?ip=$\{ip}&token=mir6.com\`
|
||||
|
||||
if (isV4) {
|
||||
const data = await axios.get(
|
||||
\`https://ipv4.ip.mir6.com/api_json.php?ip=$\{ip}&token=mir6.com\`,
|
||||
{
|
||||
timeout,
|
||||
},
|
||||
) as IPResponseData
|
||||
|
||||
const {
|
||||
data: { city, country, districts, isp, province, net },
|
||||
} = data.data
|
||||
return {
|
||||
cityName: districts,
|
||||
countryName: country + province,
|
||||
regionName: city,
|
||||
ip,
|
||||
ispDomain: isp,
|
||||
ownerDomain: isp || net,
|
||||
}
|
||||
} else {
|
||||
const { data } = (await axios.get(
|
||||
\`http://ip-api.com/json/$\{ip}\`,
|
||||
{
|
||||
timeout,
|
||||
},
|
||||
)) as any
|
||||
|
||||
const res = {
|
||||
cityName: data.city,
|
||||
countryName: data.country,
|
||||
ip: data.query,
|
||||
ispDomain: data.as,
|
||||
ownerDomain: data.org,
|
||||
regionName: data.region_name,
|
||||
} as const
|
||||
|
||||
return res
|
||||
}
|
||||
} catch (e) {
|
||||
ctx.throws(500, \`IP API 调用失败,$\{e.message}\`)
|
||||
}
|
||||
};
|
||||
`.trim()}\n${interfaceCode}`
|
||||
const ipQueryFnCode =
|
||||
"import { isIPv4, isIPv6 } from 'net'\n\n\nconst TIMEOUT = 5000\n\nexport default async function handler(ctx: Context, timeout = TIMEOUT) {\n const { ip } = ctx.req.query\n\n if (!ip) { ctx.res.throws(422, 'ip is empty') }\n const cache = ctx.storage.cache\n const hasCatch = await cache.get(ip)\n if (hasCatch) return JSON.parse(hasCatch)\n\n const result = await getIp(ctx, ip);\n await cache.set(ip, result)\n return result\n}\n\nasync function getIp(ctx: Context, ip: string, timeout = TIMEOUT) {\n const isV4 = isIPv4(ip)\n const isV6 = isIPv6(ip)\n const { axios } = await (ctx.getService('http'))\n if (!isV4 && !isV6) {\n ctx.throws(422, 'Invalid IP')\n }\n try {\n const data = await axios.get('http://ip-api.com/json/' + ip + '?lang=zh-CN').then(data => data.data) as Ip\n const res: FinalIpRecord = {\n cityName: data.city,\n countryName: data.country,\n ip: data.query,\n ispDomain: data.isp,\n ownerDomain: data.org,\n regionName: data.regionName\n\n }\n\n return res\n } catch (e) {\n ctx.throws(500, `IP API 调用失败,${e.message}`)\n }\n};\n\n\ninterface FinalIpRecord {\n cityName: string\n countryName: string\n ip: string\n ispDomain: string\n ownerDomain: string\n regionName: string\n}\ninterface Ip {\n country: string;\n countryCode: string;\n region: string;\n regionName: string;\n city: string;\n zip: string;\n lat: number;\n lon: number;\n timezone: string;\n isp: string;\n org: string;\n as: string;\n query: string;\n}"
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default {
|
||||
|
||||
Reference in New Issue
Block a user