0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-02-24 22:46:02 -05:00

refactor: seed within create local db client

This commit is contained in:
bholmesdev 2024-03-01 09:09:42 -05:00
parent ec4730a82d
commit 48dca901bc
2 changed files with 77 additions and 14 deletions

View file

@ -96,29 +96,29 @@ export function getLocalVirtualModContents({
); );
return ` return `
import { asDrizzleTable, createLocalDatabaseClient, seedLocal } from ${RUNTIME_IMPORT}; import { asDrizzleTable, createLocalDatabaseClient } from ${RUNTIME_IMPORT};
${ ${
useBundledDbUrl useBundledDbUrl
? `import dbUrl from ${JSON.stringify(`${dbUrl}?fileurl`)};` ? `import dbUrl from ${JSON.stringify(`${dbUrl}?fileurl`)};`
: `const dbUrl = ${JSON.stringify(dbUrl)};` : `const dbUrl = ${JSON.stringify(dbUrl)};`
} }
export const db = createLocalDatabaseClient({ dbUrl }); export const db = await createLocalDatabaseClient({
dbUrl,
seedProps: ${
shouldSeed
? `{
tables: ${JSON.stringify(tables)},
fileGlob: import.meta.glob(${JSON.stringify(seedFilePaths)}),
}`
: 'undefined'
},
});
export * from ${RUNTIME_DRIZZLE_IMPORT}; export * from ${RUNTIME_DRIZZLE_IMPORT};
export * from ${RUNTIME_CONFIG_IMPORT}; export * from ${RUNTIME_CONFIG_IMPORT};
${getStringifiedCollectionExports(tables)} ${getStringifiedCollectionExports(tables)}
${
shouldSeed
? `await seedLocal({
db,
tables: ${JSON.stringify(tables)},
fileGlob: import.meta.glob(${JSON.stringify(seedFilePaths)}),
});`
: ''
}
`; `;
} }

View file

@ -1,15 +1,28 @@
import type { InStatement } from '@libsql/client'; import type { InStatement } from '@libsql/client';
import { createClient } from '@libsql/client'; import { LibsqlError, createClient } from '@libsql/client';
import type { LibSQLDatabase } from 'drizzle-orm/libsql'; import type { LibSQLDatabase } from 'drizzle-orm/libsql';
import { drizzle as drizzleLibsql } from 'drizzle-orm/libsql'; import { drizzle as drizzleLibsql } from 'drizzle-orm/libsql';
import { drizzle as drizzleProxy } from 'drizzle-orm/sqlite-proxy'; import { drizzle as drizzleProxy } from 'drizzle-orm/sqlite-proxy';
import { z } from 'zod'; import { z } from 'zod';
import type { SqliteDB } from './index.js';
import { SEED_ERROR } from '../core/errors.js';
import type { DBTables } from '../core/types.js';
import { recreateTables } from './queries.js';
const isWebContainer = !!process.versions?.webcontainer; const isWebContainer = !!process.versions?.webcontainer;
interface LocalDatabaseClient extends LibSQLDatabase, Disposable {} interface LocalDatabaseClient extends LibSQLDatabase, Disposable {}
export function createLocalDatabaseClient({ dbUrl }: { dbUrl: string }): LocalDatabaseClient { export async function createLocalDatabaseClient({
dbUrl,
seedProps,
}: {
dbUrl: string;
seedProps?: {
tables: DBTables;
fileGlob: Record<string, () => Promise<void>>;
};
}): Promise<LocalDatabaseClient> {
const url = isWebContainer ? 'file:content.db' : dbUrl; const url = isWebContainer ? 'file:content.db' : dbUrl;
const client = createClient({ url }); const client = createClient({ url });
const db = Object.assign(drizzleLibsql(client), { const db = Object.assign(drizzleLibsql(client), {
@ -18,9 +31,59 @@ export function createLocalDatabaseClient({ dbUrl }: { dbUrl: string }): LocalDa
}, },
}); });
if (seedProps) {
await seedLocal({ db, ...seedProps });
console.log('seed finished');
}
return db; return db;
} }
/**
* Sorted by precedence.
* Ex. If both "seed.dev.ts" and "seed.ts" are present,
* "seed.dev.ts" will be used.
*/
export const SEED_DEV_FILE_NAMES_SORTED = [
'seed.development.ts',
'seed.development.js',
'seed.development.mjs',
'seed.development.mts',
'seed.dev.ts',
'seed.dev.js',
'seed.dev.mjs',
'seed.dev.mts',
'seed.ts',
'seed.js',
'seed.mjs',
'seed.mts',
];
async function seedLocal({
db,
tables,
// Glob all potential seed files to catch renames and deletions.
fileGlob,
}: {
db: SqliteDB;
tables: DBTables;
fileGlob: Record<string, () => Promise<void>>;
}) {
await recreateTables({ db, tables });
for (const fileName of SEED_DEV_FILE_NAMES_SORTED) {
const key = Object.keys(fileGlob).find((f) => f.endsWith(fileName));
if (key) {
await fileGlob[key]().catch((e) => {
if (e instanceof LibsqlError) {
throw new Error(SEED_ERROR(e.message));
}
throw e;
});
return;
}
}
}
export function createRemoteDatabaseClient(appToken: string, remoteDbURL: string) { export function createRemoteDatabaseClient(appToken: string, remoteDbURL: string) {
const url = new URL('/db/query', remoteDbURL); const url = new URL('/db/query', remoteDbURL);