mirror of
https://github.com/withastro/astro.git
synced 2025-02-03 22:29:08 -05:00
refactor: move dev to use filesystem to run seed at right time
This commit is contained in:
parent
6ad4e00cd0
commit
4e941af5fb
3 changed files with 38 additions and 73 deletions
|
@ -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 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),
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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)});
|
||||
}`
|
||||
: ''
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue