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

View file

@ -31,7 +31,12 @@ import {
vitePluginDb,
} 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 configFileDependencies: string[] = [];
let root: URL;
@ -77,17 +82,22 @@ function astroDBIntegration(): AstroIntegration {
if (connectToRemote) {
appToken = await getManagedRemoteToken();
dbPlugin = vitePluginDb({
connectToStudio: connectToRemote,
connectToRemote: true,
appToken: appToken.token,
tables,
root: config.root,
srcDir: config.srcDir,
output: config.output,
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 {
dbPlugin = vitePluginDb({
connectToStudio: false,
connectToRemote: false,
tables,
seedFiles,
root: config.root,

View file

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

View file

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