Browse Source

feat(db): update SQLite configuration and seeding process

- Changed DATABASE_URL in .env.example to use SQLite file.
- Modified refresh function calls in AppShell.vue and public.vue to remove unnecessary parameter.
- Enhanced run.sh to include seeding script execution.
- Improved seed.js to ensure proper SQLite file path resolution and directory creation.
- Introduced db-bun.ts for Bun compatibility with SQLite.
- Updated db.ts to handle better-sqlite3 integration and path management.
- Adjusted paths.ts to ensure reliable package root resolution for production.
tags/邮箱功能前置
npmrun 4 days ago
parent
commit
81eeb29f54
  1. 7
      .env.example
  2. 2
      app/components/AppShell.vue
  3. 2
      app/layouts/public.vue
  4. 1
      build-files/run.sh
  5. 22
      build-files/seed.js
  6. 21
      packages/drizzle-pkg/database/sqlite/db-bun.ts
  7. 9
      packages/drizzle-pkg/database/sqlite/db.ts
  8. BIN
      packages/drizzle-pkg/db.sqlite
  9. 4
      packages/drizzle-pkg/lib/paths.ts
  10. 2
      packages/drizzle-pkg/seed.ts

7
.env.example

@ -1,5 +1,6 @@
DATABASE_URL=postgresql://postgres:xxxxxx@localhost:6666/postgres
# Optional: first admin for an empty instance. `bun run db:seed` creates an admin only when no user has role=admin yet (same username/password rules as registration).
# DATABASE_URL=postgresql://postgres:xxxxxx@localhost:6666/postgres
DATABASE_URL=file:./db.sqlite
NITRO_PORT=3399
# Optional: first admin for an empty instance. Creates an admin only when no user has role=admin yet (same username/password rules as registration).
BOOTSTRAP_ADMIN_USERNAME=
BOOTSTRAP_ADMIN_PASSWORD=

2
app/components/AppShell.vue

@ -17,7 +17,7 @@ const { allowRegister, siteName } = useGlobalConfig()
const logoutLoading = ref(false)
onMounted(() => {
refresh(true).catch(() => {})
refresh().catch(() => {})
})
const displayName = computed(() => {

2
app/layouts/public.vue

@ -65,7 +65,7 @@ function syncModeFromStorage() {
}
onMounted(() => {
refresh(true).catch(() => {})
refresh().catch(() => {})
syncModeFromStorage()
})

1
build-files/run.sh

@ -5,4 +5,5 @@ if [ -f .env ]; then
fi
node server/migrate-sqlite.js migrations
node server/seed.js
node server/index.mjs

22
build-files/seed.js

@ -8,6 +8,7 @@
*/
import Database from 'better-sqlite3'
import { hash } from 'bcryptjs'
import { mkdirSync } from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
@ -23,12 +24,25 @@ function derivePublicSlug(username) {
return PUBLIC_SLUG_REGEX.test(lower) ? lower : null
}
function openSqlite() {
const dbUrl = process.env.DATABASE_URL || ''
const sqlitePath = dbUrl.startsWith('file:') ? dbUrl.slice(5) : dbUrl
if (!sqlitePath) {
/**
* `migrate-sqlite.js` 一致相对路径相对 `process.cwd()`例如 `.output/run.sh` 下与迁移写入同一文件
* Nitro `resolveSqliteDatabaseUrl` 在无法锚定 drizzle-pkg 时也会回退到 cwd避免迁移/seed 成功服务 CANTOPEN
*/
function resolveSqliteFilePath(dbUrl) {
const stripped = dbUrl.startsWith('file:') ? dbUrl.slice('file:'.length) : dbUrl
if (!stripped) {
throw new Error('DATABASE_URL 未设置,且未提供有效的 SQLite 文件路径')
}
if (path.isAbsolute(stripped)) {
return stripped
}
return path.resolve(process.cwd(), stripped)
}
function openSqlite() {
const dbUrl = process.env.DATABASE_URL || ''
const sqlitePath = resolveSqliteFilePath(dbUrl)
mkdirSync(path.dirname(sqlitePath), { recursive: true })
return new Database(sqlitePath)
}

21
packages/drizzle-pkg/database/sqlite/db-bun.ts

@ -0,0 +1,21 @@
import { drizzle } from "drizzle-orm/bun-sqlite";
import { resolveSqliteDatabaseUrl } from "../../lib/resolve-sqlite-url";
/**
* Bun better-sqlite3 `bun run seed.ts` 使
* Nitro/Node `db.ts`better-sqlite3
*/
const rawUrl = process.env.DATABASE_URL;
if (!rawUrl) {
throw new Error("DATABASE_URL 未设置");
}
const resolvedUrl = resolveSqliteDatabaseUrl(rawUrl);
process.env.DATABASE_URL = resolvedUrl;
const sqlitePath = resolvedUrl.startsWith("file:")
? resolvedUrl.slice("file:".length)
: resolvedUrl;
const _db = drizzle(sqlitePath);
export { _db as dbGlobal };

9
packages/drizzle-pkg/database/sqlite/db.ts

@ -1,4 +1,4 @@
import { drizzle } from "drizzle-orm/libsql";
import { drizzle } from "drizzle-orm/better-sqlite3";
import { resolveSqliteDatabaseUrl } from "../../lib/resolve-sqlite-url";
if (process.env.NODE_ENV === "production") {
@ -13,6 +13,11 @@ if (!rawUrl) {
const resolvedUrl = resolveSqliteDatabaseUrl(rawUrl);
process.env.DATABASE_URL = resolvedUrl;
const _db = drizzle(resolvedUrl);
// better-sqlite3 需要裸文件路径;`file:` 前缀仍保留在 DATABASE_URL 供 drizzle-kit 等使用
const sqlitePath = resolvedUrl.startsWith("file:")
? resolvedUrl.slice("file:".length)
: resolvedUrl;
const _db = drizzle(sqlitePath);
export { _db as dbGlobal };

BIN
packages/drizzle-pkg/db.sqlite

Binary file not shown.

4
packages/drizzle-pkg/lib/paths.ts

@ -18,7 +18,7 @@ function isDrizzlePkgRoot(dir: string): boolean {
/**
* `drizzle-pkg` `package.json``db.sqlite`
* - `import.meta` cwd `file:db.sqlite` / DBMOVED
* - chunk 退 `cwd/packages/drizzle-pkg`使 `DATABASE_URL`
* - chunk 退 `cwd/packages/drizzle-pkg`退 `process.cwd()` `.output` migrate/seed `DATABASE_URL`
*/
export function getDrizzlePkgRoot(): string {
const fromMeta = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
@ -29,5 +29,5 @@ export function getDrizzlePkgRoot(): string {
if (isDrizzlePkgRoot(fromCwd)) {
return fromCwd;
}
return fromMeta;
return process.cwd();
}

2
packages/drizzle-pkg/seed.ts

@ -1,7 +1,7 @@
import "./env";
import { hash } from "bcryptjs";
import { eq, sql } from "drizzle-orm";
import { dbGlobal } from "./lib/db";
import { dbGlobal } from "./database/sqlite/db-bun";
import { users } from "./lib/schema/auth";
/** Match `server/service/auth/index.ts` */

Loading…
Cancel
Save