@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.
Files changed (159) hide show
  1. package/.yo-rc.json +1719 -0
  2. package/{generators/project/templates/LICENSE → LICENSE} +2 -1
  3. package/README.md +44 -43
  4. package/bin/cli-main.js +61 -0
  5. package/generators/app/index.js +109 -15
  6. package/generators/app/templates/.dockerignore +5 -0
  7. package/generators/app/templates/Dockerfile +28 -0
  8. package/generators/app/templates/README.md.ejs +130 -0
  9. package/generators/app/templates/public/index.html.ejs +88 -0
  10. package/generators/app/templates/{test → src/__tests__}/README.md +0 -1
  11. package/generators/app/templates/src/__tests__/acceptance/home-page.acceptance.ts.ejs +31 -0
  12. package/generators/app/templates/src/__tests__/acceptance/ping.controller.acceptance.ts.ejs +21 -0
  13. package/generators/app/templates/src/__tests__/acceptance/test-helper.ts.ejs +32 -0
  14. package/generators/app/templates/src/application.ts.ejs +70 -0
  15. package/generators/app/templates/src/controllers/README.md +6 -0
  16. package/generators/app/templates/src/controllers/index.ts.ejs +1 -0
  17. package/generators/app/templates/src/controllers/ping.controller.ts.ejs +55 -0
  18. package/generators/app/templates/src/datasources/README.md +3 -0
  19. package/generators/app/templates/src/index.ts.ejs +39 -0
  20. package/generators/app/templates/src/migrate.ts.ejs +20 -0
  21. package/generators/app/templates/src/models/README.md +3 -0
  22. package/generators/app/templates/src/openapi-spec.ts.ejs +23 -0
  23. package/generators/app/templates/src/sequence.ts.ejs +3 -0
  24. package/generators/controller/index.js +240 -23
  25. package/generators/controller/templates/src/controllers/controller-rest-template.ts.ejs +150 -0
  26. package/generators/controller/templates/src/controllers/{controller-template.ts → controller-template.ts.ejs} +2 -2
  27. package/generators/copyright/fs.js +46 -0
  28. package/generators/copyright/git.js +78 -0
  29. package/generators/copyright/header.js +306 -0
  30. package/generators/copyright/index.js +230 -0
  31. package/generators/copyright/license.js +105 -0
  32. package/generators/datasource/index.js +341 -0
  33. package/generators/datasource/templates/datasource.ts.ejs +22 -0
  34. package/generators/discover/import-discovered-model.js +70 -0
  35. package/generators/discover/index.js +411 -0
  36. package/generators/example/downloader.js +16 -0
  37. package/generators/example/index.js +176 -0
  38. package/generators/extension/index.js +34 -5
  39. package/generators/extension/templates/README.md.ejs +32 -0
  40. package/generators/extension/templates/{test → src/__tests__}/acceptance/README.md +0 -0
  41. package/generators/extension/templates/{test → src/__tests__}/integration/README.md +0 -0
  42. package/generators/extension/templates/{test → src/__tests__}/unit/README.md +0 -0
  43. package/generators/extension/templates/src/component.ts.ejs +22 -0
  44. package/generators/extension/templates/src/controllers/README.md +3 -2
  45. package/generators/extension/templates/src/decorators/README.md +10 -4
  46. package/generators/extension/templates/src/index.ts.ejs +3 -0
  47. package/generators/extension/templates/src/keys.ts.ejs +11 -0
  48. package/generators/extension/templates/src/mixins/README.md +77 -21
  49. package/generators/extension/templates/src/providers/README.md +51 -25
  50. package/generators/extension/templates/src/repositories/README.md +1 -1
  51. package/generators/extension/templates/src/types.ts.ejs +15 -0
  52. package/generators/import-lb3-models/index.js +197 -0
  53. package/generators/import-lb3-models/lb3app-loader.js +31 -0
  54. package/generators/import-lb3-models/migrate-model.js +249 -0
  55. package/generators/import-lb3-models/model-names.js +32 -0
  56. package/generators/interceptor/index.js +178 -0
  57. package/generators/interceptor/templates/interceptor-template.ts.ejs +62 -0
  58. package/generators/model/index.js +536 -0
  59. package/generators/model/property-definition.js +85 -0
  60. package/generators/model/templates/model.ts.ejs +49 -0
  61. package/generators/observer/index.js +132 -0
  62. package/generators/observer/templates/observer-template.ts.ejs +40 -0
  63. package/generators/openapi/README.md +211 -0
  64. package/generators/openapi/index.js +535 -0
  65. package/generators/openapi/schema-helper.js +447 -0
  66. package/generators/openapi/spec-helper.js +484 -0
  67. package/generators/openapi/spec-loader.js +75 -0
  68. package/generators/openapi/templates/src/controllers/controller-template.ts.ejs +43 -0
  69. package/generators/openapi/templates/src/datasources/datasource.ts.ejs +42 -0
  70. package/generators/openapi/templates/src/models/model-template.ts.ejs +71 -0
  71. package/generators/openapi/templates/src/models/type-template.ts.ejs +13 -0
  72. package/generators/openapi/templates/src/services/service-proxy-template.ts.ejs +55 -0
  73. package/generators/openapi/utils.js +322 -0
  74. package/generators/project/templates/.eslintignore +4 -0
  75. package/generators/project/templates/.eslintrc.js.ejs +3 -0
  76. package/generators/project/templates/.mocharc.json +5 -0
  77. package/generators/project/templates/.prettierignore +0 -2
  78. package/generators/project/templates/.prettierrc +2 -1
  79. package/generators/project/templates/.vscode/launch.json +38 -0
  80. package/generators/project/templates/.vscode/settings.json +32 -0
  81. package/generators/project/templates/.vscode/tasks.json +29 -0
  82. package/generators/project/templates/DEVELOPING.md +36 -0
  83. package/generators/project/templates/_.gitignore +3 -5
  84. package/generators/project/templates/package.json.ejs +175 -0
  85. package/generators/project/templates/package.plain.json.ejs +176 -0
  86. package/generators/project/templates/tsconfig.json.ejs +39 -0
  87. package/generators/relation/base-relation.generator.js +220 -0
  88. package/generators/relation/belongs-to-relation.generator.js +196 -0
  89. package/generators/relation/has-many-relation.generator.js +200 -0
  90. package/generators/relation/has-many-through-relation.generator.js +331 -0
  91. package/generators/relation/has-one-relation.generator.js +200 -0
  92. package/generators/relation/index.js +795 -0
  93. package/generators/relation/references-many-relation.generator.js +142 -0
  94. package/generators/relation/templates/controller-relation-template-belongs-to.ts.ejs +38 -0
  95. package/generators/relation/templates/controller-relation-template-has-many-through.ts.ejs +110 -0
  96. package/generators/relation/templates/controller-relation-template-has-many.ts.ejs +110 -0
  97. package/generators/relation/templates/controller-relation-template-has-one.ts.ejs +110 -0
  98. package/generators/relation/utils.generator.js +260 -0
  99. package/generators/repository/index.js +576 -0
  100. package/generators/repository/templates/src/repositories/repository-crud-default-template.ts.ejs +21 -0
  101. package/generators/repository/templates/src/repositories/repository-kv-template.ts.ejs +19 -0
  102. package/generators/rest-crud/crud-rest-component.js +63 -0
  103. package/generators/rest-crud/index.js +423 -0
  104. package/generators/rest-crud/templates/src/model-endpoints/model.rest-config-template.ts.ejs +11 -0
  105. package/generators/service/index.js +351 -0
  106. package/generators/service/templates/local-service-class-template.ts.ejs +10 -0
  107. package/generators/service/templates/local-service-provider-template.ts.ejs +19 -0
  108. package/generators/service/templates/remote-service-proxy-template.ts.ejs +21 -0
  109. package/generators/update/index.js +55 -0
  110. package/intl/cs/messages.json +204 -0
  111. package/intl/de/messages.json +204 -0
  112. package/intl/en/messages.json +204 -0
  113. package/intl/es/messages.json +204 -0
  114. package/intl/fr/messages.json +204 -0
  115. package/intl/it/messages.json +204 -0
  116. package/intl/ja/messages.json +204 -0
  117. package/intl/ko/messages.json +204 -0
  118. package/intl/nl/messages.json +204 -0
  119. package/intl/pl/messages.json +204 -0
  120. package/intl/pt/messages.json +204 -0
  121. package/intl/ru/messages.json +204 -0
  122. package/intl/tr/messages.json +204 -0
  123. package/intl/zh-Hans/messages.json +204 -0
  124. package/intl/zh-Hant/messages.json +204 -0
  125. package/lib/artifact-generator.js +138 -39
  126. package/lib/ast-helper.js +214 -0
  127. package/lib/base-generator.js +509 -0
  128. package/lib/cli.js +233 -0
  129. package/lib/connectors.json +894 -0
  130. package/lib/debug.js +16 -0
  131. package/lib/globalize.js +12 -0
  132. package/lib/model-discoverer.js +118 -0
  133. package/lib/project-generator.js +154 -57
  134. package/lib/tab-completion.js +127 -0
  135. package/lib/update-index.js +44 -0
  136. package/lib/utils.js +689 -20
  137. package/lib/version-helper.js +299 -0
  138. package/package.json +183 -39
  139. package/CHANGELOG.md +0 -86
  140. package/bin/cli.js +0 -66
  141. package/generators/app/templates/index.js +0 -14
  142. package/generators/app/templates/src/application.ts +0 -27
  143. package/generators/app/templates/src/controllers/ping-controller.ts +0 -25
  144. package/generators/app/templates/src/index.ts +0 -25
  145. package/generators/app/templates/test/ping-controller.test.ts +0 -46
  146. package/generators/extension/templates/index.js +0 -8
  147. package/generators/extension/templates/src/component.ts +0 -14
  148. package/generators/extension/templates/src/index.ts +0 -6
  149. package/generators/project/templates/.npmrc +0 -1
  150. package/generators/project/templates/.yo-rc.json +0 -1
  151. package/generators/project/templates/README.md +0 -4
  152. package/generators/project/templates/index.d.ts +0 -6
  153. package/generators/project/templates/index.ts +0 -11
  154. package/generators/project/templates/package.json +0 -79
  155. package/generators/project/templates/package.plain.json +0 -82
  156. package/generators/project/templates/test/mocha.opts +0 -1
  157. package/generators/project/templates/tsconfig.json +0 -29
  158. package/generators/project/templates/tslint.build.json +0 -17
  159. package/generators/project/templates/tslint.json +0 -33
@@ -0,0 +1,447 @@
1
+ // Copyright IBM Corp. and LoopBack contributors 2018,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
+ 'use strict';
7
+
8
+ const {
9
+ isExtension,
10
+ titleCase,
11
+ escapePropertyName,
12
+ printSpecObject,
13
+ toFileName,
14
+ printJsonSchema,
15
+ } = require('./utils');
16
+
17
+ function setImport(typeSpec) {
18
+ if (typeSpec.fileName) {
19
+ typeSpec.import = `import {${typeSpec.className}} from './${getBaseName(
20
+ typeSpec.fileName,
21
+ )}';`;
22
+ }
23
+ }
24
+
25
+ function getTypeSpec(schema, options) {
26
+ const objectTypeMapping = options.objectTypeMapping;
27
+ const schemaMapping = options.schemaMapping || {};
28
+ const resolvedSchema = resolveSchema(schemaMapping, schema);
29
+ let typeSpec = objectTypeMapping.get(resolvedSchema);
30
+ if (!typeSpec) {
31
+ typeSpec = {};
32
+ objectTypeMapping.set(resolvedSchema, typeSpec);
33
+ }
34
+ setImport(typeSpec);
35
+ return typeSpec;
36
+ }
37
+
38
+ function getDefault(schema, options) {
39
+ let defaultVal = '';
40
+ if (options && options.includeDefault && schema.default !== undefined) {
41
+ defaultVal = ' = ' + printSpecObject(schema.default);
42
+ }
43
+ return defaultVal;
44
+ }
45
+
46
+ function getBaseName(tsFileName) {
47
+ if (tsFileName.endsWith('.ts')) {
48
+ return tsFileName.substring(0, tsFileName.length - 3);
49
+ }
50
+ return tsFileName;
51
+ }
52
+
53
+ /**
54
+ * Add the import statements to the given type spec's imports
55
+ * @param {object} typeSpec
56
+ * @param {string[]} imports
57
+ */
58
+ function addImports(typeSpec, ...imports) {
59
+ typeSpec.imports = typeSpec.imports || [];
60
+ for (const i of imports) {
61
+ if (i == null) continue;
62
+ // Skip circular import
63
+ if (typeSpec.import === i) continue;
64
+ if (!typeSpec.imports.includes(i)) {
65
+ typeSpec.imports.push(i);
66
+ }
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Collect import statements from a referenced type
72
+ * @param {*} typeSpec
73
+ * @param {*} referencedType
74
+ */
75
+ function collectImports(typeSpec, referencedType) {
76
+ if (referencedType.className != null) {
77
+ // Add the referenced import
78
+ addImports(typeSpec, referencedType.import);
79
+ } else {
80
+ if (Array.isArray(referencedType.imports)) {
81
+ addImports(typeSpec, ...referencedType.imports);
82
+ }
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Map composite type (oneOf|anyOf|allOf)
88
+ * @param {object} schema
89
+ * @param {object} options
90
+ */
91
+ function mapCompositeType(schema, options) {
92
+ options = Object.assign({}, options, {includeDefault: false});
93
+ const typeSpec = getTypeSpec(schema, options);
94
+ let separator = '';
95
+ let candidates = [];
96
+ if (Array.isArray(schema.oneOf)) {
97
+ separator = ' | ';
98
+ candidates = schema.oneOf;
99
+ } else if (Array.isArray(schema.anyOf)) {
100
+ separator = ' | ';
101
+ candidates = schema.anyOf;
102
+ } else if (Array.isArray(schema.allOf)) {
103
+ separator = ' & ';
104
+ candidates = schema.allOf;
105
+ }
106
+ if (!separator) return undefined;
107
+ const types = candidates.map(t => mapSchemaType(t, options));
108
+ const members = Array.from(new Set(types));
109
+ typeSpec.members = members;
110
+ const defaultVal = getDefault(schema, options);
111
+ const memberSignatures = members.map(m => m.signature).join(separator);
112
+ typeSpec.declaration = memberSignatures;
113
+ typeSpec.signature = (typeSpec.className || memberSignatures) + defaultVal;
114
+ members.forEach(m => collectImports(typeSpec, m));
115
+ return typeSpec;
116
+ }
117
+
118
+ function mapArrayType(schema, options) {
119
+ if (schema.type === 'array') {
120
+ const opts = Object.assign({}, options, {includeDefault: false});
121
+ const typeSpec = getTypeSpec(schema, options);
122
+ const itemTypeSpec = mapSchemaType(schema.items, opts);
123
+ const defaultVal = getDefault(schema, options);
124
+ let arrayType = `${itemTypeSpec.signature}[]`;
125
+ if (itemTypeSpec.signature.match(/[\|\&]/)) {
126
+ // The type is a union or intersection
127
+ arrayType = `(${itemTypeSpec.signature})[]`;
128
+ }
129
+ typeSpec.name = arrayType;
130
+ typeSpec.declaration = arrayType;
131
+ typeSpec.signature = (typeSpec.className || arrayType) + defaultVal;
132
+ typeSpec.itemType = itemTypeSpec;
133
+ collectImports(typeSpec, itemTypeSpec);
134
+ return typeSpec;
135
+ }
136
+ return undefined;
137
+ }
138
+
139
+ function mapObjectType(schema, options) {
140
+ if (schema.type === 'object' || schema.properties) {
141
+ const defaultVal = getDefault(schema, options);
142
+ const typeSpec = getTypeSpec(schema, options);
143
+ if (typeSpec.className) {
144
+ typeSpec.kind = 'class';
145
+ } else {
146
+ typeSpec.imports = [];
147
+ }
148
+ if (typeSpec.declaration != null) {
149
+ if (typeSpec.declaration === '') {
150
+ typeSpec.signature = typeSpec.className;
151
+ }
152
+ return typeSpec;
153
+ } else {
154
+ typeSpec.declaration = ''; // in-progress
155
+ }
156
+ const properties = [];
157
+ const required = schema.required || [];
158
+ for (const p in schema.properties) {
159
+ const propSchema = {...schema.properties[p]};
160
+ const suffix = required.includes(p) ? '' : '?';
161
+ const propertyType = mapSchemaType(
162
+ schema.properties[p],
163
+ Object.assign({}, options, {
164
+ includeDefault: !!typeSpec.className, // Only include default for class
165
+ }),
166
+ );
167
+ // The property name might have chars such as `-`
168
+ const propName = escapePropertyName(p);
169
+
170
+ const propSchemaJson = printJsonSchema(propSchema);
171
+
172
+ let propDecoration = `@property({jsonSchema: ${propSchemaJson}})`;
173
+
174
+ if (required.includes(p)) {
175
+ propDecoration = `@property({required: true, jsonSchema: ${propSchemaJson}})`;
176
+ }
177
+
178
+ if (propertyType.itemType) {
179
+ const itemType =
180
+ propertyType.itemType.kind === 'class'
181
+ ? propertyType.itemType.className
182
+ : // The item type can be an alias such as `export type ID = string`
183
+ getJSType(propertyType.itemType.declaration) ||
184
+ // The item type can be `string`
185
+ getJSType(propertyType.itemType.name);
186
+ if (itemType) {
187
+ // Use `@property.array` for array types
188
+ propDecoration = `@property.array(${itemType}, {jsonSchema: ${propSchemaJson}})`;
189
+ if (propertyType.itemType.className) {
190
+ // The referenced item type is either a class or type
191
+ collectImports(typeSpec, propertyType.itemType);
192
+ }
193
+ }
194
+ }
195
+ const propSpec = {
196
+ name: p,
197
+ signature: `${propName + suffix}: ${propertyType.signature};`,
198
+ decoration: propDecoration,
199
+ };
200
+ if (schema.properties[p].description) {
201
+ propSpec.description = schema.properties[p].description;
202
+ }
203
+ collectImports(typeSpec, propertyType);
204
+ properties.push(propSpec);
205
+ }
206
+ typeSpec.properties = properties;
207
+ typeSpec.importProperty = properties.length > 0;
208
+
209
+ // Handle `additionalProperties`
210
+ if (schema.additionalProperties === true) {
211
+ const signature = '[additionalProperty: string]: any;';
212
+ typeSpec.properties.push({
213
+ name: '',
214
+ description: 'additionalProperties',
215
+ comment: 'eslint-disable-next-line @typescript-eslint/no-explicit-any',
216
+ signature,
217
+ });
218
+ } else if (schema.additionalProperties) {
219
+ // TypeScript does not like `[additionalProperty: string]: string;`
220
+ /*
221
+ const signature =
222
+ '[additionalProperty: string]: ' +
223
+ mapSchemaType(schema.additionalProperties).signature +
224
+ ';';
225
+ */
226
+ const signature = '[additionalProperty: string]: any;';
227
+ typeSpec.properties.push({
228
+ name: '',
229
+ description: 'additionalProperties',
230
+ comment: 'eslint-disable-next-line @typescript-eslint/no-explicit-any',
231
+ signature,
232
+ });
233
+ }
234
+ const propertySignatures = properties.map(p => {
235
+ if (p.comment) return ` // ${p.comment}\n ${p.signature}`;
236
+ return p.signature;
237
+ });
238
+ typeSpec.declaration = `{
239
+ ${propertySignatures.join('\n ')}
240
+ }`;
241
+ typeSpec.signature =
242
+ (typeSpec.className || typeSpec.declaration) + defaultVal;
243
+ return typeSpec;
244
+ }
245
+ return undefined;
246
+ }
247
+
248
+ function mapPrimitiveType(schema, options) {
249
+ /**
250
+ * integer integer int32 signed 32 bits
251
+ * long integer int64 signed 64 bits
252
+ * float number float
253
+ * double number double
254
+ * string string
255
+ * byte string byte base64 encoded characters
256
+ * binary string binary any sequence of octets
257
+ * boolean boolean
258
+ * date string date As defined by full-date - RFC3339
259
+ * dateTime string date-time As defined by date-time - RFC3339
260
+ * password string password A hint to UIs to obscure input.
261
+ */
262
+ let jsType = 'string';
263
+ switch (schema.type) {
264
+ case 'integer':
265
+ case 'number':
266
+ jsType = 'number';
267
+ break;
268
+ case 'boolean':
269
+ jsType = 'boolean';
270
+ break;
271
+ case 'string':
272
+ switch (schema.format) {
273
+ case 'date':
274
+ jsType = 'string';
275
+ break;
276
+ case 'date-time':
277
+ jsType = 'Date';
278
+ break;
279
+ case 'binary':
280
+ jsType = 'Buffer';
281
+ break;
282
+ case 'byte':
283
+ case 'password':
284
+ jsType = 'string';
285
+ break;
286
+ }
287
+ break;
288
+ }
289
+ // Handle enums
290
+ if (Array.isArray(schema.enum)) {
291
+ jsType = schema.enum.map(v => printSpecObject(v)).join(' | ');
292
+ }
293
+ const typeSpec = getTypeSpec(schema, options);
294
+ const defaultVal = getDefault(schema, options);
295
+ typeSpec.declaration = jsType;
296
+ typeSpec.signature = typeSpec.className || typeSpec.declaration + defaultVal;
297
+ typeSpec.name = typeSpec.name || jsType;
298
+ return typeSpec;
299
+ }
300
+
301
+ const JSTypeMapping = {
302
+ number: Number,
303
+ boolean: Boolean,
304
+ string: String,
305
+ Date: Date,
306
+ Buffer: Buffer,
307
+ };
308
+
309
+ /**
310
+ * Mapping simple type names to JS Type constructors
311
+ * @param {string} type Simple type name
312
+ */
313
+ function getJSType(type) {
314
+ const ctor = JSTypeMapping[type];
315
+ return ctor && ctor.name;
316
+ }
317
+
318
+ /**
319
+ *
320
+ * https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#data-types
321
+ *
322
+ * @param {object} schema
323
+ */
324
+ function mapSchemaType(schema, options) {
325
+ options = options || {};
326
+ if (!options.objectTypeMapping) {
327
+ options.objectTypeMapping = new Map();
328
+ }
329
+
330
+ const typeSpec = getTypeSpec(schema, options);
331
+ if (typeSpec.signature) return typeSpec;
332
+
333
+ const compositeType = mapCompositeType(schema, options);
334
+ if (compositeType) {
335
+ return compositeType;
336
+ }
337
+
338
+ const arrayType = mapArrayType(schema, options);
339
+ if (arrayType) {
340
+ return arrayType;
341
+ }
342
+
343
+ const objectType = mapObjectType(schema, options);
344
+ if (objectType) {
345
+ return objectType;
346
+ }
347
+
348
+ return mapPrimitiveType(schema, options);
349
+ }
350
+
351
+ /**
352
+ * Map the schema by `x-$ref`
353
+ * @param {object} schemaMapping
354
+ * @param {object} schema
355
+ */
356
+ function resolveSchema(schemaMapping, schema) {
357
+ if (!schema['x-$ref']) return schema;
358
+ let resolved = schema;
359
+ while (resolved && resolved['x-$ref']) {
360
+ resolved = schemaMapping[resolved['x-$ref']];
361
+ }
362
+ return resolved || schema;
363
+ }
364
+
365
+ /**
366
+ * Generate model definitions from openapi spec
367
+ * @param {object} apiSpec
368
+ */
369
+ function generateModelSpecs(apiSpec, options) {
370
+ options = options || {};
371
+ const objectTypeMapping = (options.objectTypeMapping =
372
+ options.objectTypeMapping || new Map());
373
+
374
+ const schemaMapping = (options.schemaMapping = options.schemaMapping || {});
375
+
376
+ registerNamedSchemas(apiSpec, options);
377
+
378
+ const models = [];
379
+ // Generate models from schema objects
380
+ for (const s in options.schemaMapping) {
381
+ if (isExtension(s)) continue;
382
+ const schema = options.schemaMapping[s];
383
+ const model = mapSchemaType(schema, {objectTypeMapping, schemaMapping});
384
+ // `model` is `undefined` for primitive types
385
+ if (model == null) continue;
386
+ if (model.className) {
387
+ // The model might be a $ref
388
+ if (!models.includes(model)) {
389
+ models.push(model);
390
+ }
391
+ }
392
+ }
393
+ return models;
394
+ }
395
+
396
+ /**
397
+ * Register the named schema
398
+ * @param {string} schemaName Schema name
399
+ * @param {object} schema Schema object
400
+ * @param {object} typeRegistry Options for objectTypeMapping & schemaMapping
401
+ */
402
+ function registerSchema(schemaName, schema, typeRegistry) {
403
+ if (typeRegistry.objectTypeMapping.get(schema)) return;
404
+ typeRegistry.schemaMapping[`#/components/schemas/${schemaName}`] = schema;
405
+ const className = titleCase(schemaName);
406
+ typeRegistry.objectTypeMapping.set(schema, {
407
+ description: schema.description || schemaName,
408
+ name: schemaName,
409
+ className,
410
+ fileName: getModelFileName(schemaName),
411
+ properties: [],
412
+ imports: [],
413
+ });
414
+ }
415
+
416
+ /**
417
+ * Register spec.components.schemas
418
+ * @param {*} apiSpec OpenAPI spec
419
+ * @param {*} typeRegistry options for objectTypeMapping & schemaMapping
420
+ */
421
+ function registerNamedSchemas(apiSpec, typeRegistry) {
422
+ const schemas =
423
+ (apiSpec && apiSpec.components && apiSpec.components.schemas) || {};
424
+
425
+ // First map schema objects to names
426
+ for (const s in schemas) {
427
+ if (isExtension(s)) continue;
428
+ const schema = schemas[s];
429
+ registerSchema(s, schema, typeRegistry);
430
+ }
431
+ }
432
+
433
+ function getModelFileName(modelName) {
434
+ let name = modelName;
435
+ if (modelName.endsWith('Model')) {
436
+ name = modelName.substring(0, modelName.length - 'Model'.length);
437
+ }
438
+ return toFileName(name) + '.model.ts';
439
+ }
440
+
441
+ module.exports = {
442
+ mapSchemaType,
443
+ registerSchema,
444
+ registerNamedSchemas,
445
+ generateModelSpecs,
446
+ getModelFileName,
447
+ };