Skip to content

Commit

Permalink
feat: init
Browse files Browse the repository at this point in the history
  • Loading branch information
ccbikai committed May 25, 2024
0 parents commit bd47e75
Show file tree
Hide file tree
Showing 298 changed files with 21,915 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# editorconfig.org
root = true

[*]
indent_size = 2
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
NUXT_PUBLIC_PREVIEW_MODE=true
NUXT_PUBLIC_SLUG_DEFAULT_LENGTH=5
NUXT_SITE_TOKEN=SinkCool
NUXT_REDIRECT_STATUS_CODE=308
NUXT_HOME_URL="https://sink.cool"
NUXT_CF_ACCOUNT_ID=123456
NUXT_CF_API_TOKEN=CloudflareAPIToken
NUXT_DATASET=sink_v0
NUXT_AI_MODEL="@cf/meta/llama-3-8b-instruct"
NUXT_AI_PROMPT="You are a URL shortening assistant......"
27 changes: 27 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist

# Node dependencies
node_modules

# Logs
logs
*.log

# Misc
.DS_Store
.fleet
.idea

# Local env files
.env
.env.*
!.env.example
.wrangler
site
cache
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v20
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shamefully-hoist=true
5 changes: 5 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"vue.volar"
]
}
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
// Enable ESlint flat config support
"eslint.experimental.useFlatConfig": true
}
661 changes: 661 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# ⚡ Sink

**A Simple / Speedy / Secrue Link Shortener with Analytics, 100% run on Cloudflare.**

![Hero](./public/image.png)

----

## ✨ Features

- **URL Shortening:** Compress your URLs to their minimal length.
- **Analytics:** Monitor link analytics and gather insightful statistics.
- **Serverless:** Deploy without the need for traditional servers.
- **Customizable Slug:** Support for personalized slugs.
- **🪄 AI Slug:** Leverage AI to generate slugs.
- **Link Expiration:** Set expiration dates for your links.

## 🪧 Demo

Experience the demo at [Sink.Cool](https://sink.cool/dashboard). Log in using the Site Token below:

```txt
Site Token: SinkCool
```

## 🧱 Technologies Used

- **Framework**: [Nuxt](https://nuxt.com/)
- **Database**: [Cloudflare Workers KV](https://developers.cloudflare.com/kv/)
- **Analytics Engine**: [Cloudflare Workers Analytics Engine](https://developers.cloudflare.com/analytics/)
- **UI Components**: [Shadcn-vue](https://www.shadcn-vue.com/)
- **Styling:** [Tailwind CSS](https://tailwindcss.com/)
- **Deployment**: [Cloudflare](https://www.cloudflare.com/)

## 🚗 Roadmap [WIP]

We welcome your contributions and PRs.

- [ ] Browser Extension
- [ ] Raycast Extension
- [ ] Apple Shortcuts
- [ ] Enhanced Link Management (with Cloudflare D1)
- [ ] Analytics Enhancements (Support for merging filter conditions)
- [ ] Dashboard Performance Optimization (Infinite loading)
- [ ] Units Test
- [ ] Support for Other Deployment Platforms

## 🏗️ Deployment

1. [Fork](https://github.com/ccbikai/Sink/fork) the repository to your GitHub account.
2. Create a [Cloudflare Pages](https://developers.cloudflare.com/pages/) project.
3. Select the `Sink` repository and the `Nuxt.js` preset.
4. Configure environment variables.
1. `NUXT_SITE_TOKEN` length must exceed **8**.
2. `NUXT_CF_ACCOUNT_ID` [find your account ID](https://developers.cloudflare.com/fundamentals/setup/find-account-and-zone-ids/).
3. `NUXT_CF_API_TOKEN` Create a [Cloudflare API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/). This token requires `Account.Account Analytics` permissions at the very least. [Reference.](https://developers.cloudflare.com/analytics/analytics-engine/sql-api/#authentication).

5. Save and deploy.
6. Cancel the deployment, navigate to `Settings` -> `Functions`.
1. KV namespace bindings. Bind the variable name `KV` to a KV namespace.
2. Workers AI Bindings. Bind the variable name `AI` to the Workers AI Catalog. _Optional_
3. Analytics Engine bindings. Bind the variable name `ANALYTICS` to the `sink` dataset, and enable [Cloudflare Analytics Engine beta](https://developers.cloudflare.com/analytics/analytics-engine/get-started/) for your account.
7. Redeploy.

## ⚒️ Configuration

[Configuration Docs](./docs/configuration.md)

## 💖 Credits

1. [**Cloudflare**](https://www.cloudflare.com/)
2. [**NuxtHub**](https://hub.nuxt.com/)
3. [**Astroship**](https://astroship.web3templates.com/)

## ☕ Sponsor

1. [Follow Me on X(Twitter)](https://x.com/ccbikai).
2. [Become a sponsor to on GitHub](https://github.com/sponsors/ccbikai).
10 changes: 10 additions & 0 deletions app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default defineAppConfig({
title: 'Sink',
description: 'A Simple / Speedy / Secrue Link Shortener with Analytics, 100% run on Cloudflare.',
image: 'https://sink.cool/banner.png',
previewTTL: 24 * 3600, // 24h
slugRegex: /^[a-z0-9]+(?:-[a-z0-9]+)*$/i,
reserveSlug: [
'dashboard',
],
})
35 changes: 35 additions & 0 deletions app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup>
const { title, description, image } = useAppConfig()
useSeoMeta({
title,
description,
ogTitle: title,
ogDescription: description,
ogImage: image,
twitterTitle: title,
twitterDescription: description,
twitterImage: image,
twitterCard: 'summary_large_image',
})
useHead({
htmlAttrs: {
lang: 'en',
},
link: [
{
rel: 'icon',
type: 'image/png',
href: '/sink.png',
},
],
})
</script>

<template>
<NuxtLayout>
<NuxtLoadingIndicator color="#000" />
<NuxtPage />
<Toaster />
</NuxtLayout>
</template>
91 changes: 91 additions & 0 deletions assets/css/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;

--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;

--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;

--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;

--border: 240 5.9% 90%;
--input: 240 5.9% 90%;

--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;

--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;

--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;

--ring: 240 10% 3.9%;

--radius: 0.5rem;

--vis-tooltip-background-color: none !important;
--vis-tooltip-border-color: none !important;
--vis-tooltip-text-color: none !important;
--vis-tooltip-shadow-color: none !important;
--vis-tooltip-backdrop-filter: none !important;
--vis-tooltip-padding: none !important;

--vis-primary-color: 198 93% 60%;
--vis-secondary-color: 158 64% 52%;
/* --vis-secondary-color: 160 81% 40%; */
/* --vis-secondary-color: var(--primary); */
--vis-text-color: var(--muted-foreground);
}

.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;

--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;

--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;

--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;

--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;

--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;

--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;

--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;

--ring: 240 4.9% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
1 change: 1 addition & 0 deletions assets/images/404.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/cloudflare.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/images/hero.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/nuxtjs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/location/world-topo.json

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://shadcn-vue.com/schema.json",
"style": "default",
"typescript": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "assets/css/tailwind.css",
"baseColor": "zinc",
"cssVariables": true
},
"framework": "nuxt",
"aliases": {
"components": "@/components",
"utils": "@/utils"
}
}
37 changes: 37 additions & 0 deletions components/dashboard/Breadcrumb.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script setup>
import { NuxtLink } from '#components'
defineProps({
title: {
type: String,
required: true,
},
})
</script>

<template>
<Breadcrumb class="flex justify-between">
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="/">
Sink
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbLink
:as="NuxtLink"
to="/dashboard"
>
Dashboard
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbPage>{{ title }}</BreadcrumbPage>
</BreadcrumbItem>
</BreadcrumbList>

<DashboardLogout />
</Breadcrumb>
</template>
Loading

0 comments on commit bd47e75

Please sign in to comment.