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';
|
} 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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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};
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue