@@ -2,25 +2,54 @@ import { resolve } from 'path';
22import { spawn } from 'child_process' ;
33
44import { errors , LaunchQLOptions } from '@launchql/types' ;
5- import { getSpawnEnvWithPg } from 'pg-env' ;
5+ import { getSpawnEnvWithPg , PgConfig } from 'pg-env' ;
66import { Logger } from '@launchql/logger' ;
77import { getPgPool } from 'pg-cache' ;
88import { deployCommand } from '../migrate/deploy-command' ;
99import { LaunchQLProject } from '../class/launchql' ;
10+ import { packageModule } from '../package' ;
1011
1112interface Extensions {
1213 resolved : string [ ] ;
1314 external : string [ ] ;
1415}
1516
17+ // Cache for fast deployment
18+ const deployFastCache : Record < string , Awaited < ReturnType < typeof packageModule > > > = { } ;
19+
20+ const getCacheKey = (
21+ pg : Partial < PgConfig > | undefined ,
22+ name : string ,
23+ database : string
24+ ) : string => {
25+ const { host, port, user } = pg ?? { } ;
26+ return `${ host ?? 'localhost' } :${ port ?? 5432 } :${ user ?? 'user' } :${ database } :${ name } ` ;
27+ } ;
28+
1629const log = new Logger ( 'deploy' ) ;
1730
1831export const deploy = async (
1932 opts : LaunchQLOptions ,
2033 name : string ,
2134 database : string ,
2235 dir : string ,
23- options ?: { useSqitch ?: boolean ; useTransaction ?: boolean }
36+ options ?: {
37+ useSqitch ?: boolean ;
38+ useTransaction ?: boolean ;
39+ /**
40+ * If true, use the fast deployment strategy
41+ * This will skip the sqitch deployment and new migration system and simply deploy the packaged sql
42+ */
43+ fast ?: boolean ;
44+ /**
45+ * if fast is true, you can choose to use the plan file or simply leverage the dependencies
46+ */
47+ usePlan ?: boolean ;
48+ /**
49+ * if fast is true, you can choose to cache the packaged module
50+ */
51+ cache ?: boolean ;
52+ }
2453) : Promise < Extensions > => {
2554 const mod = new LaunchQLProject ( dir ) ;
2655
@@ -35,10 +64,7 @@ export const deploy = async (
3564 log . info ( `📦 Resolving dependencies for ${ name } ...` ) ;
3665 const extensions : Extensions = mod . getModuleExtensions ( ) ;
3766
38- const pgPool = getPgPool ( {
39- ...opts . pg ,
40- database
41- } ) ;
67+ const pgPool = getPgPool ( { ...opts . pg , database } ) ;
4268
4369 log . success ( `🚀 Starting deployment to database ${ database } ...` ) ;
4470
@@ -54,7 +80,42 @@ export const deploy = async (
5480 log . info ( `📂 Deploying local module: ${ extension } ` ) ;
5581 log . debug ( `→ Path: ${ modulePath } ` ) ;
5682
57- if ( options ?. useSqitch ) {
83+ if ( options ?. fast ) {
84+ // Use fast deployment strategy
85+ const localProject = new LaunchQLProject ( modulePath ) ;
86+ const cacheKey = getCacheKey ( opts . pg , extension , database ) ;
87+
88+ if ( options ?. cache && deployFastCache [ cacheKey ] ) {
89+ log . warn ( `⚡ Using cached pkg for ${ extension } .` ) ;
90+ await pgPool . query ( deployFastCache [ cacheKey ] . sql ) ;
91+ continue ;
92+ }
93+
94+ let pkg ;
95+ try {
96+ pkg = await packageModule ( localProject . modulePath , {
97+ usePlan : options ?. usePlan ?? true ,
98+ extension : false
99+ } ) ;
100+ } catch ( err ) {
101+ log . error ( `❌ Failed to package module "${ extension } " at path: ${ modulePath } ` ) ;
102+ log . error ( ` Error: ${ err instanceof Error ? err . message : String ( err ) } ` ) ;
103+ console . error ( err ) ; // Preserve full stack trace
104+ throw errors . DEPLOYMENT_FAILED ( {
105+ type : 'Deployment' ,
106+ module : extension
107+ } ) ;
108+ }
109+
110+ log . debug ( `→ Command: sqitch deploy db:pg:${ database } ` ) ;
111+ log . debug ( `> ${ pkg . sql } ` ) ;
112+
113+ await pgPool . query ( pkg . sql ) ;
114+
115+ if ( options ?. cache ) {
116+ deployFastCache [ cacheKey ] = pkg ;
117+ }
118+ } else if ( options ?. useSqitch ) {
58119 // Use legacy sqitch
59120 log . debug ( `→ Command: sqitch deploy db:pg:${ database } ` ) ;
60121
0 commit comments