Skip to content

Commit

Permalink
Use static imports for integration seed files in astro:db (#10381)
Browse files Browse the repository at this point in the history
* Use static imports for integration seed files in `astro:db`

* Add changeset

* Add build test for integrations fixture

* chore: comment on top-level seed imports

* fix: random db id for tests

* fix: set db id from build before

* wip: remove reset on env variable

* wip: move random db id env to top of test file

* refactor: remove unlink from db startup

* chore: remove random db id completely??

---------

Co-authored-by: bholmesdev <hey@bholmes.dev>
  • Loading branch information
delucis and bholmesdev authored Mar 11, 2024
1 parent 0e074fb commit 8cceab5
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/perfect-experts-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrojs/db": patch
---

Fixes builds for projects using integration seed files
5 changes: 1 addition & 4 deletions packages/db/src/core/consts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { randomUUID } from 'node:crypto';
import { readFileSync } from 'node:fs';

export const PACKAGE_NAME = JSON.parse(
Expand All @@ -12,9 +11,7 @@ export const DB_TYPES_FILE = 'db-types.d.ts';

export const VIRTUAL_MODULE_ID = 'astro:db';

export const DB_PATH = `.astro/${
process.env.ASTRO_TEST_RANDOM_DB_ID ? randomUUID() : 'content.db'
}`;
export const DB_PATH = '.astro/content.db';

export const CONFIG_FILE_NAMES = ['config.ts', 'config.js', 'config.mts', 'config.mjs'];

Expand Down
11 changes: 4 additions & 7 deletions packages/db/src/core/integration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,10 @@ function astroDBIntegration(): AstroIntegration {
seedFiles.get = () => integrationSeedPaths;
configFileDependencies = dependencies;

if (!connectToStudio) {
const dbUrl = new URL(DB_PATH, config.root);
if (existsSync(dbUrl)) {
await rm(dbUrl);
}
await mkdir(dirname(fileURLToPath(dbUrl)), { recursive: true });
await writeFile(dbUrl, '');
const localDbUrl = new URL(DB_PATH, config.root);
if (!connectToStudio && !existsSync(localDbUrl)) {
await mkdir(dirname(fileURLToPath(localDbUrl)), { recursive: true });
await writeFile(localDbUrl, '');
}

await typegen({ tables: tables.get() ?? {}, root: config.root });
Expand Down
20 changes: 13 additions & 7 deletions packages/db/src/core/integration/vite-plugin-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,23 @@ export function getLocalVirtualModContents({
(name) => new URL(name, getDbDirectoryUrl('file:///')).pathname
);
const resolveId = (id: string) => (id.startsWith('.') ? resolve(fileURLToPath(root), id) : id);
const integrationSeedFilePaths = seedFiles.map((pathOrUrl) =>
typeof pathOrUrl === 'string' ? resolveId(pathOrUrl) : pathOrUrl.pathname
);
const integrationSeedImports = integrationSeedFilePaths.map(
(filePath) => `() => import(${JSON.stringify(filePath)})`
);
// Use top-level imports to correctly resolve `astro:db` within seed files.
// Dynamic imports cause a silent build failure,
// potentially because of circular module references.
const integrationSeedImportStatements: string[] = [];
const integrationSeedImportNames: string[] = [];
seedFiles.forEach((pathOrUrl, index) => {
const path = typeof pathOrUrl === 'string' ? resolveId(pathOrUrl) : pathOrUrl.pathname;
const importName = 'integration_seed_' + index;
integrationSeedImportStatements.push(`import ${importName} from ${JSON.stringify(path)};`);
integrationSeedImportNames.push(importName);
});

const dbUrl = new URL(DB_PATH, root);
return `
import { asDrizzleTable, createLocalDatabaseClient } from ${RUNTIME_IMPORT};
${shouldSeed ? `import { seedLocal } from ${RUNTIME_IMPORT};` : ''}
${shouldSeed ? integrationSeedImportStatements.join('\n') : ''}
const dbUrl = ${JSON.stringify(dbUrl)};
export const db = createLocalDatabaseClient({ dbUrl });
Expand All @@ -133,7 +139,7 @@ ${
shouldSeed
? `await seedLocal({
userSeedGlob: import.meta.glob(${JSON.stringify(userSeedFilePaths)}, { eager: true }),
integrationSeedImports: [${integrationSeedImports.join(',')}],
integrationSeedFunctions: [${integrationSeedImportNames.join(',')}],
});`
: ''
}
Expand Down
9 changes: 4 additions & 5 deletions packages/db/src/runtime/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ export { createRemoteDatabaseClient, createLocalDatabaseClient } from './db-clie
export async function seedLocal({
// Glob all potential seed files to catch renames and deletions.
userSeedGlob,
integrationSeedImports,
integrationSeedFunctions: integrationSeedFunctions,
}: {
userSeedGlob: Record<string, { default?: () => Promise<void> }>;
integrationSeedImports: Array<() => Promise<{ default: () => Promise<void> }>>;
integrationSeedFunctions: Array<() => Promise<void>>;
}) {
const seedFilePath = Object.keys(userSeedGlob)[0];
if (seedFilePath) {
Expand All @@ -43,9 +43,8 @@ export async function seedLocal({
throw e;
}
}
for (const importModule of integrationSeedImports) {
const mod = await importModule();
await mod.default().catch((e) => {
for (const seedFn of integrationSeedFunctions) {
await seedFn().catch((e) => {
if (e instanceof LibsqlError) {
throw new Error(SEED_ERROR(e.message));
}
Expand Down
5 changes: 0 additions & 5 deletions packages/db/test/basics.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ describe('astro:db', () => {
});
});

// Note (@bholmesdev) generate a random database id on startup.
// Ensures database connections don't conflict
// when multiple dev servers are run in parallel on the same project.
process.env.ASTRO_TEST_RANDOM_DB_ID = 'true';
describe('development', () => {
let devServer;

Expand All @@ -26,7 +22,6 @@ describe('astro:db', () => {

after(async () => {
await devServer.stop();
process.env.ASTRO_TEST_RANDOM_DB_ID = undefined;
});

it('Prints the list of authors', async () => {
Expand Down
29 changes: 24 additions & 5 deletions packages/db/test/integrations.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ describe('astro:db with integrations', () => {
});
});

// Note(bholmesdev): Use in-memory db to avoid
// Multiple dev servers trying to unlink and remount
// the same database file.
process.env.TEST_IN_MEMORY_DB = 'true';
describe('development', () => {
let devServer;

Expand All @@ -24,7 +20,6 @@ describe('astro:db with integrations', () => {

after(async () => {
await devServer.stop();
process.env.TEST_IN_MEMORY_DB = undefined;
});

it('Prints the list of authors from user-defined table', async () => {
Expand All @@ -45,4 +40,28 @@ describe('astro:db with integrations', () => {
expect(ul.children().eq(0).text()).to.equal('Pancakes');
});
});

describe('build', () => {
before(async () => {
await fixture.build();
});

it('Prints the list of authors from user-defined table', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerioLoad(html);

const ul = $('.authors-list');
expect(ul.children()).to.have.a.lengthOf(5);
expect(ul.children().eq(0).text()).to.equal('Ben');
});

it('Prints the list of menu items from integration-defined table', async () => {
const html = await fixture.readFile('/index.html');
const $ = cheerioLoad(html);

const ul = $('ul.menu');
expect(ul.children()).to.have.a.lengthOf(4);
expect(ul.children().eq(0).text()).to.equal('Pancakes');
});
});
});

0 comments on commit 8cceab5

Please sign in to comment.