mirror of
https://github.com/ArthurDanjou/arthome.git
synced 2026-01-14 12:14:33 +01:00
Working on arthome
This commit is contained in:
19
app/app.vue
19
app/app.vue
@@ -1,22 +1,15 @@
|
||||
<script lang="ts" setup>
|
||||
useHead({
|
||||
link: [{ rel: 'icon', type: 'image/png', href: '/favicon.ico' }],
|
||||
title: 'Home by Arthur Danjou',
|
||||
title: 'ArtHome by Arthur Danjou',
|
||||
})
|
||||
|
||||
const { loggedIn, clear, user } = useUserSession()
|
||||
const colorMode = useColorMode()
|
||||
const authorized = await isAuthorized()
|
||||
|
||||
onMounted(async () => {
|
||||
if (!authorized) {
|
||||
navigateTo('/')
|
||||
}
|
||||
})
|
||||
|
||||
watch(loggedIn, async () => {
|
||||
if (!loggedIn.value) {
|
||||
navigateTo('/')
|
||||
navigateTo('/login')
|
||||
}
|
||||
})
|
||||
|
||||
@@ -24,6 +17,12 @@ function toggleColorMode() {
|
||||
colorMode.preference = colorMode.preference === 'dark' ? 'light' : 'dark'
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
await clear()
|
||||
navigateTo('/login')
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
defineShortcuts({
|
||||
t: () => toggleColorMode(),
|
||||
c: () => toggleColorMode(),
|
||||
@@ -43,7 +42,7 @@ defineShortcuts({
|
||||
square
|
||||
trailing-icon="i-ph:person-arms-spread-duotone"
|
||||
variant="ghost"
|
||||
@click="clear"
|
||||
@click="logout"
|
||||
/>
|
||||
</UTooltip>
|
||||
<UButton
|
||||
|
||||
13
app/components/Category.vue
Normal file
13
app/components/Category.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
18
app/components/Tab.vue
Normal file
18
app/components/Tab.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import type { Tab } from '~~/server/utils/db'
|
||||
|
||||
defineProps<{
|
||||
tab: PropType<Tab>
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
Tab
|
||||
{{ tab }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,10 +0,0 @@
|
||||
export async function isAuthorized() {
|
||||
const { user } = useUserSession()
|
||||
const { data: authorized } = await useFetch('/api/authorized', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
email: user.value?.email ?? 'test@nuxt.com',
|
||||
},
|
||||
})
|
||||
return authorized.value
|
||||
}
|
||||
13
app/composables/categories.ts
Normal file
13
app/composables/categories.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export function useCategories() {
|
||||
async function getCategories() {
|
||||
return useAsyncData<CategoryType[]>(async () => {
|
||||
const res = await $fetch('/api/categories')
|
||||
console.log('res', res)
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
getCategories,
|
||||
}
|
||||
}
|
||||
21
app/composables/tabs.ts
Normal file
21
app/composables/tabs.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export function useTabs() {
|
||||
async function createTab(tab: TabType) {
|
||||
console.log('createTab', tab)
|
||||
return tab
|
||||
}
|
||||
|
||||
async function deleteTab(tab: TabType) {
|
||||
console.log('deleteTab', tab)
|
||||
return tab
|
||||
}
|
||||
|
||||
async function updateTab(tab: TabType) {
|
||||
console.log('updateTab', tab)
|
||||
return tab
|
||||
}
|
||||
|
||||
return {
|
||||
createTab,
|
||||
deleteTab,
|
||||
}
|
||||
}
|
||||
21
app/composables/toasts.ts
Normal file
21
app/composables/toasts.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export function useSuccessToast(title: string, description?: string) {
|
||||
const toast = useToast()
|
||||
|
||||
toast.add({
|
||||
title,
|
||||
description,
|
||||
color: 'green',
|
||||
icon: 'i-ph:check-circle-duotone',
|
||||
})
|
||||
}
|
||||
|
||||
export function useErrorToast(title: string, description?: string) {
|
||||
const toast = useToast()
|
||||
|
||||
toast.add({
|
||||
title,
|
||||
description,
|
||||
color: 'red',
|
||||
icon: 'i-ph:x-circle-duotone',
|
||||
})
|
||||
}
|
||||
22
app/composables/user-limit.ts
Normal file
22
app/composables/user-limit.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
export function useUserLimit() {
|
||||
function hasUserFreePlan() {
|
||||
return true
|
||||
}
|
||||
|
||||
function getRemainingCategories() {
|
||||
if (!hasUserFreePlan())
|
||||
return -1
|
||||
return 3
|
||||
}
|
||||
|
||||
function getRemainingTabs(category_id: number) {
|
||||
if (!hasUserFreePlan())
|
||||
return -1
|
||||
return category_id * 3
|
||||
}
|
||||
|
||||
return {
|
||||
getRemainingCategories,
|
||||
getRemainingTabs,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
export default defineNuxtRouteMiddleware(async () => {
|
||||
const { loggedIn } = useUserSession()
|
||||
const authorized = await isAuthorized()
|
||||
|
||||
if (!loggedIn.value || !authorized) {
|
||||
return navigateTo('/')
|
||||
if (!loggedIn.value) {
|
||||
return navigateTo('/login')
|
||||
}
|
||||
})
|
||||
|
||||
7
app/middleware/ghost.ts
Normal file
7
app/middleware/ghost.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export default defineNuxtRouteMiddleware(async () => {
|
||||
const { loggedIn } = useUserSession()
|
||||
|
||||
if (loggedIn.value) {
|
||||
return navigateTo('/')
|
||||
}
|
||||
})
|
||||
13
app/pages/[user].vue
Normal file
13
app/pages/[user].vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
const router = useRouter()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
{{ router.currentRoute.value.params.user }}
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,41 +0,0 @@
|
||||
<script lang="ts" setup>
|
||||
definePageMeta({
|
||||
middleware: 'auth',
|
||||
})
|
||||
|
||||
const date = ref<Date>(new Date())
|
||||
onMounted(() => {
|
||||
setInterval(() => date.value = new Date(), 1000)
|
||||
})
|
||||
|
||||
const apps = await queryContent('/').find()
|
||||
const dev = apps.filter(app => app._dir === 'dev')
|
||||
const perso = apps.filter(app => app._dir === 'perso')
|
||||
const maths = apps.filter(app => app._dir === 'maths')
|
||||
const social = apps.filter(app => app._dir === 'social')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="my-12">
|
||||
<div v-if="date" class="flex flex-col items-center">
|
||||
<h1 class="text-6xl md:text-9xl font-bold">
|
||||
{{ useDateFormat(date, 'HH') }}
|
||||
<span class="animate-pulse">:</span>
|
||||
{{ useDateFormat(date, 'mm') }}
|
||||
</h1>
|
||||
<h1 class="text-2xl md:text-5xl">
|
||||
{{ useDateFormat(date, 'dddd D MMMM YYYY', { locales: () => 'fr-FR' }) }}
|
||||
</h1>
|
||||
</div>
|
||||
<div v-if="apps" class="space-y-12 mt-12">
|
||||
<section class="grid grid-cols-1 auto-rows-auto sm:grid-cols-3 gap-4">
|
||||
<Weather />
|
||||
<Map />
|
||||
</section>
|
||||
<Application :apps="perso" title="Personnel" />
|
||||
<Application :apps="social" title="Social" />
|
||||
<Application :apps="dev" title="Développement" />
|
||||
<Application :apps="maths" title="Mathématiques" />
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
@@ -1,64 +1,54 @@
|
||||
<script lang="ts" setup>
|
||||
const { loggedIn } = useUserSession()
|
||||
const authorized = await isAuthorized()
|
||||
|
||||
onMounted(() => {
|
||||
if (authorized) {
|
||||
navigateTo('/home')
|
||||
}
|
||||
definePageMeta({
|
||||
middleware: 'auth',
|
||||
})
|
||||
|
||||
const date = ref<Date>(new Date())
|
||||
onMounted(() => {
|
||||
setInterval(() => date.value = new Date(), 1000)
|
||||
})
|
||||
|
||||
const { user, session } = useUserSession()
|
||||
|
||||
const { getCategories } = useCategories()
|
||||
const categories = await getCategories()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen flex items-center justify-center">
|
||||
<UCard class="w-full md:w-1/2">
|
||||
<template #header>
|
||||
<h1 class="font-bold text-black dark:text-white text-lg space-y-2">
|
||||
Welcome to ArtHome
|
||||
</h1>
|
||||
</template>
|
||||
<template #default>
|
||||
<p>
|
||||
ArtHome is a private platform. You need to request access to be able to use it by asking to
|
||||
<a
|
||||
class="duration-300 underline-offset-2 text-md text-black dark:text-white underline decoration-gray-300 dark:decoration-neutral-700 hover:decoration-black dark:hover:decoration-white"
|
||||
href="mailto:arthurdanjou@outlook.fr"
|
||||
rel="noopener"
|
||||
target="_blank"
|
||||
>Arthur Danjou</a>
|
||||
</p>
|
||||
<div v-if="!loggedIn" class="flex gap-2 mt-2">
|
||||
<UButton
|
||||
:external="true"
|
||||
color="black"
|
||||
icon="i-ph:github-logo-duotone"
|
||||
label="GitHub"
|
||||
to="/auth/github"
|
||||
/>
|
||||
<UButton
|
||||
:external="true"
|
||||
color="red"
|
||||
icon="i-ph:google-logo-duotone"
|
||||
label="Google"
|
||||
to="/auth/google"
|
||||
/>
|
||||
</div>
|
||||
<UButton
|
||||
v-if="authorized"
|
||||
color="black"
|
||||
icon="i-ph:house-duotone"
|
||||
label="Go Home"
|
||||
to="/home"
|
||||
<main v-if="user" class="my-12">
|
||||
<div v-if="date" class="flex flex-col items-center">
|
||||
<h1 class="text-6xl md:text-9xl font-bold">
|
||||
{{ useDateFormat(date, 'HH') }}
|
||||
<span class="animate-pulse">:</span>
|
||||
{{ useDateFormat(date, 'mm') }}
|
||||
</h1>
|
||||
<h1 class="text-2xl md:text-5xl">
|
||||
{{ useDateFormat(date, 'dddd D MMMM YYYY', { locales: user.language }) }}
|
||||
</h1>
|
||||
</div>
|
||||
<div>
|
||||
{{ user }}
|
||||
</div>
|
||||
<div>
|
||||
{{ session }}
|
||||
</div>
|
||||
<div>
|
||||
{{ user === session.user }}
|
||||
</div>
|
||||
<div v-if="categories">
|
||||
{{ categories }}
|
||||
</div>
|
||||
<div>
|
||||
<Category>
|
||||
<Tab
|
||||
:tab="{
|
||||
name: 'Test',
|
||||
nameVisible: true,
|
||||
icon: 'i-ph:cloud-duotone',
|
||||
color: 'blue',
|
||||
}"
|
||||
/>
|
||||
<p v-if="!authorized && loggedIn" class="text-red-500 font-medium">
|
||||
You're not authorized to access
|
||||
</p>
|
||||
</template>
|
||||
<template #footer>
|
||||
<p class="italic text-sm">
|
||||
No personal informations regarding your account are stored in database.
|
||||
</p>
|
||||
</template>
|
||||
</UCard>
|
||||
</div>
|
||||
</Category>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
104
app/pages/login.vue
Normal file
104
app/pages/login.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<script lang="ts" setup>
|
||||
import { z } from 'zod'
|
||||
import { useSession } from 'h3'
|
||||
import type { FormSubmitEvent } from '#ui/types'
|
||||
|
||||
const { loggedIn } = useUserSession()
|
||||
|
||||
definePageMeta({
|
||||
middleware: 'ghost',
|
||||
})
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().email('Invalid email'),
|
||||
})
|
||||
|
||||
const form = ref()
|
||||
type Schema = z.output<typeof schema>
|
||||
const state = reactive({ email: undefined })
|
||||
|
||||
async function onSubmit(event: FormSubmitEvent<Schema>) {
|
||||
// Do something with data
|
||||
// todo: add login logic
|
||||
console.log(event.data)
|
||||
state.email = ''
|
||||
}
|
||||
|
||||
const message = useState<string>('message')
|
||||
if (import.meta.server) {
|
||||
const session = await useSession(useRequestEvent()!, {
|
||||
password: useRuntimeConfig().session.password,
|
||||
})
|
||||
|
||||
message.value = session.data.message
|
||||
|
||||
await session.update({
|
||||
message: '',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen flex flex-col items-center justify-center">
|
||||
<h1 class="tracking-widest text-4xl font-bold text-black dark:text-white mb-12">
|
||||
ArtHome
|
||||
</h1>
|
||||
<div class="w-full md:w-1/3">
|
||||
<UAlert
|
||||
v-if="message"
|
||||
class="mb-8"
|
||||
color="red"
|
||||
variant="outline"
|
||||
:close-button="{ icon: 'i-ph:x-circle-duotone', color: 'red', variant: 'link', padded: false }"
|
||||
:description="message"
|
||||
@close="message = ''"
|
||||
/>
|
||||
</div>
|
||||
<UCard class="w-full md:w-1/3 mt-2">
|
||||
<template #header>
|
||||
<h1 class="text-center font-bold text-black dark:text-white text-lg py-2">
|
||||
Sign in to your ArtHome account
|
||||
</h1>
|
||||
</template>
|
||||
<template #default>
|
||||
<div v-if="!loggedIn" class="flex flex-col gap-4 p-4">
|
||||
<UForm ref="form" :schema="schema" :state="state" class="space-y-4" @submit="onSubmit">
|
||||
<UFormGroup name="email">
|
||||
<UInput v-model="state.email" color="gray" placeholder="arthur@arthome.com" />
|
||||
</UFormGroup>
|
||||
<UButton
|
||||
:external="true"
|
||||
color="gray"
|
||||
icon="i-ph:envelope-duotone"
|
||||
label="Continue with Email"
|
||||
block
|
||||
type="submit"
|
||||
/>
|
||||
</UForm>
|
||||
<UDivider label="or" />
|
||||
<UButton
|
||||
:external="true"
|
||||
color="gray"
|
||||
icon="i-ph:github-logo-duotone"
|
||||
label="Continue with GitHub"
|
||||
block
|
||||
to="/auth/github"
|
||||
/>
|
||||
<UButton
|
||||
:external="true"
|
||||
color="gray"
|
||||
icon="i-ph:google-logo-duotone"
|
||||
label="Continue With Google"
|
||||
block
|
||||
to="/auth/google"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<p class="italic text-xs">
|
||||
We only store your email address, name and profile picture. We will never share your data with third parties.
|
||||
</p>
|
||||
</template>
|
||||
</UCard>
|
||||
</div>
|
||||
</template>
|
||||
24
app/pages/profile.vue
Normal file
24
app/pages/profile.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<script setup lang="ts">
|
||||
const { user, loggedIn, session, clear } = useUserSession()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
User: {{ user }}
|
||||
</div>
|
||||
<div>
|
||||
LoggedIn: {{ loggedIn }}
|
||||
</div>
|
||||
<div>
|
||||
Session: {{ session }}
|
||||
</div>
|
||||
<div @click="clear">
|
||||
clear
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,7 +1,13 @@
|
||||
import type { Config } from 'drizzle-kit'
|
||||
import { config } from 'dotenv'
|
||||
|
||||
config()
|
||||
|
||||
export default {
|
||||
dialect: 'sqlite',
|
||||
dialect: 'postgresql',
|
||||
schema: './server/database/schema.ts',
|
||||
out: './server/database/migrations',
|
||||
dbCredentials: {
|
||||
url: process.env.NUXT_POSTGRES_URL,
|
||||
},
|
||||
} satisfies Config
|
||||
|
||||
@@ -35,7 +35,8 @@ export default defineNuxtConfig({
|
||||
hub: {
|
||||
cache: true,
|
||||
analytics: true,
|
||||
database: true,
|
||||
blob: true,
|
||||
kv: true,
|
||||
},
|
||||
|
||||
// Nuxt Icon
|
||||
@@ -79,6 +80,10 @@ export default defineNuxtConfig({
|
||||
lang: '',
|
||||
units: '',
|
||||
},
|
||||
postgres: {
|
||||
url: '',
|
||||
dir: './server/db',
|
||||
},
|
||||
public: {
|
||||
mapbox: {
|
||||
style: '',
|
||||
|
||||
12
package.json
12
package.json
@@ -8,7 +8,10 @@
|
||||
"remote": "nuxt dev --remote --host",
|
||||
"postinstall": "nuxt prepare",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"db:generate": "drizzle-kit generate"
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:migrate": "drizzle-kit migrate",
|
||||
"db:push": "drizzle-kit push",
|
||||
"db:pull": "drizzle-kit pull"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxt/content": "^2.13.2",
|
||||
@@ -16,9 +19,10 @@
|
||||
"@nuxthq/studio": "^2.0.3",
|
||||
"@nuxthub/core": "^0.7.3",
|
||||
"@nuxtjs/google-fonts": "^3.2.0",
|
||||
"drizzle-orm": "^0.32.1",
|
||||
"drizzle-orm": "^0.33.0",
|
||||
"h3-zod": "^0.5.3",
|
||||
"nuxt-auth-utils": "^0.3.4",
|
||||
"postgres": "^3.4.4",
|
||||
"vue": "^3.4.38",
|
||||
"vue-router": "^4.4.3",
|
||||
"zod": "^3.23.8"
|
||||
@@ -28,9 +32,11 @@
|
||||
"@nuxt/devtools": "^1.3.14",
|
||||
"@nuxt/ui": "^2.18.4",
|
||||
"@types/node": "^22.4.2",
|
||||
"@types/pg": "^8.11.6",
|
||||
"@vueuse/core": "^11.0.1",
|
||||
"@vueuse/nuxt": "^11.0.1",
|
||||
"drizzle-kit": "^0.23.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"drizzle-kit": "^0.24.1",
|
||||
"eslint": "^9.9.0",
|
||||
"mapbox-gl": "^3.6.0",
|
||||
"nuxt": "^3.13.0",
|
||||
|
||||
252
pnpm-lock.yaml
generated
252
pnpm-lock.yaml
generated
@@ -10,7 +10,7 @@ importers:
|
||||
dependencies:
|
||||
'@nuxt/content':
|
||||
specifier: ^2.13.2
|
||||
version: 2.13.2(ioredis@5.4.1)(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))
|
||||
version: 2.13.2(ioredis@5.4.1)(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))
|
||||
'@nuxt/image':
|
||||
specifier: ^1.7.0
|
||||
version: 1.7.0(ioredis@5.4.1)(magicast@0.3.4)(rollup@4.21.0)
|
||||
@@ -24,14 +24,17 @@ importers:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0(magicast@0.3.4)(rollup@4.21.0)
|
||||
drizzle-orm:
|
||||
specifier: ^0.32.1
|
||||
version: 0.32.2(@cloudflare/workers-types@4.20240821.1)
|
||||
specifier: ^0.33.0
|
||||
version: 0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4)
|
||||
h3-zod:
|
||||
specifier: ^0.5.3
|
||||
version: 0.5.3(h3@1.12.0)(zod@3.23.8)
|
||||
nuxt-auth-utils:
|
||||
specifier: ^0.3.4
|
||||
version: 0.3.4(magicast@0.3.4)(rollup@4.21.0)
|
||||
postgres:
|
||||
specifier: ^3.4.4
|
||||
version: 3.4.4
|
||||
vue:
|
||||
specifier: ^3.4.38
|
||||
version: 3.4.38(typescript@5.5.4)
|
||||
@@ -54,15 +57,21 @@ importers:
|
||||
'@types/node':
|
||||
specifier: ^22.4.2
|
||||
version: 22.5.0
|
||||
'@types/pg':
|
||||
specifier: ^8.11.6
|
||||
version: 8.11.6
|
||||
'@vueuse/core':
|
||||
specifier: ^11.0.1
|
||||
version: 11.0.1(vue@3.4.38(typescript@5.5.4))
|
||||
'@vueuse/nuxt':
|
||||
specifier: ^11.0.1
|
||||
version: 11.0.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))
|
||||
version: 11.0.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))
|
||||
dotenv:
|
||||
specifier: ^16.4.5
|
||||
version: 16.4.5
|
||||
drizzle-kit:
|
||||
specifier: ^0.23.0
|
||||
version: 0.23.2
|
||||
specifier: ^0.24.1
|
||||
version: 0.24.1
|
||||
eslint:
|
||||
specifier: ^9.9.0
|
||||
version: 9.9.0(jiti@1.21.6)
|
||||
@@ -71,7 +80,7 @@ importers:
|
||||
version: 3.6.0
|
||||
nuxt:
|
||||
specifier: ^3.13.0
|
||||
version: 3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4))
|
||||
version: 3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4))
|
||||
nuxt-mapbox:
|
||||
specifier: ^1.6.0
|
||||
version: 1.6.0(magicast@0.3.4)(rollup@4.21.0)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))
|
||||
@@ -364,8 +373,8 @@ packages:
|
||||
peerDependencies:
|
||||
postcss-selector-parser: ^6.0.13
|
||||
|
||||
'@drizzle-team/brocli@0.8.2':
|
||||
resolution: {integrity: sha512-zTrFENsqGvOkBOuHDC1pXCkDXNd2UhP4lI3gYGhQ1R1SPeAAfqzPsV1dcpMy4uNU6kB5VpU5NGhvwxVNETR02A==}
|
||||
'@drizzle-team/brocli@0.10.1':
|
||||
resolution: {integrity: sha512-AHy0vjc+n/4w/8Mif+w86qpppHuF3AyXbcWW+R/W7GNA3F5/p2nuhlkCJaTXSLZheB4l1rtHzOfr9A7NwoR/Zg==}
|
||||
|
||||
'@es-joy/jsdoccomment@0.43.1':
|
||||
resolution: {integrity: sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==}
|
||||
@@ -1873,6 +1882,9 @@ packages:
|
||||
'@types/pbf@3.0.5':
|
||||
resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==}
|
||||
|
||||
'@types/pg@8.11.6':
|
||||
resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==}
|
||||
|
||||
'@types/resolve@1.20.2':
|
||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||
|
||||
@@ -2965,12 +2977,12 @@ packages:
|
||||
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
drizzle-kit@0.23.2:
|
||||
resolution: {integrity: sha512-NWkQ7GD2OTbQ7HzcjsaCOf3n0tlFPSEAF38fvDpwDj8jRbGWGFtN2cD8I8wp4lU+5Os/oyP2xycTKGLHdPipUw==}
|
||||
drizzle-kit@0.24.1:
|
||||
resolution: {integrity: sha512-y47ZuFpy3ZEz5v2P4Q4m7CZpC9infdmFAVP8klfl92hyBBvgWlyFnriDkycK2HXqB1PrYWNTck2p5TfFY5+EWw==}
|
||||
hasBin: true
|
||||
|
||||
drizzle-orm@0.32.2:
|
||||
resolution: {integrity: sha512-3fXKzPzrgZIcnWCSLiERKN5Opf9Iagrag75snfFlKeKSYB1nlgPBshzW3Zn6dQymkyiib+xc4nIz0t8U+Xdpuw==}
|
||||
drizzle-orm@0.33.0:
|
||||
resolution: {integrity: sha512-SHy72R2Rdkz0LEq0PSG/IdvnT3nGiWuRk+2tXZQ90GVq/XQhpCzu/EFT3V2rox+w8MlkBQxifF8pCStNYnERfA==}
|
||||
peerDependencies:
|
||||
'@aws-sdk/client-rds-data': '>=3'
|
||||
'@cloudflare/workers-types': '>=3'
|
||||
@@ -4637,6 +4649,9 @@ packages:
|
||||
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
obuf@1.1.2:
|
||||
resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==}
|
||||
|
||||
ofetch@1.3.4:
|
||||
resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==}
|
||||
|
||||
@@ -4793,6 +4808,48 @@ packages:
|
||||
perfect-debounce@1.0.0:
|
||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
||||
|
||||
pg-cloudflare@1.1.1:
|
||||
resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==}
|
||||
|
||||
pg-connection-string@2.6.4:
|
||||
resolution: {integrity: sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==}
|
||||
|
||||
pg-int8@1.0.1:
|
||||
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
pg-numeric@1.0.2:
|
||||
resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pg-pool@3.6.2:
|
||||
resolution: {integrity: sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==}
|
||||
peerDependencies:
|
||||
pg: '>=8.0'
|
||||
|
||||
pg-protocol@1.6.1:
|
||||
resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==}
|
||||
|
||||
pg-types@2.2.0:
|
||||
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pg-types@4.0.2:
|
||||
resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
pg@8.12.0:
|
||||
resolution: {integrity: sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
peerDependencies:
|
||||
pg-native: '>=3.0.1'
|
||||
peerDependenciesMeta:
|
||||
pg-native:
|
||||
optional: true
|
||||
|
||||
pgpass@1.0.5:
|
||||
resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
|
||||
|
||||
picocolors@1.0.1:
|
||||
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
|
||||
|
||||
@@ -5036,6 +5093,45 @@ packages:
|
||||
resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
postgres-array@2.0.0:
|
||||
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postgres-array@3.0.2:
|
||||
resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postgres-bytea@1.0.0:
|
||||
resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-bytea@3.0.0:
|
||||
resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
postgres-date@1.0.7:
|
||||
resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-date@2.1.0:
|
||||
resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postgres-interval@1.2.0:
|
||||
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-interval@3.0.0:
|
||||
resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postgres-range@1.1.4:
|
||||
resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==}
|
||||
|
||||
postgres@3.4.4:
|
||||
resolution: {integrity: sha512-IbyN+9KslkqcXa8AO9fxpk97PA4pzewvpi2B3Dwy9u4zpV32QicaEdgmF3eSQUzdRk7ttDHQejNgAEr4XoeH4A==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
potpack@2.0.0:
|
||||
resolution: {integrity: sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==}
|
||||
|
||||
@@ -5471,6 +5567,10 @@ packages:
|
||||
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
split2@4.2.0:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
|
||||
stable-hash@0.0.4:
|
||||
resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==}
|
||||
|
||||
@@ -6577,7 +6677,7 @@ snapshots:
|
||||
dependencies:
|
||||
postcss-selector-parser: 6.1.2
|
||||
|
||||
'@drizzle-team/brocli@0.8.2': {}
|
||||
'@drizzle-team/brocli@0.10.1': {}
|
||||
|
||||
'@es-joy/jsdoccomment@0.43.1':
|
||||
dependencies:
|
||||
@@ -7254,13 +7354,13 @@ snapshots:
|
||||
'@nodelib/fs.scandir': 2.1.5
|
||||
fastq: 1.17.1
|
||||
|
||||
'@nuxt/content@2.13.2(ioredis@5.4.1)(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))':
|
||||
'@nuxt/content@2.13.2(ioredis@5.4.1)(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))':
|
||||
dependencies:
|
||||
'@nuxt/kit': 3.13.0(magicast@0.3.4)(rollup@4.21.0)
|
||||
'@nuxtjs/mdc': 0.8.3(magicast@0.3.4)(rollup@4.21.0)
|
||||
'@vueuse/core': 10.11.1(vue@3.4.38(typescript@5.5.4))
|
||||
'@vueuse/head': 2.0.0(vue@3.4.38(typescript@5.5.4))
|
||||
'@vueuse/nuxt': 10.11.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))
|
||||
'@vueuse/nuxt': 10.11.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))
|
||||
consola: 3.2.3
|
||||
defu: 6.1.4
|
||||
destr: 2.0.3
|
||||
@@ -8111,6 +8211,12 @@ snapshots:
|
||||
|
||||
'@types/pbf@3.0.5': {}
|
||||
|
||||
'@types/pg@8.11.6':
|
||||
dependencies:
|
||||
'@types/node': 22.5.0
|
||||
pg-protocol: 1.6.1
|
||||
pg-types: 4.0.2
|
||||
|
||||
'@types/resolve@1.20.2': {}
|
||||
|
||||
'@types/responselike@1.0.3':
|
||||
@@ -8544,13 +8650,13 @@ snapshots:
|
||||
|
||||
'@vueuse/metadata@11.0.1': {}
|
||||
|
||||
'@vueuse/nuxt@10.11.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))':
|
||||
'@vueuse/nuxt@10.11.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))':
|
||||
dependencies:
|
||||
'@nuxt/kit': 3.13.0(magicast@0.3.4)(rollup@4.21.0)
|
||||
'@vueuse/core': 10.11.1(vue@3.4.38(typescript@5.5.4))
|
||||
'@vueuse/metadata': 10.11.1
|
||||
local-pkg: 0.5.0
|
||||
nuxt: 3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4))
|
||||
nuxt: 3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4))
|
||||
vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4))
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
@@ -8559,13 +8665,13 @@ snapshots:
|
||||
- supports-color
|
||||
- vue
|
||||
|
||||
'@vueuse/nuxt@11.0.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))':
|
||||
'@vueuse/nuxt@11.0.1(magicast@0.3.4)(nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)))(rollup@4.21.0)(vue@3.4.38(typescript@5.5.4))':
|
||||
dependencies:
|
||||
'@nuxt/kit': 3.13.0(magicast@0.3.4)(rollup@4.21.0)
|
||||
'@vueuse/core': 11.0.1(vue@3.4.38(typescript@5.5.4))
|
||||
'@vueuse/metadata': 11.0.1
|
||||
local-pkg: 0.5.0
|
||||
nuxt: 3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4))
|
||||
nuxt: 3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4))
|
||||
vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4))
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
@@ -9168,9 +9274,9 @@ snapshots:
|
||||
|
||||
date-fns@3.6.0: {}
|
||||
|
||||
db0@0.1.4(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1)):
|
||||
db0@0.1.4(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4)):
|
||||
optionalDependencies:
|
||||
drizzle-orm: 0.32.2(@cloudflare/workers-types@4.20240821.1)
|
||||
drizzle-orm: 0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4)
|
||||
|
||||
de-indent@1.0.2: {}
|
||||
|
||||
@@ -9291,18 +9397,21 @@ snapshots:
|
||||
|
||||
dotenv@16.4.5: {}
|
||||
|
||||
drizzle-kit@0.23.2:
|
||||
drizzle-kit@0.24.1:
|
||||
dependencies:
|
||||
'@drizzle-team/brocli': 0.8.2
|
||||
'@drizzle-team/brocli': 0.10.1
|
||||
'@esbuild-kit/esm-loader': 2.6.5
|
||||
esbuild: 0.19.12
|
||||
esbuild-register: 3.6.0(esbuild@0.19.12)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1):
|
||||
drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4):
|
||||
optionalDependencies:
|
||||
'@cloudflare/workers-types': 4.20240821.1
|
||||
'@types/pg': 8.11.6
|
||||
pg: 8.12.0
|
||||
postgres: 3.4.4
|
||||
|
||||
duplexer@0.1.2: {}
|
||||
|
||||
@@ -11245,7 +11354,7 @@ snapshots:
|
||||
mlly: 1.7.1
|
||||
pkg-types: 1.1.3
|
||||
|
||||
nitropack@2.9.7(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(magicast@0.3.4):
|
||||
nitropack@2.9.7(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(magicast@0.3.4):
|
||||
dependencies:
|
||||
'@cloudflare/kv-asset-handler': 0.3.4
|
||||
'@netlify/functions': 2.8.1
|
||||
@@ -11268,7 +11377,7 @@ snapshots:
|
||||
cookie-es: 1.2.2
|
||||
croner: 8.1.1
|
||||
crossws: 0.2.4
|
||||
db0: 0.1.4(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))
|
||||
db0: 0.1.4(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))
|
||||
defu: 6.1.4
|
||||
destr: 2.0.3
|
||||
dot-prop: 8.0.2
|
||||
@@ -11456,7 +11565,7 @@ snapshots:
|
||||
- utf-8-validate
|
||||
- vite
|
||||
|
||||
nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)):
|
||||
nuxt@3.13.0(@parcel/watcher@2.4.1)(@types/node@22.5.0)(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(eslint@9.9.0(jiti@1.21.6))(ioredis@5.4.1)(magicast@0.3.4)(meow@9.0.0)(optionator@0.9.4)(rollup@4.21.0)(terser@5.31.6)(typescript@5.5.4)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.0.29(typescript@5.5.4)):
|
||||
dependencies:
|
||||
'@nuxt/devalue': 2.0.2
|
||||
'@nuxt/devtools': 1.3.14(rollup@4.21.0)(vite@5.4.2(@types/node@22.5.0)(terser@5.31.6))
|
||||
@@ -11490,7 +11599,7 @@ snapshots:
|
||||
knitwork: 1.1.0
|
||||
magic-string: 0.30.11
|
||||
mlly: 1.7.1
|
||||
nitropack: 2.9.7(drizzle-orm@0.32.2(@cloudflare/workers-types@4.20240821.1))(magicast@0.3.4)
|
||||
nitropack: 2.9.7(drizzle-orm@0.33.0(@cloudflare/workers-types@4.20240821.1)(@types/pg@8.11.6)(pg@8.12.0)(postgres@3.4.4))(magicast@0.3.4)
|
||||
nuxi: 3.12.0
|
||||
nypm: 0.3.9
|
||||
ofetch: 1.3.4
|
||||
@@ -11576,6 +11685,8 @@ snapshots:
|
||||
|
||||
object-hash@3.0.0: {}
|
||||
|
||||
obuf@1.1.2: {}
|
||||
|
||||
ofetch@1.3.4:
|
||||
dependencies:
|
||||
destr: 2.0.3
|
||||
@@ -11747,6 +11858,58 @@ snapshots:
|
||||
|
||||
perfect-debounce@1.0.0: {}
|
||||
|
||||
pg-cloudflare@1.1.1:
|
||||
optional: true
|
||||
|
||||
pg-connection-string@2.6.4:
|
||||
optional: true
|
||||
|
||||
pg-int8@1.0.1: {}
|
||||
|
||||
pg-numeric@1.0.2: {}
|
||||
|
||||
pg-pool@3.6.2(pg@8.12.0):
|
||||
dependencies:
|
||||
pg: 8.12.0
|
||||
optional: true
|
||||
|
||||
pg-protocol@1.6.1: {}
|
||||
|
||||
pg-types@2.2.0:
|
||||
dependencies:
|
||||
pg-int8: 1.0.1
|
||||
postgres-array: 2.0.0
|
||||
postgres-bytea: 1.0.0
|
||||
postgres-date: 1.0.7
|
||||
postgres-interval: 1.2.0
|
||||
optional: true
|
||||
|
||||
pg-types@4.0.2:
|
||||
dependencies:
|
||||
pg-int8: 1.0.1
|
||||
pg-numeric: 1.0.2
|
||||
postgres-array: 3.0.2
|
||||
postgres-bytea: 3.0.0
|
||||
postgres-date: 2.1.0
|
||||
postgres-interval: 3.0.0
|
||||
postgres-range: 1.1.4
|
||||
|
||||
pg@8.12.0:
|
||||
dependencies:
|
||||
pg-connection-string: 2.6.4
|
||||
pg-pool: 3.6.2(pg@8.12.0)
|
||||
pg-protocol: 1.6.1
|
||||
pg-types: 2.2.0
|
||||
pgpass: 1.0.5
|
||||
optionalDependencies:
|
||||
pg-cloudflare: 1.1.1
|
||||
optional: true
|
||||
|
||||
pgpass@1.0.5:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
optional: true
|
||||
|
||||
picocolors@1.0.1: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
@@ -11971,6 +12134,34 @@ snapshots:
|
||||
picocolors: 1.0.1
|
||||
source-map-js: 1.2.0
|
||||
|
||||
postgres-array@2.0.0:
|
||||
optional: true
|
||||
|
||||
postgres-array@3.0.2: {}
|
||||
|
||||
postgres-bytea@1.0.0:
|
||||
optional: true
|
||||
|
||||
postgres-bytea@3.0.0:
|
||||
dependencies:
|
||||
obuf: 1.1.2
|
||||
|
||||
postgres-date@1.0.7:
|
||||
optional: true
|
||||
|
||||
postgres-date@2.1.0: {}
|
||||
|
||||
postgres-interval@1.2.0:
|
||||
dependencies:
|
||||
xtend: 4.0.2
|
||||
optional: true
|
||||
|
||||
postgres-interval@3.0.0: {}
|
||||
|
||||
postgres-range@1.1.4: {}
|
||||
|
||||
postgres@3.4.4: {}
|
||||
|
||||
potpack@2.0.0: {}
|
||||
|
||||
prebuild-install@7.1.2:
|
||||
@@ -12516,6 +12707,9 @@ snapshots:
|
||||
|
||||
speakingurl@14.0.1: {}
|
||||
|
||||
split2@4.2.0:
|
||||
optional: true
|
||||
|
||||
stable-hash@0.0.4: {}
|
||||
|
||||
stacktracey@2.1.8:
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { useValidatedBody, z } from 'h3-zod'
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const users = await useDB().select().from(tables.users).all()
|
||||
const { email } = await useValidatedBody(event, {
|
||||
email: z.string(),
|
||||
})
|
||||
const user = users.find(user => user.email === email)
|
||||
return !!user
|
||||
})
|
||||
7
server/api/categories/index.get.ts
Normal file
7
server/api/categories/index.get.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const user = await getUserSession(event)
|
||||
console.log('session', user)
|
||||
return useDrizzle().query.categories.findMany({
|
||||
where: eq(tables.users.id, user.id),
|
||||
})
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
CREATE TABLE `users`
|
||||
(
|
||||
`id` integer PRIMARY KEY NOT NULL,
|
||||
`name` text DEFAULT '',
|
||||
`email` text DEFAULT '',
|
||||
`created_at` text DEFAULT (CURRENT_DATE)
|
||||
);
|
||||
73
server/database/migrations/0000_wild_luke_cage.sql
Normal file
73
server/database/migrations/0000_wild_luke_cage.sql
Normal file
@@ -0,0 +1,73 @@
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."subscription" AS ENUM('free', 'paid');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "categories" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"name" text DEFAULT '' NOT NULL,
|
||||
"name_visible" boolean DEFAULT true NOT NULL,
|
||||
"icon" text DEFAULT 'i-ph:circle-wavy-question-duotone' NOT NULL,
|
||||
"color" text DEFAULT 'gray' NOT NULL,
|
||||
"page_id" integer NOT NULL,
|
||||
"created_at" timestamp (3) DEFAULT now(),
|
||||
"updated_at" timestamp (3)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "pages" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"user_id" integer NOT NULL,
|
||||
"created_at" timestamp (3) DEFAULT now(),
|
||||
"updated_at" timestamp (3)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "tabs" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"name" text DEFAULT '' NOT NULL,
|
||||
"name_visible" boolean DEFAULT true NOT NULL,
|
||||
"icon" text DEFAULT 'i-ph:circle-wavy-question-duotone' NOT NULL,
|
||||
"color" text DEFAULT 'gray' NOT NULL,
|
||||
"category_id" integer NOT NULL,
|
||||
"created_at" timestamp (3) DEFAULT now(),
|
||||
"updated_at" timestamp (3)
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "users" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"username" text NOT NULL,
|
||||
"name" text NOT NULL,
|
||||
"email" text NOT NULL,
|
||||
"github_id" text,
|
||||
"github_token" text,
|
||||
"google_id" text,
|
||||
"google_token" text,
|
||||
"description" text DEFAULT '',
|
||||
"private" boolean DEFAULT false NOT NULL,
|
||||
"timezone" text DEFAULT 'undefined' NOT NULL,
|
||||
"location" text DEFAULT 'undefined' NOT NULL,
|
||||
"subscription" "subscription" DEFAULT 'free' NOT NULL,
|
||||
"created_at" timestamp (3) DEFAULT now(),
|
||||
"updated_at" timestamp (3),
|
||||
CONSTRAINT "users_email_unique" UNIQUE("email"),
|
||||
CONSTRAINT "users_github_id_unique" UNIQUE("github_id"),
|
||||
CONSTRAINT "users_google_id_unique" UNIQUE("google_id")
|
||||
);
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "categories" ADD CONSTRAINT "categories_page_id_pages_id_fk" FOREIGN KEY ("page_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "pages" ADD CONSTRAINT "pages_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "tabs" ADD CONSTRAINT "tabs_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE cascade ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
4
server/database/migrations/0001_goofy_dormammu.sql
Normal file
4
server/database/migrations/0001_goofy_dormammu.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE "categories" ALTER COLUMN "id" SET DATA TYPE integer;--> statement-breakpoint
|
||||
ALTER TABLE "pages" ALTER COLUMN "id" SET DATA TYPE integer;--> statement-breakpoint
|
||||
ALTER TABLE "tabs" ALTER COLUMN "id" SET DATA TYPE integer;--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "id" SET DATA TYPE integer;
|
||||
@@ -1,2 +0,0 @@
|
||||
ALTER TABLE `users`
|
||||
ADD `description` text DEFAULT '';
|
||||
13
server/database/migrations/0002_slim_whistler.sql
Normal file
13
server/database/migrations/0002_slim_whistler.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
ALTER TABLE "categories" ALTER COLUMN "name" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "categories" ALTER COLUMN "name_visible" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "categories" ALTER COLUMN "icon" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "categories" ALTER COLUMN "color" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "tabs" ALTER COLUMN "name" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "tabs" ALTER COLUMN "name_visible" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "tabs" ALTER COLUMN "icon" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "tabs" ALTER COLUMN "color" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "private" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "timezone" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "location" SET DEFAULT 'unknown';--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "location" DROP NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "subscription" DROP NOT NULL;
|
||||
1
server/database/migrations/0003_curious_solo.sql
Normal file
1
server/database/migrations/0003_curious_solo.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "users" ADD COLUMN "avatar" text DEFAULT '';
|
||||
2
server/database/migrations/0004_sharp_shocker.sql
Normal file
2
server/database/migrations/0004_sharp_shocker.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "users" RENAME COLUMN "timezone" TO "language";--> statement-breakpoint
|
||||
ALTER TABLE "users" ALTER COLUMN "language" SET DEFAULT 'english';
|
||||
1
server/database/migrations/0005_tense_the_order.sql
Normal file
1
server/database/migrations/0005_tense_the_order.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "users" ALTER COLUMN "language" SET DEFAULT 'en-EN';
|
||||
@@ -1,57 +1,357 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "a30470ea-8de9-4ff0-b0c9-d6b8a6264726",
|
||||
"id": "a8ec7e1e-1087-4ab5-be19-459dc9b0a4e0",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"users": {
|
||||
"name": "users",
|
||||
"public.categories": {
|
||||
"name": "categories",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"page_id": {
|
||||
"name": "page_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"categories_page_id_pages_id_fk": {
|
||||
"name": "categories_page_id_pages_id_fk",
|
||||
"tableFrom": "categories",
|
||||
"tableTo": "pages",
|
||||
"columnsFrom": [
|
||||
"page_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.pages": {
|
||||
"name": "pages",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"pages_user_id_users_id_fk": {
|
||||
"name": "pages_user_id_users_id_fk",
|
||||
"tableFrom": "pages",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.tabs": {
|
||||
"name": "tabs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"category_id": {
|
||||
"name": "category_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"tabs_category_id_categories_id_fk": {
|
||||
"name": "tabs_category_id_categories_id_fk",
|
||||
"tableFrom": "tabs",
|
||||
"tableTo": "categories",
|
||||
"columnsFrom": [
|
||||
"category_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "''"
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"github_id": {
|
||||
"name": "github_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"github_token": {
|
||||
"name": "github_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_token": {
|
||||
"name": "google_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "(CURRENT_DATE)"
|
||||
"default": "''"
|
||||
},
|
||||
"private": {
|
||||
"name": "private",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"timezone": {
|
||||
"name": "timezone",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'undefined'"
|
||||
},
|
||||
"location": {
|
||||
"name": "location",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'undefined'"
|
||||
},
|
||||
"subscription": {
|
||||
"name": "subscription",
|
||||
"type": "subscription",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
"uniqueConstraints": {
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
},
|
||||
"users_github_id_unique": {
|
||||
"name": "users_github_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"github_id"
|
||||
]
|
||||
},
|
||||
"users_google_id_unique": {
|
||||
"name": "users_google_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"google_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
"enums": {
|
||||
"public.subscription": {
|
||||
"name": "subscription",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"paid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +1,357 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"id": "77aafe70-876c-4c45-84d6-5261fa288bae",
|
||||
"prevId": "a30470ea-8de9-4ff0-b0c9-d6b8a6264726",
|
||||
"id": "0550ff2a-d819-4a38-a515-915d5ef620a6",
|
||||
"prevId": "a8ec7e1e-1087-4ab5-be19-459dc9b0a4e0",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"users": {
|
||||
"name": "users",
|
||||
"public.categories": {
|
||||
"name": "categories",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"page_id": {
|
||||
"name": "page_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"categories_page_id_pages_id_fk": {
|
||||
"name": "categories_page_id_pages_id_fk",
|
||||
"tableFrom": "categories",
|
||||
"tableTo": "pages",
|
||||
"columnsFrom": [
|
||||
"page_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.pages": {
|
||||
"name": "pages",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"pages_user_id_users_id_fk": {
|
||||
"name": "pages_user_id_users_id_fk",
|
||||
"tableFrom": "pages",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.tabs": {
|
||||
"name": "tabs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"category_id": {
|
||||
"name": "category_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"tabs_category_id_categories_id_fk": {
|
||||
"name": "tabs_category_id_categories_id_fk",
|
||||
"tableFrom": "tabs",
|
||||
"tableTo": "categories",
|
||||
"columnsFrom": [
|
||||
"category_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "''"
|
||||
"notNull": true
|
||||
},
|
||||
"github_id": {
|
||||
"name": "github_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"github_token": {
|
||||
"name": "github_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_token": {
|
||||
"name": "google_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "''"
|
||||
},
|
||||
"private": {
|
||||
"name": "private",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": false
|
||||
},
|
||||
"timezone": {
|
||||
"name": "timezone",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'undefined'"
|
||||
},
|
||||
"location": {
|
||||
"name": "location",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'undefined'"
|
||||
},
|
||||
"subscription": {
|
||||
"name": "subscription",
|
||||
"type": "subscription",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": "(CURRENT_DATE)"
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
"uniqueConstraints": {
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
},
|
||||
"users_github_id_unique": {
|
||||
"name": "users_github_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"github_id"
|
||||
]
|
||||
},
|
||||
"users_google_id_unique": {
|
||||
"name": "users_google_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"google_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
"enums": {
|
||||
"public.subscription": {
|
||||
"name": "subscription",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"paid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
357
server/database/migrations/meta/0002_snapshot.json
Normal file
357
server/database/migrations/meta/0002_snapshot.json
Normal file
@@ -0,0 +1,357 @@
|
||||
{
|
||||
"id": "7d4e591a-f6c7-48eb-b9e8-e0e200bfea26",
|
||||
"prevId": "0550ff2a-d819-4a38-a515-915d5ef620a6",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.categories": {
|
||||
"name": "categories",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"page_id": {
|
||||
"name": "page_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"categories_page_id_pages_id_fk": {
|
||||
"name": "categories_page_id_pages_id_fk",
|
||||
"tableFrom": "categories",
|
||||
"tableTo": "pages",
|
||||
"columnsFrom": [
|
||||
"page_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.pages": {
|
||||
"name": "pages",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"pages_user_id_users_id_fk": {
|
||||
"name": "pages_user_id_users_id_fk",
|
||||
"tableFrom": "pages",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.tabs": {
|
||||
"name": "tabs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"category_id": {
|
||||
"name": "category_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"tabs_category_id_categories_id_fk": {
|
||||
"name": "tabs_category_id_categories_id_fk",
|
||||
"tableFrom": "tabs",
|
||||
"tableTo": "categories",
|
||||
"columnsFrom": [
|
||||
"category_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"github_id": {
|
||||
"name": "github_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"github_token": {
|
||||
"name": "github_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_token": {
|
||||
"name": "google_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"private": {
|
||||
"name": "private",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"timezone": {
|
||||
"name": "timezone",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'undefined'"
|
||||
},
|
||||
"location": {
|
||||
"name": "location",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'unknown'"
|
||||
},
|
||||
"subscription": {
|
||||
"name": "subscription",
|
||||
"type": "subscription",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'free'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
},
|
||||
"users_github_id_unique": {
|
||||
"name": "users_github_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"github_id"
|
||||
]
|
||||
},
|
||||
"users_google_id_unique": {
|
||||
"name": "users_google_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"google_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription": {
|
||||
"name": "subscription",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"paid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
364
server/database/migrations/meta/0003_snapshot.json
Normal file
364
server/database/migrations/meta/0003_snapshot.json
Normal file
@@ -0,0 +1,364 @@
|
||||
{
|
||||
"id": "d4ae60ba-5be1-4aa9-90d7-0690a599bf8e",
|
||||
"prevId": "7d4e591a-f6c7-48eb-b9e8-e0e200bfea26",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.categories": {
|
||||
"name": "categories",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"page_id": {
|
||||
"name": "page_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"categories_page_id_pages_id_fk": {
|
||||
"name": "categories_page_id_pages_id_fk",
|
||||
"tableFrom": "categories",
|
||||
"tableTo": "pages",
|
||||
"columnsFrom": [
|
||||
"page_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.pages": {
|
||||
"name": "pages",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"pages_user_id_users_id_fk": {
|
||||
"name": "pages_user_id_users_id_fk",
|
||||
"tableFrom": "pages",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.tabs": {
|
||||
"name": "tabs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"category_id": {
|
||||
"name": "category_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"tabs_category_id_categories_id_fk": {
|
||||
"name": "tabs_category_id_categories_id_fk",
|
||||
"tableFrom": "tabs",
|
||||
"tableTo": "categories",
|
||||
"columnsFrom": [
|
||||
"category_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"github_id": {
|
||||
"name": "github_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"github_token": {
|
||||
"name": "github_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_token": {
|
||||
"name": "google_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"private": {
|
||||
"name": "private",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"timezone": {
|
||||
"name": "timezone",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'undefined'"
|
||||
},
|
||||
"location": {
|
||||
"name": "location",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'unknown'"
|
||||
},
|
||||
"subscription": {
|
||||
"name": "subscription",
|
||||
"type": "subscription",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'free'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
},
|
||||
"users_github_id_unique": {
|
||||
"name": "users_github_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"github_id"
|
||||
]
|
||||
},
|
||||
"users_google_id_unique": {
|
||||
"name": "users_google_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"google_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription": {
|
||||
"name": "subscription",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"paid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
364
server/database/migrations/meta/0004_snapshot.json
Normal file
364
server/database/migrations/meta/0004_snapshot.json
Normal file
@@ -0,0 +1,364 @@
|
||||
{
|
||||
"id": "704c03b2-8d7f-47ce-a551-95289048c5f2",
|
||||
"prevId": "d4ae60ba-5be1-4aa9-90d7-0690a599bf8e",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.categories": {
|
||||
"name": "categories",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"page_id": {
|
||||
"name": "page_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"categories_page_id_pages_id_fk": {
|
||||
"name": "categories_page_id_pages_id_fk",
|
||||
"tableFrom": "categories",
|
||||
"tableTo": "pages",
|
||||
"columnsFrom": [
|
||||
"page_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.pages": {
|
||||
"name": "pages",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"pages_user_id_users_id_fk": {
|
||||
"name": "pages_user_id_users_id_fk",
|
||||
"tableFrom": "pages",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.tabs": {
|
||||
"name": "tabs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"category_id": {
|
||||
"name": "category_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"tabs_category_id_categories_id_fk": {
|
||||
"name": "tabs_category_id_categories_id_fk",
|
||||
"tableFrom": "tabs",
|
||||
"tableTo": "categories",
|
||||
"columnsFrom": [
|
||||
"category_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"github_id": {
|
||||
"name": "github_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"github_token": {
|
||||
"name": "github_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_token": {
|
||||
"name": "google_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"private": {
|
||||
"name": "private",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"language": {
|
||||
"name": "language",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'english'"
|
||||
},
|
||||
"location": {
|
||||
"name": "location",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'unknown'"
|
||||
},
|
||||
"subscription": {
|
||||
"name": "subscription",
|
||||
"type": "subscription",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'free'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
},
|
||||
"users_github_id_unique": {
|
||||
"name": "users_github_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"github_id"
|
||||
]
|
||||
},
|
||||
"users_google_id_unique": {
|
||||
"name": "users_google_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"google_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription": {
|
||||
"name": "subscription",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"paid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
364
server/database/migrations/meta/0005_snapshot.json
Normal file
364
server/database/migrations/meta/0005_snapshot.json
Normal file
@@ -0,0 +1,364 @@
|
||||
{
|
||||
"id": "e891a8e0-61c1-4351-90fe-caace29457a8",
|
||||
"prevId": "704c03b2-8d7f-47ce-a551-95289048c5f2",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.categories": {
|
||||
"name": "categories",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"page_id": {
|
||||
"name": "page_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"categories_page_id_pages_id_fk": {
|
||||
"name": "categories_page_id_pages_id_fk",
|
||||
"tableFrom": "categories",
|
||||
"tableTo": "pages",
|
||||
"columnsFrom": [
|
||||
"page_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.pages": {
|
||||
"name": "pages",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"pages_user_id_users_id_fk": {
|
||||
"name": "pages_user_id_users_id_fk",
|
||||
"tableFrom": "pages",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.tabs": {
|
||||
"name": "tabs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"name_visible": {
|
||||
"name": "name_visible",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"icon": {
|
||||
"name": "icon",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'i-ph:circle-wavy-question-duotone'"
|
||||
},
|
||||
"color": {
|
||||
"name": "color",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'gray'"
|
||||
},
|
||||
"category_id": {
|
||||
"name": "category_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"tabs_category_id_categories_id_fk": {
|
||||
"name": "tabs_category_id_categories_id_fk",
|
||||
"tableFrom": "tabs",
|
||||
"tableTo": "categories",
|
||||
"columnsFrom": [
|
||||
"category_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true
|
||||
},
|
||||
"username": {
|
||||
"name": "username",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"github_id": {
|
||||
"name": "github_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"github_token": {
|
||||
"name": "github_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_token": {
|
||||
"name": "google_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"description": {
|
||||
"name": "description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"avatar": {
|
||||
"name": "avatar",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"private": {
|
||||
"name": "private",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"language": {
|
||||
"name": "language",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'en-EN'"
|
||||
},
|
||||
"location": {
|
||||
"name": "location",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'unknown'"
|
||||
},
|
||||
"subscription": {
|
||||
"name": "subscription",
|
||||
"type": "subscription",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'free'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "timestamp (3)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"users_email_unique": {
|
||||
"name": "users_email_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"email"
|
||||
]
|
||||
},
|
||||
"users_github_id_unique": {
|
||||
"name": "users_github_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"github_id"
|
||||
]
|
||||
},
|
||||
"users_google_id_unique": {
|
||||
"name": "users_google_id_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"google_id"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription": {
|
||||
"name": "subscription",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"paid"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,48 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "sqlite",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "6",
|
||||
"when": 1724341642346,
|
||||
"tag": "0000_salty_thena",
|
||||
"version": "7",
|
||||
"when": 1724455773734,
|
||||
"tag": "0000_wild_luke_cage",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "6",
|
||||
"when": 1724343948344,
|
||||
"tag": "0001_medical_joshua_kane",
|
||||
"version": "7",
|
||||
"when": 1724455851539,
|
||||
"tag": "0001_goofy_dormammu",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1724456130150,
|
||||
"tag": "0002_slim_whistler",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1724528975297,
|
||||
"tag": "0003_curious_solo",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1724531645621,
|
||||
"tag": "0004_sharp_shocker",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1724532003950,
|
||||
"tag": "0005_tense_the_order",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,75 @@
|
||||
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
|
||||
import { sql } from 'drizzle-orm'
|
||||
import { boolean, integer, pgEnum, pgTable, text } from 'drizzle-orm/pg-core'
|
||||
import { relations } from 'drizzle-orm'
|
||||
import { id, timestamps } from '../utils/dbFields'
|
||||
import { Subscription } from '../../types/types'
|
||||
|
||||
export const users = sqliteTable('users', {
|
||||
id: integer('id').primaryKey(),
|
||||
name: text('name').default(''),
|
||||
email: text('email').default(''),
|
||||
export const subscriptionEnum = pgEnum('subscription', Subscription)
|
||||
|
||||
export const users = pgTable('users', {
|
||||
id,
|
||||
username: text('username').notNull(),
|
||||
name: text('name').notNull(),
|
||||
email: text('email').notNull().unique(),
|
||||
githubId: text('github_id').unique(),
|
||||
githubToken: text('github_token'),
|
||||
googleId: text('google_id').unique(),
|
||||
googleToken: text('google_token'),
|
||||
description: text('description').default(''),
|
||||
createdAt: text('created_at').default(sql`(CURRENT_DATE)`),
|
||||
avatar: text('avatar').default(''),
|
||||
private: boolean('private').default(false),
|
||||
language: text('language').default('en-EN'),
|
||||
location: text('location').default('unknown'),
|
||||
subscription: subscriptionEnum('subscription').default('free'),
|
||||
...timestamps,
|
||||
})
|
||||
|
||||
export const pages = pgTable('pages', {
|
||||
id,
|
||||
userId: integer('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
...timestamps,
|
||||
})
|
||||
|
||||
export const categories = pgTable('categories', {
|
||||
id,
|
||||
name: text('name').default(''),
|
||||
nameVisible: boolean('name_visible').default(true),
|
||||
icon: text('icon').default('i-ph:circle-wavy-question-duotone'),
|
||||
color: text('color').default('gray'),
|
||||
pageId: integer('page_id')
|
||||
.notNull()
|
||||
.references(() => pages.id, { onDelete: 'cascade' }),
|
||||
...timestamps,
|
||||
})
|
||||
|
||||
export const tabs = pgTable('tabs', {
|
||||
id,
|
||||
name: text('name').default(''),
|
||||
nameVisible: boolean('name_visible').default(true),
|
||||
icon: text('icon').default('i-ph:circle-wavy-question-duotone'),
|
||||
color: text('color').default('gray'),
|
||||
categoryId: integer('category_id')
|
||||
.notNull()
|
||||
.references(() => categories.id, { onDelete: 'cascade' }),
|
||||
...timestamps,
|
||||
})
|
||||
|
||||
export const usersRelations = relations(users, ({ one }) => ({
|
||||
page: one(pages, {
|
||||
fields: [users.id],
|
||||
references: [pages.userId],
|
||||
}),
|
||||
}))
|
||||
|
||||
export const pagesRelations = relations(pages, ({ many }) => ({
|
||||
categories: many(categories),
|
||||
}))
|
||||
|
||||
export const categoriesRelations = relations(categories, ({ one, many }) => ({
|
||||
page: one(pages, {
|
||||
fields: [categories.pageId],
|
||||
references: [pages.id],
|
||||
}),
|
||||
tabs: many(tabs),
|
||||
}))
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import { consola } from 'consola'
|
||||
import { migrate } from 'drizzle-orm/d1/migrator'
|
||||
|
||||
export default defineNitroPlugin(async () => {
|
||||
if (!import.meta.dev)
|
||||
return
|
||||
|
||||
onHubReady(async () => {
|
||||
await migrate(useDB(), { migrationsFolder: 'server/database/migrations' })
|
||||
.then(() => {
|
||||
consola.success('Database migrations done')
|
||||
})
|
||||
.catch((err) => {
|
||||
consola.error('Database migrations failed', err)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -2,17 +2,85 @@ export default oauthGitHubEventHandler({
|
||||
config: {
|
||||
emailRequired: true,
|
||||
},
|
||||
async onSuccess(event, { user }) {
|
||||
await setUserSession(event, {
|
||||
user: {
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
},
|
||||
async onSuccess(event, { user: oauthUser, tokens }) {
|
||||
const userSession = await getUserSession(event)
|
||||
|
||||
// If the user is already signed in, link the account
|
||||
if (userSession?.id) {
|
||||
const user = await findUserById(userSession.id)
|
||||
|
||||
if (user) {
|
||||
await updateUser(userSession.id, {
|
||||
githubId: oauthUser.id,
|
||||
githubToken: tokens.access_token,
|
||||
})
|
||||
|
||||
await setUserSession(event, {
|
||||
id: userSession.id,
|
||||
user: userSession,
|
||||
githubId: oauthUser.id,
|
||||
})
|
||||
|
||||
return sendRedirect(event, '/')
|
||||
}
|
||||
}
|
||||
|
||||
// If the user is not signed in, search for an existing user with that GitHub ID
|
||||
// If it exists, sign in as that user and refresh the token
|
||||
let user = await findUserByGitHubId(oauthUser.id)
|
||||
|
||||
if (user) {
|
||||
await updateUser(user.id, {
|
||||
githubId: oauthUser.id,
|
||||
githubToken: tokens.access_token,
|
||||
})
|
||||
|
||||
await setUserSession(event, {
|
||||
id: user.id,
|
||||
user,
|
||||
})
|
||||
|
||||
return sendRedirect(event, '/')
|
||||
}
|
||||
|
||||
// If the user is not signed in, search for an existing user with that email address without a GitHub ID
|
||||
// If it exists, tells the user to sign in with that account and link the GitHub account
|
||||
user = await findUserBy(
|
||||
and(
|
||||
eq(tables.users.email, oauthUser.email),
|
||||
isNull(tables.users.githubId),
|
||||
),
|
||||
)
|
||||
|
||||
if (user) {
|
||||
await updateSession(event, {
|
||||
password: useRuntimeConfig(event).session.password,
|
||||
}, {
|
||||
message: 'An existing account for this email already exists. Please login and visit your profile settings to add support for GitHub authentication.',
|
||||
})
|
||||
return sendRedirect(event, '/login')
|
||||
}
|
||||
|
||||
// If the user is not signed in and no user exists with that GitHub ID or email address, create a new user
|
||||
const createdUser = await createUser({
|
||||
username: oauthUser.login as string,
|
||||
description: oauthUser.bio as string,
|
||||
name: oauthUser.name as string,
|
||||
email: oauthUser.email as string,
|
||||
avatar: oauthUser.avatar_url as string,
|
||||
githubId: oauthUser.id as number,
|
||||
githubToken: tokens.access_token as string,
|
||||
language: 'en-US',
|
||||
location: 'unknown',
|
||||
private: false,
|
||||
subscription: 'free',
|
||||
})
|
||||
return sendRedirect(event, '/home')
|
||||
},
|
||||
onError(event, error) {
|
||||
console.error('GitHub OAuth error:', error)
|
||||
|
||||
await setUserSession(event, {
|
||||
id: createdUser.id,
|
||||
user: createdUser,
|
||||
})
|
||||
|
||||
return sendRedirect(event, '/')
|
||||
},
|
||||
})
|
||||
|
||||
@@ -2,17 +2,85 @@ export default oauthGoogleEventHandler({
|
||||
config: {
|
||||
emailRequired: true,
|
||||
},
|
||||
async onSuccess(event, { user }) {
|
||||
await setUserSession(event, {
|
||||
user: {
|
||||
email: user.email,
|
||||
name: user.name,
|
||||
},
|
||||
async onSuccess(event, { user: oauthUser, tokens }) {
|
||||
const userSession = await getUserSession(event)
|
||||
|
||||
// If the user is already signed in, link the account
|
||||
if (userSession?.id) {
|
||||
const user = await findUserById(userSession.id)
|
||||
|
||||
if (user) {
|
||||
await updateUser(userSession.id, {
|
||||
googleId: oauthUser.sub,
|
||||
googleToken: tokens.access_token,
|
||||
})
|
||||
|
||||
await replaceUserSession(event, {
|
||||
id: userSession.id,
|
||||
user: userSession,
|
||||
googleId: oauthUser.sub,
|
||||
})
|
||||
|
||||
return sendRedirect(event, '/')
|
||||
}
|
||||
}
|
||||
|
||||
// If the user is not signed in, search for an existing user with that Google ID
|
||||
// If it exists, sign in as that user and refresh the token
|
||||
let user = await findUserByGoogleId(oauthUser.sub)
|
||||
|
||||
if (user) {
|
||||
await updateUser(user.id, {
|
||||
googleId: oauthUser.sub,
|
||||
googleToken: tokens.access_token,
|
||||
})
|
||||
|
||||
await replaceUserSession(event, {
|
||||
id: user.id,
|
||||
user,
|
||||
})
|
||||
|
||||
return sendRedirect(event, '/')
|
||||
}
|
||||
|
||||
// If the user is not signed in, search for an existing user with that email address without a Google ID
|
||||
// If it exists, tells the user to sign in with that account and link the Google account
|
||||
user = await findUserBy(
|
||||
and(
|
||||
eq(tables.users.email, oauthUser.email),
|
||||
isNull(tables.users.googleId),
|
||||
),
|
||||
)
|
||||
|
||||
if (user) {
|
||||
await updateSession(event, {
|
||||
password: useRuntimeConfig(event).session.password,
|
||||
}, {
|
||||
message: 'An existing account for this email already exists. Please login and visit your profile settings to add support for Google authentication.',
|
||||
})
|
||||
return sendRedirect(event, '/login')
|
||||
}
|
||||
|
||||
// If the user is not signed in and no user exists with that Google ID or email address, create a new user
|
||||
const createdUser = await createUser({
|
||||
username: oauthUser.name as string,
|
||||
description: '',
|
||||
name: `${oauthUser.given_name} ${oauthUser.family_name}`,
|
||||
email: oauthUser.email as string,
|
||||
avatar: oauthUser.picture as string,
|
||||
googleId: oauthUser.sub as number,
|
||||
googleToken: tokens.access_token as string,
|
||||
language: 'en-US',
|
||||
location: 'unknown',
|
||||
private: false,
|
||||
subscription: 'free',
|
||||
})
|
||||
return sendRedirect(event, '/home')
|
||||
},
|
||||
onError(event, error) {
|
||||
console.error('Google OAuth error:', error)
|
||||
|
||||
await replaceUserSession(event, {
|
||||
id: createdUser.id,
|
||||
user: createdUser,
|
||||
})
|
||||
|
||||
return sendRedirect(event, '/')
|
||||
},
|
||||
})
|
||||
|
||||
5
server/routes/images/[...pathname].ts
Normal file
5
server/routes/images/[...pathname].ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default eventHandler(async (event) => {
|
||||
const { pathname } = getRouterParams(event)
|
||||
|
||||
return hubBlob().serve(event, pathname)
|
||||
})
|
||||
@@ -1,10 +1,18 @@
|
||||
import { drizzle } from 'drizzle-orm/d1'
|
||||
import postgres from 'postgres'
|
||||
import { drizzle } from 'drizzle-orm/postgres-js'
|
||||
import * as schema from '../database/schema'
|
||||
|
||||
export { sql, eq, and, or, asc, desc, sum } from 'drizzle-orm'
|
||||
export { sql, eq, and, or, asc, desc, sum, isNull } from 'drizzle-orm'
|
||||
|
||||
export const tables = schema
|
||||
|
||||
export function useDB() {
|
||||
return drizzle(hubDatabase(), { schema })
|
||||
export function useDrizzle() {
|
||||
const config = useRuntimeConfig()
|
||||
return drizzle(postgres(config.postgres.url, { prepare: false }), { schema })
|
||||
}
|
||||
|
||||
export type UserType = typeof schema.users.$inferSelect
|
||||
export type UserInsert = typeof schema.users.$inferInsert
|
||||
|
||||
export type TabType = typeof schema.tabs.$inferSelect
|
||||
export type CategoryType = typeof schema.categories.$inferSelect
|
||||
|
||||
20
server/utils/dbFields.ts
Normal file
20
server/utils/dbFields.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import * as pg from 'drizzle-orm/pg-core'
|
||||
|
||||
/**
|
||||
* A centralized list of standardized Drizzle ORM schema field definitions to prevent duplication errors
|
||||
*/
|
||||
|
||||
export const createdAt = pg
|
||||
.timestamp('created_at', { mode: 'date', precision: 3 })
|
||||
.defaultNow()
|
||||
|
||||
export const updatedAt = pg
|
||||
.timestamp('updated_at', { mode: 'date', precision: 3 })
|
||||
.$onUpdate(() => new Date())
|
||||
|
||||
export const id = pg.integer('id').primaryKey({ autoIncrement: true })
|
||||
|
||||
export const timestamps = {
|
||||
createdAt,
|
||||
updatedAt,
|
||||
}
|
||||
58
server/utils/users.ts
Normal file
58
server/utils/users.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import type { SQL } from 'drizzle-orm'
|
||||
import type { UserInsert } from '~~/server/utils/db'
|
||||
|
||||
export async function findUserById(userId: number) {
|
||||
return useDrizzle()
|
||||
.query
|
||||
.users
|
||||
.findFirst({
|
||||
where: eq(tables.users.id, userId),
|
||||
})
|
||||
}
|
||||
|
||||
export async function findUserByGitHubId(githubId: number) {
|
||||
return useDrizzle()
|
||||
.query
|
||||
.users
|
||||
.findFirst({
|
||||
where: eq(tables.users.githubId, githubId),
|
||||
})
|
||||
}
|
||||
|
||||
export async function findUserByGoogleId(googleId: string) {
|
||||
return useDrizzle()
|
||||
.query
|
||||
.users
|
||||
.findFirst({
|
||||
where: eq(tables.users.googleId, googleId),
|
||||
})
|
||||
}
|
||||
|
||||
export async function findUserBy(query: SQL | undefined) {
|
||||
return useDrizzle()
|
||||
.query
|
||||
.users
|
||||
.findFirst({
|
||||
where: query,
|
||||
})
|
||||
}
|
||||
|
||||
export async function createUser(user: UserInsert) {
|
||||
return useDrizzle()
|
||||
.insert(tables.users)
|
||||
.values(user)
|
||||
.returning()
|
||||
}
|
||||
|
||||
export async function updateUser(userId: number, user: Partial<UserInsert>) {
|
||||
return useDrizzle()
|
||||
.update(tables.users)
|
||||
.set(user)
|
||||
.where(eq(tables.users.id, userId))
|
||||
}
|
||||
|
||||
export async function deleteProfilePicture(avatar: string) {
|
||||
if (avatar.startsWith('profile-pictures/')) {
|
||||
await hubBlob().delete(avatar)
|
||||
}
|
||||
}
|
||||
26
types/auth.d.ts
vendored
26
types/auth.d.ts
vendored
@@ -1,13 +1,35 @@
|
||||
// auth.d.ts
|
||||
import type { Subscription } from '~~/types/types'
|
||||
|
||||
declare module '#auth-utils' {
|
||||
interface User {
|
||||
email: string
|
||||
id: number
|
||||
name: string
|
||||
username: string
|
||||
email: string
|
||||
avatar: string | null
|
||||
githubId?: number | null
|
||||
googleId?: string | null
|
||||
description: string
|
||||
private: boolean
|
||||
language: string
|
||||
location: string
|
||||
subscription: Subscription
|
||||
}
|
||||
|
||||
interface UserSession {
|
||||
email: string
|
||||
id: number
|
||||
name: string
|
||||
username: string
|
||||
email: string
|
||||
avatar: string | null
|
||||
githubId?: number | null
|
||||
googleId?: string | null
|
||||
description: string
|
||||
private: boolean
|
||||
language: string
|
||||
location: string
|
||||
subscription: Subscription
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import type { ParsedContent } from '@nuxt/content'
|
||||
|
||||
export const Subscription = ['free', 'paid'] as const
|
||||
|
||||
// todo: delete
|
||||
export interface AppType extends ParsedContent {
|
||||
primary?: boolean
|
||||
name: string
|
||||
|
||||
Reference in New Issue
Block a user