From 4e941af5fbc0ef17737df2b2348d8b5e529f0ae1 Mon Sep 17 00:00:00 2001 From: bholmesdev Date: Thu, 11 Jan 2024 15:40:36 -0500 Subject: [PATCH] refactor: move dev to use filesystem to run seed at right time --- packages/db/src/integration.ts | 19 +++++------ packages/db/src/internal.ts | 55 ++++++++++++++----------------- packages/db/src/vite-plugin-db.ts | 37 +++------------------ 3 files changed, 38 insertions(+), 73 deletions(-) diff --git a/packages/db/src/integration.ts b/packages/db/src/integration.ts index eeaacc82f9..cfc292f27f 100644 --- a/packages/db/src/integration.ts +++ b/packages/db/src/integration.ts @@ -3,29 +3,29 @@ import { vitePluginDb } from './vite-plugin-db.js'; import { vitePluginInjectEnvTs } from './vite-plugin-inject-env-ts.js'; import { typegen } from './typegen.js'; import { collectionsSchema } from './types.js'; -import { seed } from './seed.js'; import { existsSync } from 'fs'; import { rm } from 'fs/promises'; import { getDbUrl } from './consts.js'; +import { createDb, setupDbTables } from './internal.js'; export function integration(): AstroIntegration { return { name: 'astro:db', hooks: { - async 'astro:config:setup'({ updateConfig, config, command }) { + async 'astro:config:setup'({ logger, updateConfig, config, command }) { if (command === 'preview') return; // TODO: refine where we load collections // @matthewp: may want to load collections by path at runtime const collections = collectionsSchema.parse(config.db?.collections ?? {}); - const isDev = command === 'dev'; - if (command === 'build') { - const dbUrl = getDbUrl(config.root); - if (existsSync(dbUrl)) { - await rm(dbUrl); - } - await seed({ collections, root: config.root }); + const dbUrl = getDbUrl(config.root); + if (existsSync(dbUrl)) { + await rm(dbUrl); } + const db = await createDb({ dbUrl: dbUrl.href }); + await setupDbTables({ db, collections, logger }); + logger.info('Collections set up 🚀'); + updateConfig({ vite: { plugins: [ @@ -34,7 +34,6 @@ export function integration(): AstroIntegration { vitePluginDb({ collections, root: config.root, - isDev, }), // @ts-ignore vitePluginInjectEnvTs(config), diff --git a/packages/db/src/internal.ts b/packages/db/src/internal.ts index 43460e70ad..a77f571eac 100644 --- a/packages/db/src/internal.ts +++ b/packages/db/src/internal.ts @@ -24,6 +24,7 @@ import { } from 'drizzle-orm/sqlite-core'; import { z } from 'zod'; import { nanoid } from 'nanoid'; +import type { AstroIntegrationLogger } from 'astro'; export type SqliteDB = SqliteRemoteDatabase; export type { @@ -38,25 +39,21 @@ export type { const sqlite = new SQLiteAsyncDialect(); -export async function createDb({ - collections, - dbUrl, - createTables = false, -}: { - collections: DBCollections; - dbUrl: string; - createTables?: boolean; -}) { +export async function createDb({ dbUrl }: { dbUrl: string }) { const client = createClient({ url: dbUrl }); const db = drizzle(client); - - if (createTables) { - await createDbTables(db, collections); - } return db; } -async function createDbTables(db: LibSQLDatabase, collections: DBCollections) { +export async function setupDbTables({ + db, + collections, + logger, +}: { + db: LibSQLDatabase; + collections: DBCollections; + logger: AstroIntegrationLogger; +}) { const setupQueries: SQL[] = []; for (const [name, collection] of Object.entries(collections)) { const dropQuery = sql.raw(`DROP TABLE IF EXISTS ${name}`); @@ -66,6 +63,20 @@ async function createDbTables(db: LibSQLDatabase, collections: DBCollections) { for (const q of setupQueries) { await db.run(q); } + for (const [name, collection] of Object.entries(collections)) { + if (!collection.data) continue; + + const table = collectionToTable(name, collection); + try { + await db.insert(table).values(await collection.data()); + } catch (e) { + logger.error( + `Failed to seed ${bold( + name + )} data. Did you update to match recent schema changes? Full error:\n\n${e}` + ); + } + } } export function getCreateTableQuery(collectionName: string, collection: DBCollection) { @@ -83,22 +94,6 @@ export function getCreateTableQuery(collectionName: string, collection: DBCollec return query; } -export async function executeCollectionDataFn({ - db, - collectionName, - collection, -}: { - db: LibSQLDatabase; - collectionName: string; - collection: DBCollection; -}) { - const { data } = collection; - if (!data) return; - - const table = collectionToTable(collectionName, collection); - await db.insert(table).values(await data()); -} - function schemaTypeToSqlType(type: FieldType): 'text' | 'integer' { switch (type) { case 'date': diff --git a/packages/db/src/vite-plugin-db.ts b/packages/db/src/vite-plugin-db.ts index e251701478..fd3647bc58 100644 --- a/packages/db/src/vite-plugin-db.ts +++ b/packages/db/src/vite-plugin-db.ts @@ -1,13 +1,5 @@ import { existsSync } from 'node:fs'; -import { fileURLToPath } from 'node:url'; -import { red } from 'kleur/colors'; -import { - DRIZZLE_MOD_IMPORT, - INTERNAL_MOD_IMPORT, - SUPPORTED_SEED_FILES, - VIRTUAL_MODULE_ID, - getDbUrl, -} from './consts.js'; +import { DRIZZLE_MOD_IMPORT, INTERNAL_MOD_IMPORT, VIRTUAL_MODULE_ID, getDbUrl } from './consts.js'; import type { DBCollections } from './types.js'; import type { Plugin as VitePlugin } from 'vite'; @@ -16,11 +8,9 @@ const resolvedVirtualModuleId = '\0' + VIRTUAL_MODULE_ID; export function vitePluginDb({ collections, root, - isDev, }: { collections: DBCollections; root: URL; - isDev: boolean; }): VitePlugin { return { name: 'astro:db', @@ -32,29 +22,20 @@ export function vitePluginDb({ }, load(id) { if (id !== resolvedVirtualModuleId) return; - return getVirtualModContents({ collections, root, isDev }); + return getVirtualModContents({ collections, root }); }, }; } -const seedErrorMessage = `${red( - '⚠️ Failed to seed data.' -)} Is the seed file out-of-date with recent schema changes?`; - export function getVirtualModContents({ collections, root, - isDev, }: { collections: DBCollections; root: URL; - isDev: boolean; }) { - const seedFile = SUPPORTED_SEED_FILES.map((f) => fileURLToPath(new URL(f, root))).find((f) => - existsSync(f) - ); - const dbUrl = isDev ? ':memory:' : getDbUrl(root).href; - const shouldSetUpDb = isDev || !existsSync(getDbUrl(root)); + const dbUrl = getDbUrl(root).href; + const shouldSetUpDb = !existsSync(getDbUrl(root)); return ` import { collectionToTable, createDb } from ${INTERNAL_MOD_IMPORT}; @@ -66,16 +47,6 @@ export const db = await createDb(${JSON.stringify({ export * from ${DRIZZLE_MOD_IMPORT}; ${getStringifiedCollectionExports(collections)} - -${ - seedFile && isDev - ? `try { - await import(${JSON.stringify(seedFile)}); -} catch { - console.error(${JSON.stringify(seedErrorMessage)}); -}` - : '' -} `; }