diff --git a/.changeset/bright-students-worry.md b/.changeset/bright-students-worry.md new file mode 100644 index 000000000000..c18caa130422 --- /dev/null +++ b/.changeset/bright-students-worry.md @@ -0,0 +1,16 @@ +--- +"@astrojs/db": minor +--- + +Changes the seed file format to require exporting a default function instead of running seed code at the top level. + +To migrate a seed file, wrap your existing code in a default function export: + +```diff +// db/seed.ts +import { db, Table } from 'astro:db'; + ++ export default async function() { + await db.insert(Table).values({ foo: 'bar' }); ++ } +``` diff --git a/packages/db/src/core/errors.ts b/packages/db/src/core/errors.ts index 4931b2bc5fcc..86f94b9bc60f 100644 --- a/packages/db/src/core/errors.ts +++ b/packages/db/src/core/errors.ts @@ -37,6 +37,13 @@ export const SEED_ERROR = (error: string) => { return `${red(`Error while seeding database:`)}\n\n${error}`; }; +export const SEED_DEFAULT_EXPORT_ERROR = (fileName: string) => { + return ( + red('Error while seeding database:') + + `\n\nMissing default function export in ${bold(fileName)}` + ); +}; + export const REFERENCE_DNE_ERROR = (columnName: string) => { return `Column ${bold( columnName diff --git a/packages/db/src/runtime/queries.ts b/packages/db/src/runtime/queries.ts index 63d04768b638..6a2aff99fd79 100644 --- a/packages/db/src/runtime/queries.ts +++ b/packages/db/src/runtime/queries.ts @@ -7,6 +7,7 @@ import { FOREIGN_KEY_REFERENCES_EMPTY_ERROR, FOREIGN_KEY_REFERENCES_LENGTH_ERROR, REFERENCE_DNE_ERROR, + SEED_DEFAULT_EXPORT_ERROR, SEED_ERROR, } from '../core/errors.js'; import type { @@ -35,19 +36,25 @@ export async function seedLocal({ }: { db: SqliteDB; tables: DBTables; - fileGlob: Record Promise>; + fileGlob: Record Promise<{ default?: () => Promise }>>; }) { await recreateTables({ db, tables }); for (const fileName of SEED_DEV_FILE_NAME) { const key = Object.keys(fileGlob).find((f) => f.endsWith(fileName)); if (key) { - await fileGlob[key]().catch((e) => { + try { + const mod = await fileGlob[key](); + if (!mod.default) { + throw new Error(SEED_DEFAULT_EXPORT_ERROR(key)); + } + await mod.default(); + } catch (e) { if (e instanceof LibsqlError) { throw new Error(SEED_ERROR(e.message)); } throw e; - }); - return; + } + break; } } } diff --git a/packages/db/test/fixtures/basics/db/seed.ts b/packages/db/test/fixtures/basics/db/seed.ts index 33d82d523782..86736c627666 100644 --- a/packages/db/test/fixtures/basics/db/seed.ts +++ b/packages/db/test/fixtures/basics/db/seed.ts @@ -2,18 +2,20 @@ import { asDrizzleTable } from '@astrojs/db/utils'; import { Themes as ThemesConfig } from './theme'; import { Author, db } from 'astro:db'; -const Themes = asDrizzleTable('Themes', ThemesConfig); +export default async function () { + const Themes = asDrizzleTable('Themes', ThemesConfig); -await db - .insert(Themes) - .values([{ name: 'dracula' }, { name: 'monokai', added: new Date() }]) - .returning({ name: Themes.name }); -await db - .insert(Author) - .values([ - { name: 'Ben' }, - { name: 'Nate' }, - { name: 'Erika' }, - { name: 'Bjorn' }, - { name: 'Sarah' }, - ]); + await db + .insert(Themes) + .values([{ name: 'dracula' }, { name: 'monokai', added: new Date() }]) + .returning({ name: Themes.name }); + await db + .insert(Author) + .values([ + { name: 'Ben' }, + { name: 'Nate' }, + { name: 'Erika' }, + { name: 'Bjorn' }, + { name: 'Sarah' }, + ]); +} diff --git a/packages/db/test/fixtures/recipes/db/seed.ts b/packages/db/test/fixtures/recipes/db/seed.ts index 7a4892376fde..1ca219f15bf8 100644 --- a/packages/db/test/fixtures/recipes/db/seed.ts +++ b/packages/db/test/fixtures/recipes/db/seed.ts @@ -1,60 +1,62 @@ import { Ingredient, Recipe, db } from 'astro:db'; -const pancakes = await db - .insert(Recipe) - .values({ - title: 'Pancakes', - description: 'A delicious breakfast', - }) - .returning() - .get(); +export default async function () { + const pancakes = await db + .insert(Recipe) + .values({ + title: 'Pancakes', + description: 'A delicious breakfast', + }) + .returning() + .get(); -await db.insert(Ingredient).values([ - { - name: 'Flour', - quantity: 1, - recipeId: pancakes.id, - }, - { - name: 'Eggs', - quantity: 2, - recipeId: pancakes.id, - }, - { - name: 'Milk', - quantity: 1, - recipeId: pancakes.id, - }, -]); + await db.insert(Ingredient).values([ + { + name: 'Flour', + quantity: 1, + recipeId: pancakes.id, + }, + { + name: 'Eggs', + quantity: 2, + recipeId: pancakes.id, + }, + { + name: 'Milk', + quantity: 1, + recipeId: pancakes.id, + }, + ]); -const pizza = await db - .insert(Recipe) - .values({ - title: 'Pizza', - description: 'A delicious dinner', - }) - .returning() - .get(); + const pizza = await db + .insert(Recipe) + .values({ + title: 'Pizza', + description: 'A delicious dinner', + }) + .returning() + .get(); -await db.insert(Ingredient).values([ - { - name: 'Flour', - quantity: 1, - recipeId: pizza.id, - }, - { - name: 'Eggs', - quantity: 2, - recipeId: pizza.id, - }, - { - name: 'Milk', - quantity: 1, - recipeId: pizza.id, - }, - { - name: 'Tomato Sauce', - quantity: 1, - recipeId: pizza.id, - }, -]); + await db.insert(Ingredient).values([ + { + name: 'Flour', + quantity: 1, + recipeId: pizza.id, + }, + { + name: 'Eggs', + quantity: 2, + recipeId: pizza.id, + }, + { + name: 'Milk', + quantity: 1, + recipeId: pizza.id, + }, + { + name: 'Tomato Sauce', + quantity: 1, + recipeId: pizza.id, + }, + ]); +} diff --git a/packages/db/test/fixtures/ticketing-example/db/seed.ts b/packages/db/test/fixtures/ticketing-example/db/seed.ts index c9789cbd666d..f68a0c85b098 100644 --- a/packages/db/test/fixtures/ticketing-example/db/seed.ts +++ b/packages/db/test/fixtures/ticketing-example/db/seed.ts @@ -1,10 +1,12 @@ import { Event, db } from 'astro:db'; -await db.insert(Event).values({ - name: 'Sampha LIVE in Brooklyn', - description: - 'Sampha is on tour with his new, flawless album Lahai. Come see the live performance outdoors in Prospect Park. Yes, there will be a grand piano 🎹', - date: new Date('2024-01-01'), - ticketPrice: 10000, - location: 'Brooklyn, NY', -}); +export default async function () { + await db.insert(Event).values({ + name: 'Sampha LIVE in Brooklyn', + description: + 'Sampha is on tour with his new, flawless album Lahai. Come see the live performance outdoors in Prospect Park. Yes, there will be a grand piano 🎹', + date: new Date('2024-01-01'), + ticketPrice: 10000, + location: 'Brooklyn, NY', + }); +}