@loopback/cli 4.0.0-alpha.9 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.yo-rc.json +1719 -0
- package/{generators/project/templates/LICENSE → LICENSE} +2 -1
- package/README.md +44 -43
- package/bin/cli-main.js +61 -0
- package/generators/app/index.js +109 -15
- package/generators/app/templates/.dockerignore +5 -0
- package/generators/app/templates/Dockerfile +28 -0
- package/generators/app/templates/README.md.ejs +130 -0
- package/generators/app/templates/public/index.html.ejs +88 -0
- package/generators/app/templates/{test → src/__tests__}/README.md +0 -1
- package/generators/app/templates/src/__tests__/acceptance/home-page.acceptance.ts.ejs +31 -0
- package/generators/app/templates/src/__tests__/acceptance/ping.controller.acceptance.ts.ejs +21 -0
- package/generators/app/templates/src/__tests__/acceptance/test-helper.ts.ejs +32 -0
- package/generators/app/templates/src/application.ts.ejs +70 -0
- package/generators/app/templates/src/controllers/README.md +6 -0
- package/generators/app/templates/src/controllers/index.ts.ejs +1 -0
- package/generators/app/templates/src/controllers/ping.controller.ts.ejs +55 -0
- package/generators/app/templates/src/datasources/README.md +3 -0
- package/generators/app/templates/src/index.ts.ejs +39 -0
- package/generators/app/templates/src/migrate.ts.ejs +20 -0
- package/generators/app/templates/src/models/README.md +3 -0
- package/generators/app/templates/src/openapi-spec.ts.ejs +23 -0
- package/generators/app/templates/src/sequence.ts.ejs +3 -0
- package/generators/controller/index.js +240 -23
- package/generators/controller/templates/src/controllers/controller-rest-template.ts.ejs +150 -0
- package/generators/controller/templates/src/controllers/{controller-template.ts → controller-template.ts.ejs} +2 -2
- package/generators/copyright/fs.js +46 -0
- package/generators/copyright/git.js +78 -0
- package/generators/copyright/header.js +306 -0
- package/generators/copyright/index.js +230 -0
- package/generators/copyright/license.js +105 -0
- package/generators/datasource/index.js +341 -0
- package/generators/datasource/templates/datasource.ts.ejs +22 -0
- package/generators/discover/import-discovered-model.js +70 -0
- package/generators/discover/index.js +411 -0
- package/generators/example/downloader.js +16 -0
- package/generators/example/index.js +176 -0
- package/generators/extension/index.js +34 -5
- package/generators/extension/templates/README.md.ejs +32 -0
- package/generators/extension/templates/{test → src/__tests__}/acceptance/README.md +0 -0
- package/generators/extension/templates/{test → src/__tests__}/integration/README.md +0 -0
- package/generators/extension/templates/{test → src/__tests__}/unit/README.md +0 -0
- package/generators/extension/templates/src/component.ts.ejs +22 -0
- package/generators/extension/templates/src/controllers/README.md +3 -2
- package/generators/extension/templates/src/decorators/README.md +10 -4
- package/generators/extension/templates/src/index.ts.ejs +3 -0
- package/generators/extension/templates/src/keys.ts.ejs +11 -0
- package/generators/extension/templates/src/mixins/README.md +77 -21
- package/generators/extension/templates/src/providers/README.md +51 -25
- package/generators/extension/templates/src/repositories/README.md +1 -1
- package/generators/extension/templates/src/types.ts.ejs +15 -0
- package/generators/import-lb3-models/index.js +197 -0
- package/generators/import-lb3-models/lb3app-loader.js +31 -0
- package/generators/import-lb3-models/migrate-model.js +249 -0
- package/generators/import-lb3-models/model-names.js +32 -0
- package/generators/interceptor/index.js +178 -0
- package/generators/interceptor/templates/interceptor-template.ts.ejs +62 -0
- package/generators/model/index.js +536 -0
- package/generators/model/property-definition.js +85 -0
- package/generators/model/templates/model.ts.ejs +49 -0
- package/generators/observer/index.js +132 -0
- package/generators/observer/templates/observer-template.ts.ejs +40 -0
- package/generators/openapi/README.md +211 -0
- package/generators/openapi/index.js +535 -0
- package/generators/openapi/schema-helper.js +447 -0
- package/generators/openapi/spec-helper.js +484 -0
- package/generators/openapi/spec-loader.js +75 -0
- package/generators/openapi/templates/src/controllers/controller-template.ts.ejs +43 -0
- package/generators/openapi/templates/src/datasources/datasource.ts.ejs +42 -0
- package/generators/openapi/templates/src/models/model-template.ts.ejs +71 -0
- package/generators/openapi/templates/src/models/type-template.ts.ejs +13 -0
- package/generators/openapi/templates/src/services/service-proxy-template.ts.ejs +55 -0
- package/generators/openapi/utils.js +322 -0
- package/generators/project/templates/.eslintignore +4 -0
- package/generators/project/templates/.eslintrc.js.ejs +3 -0
- package/generators/project/templates/.mocharc.json +5 -0
- package/generators/project/templates/.prettierignore +0 -2
- package/generators/project/templates/.prettierrc +2 -1
- package/generators/project/templates/.vscode/launch.json +38 -0
- package/generators/project/templates/.vscode/settings.json +32 -0
- package/generators/project/templates/.vscode/tasks.json +29 -0
- package/generators/project/templates/DEVELOPING.md +36 -0
- package/generators/project/templates/_.gitignore +3 -5
- package/generators/project/templates/package.json.ejs +175 -0
- package/generators/project/templates/package.plain.json.ejs +176 -0
- package/generators/project/templates/tsconfig.json.ejs +39 -0
- package/generators/relation/base-relation.generator.js +220 -0
- package/generators/relation/belongs-to-relation.generator.js +196 -0
- package/generators/relation/has-many-relation.generator.js +200 -0
- package/generators/relation/has-many-through-relation.generator.js +331 -0
- package/generators/relation/has-one-relation.generator.js +200 -0
- package/generators/relation/index.js +795 -0
- package/generators/relation/references-many-relation.generator.js +142 -0
- package/generators/relation/templates/controller-relation-template-belongs-to.ts.ejs +38 -0
- package/generators/relation/templates/controller-relation-template-has-many-through.ts.ejs +110 -0
- package/generators/relation/templates/controller-relation-template-has-many.ts.ejs +110 -0
- package/generators/relation/templates/controller-relation-template-has-one.ts.ejs +110 -0
- package/generators/relation/utils.generator.js +260 -0
- package/generators/repository/index.js +576 -0
- package/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs +21 -0
- package/generators/repository/templates/src/repositories/repository-kv-template.ts.ejs +19 -0
- package/generators/rest-crud/crud-rest-component.js +63 -0
- package/generators/rest-crud/index.js +423 -0
- package/generators/rest-crud/templates/src/model-endpoints/model.rest-config-template.ts.ejs +11 -0
- package/generators/service/index.js +351 -0
- package/generators/service/templates/local-service-class-template.ts.ejs +10 -0
- package/generators/service/templates/local-service-provider-template.ts.ejs +19 -0
- package/generators/service/templates/remote-service-proxy-template.ts.ejs +21 -0
- package/generators/update/index.js +55 -0
- package/intl/cs/messages.json +204 -0
- package/intl/de/messages.json +204 -0
- package/intl/en/messages.json +204 -0
- package/intl/es/messages.json +204 -0
- package/intl/fr/messages.json +204 -0
- package/intl/it/messages.json +204 -0
- package/intl/ja/messages.json +204 -0
- package/intl/ko/messages.json +204 -0
- package/intl/nl/messages.json +204 -0
- package/intl/pl/messages.json +204 -0
- package/intl/pt/messages.json +204 -0
- package/intl/ru/messages.json +204 -0
- package/intl/tr/messages.json +204 -0
- package/intl/zh-Hans/messages.json +204 -0
- package/intl/zh-Hant/messages.json +204 -0
- package/lib/artifact-generator.js +138 -39
- package/lib/ast-helper.js +214 -0
- package/lib/base-generator.js +509 -0
- package/lib/cli.js +233 -0
- package/lib/connectors.json +894 -0
- package/lib/debug.js +16 -0
- package/lib/globalize.js +12 -0
- package/lib/model-discoverer.js +118 -0
- package/lib/project-generator.js +154 -57
- package/lib/tab-completion.js +127 -0
- package/lib/update-index.js +44 -0
- package/lib/utils.js +689 -20
- package/lib/version-helper.js +299 -0
- package/package.json +183 -39
- package/CHANGELOG.md +0 -86
- package/bin/cli.js +0 -66
- package/generators/app/templates/index.js +0 -14
- package/generators/app/templates/src/application.ts +0 -27
- package/generators/app/templates/src/controllers/ping-controller.ts +0 -25
- package/generators/app/templates/src/index.ts +0 -25
- package/generators/app/templates/test/ping-controller.test.ts +0 -46
- package/generators/extension/templates/index.js +0 -8
- package/generators/extension/templates/src/component.ts +0 -14
- package/generators/extension/templates/src/index.ts +0 -6
- package/generators/project/templates/.npmrc +0 -1
- package/generators/project/templates/.yo-rc.json +0 -1
- package/generators/project/templates/README.md +0 -4
- package/generators/project/templates/index.d.ts +0 -6
- package/generators/project/templates/index.ts +0 -11
- package/generators/project/templates/package.json +0 -79
- package/generators/project/templates/package.plain.json +0 -82
- package/generators/project/templates/test/mocha.opts +0 -1
- package/generators/project/templates/tsconfig.json +0 -29
- package/generators/project/templates/tslint.build.json +0 -17
- package/generators/project/templates/tslint.json +0 -33
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
// Copyright IBM Corp. and LoopBack contributors 2019,2020. All Rights Reserved.
|
|
2
|
+
// Node module: @loopback/cli
|
|
3
|
+
// This file is licensed under the MIT License.
|
|
4
|
+
// License text available at https://opensource.org/licenses/MIT
|
|
5
|
+
|
|
6
|
+
// no translation: HasMany, BelongsTo, HasOne, ReferencesMany
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const ArtifactGenerator = require('../../lib/artifact-generator');
|
|
10
|
+
const debug = require('../../lib/debug')('relation-generator');
|
|
11
|
+
const inspect = require('util').inspect;
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const chalk = require('chalk');
|
|
14
|
+
const utils = require('../../lib/utils');
|
|
15
|
+
const relationUtils = require('./utils.generator');
|
|
16
|
+
|
|
17
|
+
const BelongsToRelationGenerator = require('./belongs-to-relation.generator');
|
|
18
|
+
const HasManyRelationGenerator = require('./has-many-relation.generator');
|
|
19
|
+
const HasManyThroughRelationGenerator = require('./has-many-through-relation.generator');
|
|
20
|
+
const HasOneRelationGenerator = require('./has-one-relation.generator');
|
|
21
|
+
const ReferencesManyRelationGenerator = require('./references-many-relation.generator');
|
|
22
|
+
|
|
23
|
+
const g = require('../../lib/globalize');
|
|
24
|
+
|
|
25
|
+
const ERROR_INCORRECT_RELATION_TYPE = g.f('Incorrect relation type');
|
|
26
|
+
const ERROR_MODEL_DOES_NOT_EXIST = g.f('model does not exist.');
|
|
27
|
+
const ERROR_NO_MODELS_FOUND = g.f('No models found in');
|
|
28
|
+
const ERROR_REPOSITORY_DOES_NOT_EXIST = g.f(
|
|
29
|
+
'class does not exist. Please create repository first with "lb4 repository" command.',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const PROMPT_BASE_RELATION_CLASS = g.f('Please select the relation type');
|
|
33
|
+
const PROMPT_MESSAGE_SOURCE_MODEL = g.f('Please select source model');
|
|
34
|
+
const PROMPT_MESSAGE_TARGET_MODEL = g.f('Please select target model');
|
|
35
|
+
const PROMPT_MESSAGE_THROUGH_MODEL = g.f('Please select through model');
|
|
36
|
+
const PROMPT_MESSAGE_PROPERTY_NAME = g.f(
|
|
37
|
+
'Source property name for the relation getter (will be the relation name)',
|
|
38
|
+
);
|
|
39
|
+
const PROMPT_MESSAGE_RELATION_NAME = g.f('Relation name');
|
|
40
|
+
const PROMPT_MESSAGE_FOREIGN_KEY_NAME = g.f(
|
|
41
|
+
'Foreign key name to define on the target model',
|
|
42
|
+
);
|
|
43
|
+
const PROMPT_MESSAGE_FOREIGN_KEY_NAME_BELONGS_TO = g.f(
|
|
44
|
+
'Foreign key name to define on the source model',
|
|
45
|
+
);
|
|
46
|
+
const PROMPT_MESSAGE_FOREIGN_KEY_NAME_REFERENCES_MANY = g.f(
|
|
47
|
+
'Foreign key name to define on the source model',
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
module.exports = class RelationGenerator extends ArtifactGenerator {
|
|
51
|
+
constructor(args, opts) {
|
|
52
|
+
super(args, opts);
|
|
53
|
+
this.args = args;
|
|
54
|
+
this.opts = opts;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
setOptions() {
|
|
58
|
+
return super.setOptions();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_setupGenerator() {
|
|
62
|
+
this.option('relationType', {
|
|
63
|
+
type: String,
|
|
64
|
+
required: false,
|
|
65
|
+
description: g.f('Relation type'),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
this.option('sourceModel', {
|
|
69
|
+
type: String,
|
|
70
|
+
required: false,
|
|
71
|
+
description: g.f('Source model'),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
this.option('destinationModel', {
|
|
75
|
+
type: String,
|
|
76
|
+
required: false,
|
|
77
|
+
description: g.f('Destination model'),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
this.option('throughModel', {
|
|
81
|
+
type: String,
|
|
82
|
+
required: false,
|
|
83
|
+
description: g.f('Through model'),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
this.option('sourceModelPrimaryKey', {
|
|
87
|
+
type: String,
|
|
88
|
+
required: false,
|
|
89
|
+
description: g.f('Primary key on source model'),
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
this.option('sourceModelPrimaryKeyType', {
|
|
93
|
+
type: String,
|
|
94
|
+
required: false,
|
|
95
|
+
description: g.f('Type of the primary key on source model'),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
this.option('destinationModelPrimaryKey', {
|
|
99
|
+
type: String,
|
|
100
|
+
required: false,
|
|
101
|
+
description: g.f('Primary key on destination model'),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
this.option('destinationModelPrimaryKeyType', {
|
|
105
|
+
type: String,
|
|
106
|
+
required: false,
|
|
107
|
+
description: g.f('Type of the primary key on destination model'),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
this.option('sourceKeyOnThrough', {
|
|
111
|
+
type: String,
|
|
112
|
+
required: false,
|
|
113
|
+
description: g.f('Foreign key references source model on through model'),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
this.option('targetKeyOnThrough', {
|
|
117
|
+
type: String,
|
|
118
|
+
required: false,
|
|
119
|
+
description: g.f('Foreign key references target model on through model'),
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
this.option('defaultForeignKeyName', {
|
|
123
|
+
type: String,
|
|
124
|
+
required: false,
|
|
125
|
+
description: g.f('default foreign key name'),
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
this.option('foreignKeyName', {
|
|
129
|
+
type: String,
|
|
130
|
+
required: false,
|
|
131
|
+
description: g.f('Destination model foreign key name'),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
this.option('relationName', {
|
|
135
|
+
type: String,
|
|
136
|
+
required: false,
|
|
137
|
+
description: g.f('Relation name'),
|
|
138
|
+
});
|
|
139
|
+
this.option('defaultRelationName', {
|
|
140
|
+
type: String,
|
|
141
|
+
required: false,
|
|
142
|
+
description: g.f('Default relation name'),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
this.option('registerInclusionResolver', {
|
|
146
|
+
type: Boolean,
|
|
147
|
+
required: false,
|
|
148
|
+
description: g.f(
|
|
149
|
+
'Allow <sourceModel> queries to include data from related <destinationModel>',
|
|
150
|
+
),
|
|
151
|
+
});
|
|
152
|
+
this.artifactInfo = {
|
|
153
|
+
type: 'relation',
|
|
154
|
+
rootDir: utils.sourceRootDir,
|
|
155
|
+
outDir: utils.sourceRootDir,
|
|
156
|
+
};
|
|
157
|
+
// to check if model and repo exist
|
|
158
|
+
this.artifactInfo.modelDir = path.resolve(
|
|
159
|
+
this.artifactInfo.rootDir,
|
|
160
|
+
utils.modelsDir,
|
|
161
|
+
);
|
|
162
|
+
this.artifactInfo.repoDir = path.resolve(
|
|
163
|
+
this.artifactInfo.rootDir,
|
|
164
|
+
utils.repositoriesDir,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
super._setupGenerator();
|
|
168
|
+
this._arguments = [];
|
|
169
|
+
|
|
170
|
+
this.isChecked = {
|
|
171
|
+
relationType: false,
|
|
172
|
+
sourceModel: false,
|
|
173
|
+
destinationModel: false,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
checkLoopBackProject() {
|
|
178
|
+
if (this.shouldExit()) return;
|
|
179
|
+
return super.checkLoopBackProject();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
_getDefaultRelationName() {
|
|
183
|
+
let defaultRelationName;
|
|
184
|
+
switch (this.artifactInfo.relationType) {
|
|
185
|
+
case relationUtils.relationType.belongsTo:
|
|
186
|
+
// this is how the belongsToAccessor generates the default relation name
|
|
187
|
+
defaultRelationName = this.artifactInfo.foreignKeyName.replace(
|
|
188
|
+
/Id$/,
|
|
189
|
+
'',
|
|
190
|
+
);
|
|
191
|
+
break;
|
|
192
|
+
case relationUtils.relationType.hasMany:
|
|
193
|
+
defaultRelationName = utils.pluralize(
|
|
194
|
+
utils.camelCase(this.artifactInfo.destinationModel),
|
|
195
|
+
);
|
|
196
|
+
break;
|
|
197
|
+
case relationUtils.relationType.hasManyThrough:
|
|
198
|
+
defaultRelationName = utils.pluralize(
|
|
199
|
+
utils.camelCase(this.artifactInfo.destinationModel),
|
|
200
|
+
);
|
|
201
|
+
break;
|
|
202
|
+
case relationUtils.relationType.hasOne:
|
|
203
|
+
defaultRelationName = utils.camelCase(
|
|
204
|
+
this.artifactInfo.destinationModel,
|
|
205
|
+
);
|
|
206
|
+
break;
|
|
207
|
+
case relationUtils.relationType.referencesMany:
|
|
208
|
+
// this is how the referencesManyAccessor generates the default relation name
|
|
209
|
+
defaultRelationName = this.artifactInfo.foreignKeyName.replace(
|
|
210
|
+
/Ids$/,
|
|
211
|
+
's',
|
|
212
|
+
);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return defaultRelationName;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async _promptModelList(message, parameter, toRemove = []) {
|
|
220
|
+
let modelList;
|
|
221
|
+
try {
|
|
222
|
+
debug(`model list dir ${this.artifactInfo.modelDir}`);
|
|
223
|
+
modelList = await utils.getArtifactList(
|
|
224
|
+
this.artifactInfo.modelDir,
|
|
225
|
+
'model',
|
|
226
|
+
);
|
|
227
|
+
} catch (err) {
|
|
228
|
+
/* istanbul ignore next */
|
|
229
|
+
return this.exit(err);
|
|
230
|
+
}
|
|
231
|
+
let repoList;
|
|
232
|
+
try {
|
|
233
|
+
debug(`repository list dir ${this.artifactInfo.repoDir}`);
|
|
234
|
+
repoList = await utils.getArtifactList(
|
|
235
|
+
this.artifactInfo.repoDir,
|
|
236
|
+
'repository',
|
|
237
|
+
);
|
|
238
|
+
} catch (err) {
|
|
239
|
+
/* istanbul ignore next */
|
|
240
|
+
return this.exit(err);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (modelList.length === 0) {
|
|
244
|
+
/* istanbul ignore next */
|
|
245
|
+
return this.exit(
|
|
246
|
+
new Error(
|
|
247
|
+
`${ERROR_NO_MODELS_FOUND} ${this.artifactInfo.modelDir}.
|
|
248
|
+
${chalk.yellow(
|
|
249
|
+
'Please visit https://loopback.io/doc/en/lb4/Model-generator.html for information on how models are discovered',
|
|
250
|
+
)}`,
|
|
251
|
+
),
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (this.options[parameter]) {
|
|
256
|
+
this.isChecked[parameter] = true;
|
|
257
|
+
if (!modelList.includes(this.options[parameter])) {
|
|
258
|
+
/* istanbul ignore next */
|
|
259
|
+
return this.exit(
|
|
260
|
+
new Error(
|
|
261
|
+
`"${this.options[parameter]}" ${ERROR_MODEL_DOES_NOT_EXIST}`,
|
|
262
|
+
),
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
debug(
|
|
267
|
+
`${parameter} received from command line: ${this.options[parameter]}`,
|
|
268
|
+
);
|
|
269
|
+
this.artifactInfo[parameter] = this.options[parameter];
|
|
270
|
+
}
|
|
271
|
+
// remove source & target models from the selections of through model
|
|
272
|
+
if (toRemove.length > 0) {
|
|
273
|
+
const updateAry = [];
|
|
274
|
+
modelList.forEach(ele => {
|
|
275
|
+
if (!toRemove.includes(ele)) {
|
|
276
|
+
updateAry.push(ele);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
modelList = updateAry;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Prompt a user for model.
|
|
283
|
+
return this.prompt([
|
|
284
|
+
{
|
|
285
|
+
type: 'list',
|
|
286
|
+
name: parameter,
|
|
287
|
+
message: message,
|
|
288
|
+
choices: modelList,
|
|
289
|
+
when: !this.artifactInfo[parameter],
|
|
290
|
+
default: modelList[0],
|
|
291
|
+
},
|
|
292
|
+
]).then(props => {
|
|
293
|
+
if (this.isChecked[parameter]) return;
|
|
294
|
+
if (!modelList.includes(props[parameter])) {
|
|
295
|
+
/* istanbul ignore next */
|
|
296
|
+
return this.exit(
|
|
297
|
+
new Error(`"${props[parameter]}" ${ERROR_MODEL_DOES_NOT_EXIST}`),
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
// checks if the corresponding repository exists
|
|
301
|
+
if (!repoList.includes(props[parameter])) {
|
|
302
|
+
/* istanbul ignore next */
|
|
303
|
+
return this.exit(
|
|
304
|
+
new Error(
|
|
305
|
+
`${props[parameter]}Repository ${ERROR_REPOSITORY_DOES_NOT_EXIST}`,
|
|
306
|
+
),
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
debug(`props after ${parameter} prompt: ${inspect(props)}`);
|
|
311
|
+
Object.assign(this.artifactInfo, props);
|
|
312
|
+
return props;
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Prompt a user for Relation type
|
|
317
|
+
async promptRelationType() {
|
|
318
|
+
if (this.shouldExit()) return false;
|
|
319
|
+
const relationTypeChoices = Object.keys(relationUtils.relationType);
|
|
320
|
+
|
|
321
|
+
if (this.options.relationType) {
|
|
322
|
+
this.isChecked.relationType = true;
|
|
323
|
+
debug(
|
|
324
|
+
`Relation type received from command line: ${this.options.relationType}`,
|
|
325
|
+
);
|
|
326
|
+
if (!relationTypeChoices.includes(this.options.relationType)) {
|
|
327
|
+
/* istanbul ignore next */
|
|
328
|
+
return this.exit(new Error(ERROR_INCORRECT_RELATION_TYPE));
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
this.artifactInfo.relationType = this.options.relationType;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return this.prompt([
|
|
335
|
+
{
|
|
336
|
+
type: 'list',
|
|
337
|
+
name: 'relationType',
|
|
338
|
+
message: PROMPT_BASE_RELATION_CLASS,
|
|
339
|
+
choices: relationTypeChoices,
|
|
340
|
+
when: !this.artifactInfo.relationType,
|
|
341
|
+
validate: utils.validateClassName,
|
|
342
|
+
default: relationTypeChoices[0],
|
|
343
|
+
},
|
|
344
|
+
]).then(props => {
|
|
345
|
+
if (this.isChecked.relationType) return;
|
|
346
|
+
if (!relationTypeChoices.includes(props.relationType)) {
|
|
347
|
+
/* istanbul ignore next */
|
|
348
|
+
this.exit(new Error(ERROR_INCORRECT_RELATION_TYPE));
|
|
349
|
+
}
|
|
350
|
+
Object.assign(this.artifactInfo, props);
|
|
351
|
+
debug(`props after relation type prompt: ${inspect(props)}`);
|
|
352
|
+
return props;
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Get model list for source model.
|
|
357
|
+
async promptSourceModels() {
|
|
358
|
+
if (this.shouldExit()) return false;
|
|
359
|
+
|
|
360
|
+
return this._promptModelList(PROMPT_MESSAGE_SOURCE_MODEL, 'sourceModel');
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Get model list for target model.
|
|
364
|
+
async promptTargetModels() {
|
|
365
|
+
if (this.shouldExit()) return false;
|
|
366
|
+
|
|
367
|
+
return this._promptModelList(
|
|
368
|
+
PROMPT_MESSAGE_TARGET_MODEL,
|
|
369
|
+
'destinationModel',
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Get model list for through model.
|
|
374
|
+
async promptThroughModels() {
|
|
375
|
+
if (this.shouldExit()) return false;
|
|
376
|
+
if (this.artifactInfo.relationType === 'hasManyThrough') {
|
|
377
|
+
return this._promptModelList(
|
|
378
|
+
PROMPT_MESSAGE_THROUGH_MODEL,
|
|
379
|
+
'throughModel',
|
|
380
|
+
[this.artifactInfo.destinationModel, this.artifactInfo.sourceModel],
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Prompt foreign key if not exist:
|
|
387
|
+
* 1. From source model get primary key. If primary key does not exist -
|
|
388
|
+
* error.
|
|
389
|
+
* 2. Get primary key type from source model.
|
|
390
|
+
* 3. Generate foreign key (camelCase source class Name + primary key name).
|
|
391
|
+
* 4. Check is foreign key exist in destination model. If not - prompt.
|
|
392
|
+
* Error - if type is not the same.
|
|
393
|
+
*
|
|
394
|
+
* For belongsTo and referencesMany this is getting source key not fk.
|
|
395
|
+
*/
|
|
396
|
+
async promptForeignKey() {
|
|
397
|
+
if (this.shouldExit()) return false;
|
|
398
|
+
|
|
399
|
+
if (this.options.sourceModelPrimaryKey) {
|
|
400
|
+
this.artifactInfo.sourceModelPrimaryKey =
|
|
401
|
+
this.options.sourceModelPrimaryKey;
|
|
402
|
+
}
|
|
403
|
+
if (this.options.sourceModelPrimaryKeyType) {
|
|
404
|
+
this.artifactInfo.sourceModelPrimaryKeyType =
|
|
405
|
+
this.options.sourceModelPrimaryKeyType;
|
|
406
|
+
}
|
|
407
|
+
if (this.options.destinationModelPrimaryKey) {
|
|
408
|
+
this.artifactInfo.destinationModelPrimaryKey =
|
|
409
|
+
this.options.destinationModelPrimaryKey;
|
|
410
|
+
}
|
|
411
|
+
if (this.options.destinationModelPrimaryKeyType) {
|
|
412
|
+
this.artifactInfo.destinationModelPrimaryKeyType =
|
|
413
|
+
this.options.destinationModelPrimaryKeyType;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (!this.artifactInfo.sourceModelPrimaryKey) {
|
|
417
|
+
const sourceModelPK = await relationUtils.getModelPrimaryKeyProperty(
|
|
418
|
+
this.fs,
|
|
419
|
+
this.artifactInfo.modelDir,
|
|
420
|
+
this.artifactInfo.sourceModel,
|
|
421
|
+
);
|
|
422
|
+
if (sourceModelPK) {
|
|
423
|
+
this.artifactInfo.sourceModelPrimaryKey = sourceModelPK;
|
|
424
|
+
if (!this.artifactInfo.sourceModelPrimaryKeyType) {
|
|
425
|
+
const sourceModelPKType = relationUtils.getModelPropertyType(
|
|
426
|
+
this.artifactInfo.modelDir,
|
|
427
|
+
this.artifactInfo.sourceModel,
|
|
428
|
+
this.artifactInfo.sourceModelPrimaryKey,
|
|
429
|
+
);
|
|
430
|
+
if (sourceModelPKType) {
|
|
431
|
+
this.artifactInfo.sourceModelPrimaryKeyType = sourceModelPKType;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
} else {
|
|
435
|
+
const answer = await this.prompt([
|
|
436
|
+
{
|
|
437
|
+
type: 'input',
|
|
438
|
+
name: 'sourceModelPrimaryKey',
|
|
439
|
+
message: g.f(
|
|
440
|
+
'What is the name of ID property of the source model?',
|
|
441
|
+
),
|
|
442
|
+
when: this.artifactInfo.sourceModelPrimaryKey === undefined,
|
|
443
|
+
default: 'id',
|
|
444
|
+
},
|
|
445
|
+
]);
|
|
446
|
+
this.artifactInfo.sourceModelPrimaryKey = answer.sourceModelPrimaryKey;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (!this.artifactInfo.sourceModelPrimaryKeyType) {
|
|
450
|
+
const answer = await this.prompt([
|
|
451
|
+
{
|
|
452
|
+
type: 'list',
|
|
453
|
+
name: 'sourceModelPrimaryKeyType',
|
|
454
|
+
message: g.f('What is the type of the source model primary key?'),
|
|
455
|
+
choices: ['number', 'string', 'object'],
|
|
456
|
+
when: this.artifactInfo.sourceModelPrimaryKeyType === undefined,
|
|
457
|
+
default: 'number',
|
|
458
|
+
},
|
|
459
|
+
]);
|
|
460
|
+
this.artifactInfo.sourceModelPrimaryKeyType =
|
|
461
|
+
answer.sourceModelPrimaryKeyType;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
debug(
|
|
465
|
+
`source model primary key and type: ${this.artifactInfo.destinationModelPrimaryKey}
|
|
466
|
+
${this.artifactInfo.destinationModelPrimaryKeyType}`,
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
if (!this.artifactInfo.destinationModelPrimaryKey) {
|
|
470
|
+
const destModelPK = await relationUtils.getModelPrimaryKeyProperty(
|
|
471
|
+
this.fs,
|
|
472
|
+
this.artifactInfo.modelDir,
|
|
473
|
+
this.artifactInfo.destinationModel,
|
|
474
|
+
);
|
|
475
|
+
if (destModelPK) {
|
|
476
|
+
this.artifactInfo.destinationModelPrimaryKey = destModelPK;
|
|
477
|
+
if (!this.artifactInfo.destinationModelPrimaryKeyType) {
|
|
478
|
+
const destModelPKType = relationUtils.getModelPropertyType(
|
|
479
|
+
this.artifactInfo.modelDir,
|
|
480
|
+
this.artifactInfo.destinationModel,
|
|
481
|
+
this.artifactInfo.destinationModelPrimaryKey,
|
|
482
|
+
);
|
|
483
|
+
if (destModelPKType) {
|
|
484
|
+
this.artifactInfo.destinationModelPrimaryKeyType = destModelPKType;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
const answer = await this.prompt([
|
|
489
|
+
{
|
|
490
|
+
type: 'input',
|
|
491
|
+
name: 'destinationModelPrimaryKey',
|
|
492
|
+
message: g.f(
|
|
493
|
+
'What is the name of ID property of the target model?',
|
|
494
|
+
),
|
|
495
|
+
when: this.artifactInfo.destinationModelPrimaryKey === undefined,
|
|
496
|
+
default: 'id',
|
|
497
|
+
},
|
|
498
|
+
]);
|
|
499
|
+
this.artifactInfo.destinationModelPrimaryKey =
|
|
500
|
+
answer.destinationModelPrimaryKey;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (!this.artifactInfo.destinationModelPrimaryKeyType) {
|
|
504
|
+
const answer = await this.prompt([
|
|
505
|
+
{
|
|
506
|
+
type: 'list',
|
|
507
|
+
name: 'destinationModelPrimaryKeyType',
|
|
508
|
+
message: g.f('What is the type of the target model primary key?'),
|
|
509
|
+
choices: ['number', 'string', 'object'],
|
|
510
|
+
when: this.artifactInfo.destinationModelPrimaryKeyType === undefined,
|
|
511
|
+
default: 'number',
|
|
512
|
+
},
|
|
513
|
+
]);
|
|
514
|
+
this.artifactInfo.destinationModelPrimaryKeyType =
|
|
515
|
+
answer.destinationModelPrimaryKeyType;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
debug(
|
|
519
|
+
`destination model primary key and type: ${this.artifactInfo.destinationModelPrimaryKey}
|
|
520
|
+
${this.artifactInfo.destinationModelPrimaryKeyType}`,
|
|
521
|
+
);
|
|
522
|
+
|
|
523
|
+
// checks fks for hasManyThrough
|
|
524
|
+
if (this.artifactInfo.relationType === 'hasManyThrough') {
|
|
525
|
+
this.artifactInfo.defaultSourceKeyOnThrough =
|
|
526
|
+
utils.camelCase(this.artifactInfo.sourceModel) + 'Id';
|
|
527
|
+
this.artifactInfo.defaultTargetKeyOnThrough =
|
|
528
|
+
utils.camelCase(this.artifactInfo.destinationModel) + 'Id';
|
|
529
|
+
return this._promptKeyFromOnThroughModel();
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (this.options.foreignKeyName) {
|
|
533
|
+
debug(
|
|
534
|
+
`Foreign key name received from command line: ${this.options.foreignKeyName}`,
|
|
535
|
+
);
|
|
536
|
+
this.artifactInfo.foreignKeyName = this.options.foreignKeyName;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
switch (this.artifactInfo.relationType) {
|
|
540
|
+
case 'belongsTo':
|
|
541
|
+
this.artifactInfo.defaultForeignKeyName =
|
|
542
|
+
utils.camelCase(this.artifactInfo.destinationModel) + 'Id';
|
|
543
|
+
break;
|
|
544
|
+
case 'referencesMany':
|
|
545
|
+
this.artifactInfo.defaultForeignKeyName =
|
|
546
|
+
utils.camelCase(this.artifactInfo.destinationModel) + 'Ids';
|
|
547
|
+
break;
|
|
548
|
+
default:
|
|
549
|
+
this.artifactInfo.defaultForeignKeyName =
|
|
550
|
+
utils.camelCase(this.artifactInfo.sourceModel) + 'Id';
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
let msg;
|
|
555
|
+
switch (this.artifactInfo.relationType) {
|
|
556
|
+
case 'belongsTo':
|
|
557
|
+
msg = PROMPT_MESSAGE_FOREIGN_KEY_NAME_BELONGS_TO;
|
|
558
|
+
break;
|
|
559
|
+
case 'referencesMany':
|
|
560
|
+
msg = PROMPT_MESSAGE_FOREIGN_KEY_NAME_REFERENCES_MANY;
|
|
561
|
+
break;
|
|
562
|
+
default:
|
|
563
|
+
msg = PROMPT_MESSAGE_FOREIGN_KEY_NAME;
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const foreignKeyModel =
|
|
568
|
+
this.artifactInfo.relationType === 'belongsTo' ||
|
|
569
|
+
this.artifactInfo.relationType === 'referencesMany'
|
|
570
|
+
? this.artifactInfo.sourceModel
|
|
571
|
+
: this.artifactInfo.destinationModel;
|
|
572
|
+
|
|
573
|
+
const project = new relationUtils.AstLoopBackProject();
|
|
574
|
+
const fkFile = path.join(
|
|
575
|
+
this.artifactInfo.modelDir,
|
|
576
|
+
utils.getModelFileName(foreignKeyModel),
|
|
577
|
+
);
|
|
578
|
+
const df = project.addSourceFileAtPath(fkFile);
|
|
579
|
+
const cl = relationUtils.getClassObj(df, foreignKeyModel);
|
|
580
|
+
|
|
581
|
+
return this.prompt([
|
|
582
|
+
{
|
|
583
|
+
type: 'string',
|
|
584
|
+
name: 'foreignKeyName',
|
|
585
|
+
message: msg,
|
|
586
|
+
default: this.artifactInfo.defaultForeignKeyName,
|
|
587
|
+
when: !this.artifactInfo.foreignKeyName,
|
|
588
|
+
validate: utils.validateKeyName,
|
|
589
|
+
},
|
|
590
|
+
]).then(props => {
|
|
591
|
+
debug(`props after foreign key name prompt: ${inspect(props)}`);
|
|
592
|
+
Object.assign(this.artifactInfo, props);
|
|
593
|
+
this.artifactInfo.doesForeignKeyExist = relationUtils.doesPropertyExist(
|
|
594
|
+
cl,
|
|
595
|
+
this.artifactInfo.foreignKeyName,
|
|
596
|
+
);
|
|
597
|
+
// checks if it's the case that the fk already exists in source model and decorated by @belongsTo or @referencesMany, which should be aborted
|
|
598
|
+
if (
|
|
599
|
+
this.artifactInfo.doesForeignKeyExist &&
|
|
600
|
+
(this.artifactInfo.relationType === 'belongsTo' ||
|
|
601
|
+
this.artifactInfo.relationType === 'referencesMany')
|
|
602
|
+
) {
|
|
603
|
+
try {
|
|
604
|
+
relationUtils.doesRelationExist(cl, this.artifactInfo.foreignKeyName);
|
|
605
|
+
} catch (err) {
|
|
606
|
+
/* istanbul ignore next */
|
|
607
|
+
this.exit(err);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return props;
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
async _promptKeyFromOnThroughModel() {
|
|
615
|
+
if (this.shouldExit()) return false;
|
|
616
|
+
return this.prompt([
|
|
617
|
+
{
|
|
618
|
+
type: 'string',
|
|
619
|
+
name: 'sourceKeyOnThrough',
|
|
620
|
+
message: g.f(
|
|
621
|
+
`Foreign key name that references the ${chalk.yellow(
|
|
622
|
+
'source model',
|
|
623
|
+
)} to define on the through model`,
|
|
624
|
+
),
|
|
625
|
+
default: this.artifactInfo.defaultSourceKeyOnThrough,
|
|
626
|
+
when: !this.options.sourceKeyOnThrough,
|
|
627
|
+
validate: utils.validateKeyName,
|
|
628
|
+
},
|
|
629
|
+
]).then(props => {
|
|
630
|
+
debug(`props after foreign key name prompt: ${inspect(props)}`);
|
|
631
|
+
Object.assign(this.artifactInfo, props);
|
|
632
|
+
return this._promptKeyToOnThroughModel();
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
async _promptKeyToOnThroughModel() {
|
|
637
|
+
if (this.shouldExit()) return false;
|
|
638
|
+
return this.prompt([
|
|
639
|
+
{
|
|
640
|
+
type: 'string',
|
|
641
|
+
name: 'targetKeyOnThrough',
|
|
642
|
+
message: g.f(
|
|
643
|
+
`Foreign key name that references the ${chalk.yellow(
|
|
644
|
+
'target model',
|
|
645
|
+
)} to define on the through model`,
|
|
646
|
+
),
|
|
647
|
+
default: this.artifactInfo.defaultTargetKeyOnThrough,
|
|
648
|
+
when: !this.options.targetKeyOnThrough,
|
|
649
|
+
validate: input =>
|
|
650
|
+
utils.validateKeyToKeyFrom(
|
|
651
|
+
input,
|
|
652
|
+
this.artifactInfo.sourceKeyOnThrough,
|
|
653
|
+
),
|
|
654
|
+
},
|
|
655
|
+
]).then(props => {
|
|
656
|
+
debug(`props after foreign key name prompt: ${inspect(props)}`);
|
|
657
|
+
Object.assign(this.artifactInfo, props);
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
async promptRelationName() {
|
|
662
|
+
if (this.shouldExit()) return false;
|
|
663
|
+
if (this.options.relationName) {
|
|
664
|
+
debug(
|
|
665
|
+
`Relation name received from command line: ${this.options.relationName}`,
|
|
666
|
+
);
|
|
667
|
+
this.artifactInfo.relationName = this.options.relationName;
|
|
668
|
+
}
|
|
669
|
+
this.artifactInfo.defaultRelationName = this._getDefaultRelationName();
|
|
670
|
+
// for hasMany && hasOne, the source key is the same as the relation name
|
|
671
|
+
const msg =
|
|
672
|
+
this.artifactInfo.relationType === 'belongsTo' ||
|
|
673
|
+
this.artifactInfo.relationType === 'referencesMany'
|
|
674
|
+
? PROMPT_MESSAGE_RELATION_NAME
|
|
675
|
+
: PROMPT_MESSAGE_PROPERTY_NAME;
|
|
676
|
+
|
|
677
|
+
return this.prompt([
|
|
678
|
+
{
|
|
679
|
+
type: 'string',
|
|
680
|
+
name: 'relationName',
|
|
681
|
+
message: msg,
|
|
682
|
+
when: !this.artifactInfo.relationName,
|
|
683
|
+
default: this.artifactInfo.defaultRelationName,
|
|
684
|
+
validate: inputName =>
|
|
685
|
+
utils.validateRelationName(
|
|
686
|
+
inputName,
|
|
687
|
+
this.artifactInfo.relationType,
|
|
688
|
+
this.artifactInfo.foreignKeyName,
|
|
689
|
+
),
|
|
690
|
+
},
|
|
691
|
+
]).then(props => {
|
|
692
|
+
debug(`props after relation name prompt: ${inspect(props)}`);
|
|
693
|
+
// checks if the relation name already exists
|
|
694
|
+
this.artifactInfo.srcRepositoryFile = path.resolve(
|
|
695
|
+
this.artifactInfo.repoDir,
|
|
696
|
+
utils.getRepositoryFileName(this.artifactInfo.sourceModel),
|
|
697
|
+
);
|
|
698
|
+
this.artifactInfo.srcRepositoryClassName =
|
|
699
|
+
utils.toClassName(this.artifactInfo.sourceModel) + 'Repository';
|
|
700
|
+
this.artifactInfo.srcRepositoryFileObj =
|
|
701
|
+
new relationUtils.AstLoopBackProject().addSourceFileAtPath(
|
|
702
|
+
this.artifactInfo.srcRepositoryFile,
|
|
703
|
+
);
|
|
704
|
+
|
|
705
|
+
const repoClassDeclaration =
|
|
706
|
+
this.artifactInfo.srcRepositoryFileObj.getClassOrThrow(
|
|
707
|
+
this.artifactInfo.srcRepositoryClassName,
|
|
708
|
+
);
|
|
709
|
+
// checks if the relation name already exists in repo
|
|
710
|
+
if (
|
|
711
|
+
relationUtils.doesPropertyExist(
|
|
712
|
+
repoClassDeclaration,
|
|
713
|
+
props.relationName,
|
|
714
|
+
)
|
|
715
|
+
) {
|
|
716
|
+
/* istanbul ignore next */
|
|
717
|
+
return this.exit(
|
|
718
|
+
new Error(
|
|
719
|
+
`relation ${props.relationName} already exists in the repository ${this.artifactInfo.srcRepositoryClassName}.`,
|
|
720
|
+
),
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
Object.assign(this.artifactInfo, props);
|
|
725
|
+
return props;
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
async promptRegisterInclusionResolver() {
|
|
730
|
+
if (this.shouldExit()) return false;
|
|
731
|
+
const props = await this.prompt([
|
|
732
|
+
{
|
|
733
|
+
type: 'confirm',
|
|
734
|
+
name: 'registerInclusionResolver',
|
|
735
|
+
message: g.f(
|
|
736
|
+
'Allow %s queries to include data from related %s instances? ',
|
|
737
|
+
chalk.yellow(this.artifactInfo.sourceModel),
|
|
738
|
+
chalk.yellow(this.artifactInfo.destinationModel),
|
|
739
|
+
),
|
|
740
|
+
default: true,
|
|
741
|
+
},
|
|
742
|
+
]);
|
|
743
|
+
debug(`props after inclusion resolver promps: ${inspect(props)}`);
|
|
744
|
+
Object.assign(this.artifactInfo, props);
|
|
745
|
+
return props;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
async scaffold() {
|
|
749
|
+
if (this.shouldExit()) return false;
|
|
750
|
+
|
|
751
|
+
debug('Invoke generator...');
|
|
752
|
+
|
|
753
|
+
let relationGenerator;
|
|
754
|
+
|
|
755
|
+
this.artifactInfo.name = this.artifactInfo.relationType;
|
|
756
|
+
|
|
757
|
+
switch (this.artifactInfo.relationType) {
|
|
758
|
+
case relationUtils.relationType.belongsTo:
|
|
759
|
+
relationGenerator = new BelongsToRelationGenerator(
|
|
760
|
+
this.args,
|
|
761
|
+
this.opts,
|
|
762
|
+
);
|
|
763
|
+
break;
|
|
764
|
+
case relationUtils.relationType.hasMany:
|
|
765
|
+
relationGenerator = new HasManyRelationGenerator(this.args, this.opts);
|
|
766
|
+
break;
|
|
767
|
+
case relationUtils.relationType.hasManyThrough:
|
|
768
|
+
relationGenerator = new HasManyThroughRelationGenerator(
|
|
769
|
+
this.args,
|
|
770
|
+
this.opts,
|
|
771
|
+
);
|
|
772
|
+
break;
|
|
773
|
+
case relationUtils.relationType.hasOne:
|
|
774
|
+
relationGenerator = new HasOneRelationGenerator(this.args, this.opts);
|
|
775
|
+
break;
|
|
776
|
+
case relationUtils.relationType.referencesMany:
|
|
777
|
+
relationGenerator = new ReferencesManyRelationGenerator(
|
|
778
|
+
this.args,
|
|
779
|
+
this.opts,
|
|
780
|
+
);
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
try {
|
|
785
|
+
await relationGenerator.generateAll(this.artifactInfo);
|
|
786
|
+
} catch (error) {
|
|
787
|
+
/* istanbul ignore next */
|
|
788
|
+
this.exit(error);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
async end() {
|
|
793
|
+
await super.end();
|
|
794
|
+
}
|
|
795
|
+
};
|