@@ -14,19 +14,42 @@ const chalk = require('chalk');
14
14
const utils = require ( '../../lib/utils' ) ;
15
15
const connectors = require ( '../datasource/connectors.json' ) ;
16
16
const tsquery = require ( '../../lib/ast-helper' ) ;
17
+ const pascalCase = require ( 'change-case' ) . pascalCase ;
17
18
18
19
const VALID_CONNECTORS_FOR_REPOSITORY = [ 'KeyValueModel' , 'PersistedModel' ] ;
19
20
const KEY_VALUE_CONNECTOR = [ 'KeyValueModel' ] ;
20
21
21
22
const DEFAULT_CRUD_REPOSITORY = 'DefaultCrudRepository' ;
22
23
const KEY_VALUE_REPOSITORY = 'DefaultKeyValueRepository' ;
24
+ const BASE_REPOSITORIES = [ DEFAULT_CRUD_REPOSITORY , KEY_VALUE_REPOSITORY ] ;
25
+ const CLI_BASE_CRUD_REPOSITORIES = [
26
+ {
27
+ name : `${ DEFAULT_CRUD_REPOSITORY } ${ chalk . gray ( '(Legacy juggler bridge)' ) } ` ,
28
+ value : DEFAULT_CRUD_REPOSITORY ,
29
+ } ,
30
+ ] ;
31
+ const CLI_BASE_KEY_VALUE_REPOSITORIES = [
32
+ {
33
+ name : `${ KEY_VALUE_REPOSITORY } ${ chalk . gray (
34
+ '(For access to a key-value store)' ,
35
+ ) } `,
36
+ value : KEY_VALUE_REPOSITORY ,
37
+ } ,
38
+ ] ;
39
+ const CLI_BASE_SEPARATOR = [
40
+ {
41
+ type : 'separator' ,
42
+ line : '----- Custom Repositories -----' ,
43
+ } ,
44
+ ] ;
23
45
24
46
const REPOSITORY_KV_TEMPLATE = 'repository-kv-template.ts.ejs' ;
25
47
const REPOSITORY_CRUD_TEMPLATE = 'repository-crud-default-template.ts.ejs' ;
26
48
27
49
const PROMPT_MESSAGE_MODEL =
28
50
'Select the model(s) you want to generate a repository' ;
29
51
const PROMPT_MESSAGE_DATA_SOURCE = 'Please select the datasource' ;
52
+ const PROMPT_BASE_REPOSITORY_CLASS = 'Please select the repository base class' ;
30
53
const ERROR_READING_FILE = 'Error reading file' ;
31
54
const ERROR_NO_DATA_SOURCES_FOUND = 'No datasources found at' ;
32
55
const ERROR_NO_MODELS_FOUND = 'No models found at' ;
@@ -38,6 +61,35 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
38
61
super ( args , opts ) ;
39
62
}
40
63
64
+ /**
65
+ * Find all the base artifacts in the given path whose type matches the
66
+ * provided artifactType.
67
+ * For example, a artifactType of "repository" will search the target path for
68
+ * matches to "*.repository.base.ts"
69
+ * @param {string } dir The target directory from which to load artifacts.
70
+ * @param {string } artifactType The artifact type (ex. "model", "repository")
71
+ */
72
+ async _findBaseClasses ( dir , artifactType ) {
73
+ const paths = await utils . findArtifactPaths ( dir , artifactType + '.base' ) ;
74
+ debug ( `repository artifact paths: ${ paths } ` ) ;
75
+
76
+ // get base class and path
77
+ const baseRepositoryList = [ ] ;
78
+ for ( const p of paths ) {
79
+ //get name removing anything from .artifactType.base
80
+ const artifactFile = path . parse ( _ . last ( _ . split ( p , path . sep ) ) ) . name ;
81
+ const firstWord = _ . first ( _ . split ( artifactFile , '.' ) ) ;
82
+ const artifactName =
83
+ utils . toClassName ( firstWord ) + utils . toClassName ( artifactType ) ;
84
+
85
+ const baseRepository = { name : artifactName , file : artifactFile } ;
86
+ baseRepositoryList . push ( baseRepository ) ;
87
+ }
88
+
89
+ debug ( `repository base classes: ${ inspect ( baseRepositoryList ) } ` ) ;
90
+ return baseRepositoryList ;
91
+ }
92
+
41
93
/**
42
94
* get the property name for the id field
43
95
* @param {string } modelName
@@ -131,6 +183,13 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
131
183
description : 'A valid datasource name' ,
132
184
} ) ;
133
185
186
+ this . option ( 'repositoryBaseClass' , {
187
+ type : String ,
188
+ required : false ,
189
+ description : 'A valid repository base class' ,
190
+ default : 'DefaultCrudRepository' ,
191
+ } ) ;
192
+
134
193
return super . _setupGenerator ( ) ;
135
194
}
136
195
@@ -313,6 +372,65 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
313
372
} ) ;
314
373
}
315
374
375
+ async promptBaseClass ( ) {
376
+ debug ( 'Prompting for repository base' ) ;
377
+ if ( this . shouldExit ( ) ) return ;
378
+
379
+ const availableRepositoryList = [ ] ;
380
+
381
+ debug ( `repositoryTypeClass ${ this . artifactInfo . repositoryTypeClass } ` ) ;
382
+ // Add base repositories based on datasource type
383
+ if ( this . artifactInfo . repositoryTypeClass === KEY_VALUE_REPOSITORY )
384
+ availableRepositoryList . push ( ...CLI_BASE_KEY_VALUE_REPOSITORIES ) ;
385
+ else availableRepositoryList . push ( ...CLI_BASE_CRUD_REPOSITORIES ) ;
386
+ availableRepositoryList . push ( ...CLI_BASE_SEPARATOR ) ;
387
+
388
+ try {
389
+ this . artifactInfo . baseRepositoryList = await this . _findBaseClasses (
390
+ this . artifactInfo . outDir ,
391
+ 'repository' ,
392
+ ) ;
393
+ if (
394
+ this . artifactInfo . baseRepositoryList &&
395
+ this . artifactInfo . baseRepositoryList . length > 0
396
+ ) {
397
+ availableRepositoryList . push ( ...this . artifactInfo . baseRepositoryList ) ;
398
+ debug ( `availableRepositoryList ${ availableRepositoryList } ` ) ;
399
+ }
400
+ } catch ( err ) {
401
+ return this . exit ( err ) ;
402
+ }
403
+
404
+ if ( this . options . repositoryBaseClass ) {
405
+ debug (
406
+ `Base repository received from command line: ${
407
+ this . options . repositoryBaseClass
408
+ } `,
409
+ ) ;
410
+ this . artifactInfo . repositoryBaseClass = this . options . repositoryBaseClass ;
411
+ }
412
+
413
+ return this . prompt ( [
414
+ {
415
+ type : 'list' ,
416
+ name : 'repositoryBaseClass' ,
417
+ message : PROMPT_BASE_REPOSITORY_CLASS ,
418
+ when : this . artifactInfo . repositoryBaseClass === undefined ,
419
+ choices : availableRepositoryList ,
420
+ default : availableRepositoryList [ 0 ] ,
421
+ } ,
422
+ ] )
423
+ . then ( props => {
424
+ debug ( `props after custom repository prompt: ${ inspect ( props ) } ` ) ;
425
+ Object . assign ( this . artifactInfo , props ) ;
426
+ return props ;
427
+ } )
428
+ . catch ( err => {
429
+ debug ( `Error during repository base class prompt: ${ err . stack } ` ) ;
430
+ return this . exit ( err ) ;
431
+ } ) ;
432
+ }
433
+
316
434
async promptModelId ( ) {
317
435
if ( this . shouldExit ( ) ) return false ;
318
436
let idProperty ;
@@ -362,6 +480,22 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
362
480
async _scaffold ( ) {
363
481
if ( this . shouldExit ( ) ) return false ;
364
482
483
+ this . artifactInfo . isRepositoryBaseBuiltin = BASE_REPOSITORIES . includes (
484
+ this . artifactInfo . repositoryBaseClass ,
485
+ ) ;
486
+ debug (
487
+ `isRepositoryBaseBuiltin : ${ this . artifactInfo . isRepositoryBaseBuiltin } ` ,
488
+ ) ;
489
+ if ( ! this . artifactInfo . isRepositoryBaseBuiltin ) {
490
+ const baseIndex = _ . findIndex ( this . artifactInfo . baseRepositoryList , [
491
+ 'name' ,
492
+ this . artifactInfo . repositoryBaseClass ,
493
+ ] ) ;
494
+ this . artifactInfo . repositoryBaseFile = this . artifactInfo . baseRepositoryList [
495
+ baseIndex
496
+ ] . file ;
497
+ }
498
+
365
499
if ( this . options . name ) {
366
500
this . artifactInfo . className = utils . toClassName ( this . options . name ) ;
367
501
this . artifactInfo . outFile = utils . getRepositoryFileName (
@@ -401,6 +535,7 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
401
535
debug ( `artifactInfo: ${ inspect ( this . artifactInfo ) } ` ) ;
402
536
debug ( `Copying artifact to: ${ dest } ` ) ;
403
537
}
538
+
404
539
this . copyTemplatedFiles ( source , dest , this . artifactInfo ) ;
405
540
return ;
406
541
}
@@ -412,6 +547,13 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
412
547
? 'Repositories'
413
548
: 'Repository' ;
414
549
550
+ this . artifactInfo . modelNameList = _ . map (
551
+ this . artifactInfo . modelNameList ,
552
+ repositoryName => {
553
+ return repositoryName + 'Repository' ;
554
+ } ,
555
+ ) ;
556
+
415
557
this . artifactInfo . name = this . artifactInfo . modelNameList
416
558
? this . artifactInfo . modelNameList . join ( )
417
559
: this . artifactInfo . modelName ;
0 commit comments