@@ -6,7 +6,9 @@ import { schemas } from '@walkeros/core/dev';
66import {
77 createCommandLogger ,
88 getErrorMessage ,
9+ detectInput ,
910 type Logger ,
11+ type Platform ,
1012} from '../../core/index.js' ;
1113import { loadFlowConfig , loadJsonFromSource } from '../../config/index.js' ;
1214import { bundleCore } from '../bundle/bundler.js' ;
@@ -18,6 +20,7 @@ import type { PushCommandOptions, PushResult } from './types.js';
1820export async function pushCommand ( options : PushCommandOptions ) : Promise < void > {
1921 const logger = createCommandLogger ( options ) ;
2022 const startTime = Date . now ( ) ;
23+ let tempDir : string | undefined ;
2124
2225 try {
2326 // Step 1: Load event
@@ -56,60 +59,36 @@ export async function pushCommand(options: PushCommandOptions): Promise<void> {
5659 ) ;
5760 }
5861
59- // Step 2: Load config
60- logger . debug ( 'Loading flow configuration' ) ;
61- const { flowConfig, buildOptions } = await loadFlowConfig ( options . config , {
62- flowName : options . flow ,
63- logger,
64- } ) ;
65-
66- const platform = getPlatform ( flowConfig ) ;
67-
68- // Step 3: Bundle to temp file in config directory (so Node.js can find node_modules)
69- logger . debug ( 'Bundling flow configuration' ) ;
70- // buildOptions.configDir already handles URLs (uses cwd) vs local paths
71- const configDir = buildOptions . configDir || process . cwd ( ) ;
72- const tempDir = path . join (
73- configDir ,
74- '.tmp' ,
75- `push-${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 9 ) } ` ,
76- ) ;
77- await fs . ensureDir ( tempDir ) ;
78- const tempPath = path . join (
79- tempDir ,
80- `bundle.${ platform === 'web' ? 'js' : 'mjs' } ` ,
81- ) ;
82-
83- const pushBuildOptions = {
84- ...buildOptions ,
85- output : tempPath ,
86- // Web uses IIFE for browser-like execution, server uses ESM
87- format : platform === 'web' ? ( 'iife' as const ) : ( 'esm' as const ) ,
88- platform : platform === 'web' ? ( 'browser' as const ) : ( 'node' as const ) ,
89- ...( platform === 'web' && {
90- windowCollector : 'collector' ,
91- windowElb : 'elb' ,
92- } ) ,
93- } ;
94-
95- await bundleCore ( flowConfig , pushBuildOptions , logger , false ) ;
96-
97- logger . debug ( `Bundle created: ${ tempPath } ` ) ;
62+ // Step 2: Detect input type (config or bundle)
63+ logger . debug ( 'Detecting input type' ) ;
64+ const detected = await detectInput ( options . config , options . platform ) ;
9865
99- // Step 4: Execute based on platform
10066 let result : PushResult ;
10167
102- if ( platform === 'web' ) {
103- logger . debug ( 'Executing in web environment (JSDOM)' ) ;
104- result = await executeWebPush ( tempPath , validatedEvent , logger ) ;
105- } else if ( platform === 'server' ) {
106- logger . debug ( 'Executing in server environment (Node.js)' ) ;
107- result = await executeServerPush ( tempPath , validatedEvent , logger ) ;
68+ if ( detected . type === 'config' ) {
69+ // Config flow: load config, bundle, execute
70+ result = await executeConfigPush (
71+ options ,
72+ validatedEvent ,
73+ logger ,
74+ ( dir ) => {
75+ tempDir = dir ;
76+ } ,
77+ ) ;
10878 } else {
109- throw new Error ( `Unsupported platform: ${ platform } ` ) ;
79+ // Bundle flow: execute directly
80+ result = await executeBundlePush (
81+ detected . content ,
82+ detected . platform ! ,
83+ validatedEvent ,
84+ logger ,
85+ ( dir ) => {
86+ tempDir = dir ;
87+ } ,
88+ ) ;
11089 }
11190
112- // Step 5 : Output results
91+ // Step 3 : Output results
11392 const duration = Date . now ( ) - startTime ;
11493
11594 if ( options . json ) {
@@ -143,13 +122,6 @@ export async function pushCommand(options: PushCommandOptions): Promise<void> {
143122 process . exit ( 1 ) ;
144123 }
145124 }
146-
147- // Cleanup temp directory
148- try {
149- await fs . remove ( tempDir ) ;
150- } catch {
151- // Ignore cleanup errors
152- }
153125 } catch ( error ) {
154126 const duration = Date . now ( ) - startTime ;
155127 const errorMessage = getErrorMessage ( error ) ;
@@ -165,6 +137,109 @@ export async function pushCommand(options: PushCommandOptions): Promise<void> {
165137 }
166138
167139 process . exit ( 1 ) ;
140+ } finally {
141+ // Cleanup temp directory
142+ if ( tempDir ) {
143+ await fs . remove ( tempDir ) . catch ( ( ) => {
144+ // Ignore cleanup errors
145+ } ) ;
146+ }
147+ }
148+ }
149+
150+ /**
151+ * Execute push from config JSON (existing behavior)
152+ */
153+ async function executeConfigPush (
154+ options : PushCommandOptions ,
155+ validatedEvent : { name : string ; data : Record < string , unknown > } ,
156+ logger : Logger ,
157+ setTempDir : ( dir : string ) => void ,
158+ ) : Promise < PushResult > {
159+ // Load config
160+ logger . debug ( 'Loading flow configuration' ) ;
161+ const { flowConfig, buildOptions } = await loadFlowConfig ( options . config , {
162+ flowName : options . flow ,
163+ logger,
164+ } ) ;
165+
166+ const platform = getPlatform ( flowConfig ) ;
167+
168+ // Bundle to temp file in config directory (so Node.js can find node_modules)
169+ logger . debug ( 'Bundling flow configuration' ) ;
170+ const configDir = buildOptions . configDir || process . cwd ( ) ;
171+ const tempDir = path . join (
172+ configDir ,
173+ '.tmp' ,
174+ `push-${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 9 ) } ` ,
175+ ) ;
176+ setTempDir ( tempDir ) ;
177+ await fs . ensureDir ( tempDir ) ;
178+ const tempPath = path . join (
179+ tempDir ,
180+ `bundle.${ platform === 'web' ? 'js' : 'mjs' } ` ,
181+ ) ;
182+
183+ const pushBuildOptions = {
184+ ...buildOptions ,
185+ output : tempPath ,
186+ format : platform === 'web' ? ( 'iife' as const ) : ( 'esm' as const ) ,
187+ platform : platform === 'web' ? ( 'browser' as const ) : ( 'node' as const ) ,
188+ ...( platform === 'web' && {
189+ windowCollector : 'collector' ,
190+ windowElb : 'elb' ,
191+ } ) ,
192+ } ;
193+
194+ await bundleCore ( flowConfig , pushBuildOptions , logger , false ) ;
195+
196+ logger . debug ( `Bundle created: ${ tempPath } ` ) ;
197+
198+ // Execute based on platform
199+ if ( platform === 'web' ) {
200+ logger . debug ( 'Executing in web environment (JSDOM)' ) ;
201+ return executeWebPush ( tempPath , validatedEvent , logger ) ;
202+ } else if ( platform === 'server' ) {
203+ logger . debug ( 'Executing in server environment (Node.js)' ) ;
204+ return executeServerPush ( tempPath , validatedEvent , logger ) ;
205+ } else {
206+ throw new Error ( `Unsupported platform: ${ platform } ` ) ;
207+ }
208+ }
209+
210+ /**
211+ * Execute push from pre-built bundle
212+ */
213+ async function executeBundlePush (
214+ bundleContent : string ,
215+ platform : Platform ,
216+ validatedEvent : { name : string ; data : Record < string , unknown > } ,
217+ logger : Logger ,
218+ setTempDir : ( dir : string ) => void ,
219+ ) : Promise < PushResult > {
220+ // Write bundle to temp file
221+ const tempDir = path . join (
222+ process . cwd ( ) ,
223+ '.tmp' ,
224+ `push-${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . slice ( 2 , 9 ) } ` ,
225+ ) ;
226+ setTempDir ( tempDir ) ;
227+ await fs . ensureDir ( tempDir ) ;
228+ const tempPath = path . join (
229+ tempDir ,
230+ `bundle.${ platform === 'server' ? 'mjs' : 'js' } ` ,
231+ ) ;
232+ await fs . writeFile ( tempPath , bundleContent , 'utf8' ) ;
233+
234+ logger . debug ( `Bundle written to: ${ tempPath } ` ) ;
235+
236+ // Execute based on platform
237+ if ( platform === 'web' ) {
238+ logger . debug ( 'Executing in web environment (JSDOM)' ) ;
239+ return executeWebPush ( tempPath , validatedEvent , logger ) ;
240+ } else {
241+ logger . debug ( 'Executing in server environment (Node.js)' ) ;
242+ return executeServerPush ( tempPath , validatedEvent , logger ) ;
168243 }
169244}
170245
0 commit comments