Merge branch 'master' into nuxt-v4
This commit is contained in:
commit
65f78845bf
5 changed files with 45 additions and 5 deletions
|
|
@ -79,6 +79,8 @@ We welcome your contributions and PRs.
|
||||||
- [Raycast-Sink](https://github.com/foru17/raycast-sink)
|
- [Raycast-Sink](https://github.com/foru17/raycast-sink)
|
||||||
- [x] Apple Shortcuts
|
- [x] Apple Shortcuts
|
||||||
- [Sink Shortcuts](https://s.search1api.com/sink001)
|
- [Sink Shortcuts](https://s.search1api.com/sink001)
|
||||||
|
- [x] iOS App
|
||||||
|
- [Sink](https://apps.apple.com/app/id6745417598)
|
||||||
- [ ] Enhanced Link Management (with Cloudflare D1)
|
- [ ] Enhanced Link Management (with Cloudflare D1)
|
||||||
- [ ] Analytics Enhancements (Support for merging filter conditions)
|
- [ ] Analytics Enhancements (Support for merging filter conditions)
|
||||||
- [ ] Dashboard Performance Optimization (Infinite loading)
|
- [ ] Dashboard Performance Optimization (Infinite loading)
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@ function copyLink() {
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<span class="inline-flex items-center leading-5"><CalendarPlus2 class="w-4 h-4 mr-1" /> {{ shortDate(link.createdAt) }}</span>
|
<span class="inline-flex items-center leading-5 whitespace-nowrap"><CalendarPlus2 class="w-4 h-4 mr-1" /> {{ shortDate(link.createdAt) }}</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p>Created At: {{ longDate(link.createdAt) }}</p>
|
<p>Created At: {{ longDate(link.createdAt) }}</p>
|
||||||
|
|
@ -178,7 +178,7 @@ function copyLink() {
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger as-child>
|
<TooltipTrigger as-child>
|
||||||
<span class="inline-flex items-center leading-5"><Hourglass class="w-4 h-4 mr-1" /> {{ shortDate(link.expiration) }}</span>
|
<span class="inline-flex items-center leading-5 whitespace-nowrap"><Hourglass class="w-4 h-4 mr-1" /> {{ shortDate(link.expiration) }}</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p>Expires At: {{ longDate(link.expiration) }}</p>
|
<p>Expires At: {{ longDate(link.expiration) }}</p>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "sink",
|
"name": "sink",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.1.10",
|
"version": "0.1.11",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "pnpm@9.15.1",
|
"packageManager": "pnpm@9.15.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
38
server/api/link/upsert.post.ts
Normal file
38
server/api/link/upsert.post.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { LinkSchema } from '@/schemas/link'
|
||||||
|
|
||||||
|
export default eventHandler(async (event) => {
|
||||||
|
const link = await readValidatedBody(event, LinkSchema.parse)
|
||||||
|
const { caseSensitive } = useRuntimeConfig(event)
|
||||||
|
|
||||||
|
if (!caseSensitive) {
|
||||||
|
link.slug = link.slug.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
const { cloudflare } = event.context
|
||||||
|
const { KV } = cloudflare.env
|
||||||
|
|
||||||
|
// Check if link exists
|
||||||
|
const existingLink = await KV.get(`link:${link.slug}`, { type: 'json' })
|
||||||
|
|
||||||
|
if (existingLink) {
|
||||||
|
// If link exists, return it along with the short link
|
||||||
|
const shortLink = `${getRequestProtocol(event)}://${getRequestHost(event)}/${link.slug}`
|
||||||
|
return { link: existingLink, shortLink, status: 'existing' }
|
||||||
|
}
|
||||||
|
|
||||||
|
// If link doesn't exist, create it
|
||||||
|
const expiration = getExpiration(event, link.expiration)
|
||||||
|
|
||||||
|
await KV.put(`link:${link.slug}`, JSON.stringify(link), {
|
||||||
|
expiration,
|
||||||
|
metadata: {
|
||||||
|
expiration,
|
||||||
|
url: link.url,
|
||||||
|
comment: link.comment,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
setResponseStatus(event, 201)
|
||||||
|
const shortLink = `${getRequestProtocol(event)}://${getRequestHost(event)}/${link.slug}`
|
||||||
|
return { link, shortLink, status: 'created' }
|
||||||
|
})
|
||||||
|
|
@ -60,7 +60,7 @@ function blobs2logs(blobs: string[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useAccessLog(event: H3Event) {
|
export function useAccessLog(event: H3Event) {
|
||||||
const ip = getHeader(event, 'x-real-ip') || getRequestIP(event, { xForwardedFor: true })
|
const ip = getHeader(event, 'cf-connecting-ip') || getHeader(event, 'x-real-ip') || getRequestIP(event, { xForwardedFor: true })
|
||||||
|
|
||||||
const { host: referer } = parseURL(getHeader(event, 'referer'))
|
const { host: referer } = parseURL(getHeader(event, 'referer'))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue