Merge branch 'vercel' into dev
This commit is contained in:
commit
2a172494e7
22 changed files with 3461 additions and 2436 deletions
50
.vscode/settings.json
vendored
50
.vscode/settings.json
vendored
|
|
@ -1,4 +1,50 @@
|
|||
{
|
||||
// Enable ESlint flat config support
|
||||
"eslint.useFlatConfig": true
|
||||
// Disable the default formatter, use eslint instead
|
||||
"prettier.enable": false,
|
||||
"editor.formatOnSave": false,
|
||||
|
||||
// Auto fix
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
"source.organizeImports": "never"
|
||||
},
|
||||
|
||||
// Silent the stylistic rules in you IDE, but still auto fix them
|
||||
"eslint.rules.customizations": [
|
||||
{ "rule": "style/*", "severity": "off", "fixable": true },
|
||||
{ "rule": "format/*", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-indent", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-spacing", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-spaces", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-order", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-dangle", "severity": "off", "fixable": true },
|
||||
{ "rule": "*-newline", "severity": "off", "fixable": true },
|
||||
{ "rule": "*quotes", "severity": "off", "fixable": true },
|
||||
{ "rule": "*semi", "severity": "off", "fixable": true }
|
||||
],
|
||||
|
||||
// Enable eslint for all supported languages
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact",
|
||||
"vue",
|
||||
"html",
|
||||
"markdown",
|
||||
"json",
|
||||
"jsonc",
|
||||
"yaml",
|
||||
"toml",
|
||||
"xml",
|
||||
"gql",
|
||||
"graphql",
|
||||
"astro",
|
||||
"svelte",
|
||||
"css",
|
||||
"less",
|
||||
"scss",
|
||||
"pcss",
|
||||
"postcss"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { Flame, MousePointerClick, Users } from 'lucide-vue-next'
|
||||
import NumberFlow from '@number-flow/vue'
|
||||
import { Flame, MousePointerClick, Users } from 'lucide-vue-next'
|
||||
|
||||
const defaultData = Object.freeze({
|
||||
visits: 0,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<script setup>
|
||||
import { z } from 'zod'
|
||||
import { useForm } from 'vee-validate'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { Shuffle, Sparkles } from 'lucide-vue-next'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { DependencyType } from '@/components/ui/auto-form/interface'
|
||||
import { LinkSchema, nanoid } from '@/schemas/link'
|
||||
import { toTypedSchema } from '@vee-validate/zod'
|
||||
import { Shuffle, Sparkles } from 'lucide-vue-next'
|
||||
import { useForm } from 'vee-validate'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { z } from 'zod'
|
||||
|
||||
const props = defineProps({
|
||||
link: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { Loader } from 'lucide-vue-next'
|
||||
import { useInfiniteScroll } from '@vueuse/core'
|
||||
import { Loader } from 'lucide-vue-next'
|
||||
|
||||
const links = ref([])
|
||||
const limit = 24
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script setup>
|
||||
import { CalendarPlus2, Copy, CopyCheck, Eraser, Hourglass, Link as LinkIcon, QrCode, SquareChevronDown, SquarePen } from 'lucide-vue-next'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { CalendarPlus2, Copy, CopyCheck, Eraser, Hourglass, Link as LinkIcon, QrCode, SquareChevronDown, SquarePen } from 'lucide-vue-next'
|
||||
import { parseURL } from 'ufo'
|
||||
import { toast } from 'vue-sonner'
|
||||
import QRCode from './QRCode.vue'
|
||||
|
||||
const props = defineProps({
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ onMounted(() => {
|
|||
</Button>
|
||||
<Dialog :open="isOpen" @update:open="isOpen = !isOpen">
|
||||
<DialogContent class="overflow-hidden p-0 shadow-lg">
|
||||
<Command v-model:searchTerm="searchTerm" v-model="selectedLink" class="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||
<Command v-model:search-term="searchTerm" v-model="selectedLink" class="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
||||
<CommandInput placeholder="Type to search..." />
|
||||
<CommandList>
|
||||
<CommandEmpty v-if="searchTerm">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { VisSingleContainer, VisTopoJSONMap, VisTopoJSONMapSelectors } from '@unovis/vue'
|
||||
import { ChartTooltip } from '@/components/ui/chart'
|
||||
import { VisSingleContainer, VisTopoJSONMap, VisTopoJSONMapSelectors } from '@unovis/vue'
|
||||
|
||||
const id = inject('id')
|
||||
const startAt = inject('startAt')
|
||||
|
|
|
|||
|
|
@ -1,4 +1,13 @@
|
|||
<script setup>
|
||||
import {
|
||||
Globe,
|
||||
Laptop,
|
||||
MonitorCheck,
|
||||
Smartphone,
|
||||
Tablet,
|
||||
Terminal,
|
||||
} from 'lucide-vue-next'
|
||||
|
||||
// https://vue3-simple-icons.wyatt-herkamp.dev/
|
||||
import {
|
||||
AndroidIcon,
|
||||
|
|
@ -20,23 +29,14 @@ import {
|
|||
SamsungIcon,
|
||||
UbuntuIcon,
|
||||
VivoIcon,
|
||||
WeChatIcon,
|
||||
WearOsIcon,
|
||||
WeChatIcon,
|
||||
XiaomiIcon,
|
||||
// WindowsIcon,
|
||||
XIcon,
|
||||
XiaomiIcon,
|
||||
YandexCloudIcon,
|
||||
} from 'vue3-simple-icons'
|
||||
|
||||
import {
|
||||
Globe,
|
||||
Laptop,
|
||||
MonitorCheck,
|
||||
Smartphone,
|
||||
Tablet,
|
||||
Terminal,
|
||||
} from 'lucide-vue-next'
|
||||
|
||||
defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import heroImg from '@/assets/images/hero.svg?raw'
|
||||
import { AreaChart } from 'lucide-vue-next'
|
||||
import { GitHubIcon } from 'vue3-simple-icons'
|
||||
import heroImg from '@/assets/images/hero.svg?raw'
|
||||
|
||||
const { title, description, github } = useAppConfig()
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import { XIcon } from 'vue3-simple-icons'
|
||||
import { ArrowRight } from 'lucide-vue-next'
|
||||
import { XIcon } from 'vue3-simple-icons'
|
||||
|
||||
const { twitter } = useAppConfig()
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup>
|
||||
import { AlertCircle } from 'lucide-vue-next'
|
||||
import { z } from 'zod'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { z } from 'zod'
|
||||
|
||||
const LoginSchema = z.object({
|
||||
token: z.string().describe('SiteToken'),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
devtools: { enabled: true },
|
||||
|
||||
modules: [
|
||||
'@nuxthub/core',
|
||||
|
|
@ -9,46 +8,12 @@ export default defineNuxtConfig({
|
|||
'@nuxtjs/tailwindcss',
|
||||
'@nuxtjs/color-mode',
|
||||
],
|
||||
devtools: { enabled: true },
|
||||
|
||||
colorMode: {
|
||||
classSuffix: '',
|
||||
},
|
||||
|
||||
routeRules: {
|
||||
'/': {
|
||||
prerender: true,
|
||||
},
|
||||
'/dashboard/**': {
|
||||
ssr: false,
|
||||
},
|
||||
'/dashboard': {
|
||||
redirect: '/dashboard/links',
|
||||
},
|
||||
},
|
||||
|
||||
hub: {
|
||||
ai: true,
|
||||
analytics: true,
|
||||
blob: false,
|
||||
cache: false,
|
||||
database: false,
|
||||
kv: true,
|
||||
},
|
||||
|
||||
eslint: {
|
||||
config: {
|
||||
stylistic: true,
|
||||
standalone: false,
|
||||
},
|
||||
},
|
||||
|
||||
nitro: {
|
||||
experimental: {
|
||||
// Enable Server API documentation within NuxtHub
|
||||
openAPI: true,
|
||||
},
|
||||
},
|
||||
|
||||
runtimeConfig: {
|
||||
siteToken: 'SinkCool',
|
||||
redirectStatusCode: '301',
|
||||
|
|
@ -67,5 +32,40 @@ export default defineNuxtConfig({
|
|||
},
|
||||
},
|
||||
|
||||
routeRules: {
|
||||
'/': {
|
||||
prerender: true,
|
||||
},
|
||||
'/dashboard/**': {
|
||||
ssr: false,
|
||||
},
|
||||
'/dashboard': {
|
||||
redirect: '/dashboard/links',
|
||||
},
|
||||
},
|
||||
|
||||
compatibilityDate: '2024-07-08',
|
||||
|
||||
nitro: {
|
||||
experimental: {
|
||||
// Enable Server API documentation within NuxtHub
|
||||
openAPI: true,
|
||||
},
|
||||
},
|
||||
|
||||
hub: {
|
||||
ai: true,
|
||||
analytics: true,
|
||||
blob: false,
|
||||
cache: false,
|
||||
database: false,
|
||||
kv: true,
|
||||
},
|
||||
|
||||
eslint: {
|
||||
config: {
|
||||
stylistic: true,
|
||||
standalone: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
|||
52
package.json
52
package.json
|
|
@ -3,7 +3,7 @@
|
|||
"type": "module",
|
||||
"version": "0.1.7",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@9.7.1",
|
||||
"packageManager": "pnpm@9.15.1",
|
||||
"engines": {
|
||||
"node": ">=20.11"
|
||||
},
|
||||
|
|
@ -22,44 +22,44 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@number-flow/vue": "^0.3.3",
|
||||
"@unovis/ts": "^1.4.4",
|
||||
"@unovis/vue": "^1.4.4",
|
||||
"@vee-validate/zod": "^4.13.2",
|
||||
"@vueuse/core": "^11.0.0",
|
||||
"@unovis/ts": "^1.5.0",
|
||||
"@unovis/vue": "^1.5.0",
|
||||
"@vee-validate/zod": "^4.15.0",
|
||||
"@vueuse/core": "^12.2.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"intl-parse-accept-language": "^1.0.0",
|
||||
"lucide-vue-next": "^0.428.0",
|
||||
"lucide-vue-next": "^0.469.0",
|
||||
"mysql-bricks": "^1.1.2",
|
||||
"nanoid": "^5.0.7",
|
||||
"nanoid": "^5.0.9",
|
||||
"pluralize": "^8.0.0",
|
||||
"qr-code-styling": "1.6.0-rc.1",
|
||||
"radix-vue": "^1.9.4",
|
||||
"radix-vue": "^1.9.11",
|
||||
"ua-parser-js": "next",
|
||||
"vee-validate": "^4.13.2",
|
||||
"virtua": "^0.33.7",
|
||||
"vue-sonner": "^1.1.4",
|
||||
"vee-validate": "^4.15.0",
|
||||
"virtua": "^0.39.2",
|
||||
"vue-sonner": "^1.3.0",
|
||||
"vue3-simple-icons": "^13.2.0",
|
||||
"zod": "^3.23.8"
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@antfu/eslint-config": "^2.26.0",
|
||||
"@nuxt/eslint": "^0.5.0",
|
||||
"@nuxt/eslint-config": "^0.5.0",
|
||||
"@nuxthub/core": "^0.7.3",
|
||||
"@nuxtjs/color-mode": "^3.4.4",
|
||||
"@nuxtjs/tailwindcss": "^6.12.1",
|
||||
"@antfu/eslint-config": "^3.12.1",
|
||||
"@nuxt/eslint": "^0.7.4",
|
||||
"@nuxt/eslint-config": "^0.7.4",
|
||||
"@nuxthub/core": "^0.8.10",
|
||||
"@nuxtjs/color-mode": "^3.5.2",
|
||||
"@nuxtjs/tailwindcss": "^6.12.2",
|
||||
"@vueuse/integrations": "^12.2.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"eslint": "^9.9.0",
|
||||
"lint-staged": "^15.2.9",
|
||||
"nuxt": "^3.12.4",
|
||||
"shadcn-nuxt": "^0.10.4",
|
||||
"eslint": "^9.17.0",
|
||||
"lint-staged": "^15.2.11",
|
||||
"nuxt": "^3.14.1592",
|
||||
"shadcn-nuxt": "^0.11.3",
|
||||
"simple-git-hooks": "^2.11.1",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwind-merge": "^2.6.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"vue-tsc": "^2.0.29",
|
||||
"wrangler": "^3.72.0"
|
||||
"vue-tsc": "^2.2.0",
|
||||
"wrangler": "^3.99.0"
|
||||
},
|
||||
"simple-git-hooks": {
|
||||
"pre-commit": "npm run lint-staged"
|
||||
|
|
|
|||
5651
pnpm-lock.yaml
5651
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
import { z } from 'zod'
|
||||
import { customAlphabet } from 'nanoid'
|
||||
import { z } from 'zod'
|
||||
|
||||
const { slugRegex } = useAppConfig()
|
||||
const { caseSensitive } = useRuntimeConfig()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { z } from 'zod'
|
||||
import { destr } from 'destr'
|
||||
import { z } from 'zod'
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const url = (await getValidatedQuery(event, z.object({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { H3Event } from 'h3'
|
||||
import { z } from 'zod'
|
||||
import { QuerySchema } from '@/schemas/query'
|
||||
import { z } from 'zod'
|
||||
|
||||
const { select } = SqlBricks
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { H3Event } from 'h3'
|
||||
import { z } from 'zod'
|
||||
import { QuerySchema } from '@/schemas/query'
|
||||
import { z } from 'zod'
|
||||
|
||||
const { select } = SqlBricks
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { LinkSchema } from '@/schemas/link'
|
||||
import type { z } from 'zod'
|
||||
import { parsePath, withQuery } from 'ufo'
|
||||
import type { LinkSchema } from '@/schemas/link'
|
||||
|
||||
export default eventHandler(async (event) => {
|
||||
const { pathname: slug } = parsePath(event.path.replace(/^\/|\/$/g, '')) // remove leading and trailing slashes
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import type { H3Event } from 'h3'
|
||||
import { parseURL } from 'ufo'
|
||||
import { getFlag } from '@/utils/flag'
|
||||
import { parseAcceptLanguage } from 'intl-parse-accept-language'
|
||||
import { UAParser } from 'ua-parser-js'
|
||||
import {
|
||||
CLIs,
|
||||
|
|
@ -11,8 +12,7 @@ import {
|
|||
MediaPlayers,
|
||||
Modules,
|
||||
} from 'ua-parser-js/extensions'
|
||||
import { parseAcceptLanguage } from 'intl-parse-accept-language'
|
||||
import { getFlag } from '@/utils/flag'
|
||||
import { parseURL } from 'ufo'
|
||||
|
||||
function toBlobNumber(blob: string) {
|
||||
return +blob.replace(/\D/g, '')
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { z } from 'zod'
|
||||
import type { SelectStatement } from 'sql-bricks'
|
||||
import type { FilterSchema, QuerySchema } from '@/schemas/query'
|
||||
import type { SelectStatement } from 'sql-bricks'
|
||||
import type { z } from 'zod'
|
||||
|
||||
export type Query = z.infer<typeof QuerySchema>
|
||||
export type Filter = z.infer<typeof FilterSchema>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
export function colorGradation(count: number) {
|
||||
return Array.from(Array(count).keys()).map(i => `hsl(var(--vis-secondary-color) / ${1 - (1 / count) * i})`)
|
||||
return Array.from({ length: count }, (_, i) => `hsl(var(--vis-secondary-color) / ${1 - (1 / count) * i})`)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue