11/* eslint-disable max-len */
22import { CommandDefinition } from "../../types" ;
3- import { createWriteStream , lstatSync } from "fs" ;
3+ import { createWriteStream , lstatSync , readFileSync } from "fs" ;
44import { displayEntity , displayError , displayMessage , displayObject } from "../output" ;
55import { getHostClient } from "../common" ;
66import { getSequenceId , profileManager , sessionConfig } from "../config" ;
@@ -10,9 +10,12 @@ import { PassThrough, Writable } from "stream";
1010import { isDevelopment } from "../../utils/envs" ;
1111
1212import { resolve } from "path" ;
13- import { sequenceDelete , sequencePack , sequenceParseArgs , sequenceSendPackage , sequenceStart } from "../helpers/sequence" ;
13+ import { sequenceDelete , sequencePack , sequenceParseArgs , sequenceParseConfig , sequenceSendPackage , sequenceStart } from "../helpers/sequence" ;
1414import { ClientError } from "@scramjet/client-utils" ;
1515import { initPlatform } from "../platform" ;
16+ import { AppConfig , DeepPartial } from "@scramjet/types" ;
17+ import { isStartSequenceEndpointPayloadDTO , merge } from "@scramjet/utility" ;
18+ import { SequenceDeployArgs , SequenceStartCLIArgs } from "../../types/params" ;
1619
1720/**
1821 * Initializes `sequence` command.
@@ -108,6 +111,28 @@ export const sequence: CommandDefinition = (program) => {
108111 }
109112 ) ;
110113
114+ function validateStartupConfig ( config : DeepPartial < SequenceDeployArgs > ) {
115+ return isStartSequenceEndpointPayloadDTO ( config ) ;
116+ }
117+
118+ function loadStartupConfig ( filename : string ) : DeepPartial < SequenceDeployArgs > {
119+ if ( ! filename ) return { } ;
120+
121+ let json = { } ;
122+
123+ try {
124+ const data = readFileSync ( filename , "utf8" ) ;
125+
126+ json = JSON . parse ( data ) ;
127+ } catch ( e ) {
128+ // eslint-disable-next-line no-console
129+ console . error ( e ) ;
130+ process . exit ( 1 ) ;
131+ }
132+
133+ return json ;
134+ }
135+
111136 sequenceCmd
112137 . command ( "start" )
113138 . argument ( "<id>" , "Sequence id to start or '-' for the last uploaded" )
@@ -119,28 +144,40 @@ export const sequence: CommandDefinition = (program) => {
119144 . option ( "--output-topic <string>" , "Topic to which the output stream should be routed" )
120145 . option ( "--input-topic <string>" , "Topic to which the input stream should be routed" )
121146 . option ( "--args <json-string>" , "Arguments to be passed to the first function in the Sequence" )
147+ . option ( "--startup-config <path-to-config>" , "Path to startup config" , loadStartupConfig )
122148 . option ( "--limits <json-string>" , "Instance limits" )
123149 . description ( "Start the Sequence with or without given arguments" )
124- . action ( async ( id , { configFile, configString, outputTopic, inputTopic, args : argsStr , limits : limitsStr , instId } ) => {
125- let args ;
126-
127- if ( argsStr ) args = sequenceParseArgs ( argsStr ) ;
150+ . action ( async ( id , { startupConfig, configFile, configString, outputTopic, inputTopic, args : argsStr , limits : limitsStr , instId : instanceId } : SequenceStartCLIArgs ) => {
151+ const args = argsStr ? sequenceParseArgs ( argsStr ) : undefined ;
152+ const appConfig = await sequenceParseConfig ( configFile , configString ) ;
128153 const limits = limitsStr ? JSON . parse ( limitsStr ) : { } ;
129154
130- const instanceClient = await sequenceStart (
131- id , { configFile, configString, args, outputTopic, inputTopic, limits, instId } ) ;
155+ startupConfig ||= { } ;
156+ merge ( startupConfig , {
157+ appConfig,
158+ args,
159+ instanceId,
160+ inputTopic,
161+ outputTopic,
162+ limits
163+ } ) ;
164+
165+ if ( ! validateStartupConfig ( startupConfig ) ) {
166+ throw new Error ( "Invalid startup config" , ) ;
167+ }
168+
169+ const instanceClient = await sequenceStart ( id , {
170+ appConfig : startupConfig . appConfig as AppConfig ,
171+ args : startupConfig . args ,
172+ limits : startupConfig . limits ,
173+ instanceId : startupConfig . instanceId ,
174+ outputTopic : startupConfig . outputTopic ,
175+ inputTopic : startupConfig . inputTopic
176+ } ) ;
132177
133178 displayObject ( instanceClient , profileManager . getProfileConfig ( ) . format ) ;
134179 } ) ;
135180
136- type DeployArgs = {
137- output : string ;
138- configFile : any ;
139- configString : string ;
140- instId ?: string ;
141- args ?: string ;
142- } ;
143-
144181 sequenceCmd
145182 . command ( "deploy" )
146183 . alias ( "run" )
@@ -150,38 +187,64 @@ export const sequence: CommandDefinition = (program) => {
150187 . option ( "-s, --config-string <json-string>" , "Configuration in JSON format to be passed to the Instance context" )
151188 . option ( "--inst-id <string>" , "Start Sequence with a custom Instance Id. Should consist of 36 characters" )
152189 // TODO: check if output-topic and input-topic should be added after development
190+ . option ( "--output-topic <string>" , "Topic to which the output stream should be routed" )
191+ . option ( "--input-topic <string>" , "Topic to which the input stream should be routed" )
153192 . option ( "--args <json-string>" , "Arguments to be passed to the first function in the Sequence" )
193+ . option ( "--startup-config <path-to-config>" , "Path to startup config" , loadStartupConfig )
194+ . option ( "--limits <json-string>" , "Instance limits" )
154195 . description ( "Pack (if needed), send and start the Sequence" )
155- . action ( async ( path : string , { output : fileoutput , configFile, configString, args : argsStr , instId } : DeployArgs ) => {
156- let args ;
196+ . action ( async ( path : string , { startupConfig, output, configFile, configString, outputTopic, inputTopic, args : argsStr , limits : limitsStr , instId } : SequenceStartCLIArgs ) => {
197+ const args = argsStr ? sequenceParseArgs ( argsStr ) : undefined ;
198+ const appConfig = await sequenceParseConfig ( configFile , configString ) ;
199+ const limits = limitsStr ? JSON . parse ( limitsStr ) : { } ;
157200
158- if ( argsStr ) args = sequenceParseArgs ( argsStr ) ;
201+ startupConfig ||= { } ;
202+ merge ( startupConfig , {
203+ output,
204+ appConfig,
205+ args,
206+ instanceId : instId ,
207+ inputTopic,
208+ outputTopic,
209+ limits
210+ } ) ;
159211
160- const output = new PassThrough ( ) ;
212+ if ( ! validateStartupConfig ( startupConfig ) ) {
213+ throw new Error ( "Invalid startup config" , ) ;
214+ }
161215
162- if ( fileoutput ) {
163- const outputPath = fileoutput ? resolve ( fileoutput ) : `${ resolve ( path ) } .tar.gz` ;
216+ const compressedPackageStream = new PassThrough ( ) ;
164217
165- output . pipe ( createWriteStream ( outputPath ) ) ;
218+ if ( startupConfig . output ) {
219+ const outputPath = startupConfig . output ? resolve ( startupConfig . output ) : `${ resolve ( path ) } .tar.gz` ;
220+
221+ compressedPackageStream . pipe ( createWriteStream ( outputPath ) ) ;
166222 sessionConfig . setLastPackagePath ( outputPath ) ;
167223 }
168224 const format = profileManager . getProfileConfig ( ) . format ;
169225
170226 if ( lstatSync ( path ) . isDirectory ( ) ) {
171227 // eslint-disable-next-line @typescript-eslint/no-floating-promises
172- const sendSeqPromise = getHostClient ( ) . sendSequence ( output ) . then ( seq => {
228+ const sendSeqPromise = getHostClient ( ) . sendSequence ( compressedPackageStream ) . then ( seq => {
173229 sessionConfig . setLastSequenceId ( seq . id ) ;
174230 } ) ;
175231
176- await sequencePack ( path , { output } ) ;
232+ await sequencePack ( path , { output : compressedPackageStream } ) ;
177233 await sendSeqPromise ;
178234 } else {
179235 const sequenceClient = await sequenceSendPackage ( path , { } , false , { progress : sequenceCmd . parent ?. getOptionValue ( "progress" ) } ) ;
180236
181237 displayObject ( sequenceClient , profileManager . getProfileConfig ( ) . format ) ;
182238 }
183239
184- const instanceClient = await sequenceStart ( "-" , { configFile, configString, args, instId } ) ;
240+ const instanceClient = await sequenceStart ( "-" , {
241+ appConfig : startupConfig . appConfig as AppConfig ,
242+ args : startupConfig . args ,
243+ limits : startupConfig . limits ,
244+ instanceId : startupConfig . instanceId ,
245+ outputTopic : startupConfig . outputTopic ,
246+ inputTopic : startupConfig . inputTopic
247+ } ) ;
185248
186249 displayObject ( instanceClient , format ) ;
187250 } ) ;
0 commit comments