mirror of
https://github.com/Nezumi-2711/Sink.git
synced 2026-09-22 20:00:55 +00:00
feat: init
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import type { H3Event } from 'h3'
|
||||
import { parseURL } from 'ufo'
|
||||
import { UAParser } from 'ua-parser-js'
|
||||
import {
|
||||
Apps,
|
||||
Bots,
|
||||
CLIs,
|
||||
Emails,
|
||||
ExtraDevices,
|
||||
MediaPlayers,
|
||||
Modules,
|
||||
} from 'ua-parser-js/extensions'
|
||||
import { parseAcceptLanguage } from 'intl-parse-accept-language'
|
||||
import { getFlag } from '@/utils/flag'
|
||||
|
||||
function toBlobNumber(blob: string) {
|
||||
return +blob.replace(/\D/g, '')
|
||||
}
|
||||
|
||||
export const blobsMap = {
|
||||
blob1: 'slug',
|
||||
blob2: 'url',
|
||||
blob3: 'ua',
|
||||
blob4: 'ip',
|
||||
blob5: 'referer',
|
||||
blob6: 'country',
|
||||
blob7: 'region',
|
||||
blob8: 'city',
|
||||
blob9: 'timezone',
|
||||
blob10: 'language',
|
||||
blob11: 'os',
|
||||
blob12: 'browser',
|
||||
blob13: 'browserType',
|
||||
blob14: 'device',
|
||||
blob15: 'deviceType',
|
||||
} as const
|
||||
|
||||
export type BlobsMap = typeof blobsMap
|
||||
export type BlobsKey = keyof BlobsMap
|
||||
export type LogsKey = BlobsMap[BlobsKey]
|
||||
export type LogsMap = { [key in LogsKey]: string | undefined }
|
||||
|
||||
export const logsMap: LogsMap = Object.entries(blobsMap).reduce((acc, [k, v]) => ({ ...acc, [v]: k }), {}) as LogsMap
|
||||
|
||||
function logs2blobs(logs: LogsMap) {
|
||||
// @ts-expect-error todo
|
||||
return Object.keys(blobsMap).sort((a, b) => toBlobNumber(a) - toBlobNumber(b)).map(key => logs[blobsMap[key]] || '')
|
||||
}
|
||||
|
||||
function blobs2logs(blobs: string[]) {
|
||||
const logsList = Object.keys(blobsMap)
|
||||
|
||||
// @ts-expect-error todo
|
||||
return blobs.reduce((logs: LogsMap, blob, i) => {
|
||||
// @ts-expect-error todo
|
||||
logs[blobsMap[logsList[i]]] = blob
|
||||
return logs
|
||||
}, {})
|
||||
}
|
||||
|
||||
export function useAccessLog(event: H3Event) {
|
||||
const ip = getHeader(event, 'x-real-ip') || getRequestIP(event, { xForwardedFor: true })
|
||||
|
||||
const { host: referer } = parseURL(getHeader(event, 'referer'))
|
||||
|
||||
const acceptLanguage = getHeader(event, 'accept-language') || ''
|
||||
const language = (parseAcceptLanguage(acceptLanguage) || [])[0]
|
||||
|
||||
const userAgent = getHeader(event, 'user-agent') || ''
|
||||
const uaInfo = (new UAParser(userAgent, {
|
||||
browser: [Apps.browser || [], Bots.browser || [], CLIs.browser || [], Emails.browser || [], MediaPlayers.browser || [], Modules.browser || []].flat(),
|
||||
device: [ExtraDevices.device || []].flat(),
|
||||
})).getResult()
|
||||
|
||||
const { request: { cf } } = event.context.cloudflare
|
||||
const link = event.context.link || {}
|
||||
|
||||
const regionNames = new Intl.DisplayNames(['en'], { type: 'region' })
|
||||
const countryName = regionNames.of(cf?.country || 'WD') // fallback to "Worldwide"
|
||||
const accessLogs = {
|
||||
url: link.url,
|
||||
slug: link.slug,
|
||||
ua: userAgent,
|
||||
ip,
|
||||
referer,
|
||||
country: cf?.country,
|
||||
region: `${getFlag(cf?.country)} ${[cf?.region, countryName].filter(Boolean).join(',')}`,
|
||||
city: `${getFlag(cf?.country)} ${[cf?.city, countryName].filter(Boolean).join(',')}`,
|
||||
timezone: cf?.timezone,
|
||||
language,
|
||||
os: uaInfo?.os?.name,
|
||||
browser: uaInfo?.browser?.name,
|
||||
// @ts-expect-error todo
|
||||
browserType: uaInfo?.browser?.type,
|
||||
device: uaInfo?.device?.model,
|
||||
deviceType: uaInfo?.device?.type,
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
return hubAnalytics().put({
|
||||
indexes: [link.id], // only one index
|
||||
blobs: logs2blobs(accessLogs),
|
||||
})
|
||||
}
|
||||
else {
|
||||
console.log('access logs:', logs2blobs(accessLogs), blobs2logs(logs2blobs(accessLogs)))
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user