mirror of
https://github.com/withastro/astro.git
synced 2025-02-24 22:46:02 -05:00
feat: file watching for db/config.ts dependencies
This commit is contained in:
parent
783c22d891
commit
4f8e2754fa
7 changed files with 61 additions and 34 deletions
|
@ -13,3 +13,5 @@ export const DB_TYPES_FILE = 'db-types.d.ts';
|
|||
export const VIRTUAL_MODULE_ID = 'astro:db';
|
||||
|
||||
export const DB_PATH = '.astro/content.db';
|
||||
|
||||
export const CONFIG_FILE_NAMES = ['config.ts', 'config.js', 'config.mts', 'config.mjs'];
|
||||
|
|
|
@ -4,10 +4,10 @@ import { vitePluginInjectEnvTs } from './vite-plugin-inject-env-ts.js';
|
|||
import { typegen } from './typegen.js';
|
||||
import { existsSync } from 'fs';
|
||||
import { mkdir, rm, writeFile } from 'fs/promises';
|
||||
import { DB_PATH } from '../consts.js';
|
||||
import { CONFIG_FILE_NAMES, DB_PATH } from '../consts.js';
|
||||
import { createLocalDatabaseClient } from '../../runtime/db-client.js';
|
||||
import { dbConfigSchema, type DBTables } from '../types.js';
|
||||
import { type VitePlugin } from '../utils.js';
|
||||
import { getDbDirUrl, type VitePlugin } from '../utils.js';
|
||||
import { UNSAFE_DISABLE_STUDIO_WARNING } from '../errors.js';
|
||||
import { errorMap } from './error-map.js';
|
||||
import { dirname } from 'path';
|
||||
|
@ -20,6 +20,8 @@ import { loadConfigFile } from '../load-file.js';
|
|||
|
||||
function astroDBIntegration(): AstroIntegration {
|
||||
let connectToStudio = false;
|
||||
let configFileDependencies: string[] = [];
|
||||
let root: URL;
|
||||
let appToken: ManagedAppToken | undefined;
|
||||
let schemas = {
|
||||
tables(): DBTables {
|
||||
|
@ -32,6 +34,7 @@ function astroDBIntegration(): AstroIntegration {
|
|||
hooks: {
|
||||
'astro:config:setup': async ({ updateConfig, config, command: _command, logger }) => {
|
||||
command = _command;
|
||||
root = config.root;
|
||||
if (_command === 'preview') return;
|
||||
|
||||
let dbPlugin: VitePlugin | undefined = undefined;
|
||||
|
@ -72,8 +75,10 @@ function astroDBIntegration(): AstroIntegration {
|
|||
'astro:config:done': async ({ config, logger }) => {
|
||||
// TODO: refine where we load tables
|
||||
// @matthewp: may want to load tables by path at runtime
|
||||
const configFile = await loadConfigFile(config.root);
|
||||
const { tables = {} } = dbConfigSchema.parse(configFile?.default ?? {}, { errorMap });
|
||||
const { mod, dependencies } = await loadConfigFile(config.root);
|
||||
configFileDependencies = dependencies;
|
||||
|
||||
const { tables = {} } = dbConfigSchema.parse(mod?.default ?? {}, { errorMap });
|
||||
// Redefine getTables so our integration can grab them
|
||||
schemas.tables = () => tables;
|
||||
|
||||
|
@ -102,6 +107,18 @@ function astroDBIntegration(): AstroIntegration {
|
|||
);
|
||||
}, 100);
|
||||
},
|
||||
'astro:server:setup': async ({ server }) => {
|
||||
const filesToWatch = [
|
||||
...CONFIG_FILE_NAMES.map((c) => new URL(c, getDbDirUrl(root))),
|
||||
...configFileDependencies.map((c) => new URL(c, root)),
|
||||
];
|
||||
server.watcher.on('all', (event, relativeEntry) => {
|
||||
const entry = new URL(relativeEntry, root);
|
||||
if (filesToWatch.some((f) => entry.href === f.href)) {
|
||||
server.restart();
|
||||
}
|
||||
});
|
||||
},
|
||||
'astro:build:start': async ({ logger }) => {
|
||||
logger.info('database: ' + (connectToStudio ? yellow('remote') : blue('local database.')));
|
||||
},
|
||||
|
|
|
@ -42,15 +42,20 @@ export async function executeFile(params: ExecuteFileParams): Promise<void> {
|
|||
await importBundledFile({ code, root: params.root });
|
||||
}
|
||||
|
||||
export async function loadConfigFile(root: URL): Promise<{ default?: unknown } | undefined> {
|
||||
export async function loadConfigFile(
|
||||
root: URL
|
||||
): Promise<{ mod: { default?: unknown } | undefined; dependencies: string[] }> {
|
||||
// TODO: support any file extension
|
||||
const fileUrl = new URL('config.ts', getDbDirUrl(root));
|
||||
const { code } = await bundleFile({
|
||||
const { code, dependencies } = await bundleFile({
|
||||
virtualModContents: getConfigVirtualModContents(),
|
||||
root,
|
||||
fileUrl,
|
||||
});
|
||||
return await importBundledFile({ code, root });
|
||||
return {
|
||||
mod: await importBundledFile({ code, root }),
|
||||
dependencies,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,7 +72,7 @@ async function bundleFile({
|
|||
fileUrl: URL;
|
||||
root: URL;
|
||||
virtualModContents: string;
|
||||
}): Promise<{ code: string }> {
|
||||
}) {
|
||||
const result = await esbuild({
|
||||
absWorkingDir: process.cwd(),
|
||||
entryPoints: [fileURLToPath(fileUrl)],
|
||||
|
@ -109,6 +114,7 @@ async function bundleFile({
|
|||
|
||||
return {
|
||||
code: file.text,
|
||||
dependencies: Object.keys(result.metafile.inputs),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
26
packages/db/test/fixtures/basics/astro.config.ts
vendored
26
packages/db/test/fixtures/basics/astro.config.ts
vendored
|
@ -1,31 +1,7 @@
|
|||
import db, { defineTable, column, sql, NOW } from '@astrojs/db';
|
||||
import db from '@astrojs/db';
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
const Author = defineTable({
|
||||
columns: {
|
||||
name: column.text(),
|
||||
},
|
||||
});
|
||||
|
||||
// TODO: add back integration test
|
||||
const Themes = defineTable({
|
||||
columns: {
|
||||
name: column.text(),
|
||||
added: column.date({
|
||||
default: sql`CURRENT_TIMESTAMP`,
|
||||
}),
|
||||
updated: column.date({
|
||||
default: NOW,
|
||||
}),
|
||||
isDark: column.boolean({ default: sql`TRUE` }),
|
||||
owner: column.text({ optional: true, default: sql`NULL` }),
|
||||
},
|
||||
});
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [db()],
|
||||
db: {
|
||||
tables: { Author, Themes },
|
||||
},
|
||||
});
|
||||
|
|
12
packages/db/test/fixtures/basics/db/config.ts
vendored
Normal file
12
packages/db/test/fixtures/basics/db/config.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { defineDB, defineTable, column } from 'astro:db';
|
||||
import { Themes } from './theme';
|
||||
|
||||
const Author = defineTable({
|
||||
columns: {
|
||||
name: column.text(),
|
||||
},
|
||||
});
|
||||
|
||||
export default defineDB({
|
||||
tables: { Author, Themes },
|
||||
});
|
1
packages/db/test/fixtures/basics/db/seed.ts
vendored
1
packages/db/test/fixtures/basics/db/seed.ts
vendored
|
@ -1,4 +1,3 @@
|
|||
/// <reference path="../.astro/db-types.d.ts" />
|
||||
import { db, Author, Themes } from 'astro:db';
|
||||
|
||||
await db.batch([
|
||||
|
|
15
packages/db/test/fixtures/basics/db/theme.ts
vendored
Normal file
15
packages/db/test/fixtures/basics/db/theme.ts
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { defineTable, column, NOW, sql } from 'astro:db';
|
||||
|
||||
export const Themes = defineTable({
|
||||
columns: {
|
||||
name: column.text(),
|
||||
added: column.date({
|
||||
default: sql`CURRENT_TIMESTAMP`,
|
||||
}),
|
||||
updated: column.date({
|
||||
default: NOW,
|
||||
}),
|
||||
isDark: column.boolean({ default: sql`TRUE` }),
|
||||
owner: column.text({ optional: true, default: sql`NULL` }),
|
||||
},
|
||||
});
|
Loading…
Add table
Reference in a new issue