Skip to content

Commit e9651e1

Browse files
feat(cli): implements name for repository and change documentation
1 parent 6baeaaa commit e9651e1

File tree

3 files changed

+82
-47
lines changed

3 files changed

+82
-47
lines changed

docs/site/Repository-generator.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,20 @@ permalink: /doc/en/lb4/Repository-generator.html
1313
Adds a new [Repository or Multiple Repositories](Repositories.md) class to a
1414
LoopBack application with one single command.
1515

16-
### Notes
17-
18-
The optional argument `[<name>]`, referes to a valid datasource already created
19-
in `src/datasources` directory and should match the name property inside any of
20-
the `.json` files.
21-
22-
Service oriented datasources such as REST or SOAP are not considered valid and
23-
thus not presented to you in the selection list.
24-
25-
There should be at least one valid _(KeyValue or Persisted)_ data source and one
26-
model already created in their respective directories.
27-
2816
```sh
2917
lb4 repository [options] [<name>]
3018
```
3119

3220
### Options
3321

22+
`--datasource` : _(Optional)_ name of a valid datasource already created in
23+
src/datasources
24+
3425
`--model` : _(Optional)_ name of a valid model already created in src/models
3526

3627
`--id` : _(Optional)_ name of the property serving as **ID** in the selected
37-
model. Keep in mind that CLI will still check and try to infer a valid ID from
38-
the model file and give it priority over the one supplied here.
28+
model. If you supply this value, the CLI will not try to infer this value from
29+
the selected model file.
3930

4031
### Configuration file
4132

@@ -45,27 +36,36 @@ file.
4536

4637
```ts
4738
{
48-
"name": "validDataSourceName",
39+
"name": "repositoryNameToBeGenerated",
40+
"datasource": "validDataSourceName",
4941
"model": "validDModelName",
5042
"id": "anOptionalNameForID"
5143
}
5244
```
5345

46+
### Notes
47+
48+
Service oriented datasources such as REST or SOAP are not considered valid and
49+
thus not presented to you in the selection list.
50+
51+
There should be at least one valid _(KeyValue or Persisted)_ data source and one
52+
model already created in their respective directories.
53+
5454
{% include_relative includes/CLI-std-options.md %}
5555

5656
### Arguments
5757

58-
`<name>` - Optional argument specifyng a valid datasource name. The value should
59-
match the name property of a valid datasource in any of the `src/datasources`
60-
json files.
58+
`<name>` - Optional argument specifyng the respository name to be generated. In
59+
case you select multiple models, the first model will take this argument for its
60+
repository file name.
6161

6262
### Interactive Prompts
6363

6464
The tool will prompt you for:
6565

6666
- **Please select the datasource.** _(name)_ If the name of the datasource had
6767
been supplied from the command line, the prompt is skipped, otherwise it will
68-
present you, the list of available datasources to select one. IT will use this
68+
present you, the list of available datasources to select one. It will use this
6969
datasource to check what kind of repository it will generate.
7070

7171
- **Select the model(s) you want to generate a repository.** _(model)_ If the

packages/cli/generators/repository/index.js

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const ERROR_READING_FILE = 'Error reading file';
3131
const ERROR_NO_DATA_SOURCES_FOUND = 'No datasources found in';
3232
const ERROR_NO_MODELS_FOUND = 'No models found in';
3333
const ERROR_NO_MODEL_SELECTED = 'You did not select a valid model';
34-
const ERROR_NO_DIRECTORY = "couldn't find the directory";
34+
const ERROR_NO_DIRECTORY = 'The directory was not found';
3535

3636
module.exports = class RepositoryGenerator extends ArtifactGenerator {
3737
// Note: arguments and options should be defined in the constructor.
@@ -140,7 +140,7 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
140140

141141
_setupGenerator() {
142142
this.artifactInfo = {
143-
type: 'datasource to use ',
143+
type: 'repository ',
144144
rootDir: 'src',
145145
};
146146

@@ -171,6 +171,12 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
171171
description: 'A valid ID property name for the specified model',
172172
});
173173

174+
this.option('datasource', {
175+
type: String,
176+
required: false,
177+
description: 'A valid datasource name',
178+
});
179+
174180
return super._setupGenerator();
175181
}
176182

@@ -212,8 +218,8 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
212218
let datasourcesList;
213219

214220
// grab the datasourcename from the command line
215-
cmdDatasourceName = this.options.name
216-
? utils.toClassName(this.options.name) + 'Datasource'
221+
cmdDatasourceName = this.options.datasource
222+
? utils.toClassName(this.options.datasource) + 'Datasource'
217223
: '';
218224

219225
debug(`command line datasource is ${cmdDatasourceName}`);
@@ -344,6 +350,7 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
344350

345351
async promptModelId() {
346352
if (this.shouldExit()) return false;
353+
let idType;
347354

348355
debug(`Model ID property name from command line: ${this.options.id}`);
349356
debug(`Selected Models: ${this.artifactInfo.modelNameList}`);
@@ -364,26 +371,22 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
364371
},
365372
];
366373

367-
let idType = await this._getModelIdType(item);
368-
369-
/**
370-
* fallback by asking the user for ID property name if the user
371-
* didn't supplied any from the command line. If we inferred it, then
372-
* the supplied argument is ignored
373-
*/
374-
if (idType === null) {
375-
if (this.options.id) {
376-
idType = this.options.id;
377-
/** make sure it is only used once, in case user selected more
378-
* than one model.
379-
*/
380-
delete this.options.id;
381-
} else {
374+
// user supplied the id from the command line
375+
if (this.options.id) {
376+
debug(`passing thru this.options.id with value : ${this.options.id}`);
377+
378+
idType = this.options.id;
379+
/** make sure it is only used once, in case user selected more
380+
* than one model.
381+
*/
382+
delete this.options.id;
383+
} else {
384+
idType = await this._getModelIdType(item);
385+
if (idType === null) {
382386
const answer = await this.prompt(prompts);
383387
idType = answer.propertyName;
384388
}
385389
}
386-
387390
this.artifactInfo.idType = idType;
388391
// Generate this repository
389392
await this._scaffold();
@@ -394,12 +397,20 @@ module.exports = class RepositoryGenerator extends ArtifactGenerator {
394397
async _scaffold() {
395398
if (this.shouldExit()) return false;
396399

397-
this.artifactInfo.className = utils.toClassName(
398-
this.artifactInfo.modelName,
399-
);
400+
if (this.options.name) {
401+
this.artifactInfo.className = utils.toClassName(this.options.name);
402+
this.artifactInfo.outFile =
403+
utils.kebabCase(this.options.name) + '.repository.ts';
400404

401-
this.artifactInfo.outFile =
402-
utils.kebabCase(this.artifactInfo.modelName) + '.repository.ts';
405+
// make sure the name supplied from cmd line is only used once
406+
delete this.options.name;
407+
} else {
408+
this.artifactInfo.className = utils.toClassName(
409+
this.artifactInfo.modelName,
410+
);
411+
this.artifactInfo.outFile =
412+
utils.kebabCase(this.artifactInfo.modelName) + '.repository.ts';
413+
}
403414

404415
if (debug.enabled) {
405416
debug(`Artifact output filename set to: ${this.artifactInfo.outFile}`);

packages/cli/test/integration/generators/repository.integration.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,30 @@ describe('lb4 repository', () => {
6161
);
6262
});
6363

64+
it('generates a custom name repository', async () => {
65+
await testUtils
66+
.executeGenerator(generator)
67+
.inDir(
68+
SANDBOX_PATH,
69+
async () => await prepareGeneratorForRepository(SANDBOX_PATH),
70+
)
71+
.withArguments('myrepo --datasource dbmem --model MultiWord');
72+
const expectedFile = path.join(
73+
SANDBOX_PATH,
74+
REPOSITORY_APP_PATH,
75+
'myrepo.repository.ts',
76+
);
77+
78+
assert.file(expectedFile);
79+
assert.fileContent(
80+
expectedFile,
81+
/export class MyrepoRepository extends DefaultCrudRepository</,
82+
);
83+
assert.fileContent(expectedFile, /typeof MultiWord.prototype.pk/);
84+
assert.file(INDEX_FILE);
85+
assert.fileContent(INDEX_FILE, /export \* from '.\/myrepo.repository';/);
86+
});
87+
6488
it('generates a crud repository from a config file', async () => {
6589
await testUtils
6690
.executeGenerator(generator)
@@ -208,7 +232,7 @@ describe('lb4 repository', () => {
208232
SANDBOX_PATH,
209233
async () => await prepareGeneratorForRepository(SANDBOX_PATH),
210234
)
211-
.withArguments('dbmem --model decoratordefined');
235+
.withArguments('--datasource dbmem --model decoratordefined');
212236
const expectedFile = path.join(
213237
SANDBOX_PATH,
214238
REPOSITORY_APP_PATH,
@@ -239,7 +263,7 @@ describe('lb4 repository', () => {
239263
SANDBOX_PATH,
240264
async () => await prepareGeneratorForRepository(SANDBOX_PATH),
241265
)
242-
.withArguments('dbkv --model Defaultmodel');
266+
.withArguments('--datasource dbkv --model Defaultmodel');
243267
const expectedFile = path.join(
244268
SANDBOX_PATH,
245269
REPOSITORY_APP_PATH,
@@ -302,7 +326,7 @@ const SANDBOX_FILES = [
302326
path: CONFIG_PATH,
303327
file: 'myconfig.json',
304328
content: `{
305-
"name": "dbmem",
329+
"datasource": "dbmem",
306330
"model": "decoratordefined"
307331
}`,
308332
},

0 commit comments

Comments
 (0)