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:
parent
8e500f2f96
commit
692599c5c8
4 changed files with 63 additions and 28 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue