11import fs from 'fs'
2+ import path from 'path'
3+
4+ import { Listr } from 'listr2'
25
36import { getConfigPath } from '@redwoodjs/project-config'
7+ import { errorTelemetry } from '@redwoodjs/telemetry'
48
5- import { writeFile } from '../../lib'
9+ import { getPaths , transformTSToJS , writeFile } from '../../lib'
10+ import c from '../../lib/colors'
11+ import { isTypeScriptProject } from '../../lib/project'
612
713import {
814 command ,
@@ -11,44 +17,164 @@ import {
1117} from './setupStreamingSsr'
1218import { printTaskEpilogue } from './util'
1319
14- export const handler = async ( { force } ) => {
20+ export const handler = async ( { force, verbose } ) => {
21+ const rwPaths = getPaths ( )
1522 const redwoodTomlPath = getConfigPath ( )
1623 const configContent = fs . readFileSync ( redwoodTomlPath , 'utf-8' )
24+ const ts = isTypeScriptProject ( )
25+ const ext = path . extname ( rwPaths . web . entryClient || '' )
1726
18- if ( ! configContent . includes ( '[experimental.streamingSsr]' ) ) {
19- console . log ( 'Adding config to redwood.toml...' )
27+ const tasks = new Listr (
28+ [
29+ {
30+ title : 'Check prerequisites' ,
31+ task : ( ) => {
32+ if ( ! rwPaths . web . entryClient || ! rwPaths . web . viteConfig ) {
33+ throw new Error (
34+ 'Vite needs to be setup before you can enable Streaming SSR'
35+ )
36+ }
37+ } ,
38+ } ,
39+ {
40+ title : 'Adding config to redwood.toml...' ,
41+ task : ( _ctx , task ) => {
42+ if ( ! configContent . includes ( '[experimental.streamingSsr]' ) ) {
43+ writeFile (
44+ redwoodTomlPath ,
45+ configContent . concat (
46+ `\n[experimental.streamingSsr]\n enabled = true\n`
47+ ) ,
48+ {
49+ overwriteExisting : true , // redwood.toml always exists
50+ }
51+ )
52+ } else {
53+ if ( force ) {
54+ task . output = 'Overwriting config in redwood.toml'
2055
21- // Use string replace to preserve comments and formatting
22- writeFile (
23- redwoodTomlPath ,
24- configContent . concat ( `\n[experimental.streamingSsr]\n enabled = true\n` ) ,
56+ writeFile (
57+ redwoodTomlPath ,
58+ configContent . replace (
59+ // Enable if it's currently disabled
60+ `\n[experimental.streamingSsr]\n enabled = false\n` ,
61+ `\n[experimental.streamingSsr]\n enabled = true\n`
62+ ) ,
63+ {
64+ overwriteExisting : true , // redwood.toml always exists
65+ }
66+ )
67+ } else {
68+ task . skip (
69+ `The [experimental.streamingSsr] config block already exists in your 'redwood.toml' file.`
70+ )
71+ }
72+ }
73+ } ,
74+ options : { persistentOutput : true } ,
75+ } ,
2576 {
26- overwriteExisting : true , // redwood.toml always exists
27- }
28- )
29- } else {
30- if ( force ) {
31- console . log ( 'Updating config in redwood.toml...' )
32- writeFile (
33- redwoodTomlPath ,
34- configContent . replace (
35- // Enable if it's currently disabled
36- `\n[experimental.streamingSsr]\n enabled = false\n` ,
37- `\n[experimental.streamingSsr]\n enabled = true\n`
38- ) ,
39- {
40- overwriteExisting : true , // redwood.toml always exists
41- }
42- )
43- } else {
44- console . log ( 'Adding config to redwood.toml...' )
45- console . log (
46- " The [experimental.studio] config block already exists in your 'redwood.toml' file."
47- )
48- }
49- }
77+ title : `Adding entry.client${ ext } ...` ,
78+ task : async ( _ctx , task ) => {
79+ const entryClientTemplate = fs . readFileSync (
80+ path . resolve (
81+ __dirname ,
82+ 'templates' ,
83+ 'streamingSsr' ,
84+ 'entry.client.tsx.template'
85+ ) ,
86+ 'utf-8'
87+ )
88+ let entryClientPath = rwPaths . web . entryClient
89+ const entryClientContent = ts
90+ ? entryClientTemplate
91+ : transformTSToJS ( entryClientPath , entryClientTemplate )
92+
93+ let overwriteExisting = force
5094
51- console . log ( )
95+ if ( ! force ) {
96+ overwriteExisting = await task . prompt ( {
97+ type : 'Confirm' ,
98+ message : `Overwrite ${ entryClientPath } ?` ,
99+ } )
52100
53- printTaskEpilogue ( command , description , EXPERIMENTAL_TOPIC_ID )
101+ if ( ! overwriteExisting ) {
102+ entryClientPath = entryClientPath . replace ( ext , `.new${ ext } ` )
103+ task . output =
104+ `File will be written to ${ entryClientPath } \n` +
105+ `You'll manually need to merge it with your existing entry.client${ ext } file.`
106+ }
107+ }
108+
109+ writeFile ( entryClientPath , entryClientContent , { overwriteExisting } )
110+ } ,
111+ options : { persistentOutput : true } ,
112+ } ,
113+ {
114+ title : `Adding entry.server${ ext } ...` ,
115+ task : async ( ) => {
116+ const entryServerTemplate = fs . readFileSync (
117+ path . resolve (
118+ __dirname ,
119+ 'templates' ,
120+ 'streamingSsr' ,
121+ 'entry.server.tsx.template'
122+ ) ,
123+ 'utf-8'
124+ )
125+ // Can't use rwPaths.web.entryServer because it might not be not created yet
126+ const entryServerPath = path . join (
127+ rwPaths . web . src ,
128+ `entry.server${ ext } `
129+ )
130+ const entryServerContent = ts
131+ ? entryServerTemplate
132+ : transformTSToJS ( entryServerPath , entryServerTemplate )
133+
134+ writeFile ( entryServerPath , entryServerContent , {
135+ overwriteExisting : force ,
136+ } )
137+ } ,
138+ } ,
139+ {
140+ title : `Adding Document${ ext } ...` ,
141+ task : async ( ) => {
142+ const documentTemplate = fs . readFileSync (
143+ path . resolve (
144+ __dirname ,
145+ 'templates' ,
146+ 'streamingSsr' ,
147+ 'Document.tsx.template'
148+ ) ,
149+ 'utf-8'
150+ )
151+ const documentPath = path . join ( rwPaths . web . src , `Document${ ext } ` )
152+ const documentContent = ts
153+ ? documentTemplate
154+ : transformTSToJS ( documentPath , documentTemplate )
155+
156+ writeFile ( documentPath , documentContent , {
157+ overwriteExisting : force ,
158+ } )
159+ } ,
160+ } ,
161+ {
162+ task : ( ) => {
163+ printTaskEpilogue ( command , description , EXPERIMENTAL_TOPIC_ID )
164+ } ,
165+ } ,
166+ ] ,
167+ {
168+ rendererOptions : { collapseSubtasks : false , persistentOutput : true } ,
169+ renderer : verbose ? 'verbose' : 'default' ,
170+ }
171+ )
172+
173+ try {
174+ await tasks . run ( )
175+ } catch ( e ) {
176+ errorTelemetry ( process . argv , e . message )
177+ console . error ( c . error ( e . message ) )
178+ process . exit ( e ?. exitCode || 1 )
179+ }
54180}
0 commit comments