11import { NextRequest , NextResponse } from 'next/server'
2- import { readFile } from 'fs/promises'
3- import path from 'path'
4-
52import type { WizardResponses } from '@/types/wizard'
6- import { getTemplateConfig , type TemplateKey } from '@/lib/template-config'
7- import { getStackGuidance } from '@/lib/stack-guidance'
8-
9- function mapOutputFileToTemplateType ( outputFile : string ) : string {
10- const mapping : Record < string , string > = {
11- 'instructions-md' : 'copilot-instructions' ,
12- 'agents-md' : 'agents' ,
13- 'cursor-rules' : 'cursor-rules' ,
14- 'json-rules' : 'json-rules' ,
15- }
16-
17- return mapping [ outputFile ] ?? outputFile
18- }
3+ import { renderTemplate } from '@/lib/template-render'
194
205export async function POST (
216 request : NextRequest ,
@@ -25,113 +10,15 @@ export async function POST(
2510 const { framework, fileName } = await context . params
2611 const responses = ( await request . json ( ) ) as WizardResponses
2712
28- const frameworkFromPath =
29- framework && ! [ 'general' , 'none' , 'undefined' ] . includes ( framework )
30- ? framework
31- : undefined
32-
33- const templateKeyFromParams : TemplateKey = {
34- templateType : mapOutputFileToTemplateType ( fileName ) ,
35- stack : frameworkFromPath ,
36- }
37-
38- let templateConfig = getTemplateConfig ( templateKeyFromParams )
39-
40- if ( ! templateConfig && responses . outputFile ) {
41- const templateKeyFromBody : TemplateKey = {
42- templateType : mapOutputFileToTemplateType ( responses . outputFile ) ,
43- stack : responses . stackSelection || undefined ,
44- }
45-
46- templateConfig = getTemplateConfig ( templateKeyFromBody )
47- }
48-
49- if ( ! templateConfig ) {
50- templateConfig = getTemplateConfig ( fileName )
51- }
52-
53- if ( ! templateConfig ) {
54- return NextResponse . json (
55- { error : `Template not found for fileName: ${ fileName } ` } ,
56- { status : 404 } ,
57- )
58- }
59-
60- const templatePath = path . join ( process . cwd ( ) , 'file-templates' , templateConfig . template )
61- const template = await readFile ( templatePath , 'utf-8' )
62-
63- let generatedContent = template
64- const isJsonTemplate = templateConfig . template . toLowerCase ( ) . endsWith ( '.json' )
65-
66- const escapeForJson = ( value : string ) => {
67- const escaped = JSON . stringify ( value )
68- return escaped . slice ( 1 , - 1 )
69- }
70-
71- const replaceVariable = ( key : keyof WizardResponses , fallback = 'Not specified' ) => {
72- const placeholder = `{{${ key } }}`
73-
74- if ( ! generatedContent . includes ( placeholder ) ) {
75- return
76- }
77-
78- const value = responses [ key ]
79-
80- if ( value === null || value === undefined || value === '' ) {
81- const replacement = isJsonTemplate ? escapeForJson ( fallback ) : fallback
82- generatedContent = generatedContent . replace ( placeholder , replacement )
83- } else {
84- const replacementValue = String ( value )
85- const replacement = isJsonTemplate ? escapeForJson ( replacementValue ) : replacementValue
86- generatedContent = generatedContent . replace ( placeholder , replacement )
87- }
88- }
89-
90- replaceVariable ( 'stackSelection' )
91- replaceVariable ( 'tooling' )
92- replaceVariable ( 'language' )
93- replaceVariable ( 'projectPriority' )
94- replaceVariable ( 'codeStyle' )
95- replaceVariable ( 'variableNaming' )
96- replaceVariable ( 'fileNaming' )
97- replaceVariable ( 'componentNaming' )
98- replaceVariable ( 'exports' )
99- replaceVariable ( 'comments' )
100- replaceVariable ( 'collaboration' )
101- replaceVariable ( 'fileStructure' )
102- replaceVariable ( 'styling' )
103- replaceVariable ( 'stateManagement' )
104- replaceVariable ( 'apiLayer' )
105- replaceVariable ( 'folders' )
106- replaceVariable ( 'testingUT' )
107- replaceVariable ( 'testingE2E' )
108- replaceVariable ( 'dataFetching' )
109- replaceVariable ( 'reactPerf' )
110- replaceVariable ( 'auth' )
111- replaceVariable ( 'validation' )
112- replaceVariable ( 'logging' )
113- replaceVariable ( 'commitStyle' )
114- replaceVariable ( 'prRules' )
115- const replaceStaticPlaceholder = ( placeholderKey : string , value : string ) => {
116- const placeholder = `{{${ placeholderKey } }}`
117-
118- if ( ! generatedContent . includes ( placeholder ) ) {
119- return
120- }
121-
122- const replacement = isJsonTemplate ? escapeForJson ( value ) : value
123- generatedContent = generatedContent . replace ( placeholder , replacement )
124- }
125-
126- replaceVariable ( 'outputFile' )
127-
128- const stackGuidanceSlug = responses . stackSelection || frameworkFromPath
129- const stackGuidance = getStackGuidance ( stackGuidanceSlug )
130- replaceStaticPlaceholder ( 'stackGuidance' , stackGuidance )
13+ const rendered = await renderTemplate ( {
14+ responses,
15+ frameworkFromPath : framework ,
16+ fileNameFromPath : fileName ,
17+ } )
13118
13219 return NextResponse . json ( {
133- content : generatedContent ,
134- fileName : templateConfig . outputFileName ,
20+ content : rendered . content ,
21+ fileName : rendered . fileName ,
13522 } )
13623 } catch ( error ) {
13724 console . error ( 'Error generating file:' , error )
0 commit comments