@@ -21,7 +21,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
2121var index_exports = { } ;
2222__export ( index_exports , {
2323 LaunchStackClient : ( ) => LaunchStackClient ,
24- LaunchStackError : ( ) => LaunchStackError
24+ LaunchStackError : ( ) => LaunchStackError ,
25+ copyDirectory : ( ) => copyDirectory ,
26+ ensureDestinationAvailable : ( ) => ensureDestinationAvailable ,
27+ generateProject : ( ) => generateProject ,
28+ renderDirectory : ( ) => renderDirectory ,
29+ renderTemplate : ( ) => renderTemplate ,
30+ toDisplayName : ( ) => toDisplayName ,
31+ validateProjectName : ( ) => validateProjectName
2532} ) ;
2633module . exports = __toCommonJS ( index_exports ) ;
2734
@@ -94,8 +101,164 @@ var LaunchStackClient = class {
94101 } ) ;
95102 }
96103} ;
104+
105+ // src/generator/generate.ts
106+ var import_node_path4 = require ( "path" ) ;
107+
108+ // src/generator/files.ts
109+ var import_node_fs = require ( "fs" ) ;
110+ var import_node_path = require ( "path" ) ;
111+ var RENAMED_TEMPLATE_FILES = {
112+ "_gitignore" : ".gitignore" ,
113+ "_npmrc" : ".npmrc" ,
114+ "_env.example" : ".env.example"
115+ } ;
116+ function ensureDestinationAvailable ( destinationDirectory , overwrite = false ) {
117+ if ( ! ( 0 , import_node_fs . existsSync ) ( destinationDirectory ) ) {
118+ return ;
119+ }
120+ const contents = ( 0 , import_node_fs . readdirSync ) ( destinationDirectory ) ;
121+ if ( contents . length > 0 && ! overwrite ) {
122+ throw new Error (
123+ `Destination is not empty: ${ destinationDirectory } . Use overwrite to continue.`
124+ ) ;
125+ }
126+ }
127+ function copyDirectory ( sourceDirectory , destinationDirectory ) {
128+ if ( ! ( 0 , import_node_fs . existsSync ) ( sourceDirectory ) ) {
129+ throw new Error ( `Template directory not found: ${ sourceDirectory } ` ) ;
130+ }
131+ ( 0 , import_node_fs . mkdirSync ) ( destinationDirectory , { recursive : true } ) ;
132+ ( 0 , import_node_fs . cpSync ) ( sourceDirectory , destinationDirectory , {
133+ recursive : true ,
134+ force : true
135+ } ) ;
136+ renameTemplateFiles ( destinationDirectory ) ;
137+ }
138+ function renameTemplateFiles ( directory ) {
139+ for ( const entry of ( 0 , import_node_fs . readdirSync ) ( directory ) ) {
140+ const path = ( 0 , import_node_path . join ) ( directory , entry ) ;
141+ const stats = ( 0 , import_node_fs . statSync ) ( path ) ;
142+ if ( stats . isDirectory ( ) ) {
143+ renameTemplateFiles ( path ) ;
144+ continue ;
145+ }
146+ const replacementName = RENAMED_TEMPLATE_FILES [ ( 0 , import_node_path . basename ) ( path ) ] ;
147+ if ( ! replacementName ) {
148+ continue ;
149+ }
150+ const content = ( 0 , import_node_fs . readFileSync ) ( path ) ;
151+ const replacementPath = ( 0 , import_node_path . resolve ) ( directory , replacementName ) ;
152+ ( 0 , import_node_fs . writeFileSync ) ( replacementPath , content ) ;
153+ const { unlinkSync } = require ( "fs" ) ;
154+ unlinkSync ( path ) ;
155+ }
156+ }
157+
158+ // src/generator/names.ts
159+ var PROJECT_NAME_PATTERN = / ^ [ a - z 0 - 9 ] + (?: - [ a - z 0 - 9 ] + ) * $ / ;
160+ function validateProjectName ( projectName ) {
161+ if ( ! projectName . trim ( ) ) {
162+ throw new Error ( "Project name is required." ) ;
163+ }
164+ if ( ! PROJECT_NAME_PATTERN . test ( projectName ) ) {
165+ throw new Error (
166+ "Project name must use lowercase letters, numbers, and hyphens only."
167+ ) ;
168+ }
169+ }
170+ function toDisplayName ( projectName ) {
171+ return projectName . split ( "-" ) . filter ( Boolean ) . map ( ( part ) => part . charAt ( 0 ) . toUpperCase ( ) + part . slice ( 1 ) ) . join ( " " ) ;
172+ }
173+
174+ // src/generator/paths.ts
175+ var import_node_fs2 = require ( "fs" ) ;
176+ var import_node_path2 = require ( "path" ) ;
177+ function findPackageRoot ( ) {
178+ const candidates = [
179+ process . cwd ( ) ,
180+ ( 0 , import_node_path2 . resolve ) ( process . cwd ( ) , ".." ) ,
181+ ( 0 , import_node_path2 . resolve ) ( process . cwd ( ) , "../.." )
182+ ] ;
183+ for ( const candidate of candidates ) {
184+ if ( ( 0 , import_node_fs2 . existsSync ) ( ( 0 , import_node_path2 . resolve ) ( candidate , "package.json" ) ) ) {
185+ return candidate ;
186+ }
187+ }
188+ throw new Error ( "Could not locate the LaunchStack package root." ) ;
189+ }
190+ function getPackageRoot ( ) {
191+ return findPackageRoot ( ) ;
192+ }
193+ function getTemplateDirectory ( templateName ) {
194+ const packageRoot = getPackageRoot ( ) ;
195+ const candidates = [
196+ ( 0 , import_node_path2 . resolve ) ( packageRoot , "src" , "templates" , templateName ) ,
197+ ( 0 , import_node_path2 . resolve ) ( packageRoot , "dist" , "templates" , templateName ) ,
198+ ( 0 , import_node_path2 . resolve ) ( packageRoot , "templates" , templateName )
199+ ] ;
200+ const templateDirectory = candidates . find (
201+ ( candidate ) => ( 0 , import_node_fs2 . existsSync ) ( candidate )
202+ ) ;
203+ if ( ! templateDirectory ) {
204+ throw new Error ( `Template directory not found: ${ templateName } ` ) ;
205+ }
206+ return templateDirectory ;
207+ }
208+
209+ // src/generator/template.ts
210+ var import_node_fs3 = require ( "fs" ) ;
211+ var import_node_path3 = require ( "path" ) ;
212+ function renderTemplate ( content , variables ) {
213+ return Object . entries ( variables ) . reduce (
214+ ( rendered , [ key , value ] ) => rendered . split ( `{{${ key } }}` ) . join ( value ) ,
215+ content
216+ ) ;
217+ }
218+ function renderDirectory ( directory , variables ) {
219+ if ( ! ( 0 , import_node_fs3 . existsSync ) ( directory ) ) {
220+ throw new Error ( `Directory not found: ${ directory } ` ) ;
221+ }
222+ for ( const entry of ( 0 , import_node_fs3 . readdirSync ) ( directory ) ) {
223+ const path = ( 0 , import_node_path3 . join ) ( directory , entry ) ;
224+ const stats = ( 0 , import_node_fs3 . statSync ) ( path ) ;
225+ if ( stats . isDirectory ( ) ) {
226+ renderDirectory ( path , variables ) ;
227+ continue ;
228+ }
229+ const content = ( 0 , import_node_fs3 . readFileSync ) ( path , "utf8" ) ;
230+ const rendered = renderTemplate ( content , variables ) ;
231+ if ( rendered !== content ) {
232+ ( 0 , import_node_fs3 . writeFileSync ) ( path , rendered ) ;
233+ }
234+ }
235+ }
236+
237+ // src/generator/generate.ts
238+ function generateProject ( options ) {
239+ validateProjectName ( options . projectName ) ;
240+ const destinationDirectory = ( 0 , import_node_path4 . resolve ) ( options . destinationDirectory ) ;
241+ ensureDestinationAvailable (
242+ destinationDirectory ,
243+ options . overwrite ?? false
244+ ) ;
245+ const templateDirectory = getTemplateDirectory ( options . template ) ;
246+ copyDirectory ( templateDirectory , destinationDirectory ) ;
247+ renderDirectory ( destinationDirectory , {
248+ PROJECT_NAME : options . projectName ,
249+ PROJECT_DISPLAY_NAME : toDisplayName ( options . projectName )
250+ } ) ;
251+ return destinationDirectory ;
252+ }
97253// Annotate the CommonJS export names for ESM import in node:
982540 && ( module . exports = {
99255 LaunchStackClient,
100- LaunchStackError
256+ LaunchStackError,
257+ copyDirectory,
258+ ensureDestinationAvailable,
259+ generateProject,
260+ renderDirectory,
261+ renderTemplate,
262+ toDisplayName,
263+ validateProjectName
101264} ) ;
0 commit comments