Skip to content

Commit

Permalink
chore: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
atinux committed Jan 24, 2024
1 parent b5684a3 commit c475cde
Show file tree
Hide file tree
Showing 16 changed files with 138 additions and 235 deletions.
File renamed without changes.
3 changes: 3 additions & 0 deletions _nuxtflare/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default defineNuxtConfig({

})
27 changes: 27 additions & 0 deletions _nuxtflare/server/api/_hub/database/query.post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { z } from 'zod'

export default eventHandler(async (event) => {
const { sql, params, method } = await readValidatedBody(event, z.object({
sql: z.string(),
params: z.array(z.any()),
method: z.enum(['all', 'get', 'run', 'values'])
}).parse)

// Make sure the client is initialized first
useDatabase()
const client = useDatabaseClient()

try {
if (method === 'run')
return client.prepare(sql).run(params)
if (method === 'all' || method === 'values')
return client.prepare(sql).raw().all(params)
// method = 'get'
return client.prepare(sql).raw().get(params)
} catch (e: any) {
throw createError({
statusCode: 500,
message: `Database error: ${e.message}`
})
}
})
56 changes: 56 additions & 0 deletions _nuxtflare/server/utils/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { drizzle as drizzleD1, DrizzleD1Database } from 'drizzle-orm/d1'
import { drizzle } from 'drizzle-orm/better-sqlite3'
import type { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3'
import { drizzle as drizzleHTTP } from 'drizzle-orm/sqlite-proxy'
import type { SqliteRemoteDatabase } from 'drizzle-orm/sqlite-proxy'
import { ofetch } from 'ofetch'
// @ts-ignore
import Database from 'better-sqlite3'
import { join } from 'pathe'

// export * as tables from '~/server/database/schema'

let _db: DrizzleD1Database | BetterSQLite3Database | SqliteRemoteDatabase | null = null
let _client: any = null

export const useDatabase = () => {
if (!_db) {
const isDev = process.env.NODE_ENV === 'development'
if (process.env.DB) {
// d1 in production
_client = process.env.DB
_db = drizzleD1(_client)
} else if (isDev && process.env.NUXT_HUB_URL) {
console.log('Using D1 remote database...')
_db = drizzleHTTP(async (sql, params, method) => {
// https://orm.drizzle.team/docs/get-started-sqlite#http-proxy
try {
const rows = await ofetch('/api/db/query', {
baseURL: process.env.NUXT_HUB_URL,
method: 'POST',
body: { sql, params, method }
})
return { rows }
} catch (err) {
console.error('Error from remote database', err)
return { rows: [] }
}
})
} else if (isDev) {
// local sqlite in development
console.log('Using local database...')
_client = new Database(join(process.cwd(), './db.sqlite'))
_db = drizzle(_client)
} else {
throw new Error('No database configured for production')
}
}
return _db
}

export const useDatabaseClient = () => {
if (!_client) {
throw new Error('No client configured')
}
return _client
}
20 changes: 2 additions & 18 deletions app.config.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,6 @@
export default defineAppConfig({
ui: {
primary: 'emerald',
container: {
constrained: 'max-w-2xl'
},
card: {
header: {
base: 'flex flex-wrap items-center justify-between'
},
body: {
base: 'space-y-4'
}
},
dropdown: {
width: 'w-full',
popper: {
strategy: 'absolute'
}
}
primary: 'lime',
gray: 'neutral'
}
})
81 changes: 21 additions & 60 deletions app.vue
Original file line number Diff line number Diff line change
@@ -1,70 +1,31 @@
<script setup>
const { loggedIn } = useUserSession()
<script setup lang="ts">
const colorMode = useColorMode()
watch(loggedIn, () => {
if (!loggedIn.value) {
navigateTo('/')
}
})
function toggleColorMode() {
colorMode.preference = colorMode.preference === 'dark' ? 'light' : 'dark'
}
const color = computed(() => colorMode.value === 'dark' ? '#111827' : 'white')
useHead({
htmlAttrs: { lang: 'en' },
link: [{ rel: 'icon', href: '/icon.png' }],
})
useSeoMeta({
viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
title: 'Nuxt Todos Edge',
description:
'A Nuxt demo hosted with Edge-side rendering, authentication and queyring a SQLite database',
ogImage: '/social-image.png',
twitterImage: '/social-image.png',
twitterCard: 'summary_large_image',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ key: 'theme-color', name: 'theme-color', content: color }
],
link: [
{ rel: 'icon', href: '/favicon.ico' }
],
htmlAttrs: {
lang: 'en'
}
})
</script>

<template>
<UContainer class="min-h-screen flex flex-col justify-center">
<div class="mb-2 text-right">
<UButton
square
variant="ghost"
color="black"
:icon="$colorMode.preference === 'dark' ? 'i-heroicons-moon' : 'i-heroicons-sun'"
@click="toggleColorMode"
/>
</div>

<NuxtPage />
<div>
<NuxtLoadingIndicator />

<footer class="text-center mt-2">
<NuxtLink
href="https://github.com/atinux/nuxt-todos-edge"
target="_blank"
class="text-sm text-gray-500 hover:text-gray-700"
>
GitHub
</NuxtLink>
·
<NuxtLink
href="https://twitter.com/Atinux"
target="_blank"
class="text-sm text-gray-500 hover:text-gray-700"
>
Twitter
</NuxtLink>
</footer>
</UContainer>
<UNotifications />
</template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>

<style lang="postcss">
body {
@apply font-sans text-gray-950 bg-gray-50 dark:bg-gray-950 dark:text-gray-50;
}
</style>
<UNotifications />
</div>
</template>
5 changes: 5 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
export default defineNuxtConfig({
devtools: { enabled: true },
// extends: '@nuxt/ui-pro',
extends: [
'/Users/atinux/Projects/nuxt/ui-pro',
'./_nuxtflare'
],
modules: [
'@nuxt/ui',
'nuxt-auth-utils'
Expand Down
117 changes: 0 additions & 117 deletions pages/todos.vue

This file was deleted.

18 changes: 18 additions & 0 deletions server/api/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { sql } from 'drizzle-orm'

export default defineEventHandler(async (event) => {
const db = useDatabase()

const rows = await db.all(sql`
SELECT
name
FROM
sqlite_schema
WHERE
type = 'table' AND
name NOT LIKE 'sqlite_%' and name NOT LIKE '_litestream_%' and name NOT LIKE '__drizzle%'
;
`)

return rows
})
2 changes: 1 addition & 1 deletion server/api/todos/[id].delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default eventHandler(async (event) => {
const session = await requireUserSession(event)

// List todos for the current user
const deletedTodo = await useDB().delete(tables.todos).where(and(
const deletedTodo = await useDatabase().delete(tables.todos).where(and(
eq(tables.todos.id, id),
eq(tables.todos.userId, session.user.id)
)).returning().get()
Expand Down
2 changes: 1 addition & 1 deletion server/api/todos/[id].patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default eventHandler(async (event) => {
const session = await requireUserSession(event)

// List todos for the current user
const todo = await useDB().update(tables.todos).set({
const todo = await useDatabase().update(tables.todos).set({
completed
}).where(and(
eq(tables.todos.id, id),
Expand Down
2 changes: 1 addition & 1 deletion server/api/todos/index.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default eventHandler(async (event) => {
const session = await requireUserSession(event)

// List todos for the current user
const todos = await useDB().select().from(tables.todos).where(eq(tables.todos.userId, session.user.id)).all()
const todos = await useDatabase().select().from(tables.todos).where(eq(tables.todos.userId, session.user.id)).all()

return todos
})
2 changes: 1 addition & 1 deletion server/api/todos/index.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default eventHandler(async (event) => {
const session = await requireUserSession(event)

// List todos for the current user
const todo = await useDB().insert(tables.todos).values({
const todo = await useDatabase().insert(tables.todos).values({
userId: session.user.id,
title,
createdAt: new Date()
Expand Down
Loading

0 comments on commit c475cde

Please sign in to comment.