@@ -180,8 +180,25 @@ const enum PackageManager {
180180 bun = "bun" ,
181181}
182182
183+ /**
184+ * Middleware presets for Application template
185+ */
186+ enum MiddlewarePreset {
187+ api = "API :: REST API with security, compression, and auto-logging. (Recommended)" ,
188+ web = "Web :: Full web app with cookies and session support." ,
189+ graphql = "GraphQL :: Optimized for GraphQL APIs." ,
190+ microservice = "Microservice :: Minimal setup for microservices." ,
191+ minimal = "Minimal :: Just request parsing, customize everything yourself." ,
192+ }
193+
183194type TemplateKeys = keyof typeof Template ;
184- type ProjectFormArgs = [ PackageManager , TemplateKeys , string ] ;
195+ type MiddlewarePresetKeys = keyof typeof MiddlewarePreset ;
196+ type ProjectFormArgs = [
197+ PackageManager ,
198+ TemplateKeys ,
199+ string ,
200+ MiddlewarePresetKeys ,
201+ ] ;
185202
186203/**
187204 * Template folder mapping
@@ -191,6 +208,44 @@ const TEMPLATE_FOLDERS: Record<string, string> = {
191208 Micro : "micro" ,
192209} ;
193210
211+ /**
212+ * Middleware preset mapping to code
213+ */
214+ const PRESET_CODE : Record < string , string > = {
215+ API : `this.Middleware.applyPreset("api");` ,
216+ Web : `this.Middleware.applyPreset("web");` ,
217+ GraphQL : `this.Middleware.applyPreset("graphql");` ,
218+ Microservice : `this.Middleware.applyPreset("microservice");` ,
219+ Minimal : `this.Middleware.parse();` ,
220+ } ;
221+
222+ /**
223+ * Apply the selected middleware preset to the generated app.ts
224+ */
225+ function applyMiddlewarePreset ( directory : string , preset : string ) : void {
226+ const appTsPath = path . join ( directory , "src" , "app.ts" ) ;
227+
228+ if ( ! fs . existsSync ( appTsPath ) ) {
229+ return ;
230+ }
231+
232+ // Extract preset name from selection (e.g., "API :: ..." -> "API")
233+ const presetMatch = preset . match ( / ^ ( \w + ) : : / ) ;
234+ const presetName = presetMatch ? presetMatch [ 1 ] : "API" ;
235+
236+ const presetCode = PRESET_CODE [ presetName ] || PRESET_CODE [ "API" ] ;
237+
238+ let content = fs . readFileSync ( appTsPath , "utf-8" ) ;
239+
240+ // Replace the placeholder with the preset code
241+ content = content . replace (
242+ / \/ \/ _ _ M I D D L E W A R E _ P R E S E T _ P L A C E H O L D E R _ _ / ,
243+ presetCode ,
244+ ) ;
245+
246+ fs . writeFileSync ( appTsPath , content , "utf-8" ) ;
247+ }
248+
194249/**
195250 * Enable local template mode for testing
196251 * Set to true to use local templates instead of GitHub
@@ -221,20 +276,22 @@ const projectForm = async (
221276 name : string ;
222277 packageManager : string ;
223278 template : Template ;
279+ preset ?: MiddlewarePreset ;
224280 confirm : boolean ;
225281 } ;
226282
227- const [ packageManager , template , directory ] = args ;
283+ const [ packageManager , template , directory , preset ] = args ;
228284
229285 if ( packageManager && template ) {
230286 answer = {
231287 name : projectName ,
232288 packageManager : packageManager ,
233289 template : Template [ template ] ,
290+ preset : preset ? MiddlewarePreset [ preset ] : undefined ,
234291 confirm : true ,
235292 } ;
236293 } else {
237- answer = await inquirer . prompt ( [
294+ const baseAnswers = await inquirer . prompt ( [
238295 {
239296 type : "input" ,
240297 name : "name" ,
@@ -266,13 +323,43 @@ const projectForm = async (
266323 "Micro :: A minimalistic template for building micro APIs and serverless functions." ,
267324 ] ,
268325 } ,
326+ ] ) ;
327+
328+ // Only show preset selection for Application template
329+ let presetAnswer : { preset ?: MiddlewarePreset } = { } ;
330+ if ( baseAnswers . template . startsWith ( "Application" ) ) {
331+ presetAnswer = await inquirer . prompt ( [
332+ {
333+ type : "list" ,
334+ name : "preset" ,
335+ message : "Select a middleware preset" ,
336+ choices : [
337+ `API :: REST API with security, compression, and auto-logging. (${ chalk . yellow (
338+ "Recommended" ,
339+ ) } )`,
340+ "Web :: Full web app with cookies and session support." ,
341+ "GraphQL :: Optimized for GraphQL APIs." ,
342+ "Microservice :: Minimal setup for microservices." ,
343+ "Minimal :: Just request parsing, customize everything yourself." ,
344+ ] ,
345+ } ,
346+ ] ) ;
347+ }
348+
349+ const confirmAnswer = await inquirer . prompt ( [
269350 {
270351 type : "confirm" ,
271352 name : "confirm" ,
272353 message : "Do you want to create this project?" ,
273354 default : true ,
274355 } ,
275356 ] ) ;
357+
358+ answer = {
359+ ...baseAnswers ,
360+ ...presetAnswer ,
361+ ...confirmAnswer ,
362+ } ;
276363 }
277364
278365 if ( directory ) {
@@ -380,6 +467,11 @@ const projectForm = async (
380467 progressBar . update ( 90 , { doing : "Finalizing project" } ) ;
381468 }
382469
470+ // Apply middleware preset for Application template
471+ if ( answer . preset && templateFolder === "application" ) {
472+ applyMiddlewarePreset ( answer . name , answer . preset ) ;
473+ }
474+
383475 changePackageName ( {
384476 directory : answer . name ,
385477 name : projectName ,
0 commit comments