@@ -10,17 +10,30 @@ const AdmZip = require('adm-zip');
1010const args = process . argv . slice ( 2 ) ;
1111
1212if ( args . length < 1 ) {
13- console . error ( 'Usage: npx create-net <repo> [ProjectName]' ) ;
13+ console . error ( 'Usage: npx create-net <repo|ls> [ProjectName]' ) ;
14+ console . error ( '' ) ;
15+ console . error ( 'Commands:' ) ;
16+ console . error ( ' ls [org] List available project templates' ) ;
17+ console . error ( ' <repo> [name] Create a project from a template' ) ;
1418 console . error ( '' ) ;
1519 console . error ( 'If ProjectName is not specified, uses current directory name and extracts into current directory.' ) ;
1620 console . error ( '' ) ;
1721 console . error ( 'Examples:' ) ;
22+ console . error ( ' npx create-net ls' ) ;
23+ console . error ( ' npx create-net ls NetFrameworkTemplates' ) ;
1824 console . error ( ' npx create-net nextjs MyProject' ) ;
1925 console . error ( ' npx create-net NetFrameworkTemplates/web-netfx MyProject' ) ;
2026 console . error ( ' npx create-net nextjs (uses current directory name)' ) ;
2127 process . exit ( 1 ) ;
2228}
2329
30+ // Handle ls command to list available templates
31+ if ( args [ 0 ] === 'ls' || args [ 0 ] === 'list' ) {
32+ const targetOrg = args [ 1 ] ; // Optional organization/user name
33+ listTemplates ( targetOrg ) ;
34+ return ;
35+ }
36+
2437const repo = args [ 0 ] ;
2538let projectName = args [ 1 ] ;
2639let extractToCurrentDir = false ;
@@ -71,6 +84,98 @@ if (extractToCurrentDir) {
7184 }
7285}
7386
87+ // Function to fetch JSON from GitHub API
88+ function fetchJSON ( url ) {
89+ return new Promise ( ( resolve , reject ) => {
90+ https . get ( url , {
91+ headers : {
92+ 'User-Agent' : 'create-net'
93+ }
94+ } , ( response ) => {
95+ let data = '' ;
96+
97+ // Handle redirects
98+ if ( response . statusCode === 301 || response . statusCode === 302 ) {
99+ return fetchJSON ( response . headers . location ) . then ( resolve ) . catch ( reject ) ;
100+ }
101+
102+ if ( response . statusCode !== 200 ) {
103+ return reject ( new Error ( `HTTP ${ response . statusCode } : ${ response . statusMessage } ` ) ) ;
104+ }
105+
106+ response . on ( 'data' , chunk => data += chunk ) ;
107+ response . on ( 'end' , ( ) => {
108+ try {
109+ resolve ( JSON . parse ( data ) ) ;
110+ } catch ( err ) {
111+ reject ( err ) ;
112+ }
113+ } ) ;
114+ } ) . on ( 'error' , reject ) ;
115+ } ) ;
116+ }
117+
118+ // Function to list available templates
119+ async function listTemplates ( targetOrg ) {
120+ console . log ( 'Fetching available project templates...\n' ) ;
121+
122+ let organizations ;
123+
124+ if ( targetOrg ) {
125+ // List templates from specific organization
126+ organizations = [ { name : targetOrg , title : `${ targetOrg } Templates` } ] ;
127+ } else {
128+ // List templates from default organizations
129+ organizations = [
130+ { name : 'NetCoreTemplates' , title : '.NET Core Templates' } ,
131+ { name : 'NetFrameworkTemplates' , title : '.NET Framework Templates' }
132+ ] ;
133+ }
134+
135+ try {
136+ for ( const org of organizations ) {
137+ console . log ( `\x1b[1m${ org . title } \x1b[0m` ) ;
138+ console . log ( '─' . repeat ( 80 ) ) ;
139+
140+ try {
141+ const repos = await fetchJSON ( `https://api.github.com/orgs/${ org . name } /repos?per_page=100&sort=updated` ) ;
142+
143+ if ( ! repos || repos . length === 0 ) {
144+ console . log ( ' No templates found' ) ;
145+ } else {
146+ // Find the longest repo name for padding
147+ const maxNameLength = Math . max ( ...repos . map ( r => r . name . length ) ) ;
148+ const padding = Math . max ( maxNameLength + 2 , 25 ) ;
149+
150+ repos . forEach ( repo => {
151+ const name = repo . name . padEnd ( padding ) ;
152+ const description = repo . description || 'No description available' ;
153+ console . log ( ` ${ name } ${ description } ` ) ;
154+ } ) ;
155+ }
156+ } catch ( err ) {
157+ console . log ( ` Error fetching templates: ${ err . message } ` ) ;
158+ }
159+
160+ console . log ( '' ) ;
161+ }
162+
163+ console . log ( '\x1b[1mUsage:\x1b[0m' ) ;
164+ console . log ( ' npx create-net <repo> [ProjectName]' ) ;
165+ console . log ( ' npx create-net <org>/<repo> [ProjectName]' ) ;
166+ console . log ( ' npx create-net ls [org]' ) ;
167+ console . log ( '\n\x1b[1mExamples:\x1b[0m' ) ;
168+ console . log ( ' npx create-net ls # List all templates' ) ;
169+ console . log ( ' npx create-net ls NetFrameworkTemplates # List specific org templates' ) ;
170+ console . log ( ' npx create-net nextjs MyProject # Create from NetCoreTemplates' ) ;
171+ console . log ( ' npx create-net NetFrameworkTemplates/web-netfx MyApp # Create from specific org' ) ;
172+
173+ } catch ( err ) {
174+ console . error ( 'Error listing templates:' , err . message ) ;
175+ process . exit ( 1 ) ;
176+ }
177+ }
178+
74179// Function to download file from URL
75180function downloadFile ( url , destination ) {
76181 return new Promise ( ( resolve , reject ) => {
0 commit comments