14
14
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
********************************************************************************/
16
16
17
- import type execa = require ( 'execa' ) ;
18
- import path = require ( ' path') ;
19
- import Base = require ( 'yeoman-generator' ) ;
20
- const request = require ( 'request' ) ;
21
- const tar = require ( 'tar' ) ;
22
- const fs = require ( 'fs-extra' ) ;
17
+ import * as fs from 'node:fs/promises' ;
18
+ import * as path from 'node: path';
19
+ import * as url from 'node:url' ;
20
+ import request from 'request' ;
21
+ import tar from 'tar' ;
22
+ import Base , { BaseFeatures , BaseOptions } from 'yeoman-generator/typed' ;
23
23
24
24
const glspExamplesRepositoryTag = "generator-latest" ;
25
25
const backend = "backend" ;
@@ -40,13 +40,26 @@ enum TemplateType {
40
40
Node = 'node' ,
41
41
}
42
42
43
- module . exports = class TheiaExtension extends Base {
43
+ type ExtensionOptions = {
44
+ extensionType : ExtensionType ;
45
+ extensionName ?: string ;
46
+ browser : boolean ;
47
+ electron : boolean ;
48
+ standalone ?: boolean ;
49
+ templateType : string ;
50
+ "theia-version" : string ;
51
+ "lerna-version" : string ;
52
+ githubURL : string ;
53
+ params : unknown ;
54
+ }
55
+
56
+ export default class TheiaExtension extends Base < BaseOptions & ExtensionOptions > {
44
57
45
58
params : {
46
59
author : string
47
60
version : string
48
61
license : string
49
- extensionName : string
62
+ extensionName ? : string
50
63
extensionType : string
51
64
templateType : string
52
65
unscopedExtensionName : string
@@ -67,13 +80,14 @@ module.exports = class TheiaExtension extends Base {
67
80
rootscripts : string
68
81
containsTests : boolean
69
82
electronMainLocation : string
83
+ backend ?: boolean
70
84
} ;
71
85
72
- constructor ( args : string | string [ ] , options : Base . GeneratorOptions ) {
86
+ constructor ( args : string | string [ ] , options : BaseOptions & ExtensionOptions ) {
73
87
// For v5 generators the '<npm|pnpm|yarn> install' task is implicitely invoked by 'yeoman-environment' since 'yeoman-environment@3', see
74
88
// https://github.com/yeoman/environment/commit/ab9582a70073203c7a6b58fb6dbf1f4eba249d48#diff-54bc5f4bd40f22e081d54b6c20bbf2523e438cf2f2716b91714a1f596e4d87cd
75
89
// since we spawn the pm processes on our own in 'install()', we need to declare that here in order to avoid errors because of concurrent runs!
76
- super ( args , options , { customInstallTask : true } ) ;
90
+ super ( args , options , < BaseFeatures > { customInstallTask : true } ) ;
77
91
78
92
this . argument ( 'extensionName' , {
79
93
type : String ,
@@ -155,12 +169,12 @@ module.exports = class TheiaExtension extends Base {
155
169
}
156
170
157
171
path ( ) {
158
- this . sourceRoot ( __dirname + '/../../templates' ) ;
172
+ this . sourceRoot ( path . dirname ( url . fileURLToPath ( import . meta . url ) ) + '/../../templates' ) ;
159
173
}
160
174
161
175
async prompting ( ) {
162
- let extensionType = ( this . options as any ) . extensionType ;
163
- const inExtensionType = ( < any > Object ) . values ( ExtensionType ) . includes ( extensionType ) ;
176
+ let extensionType = this . options . extensionType ;
177
+ const inExtensionType = Object . values ( ExtensionType ) . includes ( extensionType ) ;
164
178
if ( ( extensionType === undefined ) || ! inExtensionType ) {
165
179
if ( ! ( extensionType === undefined ) ) {
166
180
this . log ( `Invalid extension type: ${ extensionType } ` ) ;
@@ -179,7 +193,7 @@ module.exports = class TheiaExtension extends Base {
179
193
{ value : ExtensionType . DiagramEditor , name : 'DiagramEditor' }
180
194
]
181
195
} ) ;
182
- ( this . options as any ) . extensionType = answer . type ;
196
+ this . options . extensionType = answer . type ;
183
197
184
198
if ( answer . type === ExtensionType . DiagramEditor ) {
185
199
const answer = await this . prompt ( {
@@ -193,7 +207,7 @@ module.exports = class TheiaExtension extends Base {
193
207
} ) ;
194
208
let template = answer . backend ;
195
209
196
- ( this . options as any ) . templateType = template ;
210
+ this . options . templateType = template ;
197
211
198
212
if ( template === TemplateType . Java ) {
199
213
this . log ( '\x1b[32m%s\x1b[0m' , 'The template will use an EMF source model on the server and generate a Theia extension ✓' )
@@ -204,22 +218,22 @@ module.exports = class TheiaExtension extends Base {
204
218
}
205
219
}
206
220
207
- let extensionName = ( this . options as any ) . extensionName ;
221
+ let extensionName = this . options . extensionName ;
208
222
// extensionName is not used within the DiagramEditor
209
223
if ( ! extensionName && this . options . extensionType !== ExtensionType . DiagramEditor ) {
210
224
const answer = await this . prompt ( {
211
225
type : 'input' ,
212
226
name : 'name' ,
213
227
message : 'The extension\'s name' ,
214
- default : ( this . options as any ) . extensionType
228
+ default : this . options . extensionType
215
229
} ) ;
216
- ( this . options as any ) . extensionName = answer . name ;
230
+ this . options . extensionName = answer . name ;
217
231
}
218
232
}
219
233
220
234
configuring ( ) {
221
- const options = this . options as any
222
- const extensionName = options . extensionName as string
235
+ const options = this . options
236
+ const extensionName = options . extensionName
223
237
let unscopedExtensionName = ''
224
238
let extensionPath = ''
225
239
let extensionPrefix = ''
@@ -234,7 +248,7 @@ module.exports = class TheiaExtension extends Base {
234
248
const templateType = options . templateType ;
235
249
const githubURL = options . githubURL ;
236
250
this . log ( extensionPrefix ) ;
237
- this . params = {
251
+ this . params = < any > {
238
252
...options ,
239
253
extensionName,
240
254
unscopedExtensionName,
@@ -245,7 +259,7 @@ module.exports = class TheiaExtension extends Base {
245
259
githubURL,
246
260
theiaVersion : options [ "theia-version" ] ,
247
261
lernaVersion : options [ "lerna-version" ] ,
248
- backend : options [ " extensionType" ] === ExtensionType . Backend ,
262
+ backend : options . extensionType === ExtensionType . Backend ,
249
263
electronMainLocation : this . getElectronMainLocation ( options [ "theia-version" ] )
250
264
}
251
265
this . params . dependencies = '' ;
@@ -259,13 +273,13 @@ module.exports = class TheiaExtension extends Base {
259
273
this . params . rootscripts = `,\n "test": "cd ${ this . params . extensionPath } && yarn test"` ;
260
274
this . params . containsTests = true ;
261
275
}
262
- options . params = this . params
276
+ options . params = this . params // piggyback the params to options and hand them over to the child generators
263
277
if ( ! options . standalone && this . params . extensionType !== ExtensionType . DiagramEditor ) {
264
278
if ( options . browser ) {
265
- this . composeWith ( require . resolve ( '../browser' ) , this . options ) ;
279
+ this . composeWith ( '../browser/index.js' , this . options ) ;
266
280
}
267
281
if ( options . electron ) {
268
- this . composeWith ( require . resolve ( '../electron' ) , this . options ) ;
282
+ this . composeWith ( '../electron/index.js' , this . options ) ;
269
283
}
270
284
}
271
285
if ( options . standalone ) {
@@ -497,7 +511,7 @@ module.exports = class TheiaExtension extends Base {
497
511
498
512
/** DiagramEditor */
499
513
if ( this . params . extensionType === ExtensionType . DiagramEditor ) {
500
- const baseDir = `./ glsp-examples-${ glspExamplesRepositoryTag } ` ;
514
+ const baseDir = `glsp-examples-${ glspExamplesRepositoryTag } ` ;
501
515
let templatePath = '' ;
502
516
if ( this . params . templateType == TemplateType . Java ) {
503
517
templatePath = '/project-templates/java-emf-theia' ;
@@ -507,13 +521,18 @@ module.exports = class TheiaExtension extends Base {
507
521
return ;
508
522
}
509
523
510
- return new Promise < void > ( ( resolve ) => {
511
- request . get ( `https://github.com/eclipse-glsp/glsp-examples/archive/refs/tags/${ glspExamplesRepositoryTag } .tar.gz` ) . pipe ( tar . x ( ) . on ( 'close' , ( ) => {
512
- fs . copy ( baseDir + '/README.md' , './README.md' ) ;
513
- fs . copy ( baseDir + templatePath , './' ) . then ( ( ) => {
514
- fs . rm ( baseDir , { recursive : true } ) ;
524
+ const dest = this . destinationPath . bind ( this ) ;
525
+
526
+ return new Promise < void > ( ( resolve , reject ) => {
527
+ request . get ( `https://github.com/eclipse-glsp/glsp-examples/archive/refs/tags/${ glspExamplesRepositoryTag } .tar.gz` ) . pipe ( tar . x ( { cwd : dest ( ) } ) . on ( 'close' , async ( ) => {
528
+ try {
529
+ await fs . cp ( dest ( baseDir , 'README.md' ) , dest ( './README.md' ) ) ;
530
+ await fs . cp ( dest ( baseDir , templatePath ) , dest ( ) , { recursive : true } ) ;
531
+ await fs . rm ( dest ( baseDir ) , { recursive : true } ) ;
515
532
resolve ( ) ;
516
- } ) ;
533
+ } catch ( e ) {
534
+ reject ( e ) ;
535
+ }
517
536
} ) ) ;
518
537
} ) ;
519
538
}
@@ -524,9 +543,9 @@ module.exports = class TheiaExtension extends Base {
524
543
}
525
544
526
545
async install ( ) {
527
- if ( ! ( this . options as any ) . skipInstall ) {
546
+ if ( ! this . options . skipInstall ) {
528
547
this . log ( 'Installing dependencies' ) ;
529
- const command : execa . ExecaChildProcess = this . spawnCommand ( 'yarn' , [ ] ) ;
548
+ const command = this . spawn ( 'yarn' , [ ] ) ;
530
549
531
550
if ( this . params . extensionType == ExtensionType . DiagramEditor ) {
532
551
command . on ( 'close' , ( code :number ) => {
@@ -573,6 +592,3 @@ module.exports = class TheiaExtension extends Base {
573
592
}
574
593
}
575
594
}
576
-
577
- module . exports . ExtensionType = ExtensionType ;
578
-
0 commit comments