1+ import type { PGlite } from '@electric-sql/pglite' ;
12import { randomUUID } from 'crypto' ;
3+ import { is } from 'drizzle-orm' ;
24import { LibSQLDatabase } from 'drizzle-orm/libsql' ;
5+ import { AnyMySqlTable , getTableConfig as mysqlTableConfig , MySqlTable } from 'drizzle-orm/mysql-core' ;
36import type { MySql2Database } from 'drizzle-orm/mysql2' ;
4- import { PgDatabase } from 'drizzle-orm/pg-core' ;
7+ import { AnyPgTable , getTableConfig as pgTableConfig , PgDatabase , PgTable } from 'drizzle-orm/pg-core' ;
8+ import { Relations } from 'drizzle-orm/relations' ;
59import { SingleStoreDriverDatabase } from 'drizzle-orm/singlestore' ;
10+ import {
11+ AnySingleStoreTable ,
12+ getTableConfig as singlestoreTableConfig ,
13+ SingleStoreTable ,
14+ } from 'drizzle-orm/singlestore-core' ;
15+ import { AnySQLiteTable , SQLiteTable } from 'drizzle-orm/sqlite-core' ;
616import {
717 columnsResolver ,
818 enumsResolver ,
@@ -22,10 +32,13 @@ import { updateUpToV6 as upPgV6, updateUpToV7 as upPgV7 } from './cli/commands/p
2232import { sqlitePushIntrospect } from './cli/commands/sqliteIntrospect' ;
2333import { logSuggestionsAndReturn } from './cli/commands/sqlitePushUtils' ;
2434import type { CasingType } from './cli/validations/common' ;
35+ import type { MysqlCredentials } from './cli/validations/mysql' ;
36+ import type { PostgresCredentials } from './cli/validations/postgres' ;
37+ import type { SingleStoreCredentials } from './cli/validations/singlestore' ;
38+ import type { SqliteCredentials } from './cli/validations/sqlite' ;
2539import { getTablesFilterByExtensions } from './extensions/getTablesFilterByExtensions' ;
2640import { originUUID } from './global' ;
2741import type { Config } from './index' ;
28- import { fillPgSnapshot } from './migrationPreparator' ;
2942import { MySqlSchema as MySQLSchemaKit , mysqlSchema , squashMysqlScheme } from './serializer/mysqlSchema' ;
3043import { generateMySqlSnapshot } from './serializer/mysqlSerializer' ;
3144import { prepareFromExports } from './serializer/pgImports' ;
@@ -39,7 +52,9 @@ import {
3952import { generateSingleStoreSnapshot } from './serializer/singlestoreSerializer' ;
4053import { SQLiteSchema as SQLiteSchemaKit , sqliteSchema , squashSqliteScheme } from './serializer/sqliteSchema' ;
4154import { generateSqliteSnapshot } from './serializer/sqliteSerializer' ;
55+ import type { Setup } from './serializer/studio' ;
4256import type { DB , SQLiteDB } from './utils' ;
57+ import { certs } from './utils/certs' ;
4358export type DrizzleSnapshotJSON = PgSchemaKit ;
4459export type DrizzleSQLiteSnapshotJSON = SQLiteSchemaKit ;
4560export type DrizzleMySQLSnapshotJSON = MySQLSchemaKit ;
@@ -68,11 +83,11 @@ export const generateDrizzleJson = (
6883 schemaFilters ,
6984 ) ;
7085
71- return fillPgSnapshot ( {
72- serialized : snapshot ,
86+ return {
87+ ... snapshot ,
7388 id,
74- idPrev : prevId ?? originUUID ,
75- } ) ;
89+ prevId : prevId ?? originUUID ,
90+ } ;
7691} ;
7792
7893export const generateMigration = async (
@@ -171,6 +186,39 @@ export const pushSchema = async (
171186 } ;
172187} ;
173188
189+ export const startStudioPostgresServer = async (
190+ imports : Record < string , unknown > ,
191+ credentials : PostgresCredentials | {
192+ driver : 'pglite' ;
193+ client : PGlite ;
194+ } ,
195+ options ?: {
196+ host ?: string ;
197+ port ?: number ;
198+ casing ?: CasingType ;
199+ } ,
200+ ) => {
201+ const { drizzleForPostgres } = await import ( './serializer/studio' ) ;
202+
203+ const pgSchema : Record < string , Record < string , AnyPgTable > > = { } ;
204+ const relations : Record < string , Relations > = { } ;
205+
206+ Object . entries ( imports ) . forEach ( ( [ k , t ] ) => {
207+ if ( is ( t , PgTable ) ) {
208+ const schema = pgTableConfig ( t ) . schema || 'public' ;
209+ pgSchema [ schema ] = pgSchema [ schema ] || { } ;
210+ pgSchema [ schema ] [ k ] = t ;
211+ }
212+
213+ if ( is ( t , Relations ) ) {
214+ relations [ k ] = t ;
215+ }
216+ } ) ;
217+
218+ const setup = await drizzleForPostgres ( credentials , pgSchema , relations , [ ] , options ?. casing ) ;
219+ await startServerFromSetup ( setup , options ) ;
220+ } ;
221+
174222// SQLite
175223
176224export const generateSQLiteDrizzleJson = async (
@@ -277,6 +325,36 @@ export const pushSQLiteSchema = async (
277325 } ;
278326} ;
279327
328+ export const startStudioSQLiteServer = async (
329+ imports : Record < string , unknown > ,
330+ credentials : SqliteCredentials ,
331+ options ?: {
332+ host ?: string ;
333+ port ?: number ;
334+ casing ?: CasingType ;
335+ } ,
336+ ) => {
337+ const { drizzleForSQLite } = await import ( './serializer/studio' ) ;
338+
339+ const sqliteSchema : Record < string , Record < string , AnySQLiteTable > > = { } ;
340+ const relations : Record < string , Relations > = { } ;
341+
342+ Object . entries ( imports ) . forEach ( ( [ k , t ] ) => {
343+ if ( is ( t , SQLiteTable ) ) {
344+ const schema = 'public' ; // sqlite does not have schemas
345+ sqliteSchema [ schema ] = sqliteSchema [ schema ] || { } ;
346+ sqliteSchema [ schema ] [ k ] = t ;
347+ }
348+
349+ if ( is ( t , Relations ) ) {
350+ relations [ k ] = t ;
351+ }
352+ } ) ;
353+
354+ const setup = await drizzleForSQLite ( credentials , sqliteSchema , relations , [ ] , options ?. casing ) ;
355+ await startServerFromSetup ( setup , options ) ;
356+ } ;
357+
280358// MySQL
281359
282360export const generateMySQLDrizzleJson = async (
@@ -382,6 +460,36 @@ export const pushMySQLSchema = async (
382460 } ;
383461} ;
384462
463+ export const startStudioMySQLServer = async (
464+ imports : Record < string , unknown > ,
465+ credentials : MysqlCredentials ,
466+ options ?: {
467+ host ?: string ;
468+ port ?: number ;
469+ casing ?: CasingType ;
470+ } ,
471+ ) => {
472+ const { drizzleForMySQL } = await import ( './serializer/studio' ) ;
473+
474+ const mysqlSchema : Record < string , Record < string , AnyMySqlTable > > = { } ;
475+ const relations : Record < string , Relations > = { } ;
476+
477+ Object . entries ( imports ) . forEach ( ( [ k , t ] ) => {
478+ if ( is ( t , MySqlTable ) ) {
479+ const schema = mysqlTableConfig ( t ) . schema || 'public' ;
480+ mysqlSchema [ schema ] = mysqlSchema [ schema ] || { } ;
481+ mysqlSchema [ schema ] [ k ] = t ;
482+ }
483+
484+ if ( is ( t , Relations ) ) {
485+ relations [ k ] = t ;
486+ }
487+ } ) ;
488+
489+ const setup = await drizzleForMySQL ( credentials , mysqlSchema , relations , [ ] , options ?. casing ) ;
490+ await startServerFromSetup ( setup , options ) ;
491+ } ;
492+
385493// SingleStore
386494
387495export const generateSingleStoreDrizzleJson = async (
@@ -489,6 +597,62 @@ export const pushSingleStoreSchema = async (
489597 } ;
490598} ;
491599
600+ export const startStudioSingleStoreServer = async (
601+ imports : Record < string , unknown > ,
602+ credentials : SingleStoreCredentials ,
603+ options ?: {
604+ host ?: string ;
605+ port ?: number ;
606+ casing ?: CasingType ;
607+ } ,
608+ ) => {
609+ const { drizzleForSingleStore } = await import ( './serializer/studio' ) ;
610+
611+ const singleStoreSchema : Record < string , Record < string , AnySingleStoreTable > > = { } ;
612+ const relations : Record < string , Relations > = { } ;
613+
614+ Object . entries ( imports ) . forEach ( ( [ k , t ] ) => {
615+ if ( is ( t , SingleStoreTable ) ) {
616+ const schema = singlestoreTableConfig ( t ) . schema || 'public' ;
617+ singleStoreSchema [ schema ] = singleStoreSchema [ schema ] || { } ;
618+ singleStoreSchema [ schema ] [ k ] = t ;
619+ }
620+
621+ if ( is ( t , Relations ) ) {
622+ relations [ k ] = t ;
623+ }
624+ } ) ;
625+
626+ const setup = await drizzleForSingleStore ( credentials , singleStoreSchema , relations , [ ] , options ?. casing ) ;
627+ await startServerFromSetup ( setup , options ) ;
628+ } ;
629+
630+ const startServerFromSetup = async ( setup : Setup , options ?: {
631+ host ?: string ;
632+ port ?: number ;
633+ } ) => {
634+ const { prepareServer } = await import ( './serializer/studio' ) ;
635+
636+ const server = await prepareServer ( setup ) ;
637+
638+ const host = options ?. host || '127.0.0.1' ;
639+ const port = options ?. port || 4983 ;
640+ const { key, cert } = ( await certs ( ) ) || { } ;
641+ server . start ( {
642+ host,
643+ port,
644+ key,
645+ cert,
646+ cb : ( err ) => {
647+ if ( err ) {
648+ console . error ( err ) ;
649+ } else {
650+ console . log ( `Studio is running at ${ key ? 'https' : 'http' } ://${ host } :${ port } ` ) ;
651+ }
652+ } ,
653+ } ) ;
654+ } ;
655+
492656export const upPgSnapshot = ( snapshot : Record < string , unknown > ) => {
493657 if ( snapshot . version === '5' ) {
494658 return upPgV7 ( upPgV6 ( snapshot ) ) ;
0 commit comments