@vkontakte/api-schema-typescript-generator 0.9.0 → 0.13.0

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/dist/generator.js CHANGED
@@ -1,15 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateStandaloneEnum = exports.generateInlineEnum = exports.generateImportsBlock = void 0;
4
- const types_1 = require("./types");
5
- const utils_1 = require("./utils");
3
+ exports.generateImportsBlock = void 0;
6
4
  const constants_1 = require("./constants");
7
5
  const helpers_1 = require("./helpers");
8
- const TypeCodeBlock_1 = require("./generators/TypeCodeBlock");
9
- function generateImportsBlock(imports, section, type) {
10
- const objectsToImport = utils_1.uniqueArray(Object.keys(imports));
6
+ const types_1 = require("./types");
7
+ const utils_1 = require("./utils");
8
+ function generateImportsBlock(refs, section, type) {
9
+ let importRefs = Object.entries(refs)
10
+ .filter(([, type]) => type === types_1.RefsDictionaryType.GenerateAndImport)
11
+ .map(([key]) => key);
12
+ importRefs = utils_1.uniqueArray(importRefs);
11
13
  const paths = {};
12
- objectsToImport.forEach((objectName) => {
14
+ importRefs.forEach((objectName) => {
13
15
  const importSection = helpers_1.getSectionFromObjectName(objectName);
14
16
  const interfaceName = helpers_1.getInterfaceName(objectName);
15
17
  let path;
@@ -37,95 +39,3 @@ function generateImportsBlock(imports, section, type) {
37
39
  return importLines.join(constants_1.newLineChar);
38
40
  }
39
41
  exports.generateImportsBlock = generateImportsBlock;
40
- function getEnumNames(object) {
41
- let { enumNames } = object;
42
- const needEnumNamesDescription = !!enumNames;
43
- if (!enumNames) {
44
- const canUseEnumNames = !object.enum.some((value) => !!+value);
45
- if (canUseEnumNames) {
46
- enumNames = [...object.enum];
47
- }
48
- }
49
- return {
50
- needEnumNamesDescription,
51
- enumNames: Array.isArray(enumNames) && enumNames.length ? enumNames : undefined,
52
- };
53
- }
54
- function generateInlineEnum(object, options = {}) {
55
- const { enumNames, needEnumNamesDescription, } = getEnumNames(object);
56
- const codeBlocks = [];
57
- let descriptionLines = [];
58
- if (enumNames) {
59
- const enumName = options.objectParentName ? `${options.objectParentName} ${object.name} enumNames` : object.name;
60
- const enumInterfaceName = helpers_1.getInterfaceName(enumName);
61
- const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
62
- type: TypeCodeBlock_1.TypeScriptCodeTypes.ConstantObject,
63
- refName: enumName,
64
- interfaceName: enumInterfaceName,
65
- needExport: true,
66
- properties: [],
67
- });
68
- if (needEnumNamesDescription) {
69
- descriptionLines.push('');
70
- }
71
- enumNames.forEach((name, index) => {
72
- const value = object.enum[index];
73
- codeBlock.addProperty({
74
- name: helpers_1.getEnumPropertyName(name.toString()),
75
- value,
76
- wrapValue: true,
77
- });
78
- if (needEnumNamesDescription) {
79
- descriptionLines.push(`\`${value}\` — ${name}`);
80
- }
81
- });
82
- if (!options.skipEnumNamesConstant) {
83
- codeBlocks.push(codeBlock);
84
- }
85
- }
86
- const values = object.enum.map((value) => utils_1.quoteJavaScriptValue(value));
87
- return {
88
- codeBlocks,
89
- imports: {},
90
- value: helpers_1.joinOneOfValues(values, true),
91
- description: descriptionLines.join(constants_1.newLineChar),
92
- };
93
- }
94
- exports.generateInlineEnum = generateInlineEnum;
95
- function generateStandaloneEnum(object, options = {}) {
96
- const { enumNames, } = getEnumNames(object);
97
- if (enumNames) {
98
- const enumName = options.objectParentName ? `${options.objectParentName} ${object.name} enum` : object.name;
99
- const enumInterfaceName = helpers_1.getInterfaceName(enumName);
100
- const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
101
- type: TypeCodeBlock_1.TypeScriptCodeTypes.Enum,
102
- refName: enumName,
103
- interfaceName: enumInterfaceName,
104
- needExport: true,
105
- properties: [],
106
- });
107
- enumNames.forEach((name, index) => {
108
- codeBlock.addProperty({
109
- name: helpers_1.getEnumPropertyName(name.toString()),
110
- value: object.enum[index],
111
- wrapValue: true,
112
- });
113
- });
114
- return {
115
- codeBlocks: [
116
- codeBlock,
117
- ],
118
- imports: {},
119
- value: enumInterfaceName,
120
- };
121
- }
122
- else {
123
- const values = object.enum.map((value) => utils_1.quoteJavaScriptValue(value));
124
- return {
125
- codeBlocks: [],
126
- imports: {},
127
- value: helpers_1.joinOneOfValues(values, true),
128
- };
129
- }
130
- }
131
- exports.generateStandaloneEnum = generateStandaloneEnum;
@@ -5,6 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.APITypingsGenerator = void 0;
7
7
  const types_1 = require("../types");
8
+ const enums_1 = require("./enums");
9
+ const methods_1 = require("./methods");
8
10
  const SchemaObject_1 = require("./SchemaObject");
9
11
  const helpers_1 = require("../helpers");
10
12
  const TypeCodeBlock_1 = require("./TypeCodeBlock");
@@ -21,7 +23,7 @@ class APITypingsGenerator {
21
23
  this.outDirPath = options.outDirPath;
22
24
  this.methodsPattern = helpers_1.prepareMethodsPattern(options.methodsPattern);
23
25
  this.methodsDefinitions = options.methodsDefinitions;
24
- this.methodsList = options.methodsDefinitions.methods;
26
+ this.methodsList = options.methodsDefinitions.methods || [];
25
27
  this.objects = this.convertJSONSchemaDictionary(options.objects);
26
28
  this.responses = this.convertJSONSchemaDictionary(options.responses);
27
29
  this.visitedRefs = {};
@@ -83,9 +85,11 @@ class APITypingsGenerator {
83
85
  if (allOfItem.ref && !this.visitedRefs[allOfItem.ref]) {
84
86
  this.visitedRefs[allOfItem.ref] = true;
85
87
  const refName = allOfItem.ref;
86
- const objectName = helpers_1.getObjectNameByRef(refName);
87
- allOfItem = this.objects[objectName];
88
- if (!allOfItem) {
88
+ const tempAllOfItem = this.getObjectByRef(refName);
89
+ if (tempAllOfItem) {
90
+ allOfItem = tempAllOfItem;
91
+ }
92
+ else {
89
93
  log_1.consoleLogErrorAndExit(`${refName} ref not found`);
90
94
  }
91
95
  }
@@ -108,10 +112,10 @@ class APITypingsGenerator {
108
112
  additionalProperties = allOfItem.properties;
109
113
  }
110
114
  else if (allOfItem.ref) {
111
- const objectName = helpers_1.getObjectNameByRef(allOfItem.ref);
112
- const refObject = this.objects[objectName];
115
+ const refObject = this.getObjectByRef(allOfItem.ref);
113
116
  if (!refObject) {
114
117
  log_1.consoleLogErrorAndExit(`${object.name} ref object in allOf is not found`);
118
+ return;
115
119
  }
116
120
  additionalProperties = this.getObjectProperties(refObject, deep + 1);
117
121
  }
@@ -130,7 +134,7 @@ class APITypingsGenerator {
130
134
  return properties;
131
135
  }
132
136
  }
133
- /*
137
+ /**
134
138
  * Filter properties with same name
135
139
  * If an object uses allOf, some nested objects may have the same properties
136
140
  */
@@ -150,7 +154,6 @@ class APITypingsGenerator {
150
154
  let imports = {};
151
155
  let codeBlocks = [];
152
156
  const properties = this.getObjectProperties(object);
153
- const requiredProperties = utils_1.arrayToMap(object.required);
154
157
  const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
155
158
  type: TypeCodeBlock_1.TypeScriptCodeTypes.Interface,
156
159
  refName: object.name,
@@ -163,14 +166,16 @@ class APITypingsGenerator {
163
166
  return this.getPrimitiveInterfaceCode(object);
164
167
  }
165
168
  properties.forEach((property) => {
166
- const { imports: newImports, value, codeBlocks: newCodeBlocks, description, } = typeString_1.generateTypeString(property, this.objects);
169
+ const { imports: newImports, value, codeBlocks: newCodeBlocks, description, } = typeString_1.generateTypeString(property, this.objects, {
170
+ objectParentName: object.name,
171
+ });
167
172
  imports = { ...imports, ...newImports };
168
173
  codeBlocks = [...codeBlocks, ...newCodeBlocks];
169
174
  codeBlock.addProperty({
170
175
  name: property.name,
171
176
  description: [property.description, description].join(constants_1.newLineChar),
172
177
  value,
173
- isRequired: helpers_1.isPatternProperty(property.name) || requiredProperties[property.name],
178
+ isRequired: helpers_1.isPatternProperty(property.name) || property.isRequired,
174
179
  });
175
180
  });
176
181
  return {
@@ -187,7 +192,7 @@ class APITypingsGenerator {
187
192
  return this.getObjectCodeBlockAsType(object);
188
193
  }
189
194
  if (object.enum) {
190
- const { codeBlocks } = generator_1.generateStandaloneEnum(object);
195
+ const { codeBlocks } = enums_1.generateEnumAsUnionType(object);
191
196
  return {
192
197
  codeBlocks: codeBlocks,
193
198
  imports: {},
@@ -243,10 +248,13 @@ class APITypingsGenerator {
243
248
  });
244
249
  this.generateObjectsFromImports(imports);
245
250
  }
251
+ getObjectByRef(ref) {
252
+ const refName = helpers_1.getObjectNameByRef(ref);
253
+ return this.objects[refName];
254
+ }
246
255
  generateObjectsFromRefs(refs) {
247
256
  Object.keys(refs).forEach((ref) => {
248
- const refName = helpers_1.getObjectNameByRef(ref);
249
- const refObject = this.objects[refName];
257
+ const refObject = this.getObjectByRef(ref);
250
258
  if (!refObject) {
251
259
  log_1.consoleLogInfo(`"${ref}" ref is not found`);
252
260
  return;
@@ -256,8 +264,7 @@ class APITypingsGenerator {
256
264
  }
257
265
  generateObjectsFromImports(imports) {
258
266
  Object.keys(imports).forEach((ref) => {
259
- const refName = helpers_1.getObjectNameByRef(ref);
260
- const refObject = this.objects[refName];
267
+ const refObject = this.getObjectByRef(ref);
261
268
  if (!refObject) {
262
269
  log_1.consoleLogInfo(`"${ref}" ref is not found`);
263
270
  return;
@@ -268,39 +275,6 @@ class APITypingsGenerator {
268
275
  generateMethodParams(methodInfo) {
269
276
  const section = helpers_1.getMethodSection(methodInfo.name);
270
277
  const interfaceName = `${methodInfo.name} params`;
271
- const parametersRaw = Array.isArray(methodInfo.parameters) ? methodInfo.parameters : [];
272
- const requiredParams = parametersRaw.reduce((acc, param) => {
273
- if (param.required) {
274
- acc[param.name] = true;
275
- }
276
- return acc;
277
- }, {});
278
- const properties = parametersRaw.map((paramRaw) => {
279
- paramRaw = { ...paramRaw };
280
- // For method params "boolean" type means 1 or 0
281
- // Real "false" boolean value will be detected by API as true
282
- if (paramRaw.type === 'boolean') {
283
- delete paramRaw.type;
284
- paramRaw.$ref = constants_1.baseBoolIntRef;
285
- }
286
- // For parameters of the "array" type, VK API still accepts only a comma-separated string
287
- // This may change in the future when the VK API starts accepting a json body
288
- if (paramRaw.type === 'array') {
289
- paramRaw.type = 'string';
290
- if (!paramRaw.description) {
291
- paramRaw.description = '';
292
- }
293
- if (paramRaw.items) {
294
- if (paramRaw.items.$ref) {
295
- this.generateObjectsFromRefs({
296
- [paramRaw.items.$ref]: true,
297
- });
298
- paramRaw.description += constants_1.newLineChar.repeat(2) + paramRaw.items.$ref;
299
- }
300
- }
301
- }
302
- return new SchemaObject_1.SchemaObject(paramRaw.name, paramRaw, interfaceName);
303
- });
304
278
  let imports = {};
305
279
  let codeBlocks = [];
306
280
  const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
@@ -310,35 +284,32 @@ class APITypingsGenerator {
310
284
  allowEmptyInterface: true,
311
285
  properties: [],
312
286
  });
313
- properties.forEach((property) => {
314
- const { imports: newImports, value, codeBlocks: newCodeBlocks, } = typeString_1.generateTypeString(property, this.objects, { skipEnumNamesConstant: true });
287
+ methodInfo.parameters.forEach((property) => {
288
+ const { imports: newImports, value, codeBlocks: newCodeBlocks, } = typeString_1.generateTypeString(property, this.objects, { needEnumNamesConstant: false });
315
289
  imports = { ...imports, ...newImports };
316
290
  codeBlocks = [...codeBlocks, ...newCodeBlocks];
317
291
  codeBlock.addProperty({
318
292
  name: property.name,
319
293
  description: property.description,
320
294
  value,
321
- isRequired: requiredParams[property.name],
295
+ isRequired: property.isRequired,
322
296
  });
323
297
  });
324
298
  this.appendToFileMap(section, imports, [...codeBlocks, codeBlock]);
325
299
  this.generateObjectsFromImports(imports);
326
300
  }
327
- getResponseObjectRef(object) {
328
- const objectName = helpers_1.getObjectNameByRef(object.ref);
301
+ getResponseObjectRef(ref) {
302
+ const objectName = helpers_1.getObjectNameByRef(ref);
329
303
  if (this.responses[objectName]) {
330
304
  return this.responses[objectName];
331
305
  }
332
- else if (this.objects[objectName]) {
333
- return this.objects[objectName];
334
- }
335
- return undefined;
306
+ return this.getObjectByRef(ref);
336
307
  }
337
308
  getObjectCodeBlockAsType(object) {
338
309
  let codeBlocks = [];
339
310
  let imports = {};
340
311
  if (object.enum) {
341
- const { codeBlocks: newCodeBlocks } = generator_1.generateStandaloneEnum(object);
312
+ const { codeBlocks: newCodeBlocks } = enums_1.generateEnumAsUnionType(object);
342
313
  codeBlocks = [
343
314
  ...newCodeBlocks,
344
315
  ];
@@ -368,36 +339,29 @@ class APITypingsGenerator {
368
339
  };
369
340
  }
370
341
  getResponseCodeBlockAsType(object, response) {
371
- let codeBlocks = [];
372
- let imports = {};
373
- if (response.enum) {
374
- const { codeBlocks: newCodeBlocks } = generator_1.generateStandaloneEnum(response);
375
- codeBlocks = [
376
- ...newCodeBlocks,
377
- ];
378
- }
379
- else {
380
- const { imports: newImports, value, codeBlocks: newCodeBlocks } = typeString_1.generateTypeString(response, this.objects);
381
- const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
382
- type: TypeCodeBlock_1.TypeScriptCodeTypes.Type,
383
- refName: object.name,
384
- interfaceName: helpers_1.getInterfaceName(object.name),
385
- description: object.description,
386
- needExport: true,
387
- properties: [],
388
- value,
389
- });
390
- imports = newImports;
391
- codeBlocks = [
342
+ const { imports, value, codeBlocks, description, } = typeString_1.generateTypeString(response, this.objects, {
343
+ objectParentName: ' ',
344
+ });
345
+ const codeBlock = new TypeCodeBlock_1.TypeCodeBlock({
346
+ type: TypeCodeBlock_1.TypeScriptCodeTypes.Type,
347
+ refName: object.name,
348
+ interfaceName: helpers_1.getInterfaceName(object.name),
349
+ description: [
350
+ object.description,
351
+ description || '',
352
+ ].join(constants_1.newLineChar),
353
+ needExport: true,
354
+ properties: [],
355
+ value,
356
+ });
357
+ return {
358
+ codeBlocks: [
392
359
  ...codeBlocks,
393
- ...newCodeBlocks,
394
360
  codeBlock,
395
- ];
396
- }
397
- return {
398
- codeBlocks,
361
+ ],
399
362
  imports,
400
363
  value: '',
364
+ description,
401
365
  };
402
366
  }
403
367
  getResponseCodeBlock(object) {
@@ -411,62 +375,35 @@ class APITypingsGenerator {
411
375
  [constants_1.basePropertyExistsRef]: true,
412
376
  };
413
377
  const objectName = helpers_1.getObjectNameByRef(object.ref);
414
- let response;
415
378
  if (nonBuildableRefs[objectName]) {
416
379
  return this.getObjectCodeBlockAsType(object);
417
380
  }
418
- else if (this.responses[objectName]) {
419
- response = this.responses[objectName];
420
- const { properties = [] } = response;
421
- const responseProperty = properties.find((property) => property.name === 'response');
422
- if (responseProperty) {
423
- response = responseProperty;
424
- if (response.ref) {
425
- return this.getResponseCodeBlockAsType(object, response);
426
- }
427
- }
428
- else {
429
- // Maybe this is a crutch?
430
- response.properties.forEach((property) => {
431
- if (response && property.parentObjectName === response.name) {
432
- response = property;
433
- return true;
434
- }
435
- return false;
436
- });
437
- }
438
- }
439
- else if (this.objects[objectName]) {
440
- response = this.objects[objectName];
441
- if (object.ref) {
442
- return this.getResponseCodeBlockAsType(object, object);
443
- }
444
- }
445
- // @ts-ignore
446
- while (response && response.ref) {
447
- response = this.getResponseObjectRef(response);
448
- }
381
+ let response = this.getResponseObjectRef(object.ref);
449
382
  if (!response) {
450
- log_1.consoleLogErrorAndExit(`"${object.name}" has no response`);
383
+ log_1.consoleLogError(`response schema object "${object.name}" has no response`, object);
451
384
  return false;
452
385
  }
453
- response.originalName = response.name;
386
+ // VK API JSON Schema specific heuristic
387
+ if (response.properties.length === 1 && response.properties[0].name === 'response') {
388
+ response = response.properties[0];
389
+ }
390
+ if (response.ref) {
391
+ return this.getResponseCodeBlockAsType(object, response);
392
+ }
393
+ response = response.clone();
454
394
  response.setName(object.name);
455
- let result;
456
395
  switch (response.type) {
457
396
  case 'object':
458
- result = this.getObjectInterfaceCode(response);
459
- break;
397
+ return this.getObjectInterfaceCode(response);
460
398
  case 'integer':
461
399
  case 'string':
462
400
  case 'boolean':
463
401
  case 'array':
464
402
  return this.getResponseCodeBlockAsType(object, response);
465
403
  default:
466
- log_1.consoleLogErrorAndExit(response.name, 'unknown type');
404
+ log_1.consoleLogErrorAndExit(response.name, 'unknown type', response.type);
467
405
  return false;
468
406
  }
469
- return result;
470
407
  }
471
408
  generateResponse(section, response) {
472
409
  const result = this.getResponseCodeBlock(response);
@@ -477,33 +414,36 @@ class APITypingsGenerator {
477
414
  this.appendToFileMap(section, imports, codeBlocks);
478
415
  this.generateObjectsFromImports(imports);
479
416
  }
480
- generateMethodParamsAndResponses(methodInfo) {
481
- const { name } = methodInfo;
482
- const section = helpers_1.getMethodSection(name);
483
- if (!utils_1.isObject(methodInfo.responses)) {
484
- log_1.consoleLogErrorAndExit(`"${name}" "responses" field is not an object.`);
417
+ generateMethodParamsAndResponses(method) {
418
+ const { name: methodName } = method;
419
+ const section = helpers_1.getMethodSection(methodName);
420
+ if (!utils_1.isObject(method.responses)) {
421
+ log_1.consoleLogErrorAndExit(`"${methodName}" "responses" field is not an object.`);
485
422
  return;
486
423
  }
487
- if (Object.keys(methodInfo.responses).length === 0) {
488
- log_1.consoleLogErrorAndExit(`"${name}" "responses" field is empty.`);
424
+ if (Object.keys(method.responses).length === 0) {
425
+ log_1.consoleLogErrorAndExit(`"${methodName}" "responses" field is empty.`);
489
426
  return;
490
427
  }
491
428
  // Comment with method name for visual sections in file
492
- const methodNameComment = new CommentCodeBlock_1.CommentCodeBlock([name]);
493
- if (methodInfo.description) {
429
+ const methodNameComment = new CommentCodeBlock_1.CommentCodeBlock([methodName]);
430
+ if (method.description) {
494
431
  methodNameComment.appendLines([
495
432
  '',
496
- methodInfo.description,
433
+ method.description,
497
434
  ]);
498
435
  }
499
436
  this.appendToFileMap(section, {}, [methodNameComment]);
500
- this.generateMethodParams(methodInfo);
501
- Object.entries(methodInfo.responses).forEach(([responseName, responseObject]) => {
502
- if (this.ignoredResponses[name] && this.ignoredResponses[name][responseName]) {
437
+ const { method: normalizedMethod, parameterRefs, } = methods_1.normalizeMethodInfo(method);
438
+ method = normalizedMethod;
439
+ this.generateObjectsFromRefs(parameterRefs);
440
+ this.generateMethodParams(new SchemaObject_1.SchemaObject(method.name, method));
441
+ Object.entries(method.responses).forEach(([responseName, responseObject]) => {
442
+ if (this.ignoredResponses[methodName] && this.ignoredResponses[methodName][responseName]) {
503
443
  return;
504
444
  }
505
- responseObject.name = `${name}_${responseName}`;
506
- this.generateResponse(section, new SchemaObject_1.SchemaObject(responseObject.name, responseObject));
445
+ const name = `${methodName}_${responseName}`;
446
+ this.generateResponse(section, new SchemaObject_1.SchemaObject(name, responseObject));
507
447
  });
508
448
  }
509
449
  generateMethods() {
@@ -38,12 +38,21 @@ class SchemaObject {
38
38
  else {
39
39
  this.required = [];
40
40
  }
41
+ if (typeof object.required === 'boolean') {
42
+ this.isRequired = object.required;
43
+ }
41
44
  this.properties = [];
42
45
  if (object.properties) {
43
46
  Object.entries(object.properties).forEach(([propertyName, property]) => {
44
47
  this.properties.push(new SchemaObject(propertyName, property, name));
45
48
  });
46
49
  }
50
+ this.parameters = [];
51
+ if (Array.isArray(object.parameters)) {
52
+ object.parameters.forEach((parameter) => {
53
+ this.parameters.push(new SchemaObject(parameter.name, parameter, `${name} param`));
54
+ });
55
+ }
47
56
  if (object.patternProperties) {
48
57
  Object.entries(object.patternProperties).forEach(([propertyName, property]) => {
49
58
  this.properties.push(new SchemaObject(helpers_1.transformPatternPropertyName(propertyName), property, name));
@@ -58,17 +67,17 @@ class SchemaObject {
58
67
  if (Array.isArray(object.allOf) && object.allOf.length > 0) {
59
68
  this.allOf = object.allOf.map((item) => new SchemaObject(name, item));
60
69
  }
61
- // Crutch
62
- // if (this.oneOf && this.oneOf.length === 1) {
63
- // this.allOf = [this.oneOf[0]];
64
- // this.oneOf = undefined;
65
- // }
66
70
  }
67
71
  setName(name) {
68
72
  this.name = name;
69
73
  if (Array.isArray(this.properties)) {
70
- this.properties.forEach((property) => property.parentObjectName = name);
74
+ this.properties.forEach((property) => {
75
+ property.parentObjectName = name;
76
+ });
71
77
  }
72
78
  }
79
+ clone() {
80
+ return Object.assign(Object.create(Object.getPrototypeOf(this)), this);
81
+ }
73
82
  }
74
83
  exports.SchemaObject = SchemaObject;
@@ -52,15 +52,11 @@ class TypeCodeBlock extends BaseCodeBlock_1.BaseCodeBlock {
52
52
  let propertyCode = [
53
53
  ` ${quoteChar}${property.name}${quoteChar}${divider} ${value}${lineEnd}`,
54
54
  ];
55
- const propertyDescriptionLines = utils_1.trimArray((property.description || '').trim().split(constants_1.newLineChar));
56
- if (propertyDescriptionLines.length) {
57
- propertyCode.unshift([
58
- ' /**',
59
- ...propertyDescriptionLines.map((line) => {
60
- return ' ' + `* ${line}`.trim();
61
- }),
62
- ' */',
63
- ].join(constants_1.newLineChar));
55
+ if (property.description) {
56
+ const commentLines = helpers_1.joinCommentLines(2, property.description);
57
+ if (commentLines.length) {
58
+ propertyCode.unshift(commentLines.join(constants_1.newLineChar));
59
+ }
64
60
  }
65
61
  return propertyCode.join(constants_1.newLineChar);
66
62
  }).join(constants_1.newLineChar);
@@ -71,16 +67,15 @@ class TypeCodeBlock extends BaseCodeBlock_1.BaseCodeBlock {
71
67
  let propertiesCode = this.getPropertiesCode();
72
68
  let before = [];
73
69
  let code = '';
70
+ if (this.refName) {
71
+ before.push(`// ${this.refName}`);
72
+ }
74
73
  if (this.description) {
75
74
  before = [
76
- '/**',
77
- ` * ${this.description}`,
78
- ' */',
75
+ ...before,
76
+ ...helpers_1.joinCommentLines(0, this.description),
79
77
  ];
80
78
  }
81
- if (this.refName) {
82
- before.push(`// ${this.refName}`);
83
- }
84
79
  switch (this.type) {
85
80
  case TypeScriptCodeTypes.Interface: {
86
81
  if (!hasProperties) {