0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-30 22:03:56 -05:00

feat(db): Add support for libSQL remotes on non-Node runtimes

This commit is contained in:
Luiz Ferraz 2024-10-08 21:10:32 -03:00
parent 8e500f2f96
commit 692599c5c8
No known key found for this signature in database
GPG key ID: B20E8273A6810404
4 changed files with 63 additions and 28 deletions

View file

@ -11,7 +11,7 @@ import {
} from '../../../errors.js'; } from '../../../errors.js';
import { import {
getLocalVirtualModContents, getLocalVirtualModContents,
getStudioVirtualModContents, getRemoteVirtualModContents,
} from '../../../integration/vite-plugin-db.js'; } from '../../../integration/vite-plugin-db.js';
import { bundleFile, importBundledFile } from '../../../load-file.js'; import { bundleFile, importBundledFile } from '../../../load-file.js';
import type { DBConfig } from '../../../types.js'; import type { DBConfig } from '../../../types.js';
@ -41,7 +41,7 @@ export async function cmd({
let virtualModContents: string; let virtualModContents: string;
if (flags.remote) { if (flags.remote) {
const appToken = await getManagedRemoteToken(flags.token); const appToken = await getManagedRemoteToken(flags.token);
virtualModContents = getStudioVirtualModContents({ virtualModContents = getRemoteVirtualModContents({
tables: dbConfig.tables ?? {}, tables: dbConfig.tables ?? {},
appToken: appToken.token, appToken: appToken.token,
isBuild: false, isBuild: false,

View file

@ -31,7 +31,12 @@ import {
vitePluginDb, vitePluginDb,
} from './vite-plugin-db.js'; } from './vite-plugin-db.js';
function astroDBIntegration(): AstroIntegration { type DBOptions = {
remoteClient?: 'native' | 'web';
};
function astroDBIntegration(options?: DBOptions): AstroIntegration {
const { remoteClient = 'native' } = options || {};
let connectToRemote = false; let connectToRemote = false;
let configFileDependencies: string[] = []; let configFileDependencies: string[] = [];
let root: URL; let root: URL;
@ -77,17 +82,22 @@ function astroDBIntegration(): AstroIntegration {
if (connectToRemote) { if (connectToRemote) {
appToken = await getManagedRemoteToken(); appToken = await getManagedRemoteToken();
dbPlugin = vitePluginDb({ dbPlugin = vitePluginDb({
connectToStudio: connectToRemote, connectToRemote: true,
appToken: appToken.token, appToken: appToken.token,
tables, tables,
root: config.root, root: config.root,
srcDir: config.srcDir, srcDir: config.srcDir,
output: config.output, output: config.output,
seedHandler, seedHandler,
// The web remote client is only used for production builds
// in order to be compatible with non-Node server runtimes.
// For local development and CLI commands, the native client
// is used for greater flexibility.
remoteClientMode: command === 'build' ? remoteClient : 'native',
}); });
} else { } else {
dbPlugin = vitePluginDb({ dbPlugin = vitePluginDb({
connectToStudio: false, connectToRemote: false,
tables, tables,
seedFiles, seedFiles,
root: config.root, root: config.root,

View file

@ -34,24 +34,25 @@ export type SeedHandler = {
type VitePluginDBParams = type VitePluginDBParams =
| { | {
connectToStudio: false; connectToRemote: false;
tables: LateTables; tables: LateTables;
seedFiles: LateSeedFiles; seedFiles: LateSeedFiles;
srcDir: URL; srcDir: URL;
root: URL; root: URL;
logger?: AstroIntegrationLogger; logger?: AstroIntegrationLogger;
output: AstroConfig['output']; output: AstroConfig['output'];
seedHandler: SeedHandler; seedHandler: SeedHandler;
} }
| { | {
connectToStudio: true; connectToRemote: true;
tables: LateTables; tables: LateTables;
appToken: string; appToken: string;
srcDir: URL; srcDir: URL;
root: URL; root: URL;
output: AstroConfig['output']; output: AstroConfig['output'];
seedHandler: SeedHandler; seedHandler: SeedHandler;
}; remoteClientMode: 'native' | 'web';
};
export function vitePluginDb(params: VitePluginDBParams): VitePlugin { export function vitePluginDb(params: VitePluginDBParams): VitePlugin {
let command: 'build' | 'serve' = 'build'; let command: 'build' | 'serve' = 'build';
@ -71,12 +72,13 @@ export function vitePluginDb(params: VitePluginDBParams): VitePlugin {
async load(id) { async load(id) {
if (id !== resolved.module && id !== resolved.importedFromSeedFile) return; if (id !== resolved.module && id !== resolved.importedFromSeedFile) return;
if (params.connectToStudio) { if (params.connectToRemote) {
return getStudioVirtualModContents({ return getRemoteVirtualModContents({
appToken: params.appToken, appToken: params.appToken,
tables: params.tables.get(), tables: params.tables.get(),
isBuild: command === 'build', isBuild: command === 'build',
output: params.output, output: params.output,
remoteClientMode: params.remoteClientMode,
}); });
} }
@ -137,16 +139,18 @@ export * from ${RUNTIME_VIRTUAL_IMPORT};
${getStringifiedTableExports(tables)}`; ${getStringifiedTableExports(tables)}`;
} }
export function getStudioVirtualModContents({ export function getRemoteVirtualModContents({
tables, tables,
appToken, appToken,
isBuild, isBuild,
output, output,
remoteClientMode,
}: { }: {
tables: DBTables; tables: DBTables;
appToken: string; appToken: string;
isBuild: boolean; isBuild: boolean;
output: AstroConfig['output']; output: AstroConfig['output'];
remoteClientMode?: 'native' | 'web';
}) { }) {
const dbInfo = getRemoteDatabaseInfo(); const dbInfo = getRemoteDatabaseInfo();
@ -185,6 +189,7 @@ export const db = await createRemoteDatabaseClient({
dbType: ${JSON.stringify(dbInfo.type)}, dbType: ${JSON.stringify(dbInfo.type)},
remoteUrl: ${dbUrlArg()}, remoteUrl: ${dbUrlArg()},
appToken: ${appTokenArg()}, appToken: ${appTokenArg()},
remoteClientMode: ${JSON.stringify(remoteClientMode)},
}); });
export * from ${RUNTIME_VIRTUAL_IMPORT}; export * from ${RUNTIME_VIRTUAL_IMPORT};

View file

@ -1,5 +1,6 @@
import type { InStatement } from '@libsql/client'; import type { InStatement } from '@libsql/client';
import { type Config as LibSQLConfig, createClient } from '@libsql/client'; import { type Config as LibSQLConfig, createClient } from '@libsql/client';
import { createClient as createLibSQLWebClient } from '@libsql/client/web';
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 { type SqliteRemoteDatabase, drizzle as drizzleProxy } from 'drizzle-orm/sqlite-proxy'; import { type SqliteRemoteDatabase, drizzle as drizzleProxy } from 'drizzle-orm/sqlite-proxy';
@ -46,6 +47,7 @@ type RemoteDbClientOptions = {
dbType: 'studio' | 'libsql'; dbType: 'studio' | 'libsql';
appToken: string; appToken: string;
remoteUrl: string | URL; remoteUrl: string | URL;
remoteClientMode?: 'native' | 'web';
}; };
export function createRemoteDatabaseClient(options: RemoteDbClientOptions) { export function createRemoteDatabaseClient(options: RemoteDbClientOptions) {
@ -53,10 +55,24 @@ export function createRemoteDatabaseClient(options: RemoteDbClientOptions) {
return options.dbType === 'studio' return options.dbType === 'studio'
? createStudioDatabaseClient(options.appToken, remoteUrl) ? createStudioDatabaseClient(options.appToken, remoteUrl)
: createRemoteLibSQLClient(options.appToken, remoteUrl, options.remoteUrl.toString()); : createRemoteLibSQLClient({
appToken: options.appToken,
remoteDbURL: remoteUrl,
rawUrl: options.remoteUrl.toString(),
remoteClientMode: options.remoteClientMode,
});
} }
function createRemoteLibSQLClient(appToken: string, remoteDbURL: URL, rawUrl: string) { type RemoteLibSQLClientOptions = {
appToken: string;
remoteDbURL: URL;
rawUrl: string;
remoteClientMode?: 'native' | 'web';
}
function createRemoteLibSQLClient({
appToken, remoteDbURL, rawUrl, remoteClientMode,
}: RemoteLibSQLClientOptions) {
const options: Partial<LibSQLConfig> = Object.fromEntries(remoteDbURL.searchParams.entries()); const options: Partial<LibSQLConfig> = Object.fromEntries(remoteDbURL.searchParams.entries());
remoteDbURL.search = ''; remoteDbURL.search = '';
@ -81,7 +97,11 @@ function createRemoteLibSQLClient(appToken: string, remoteDbURL: URL, rawUrl: st
url = 'file:' + remoteDbURL.pathname.substring(1); url = 'file:' + remoteDbURL.pathname.substring(1);
} }
const client = createClient({ const client = (
remoteClientMode === 'web'
? createLibSQLWebClient
: createClient
)({
...options, ...options,
authToken: appToken, authToken: appToken,
url, url,