@oslo-flanders/swagger-generator 1.5.0 → 2.0.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/README.md CHANGED
@@ -37,8 +37,11 @@ The service is executed from the CLI and expects the following parameters:
37
37
  | `--licenseURL` | URL of the license of the API | No | |
38
38
  | `--excludeClasses` | Classes to exclude from the generated Swagger | No | Persoon Organisatie Test |
39
39
  | `--excludeProperties` | Properties to exclude from the generated Swagger | No | voornaam achternaam |
40
- | `--outputFormat` | Output format for the generated files. Can be specified multiple times to generate multiple formats at once. | No | `application/json` (default) or `application/yaml` |
41
40
  | `--disableLinks` | Disable the creation of links | No | `true` or `false` (default) |
41
+ | `--expanded` | Disable the creation of links | No | `true` or `false` (default) |
42
+ | `--excludeClassesExpanded` | Classes to exclude from expanding their properties in JSON-LD | No | Persoon Organisatie Test |
43
+ | `--excludePropertiesExpanded` | Properties to exclude from expanding in JSON-LD | No | voornaam achternaam |
44
+ | `--outputFormat` | Output format for the generated files. Can be specified multiple times to generate multiple formats at once. | No | `application/json` (default) or `application/yaml` |
42
45
  | `--silent` | Suppress log messages | No | `true` or `false` (default) |
43
46
 
44
47
  ## Usage
@@ -6,8 +6,8 @@ export declare class SwaggerGenerationService implements IService {
6
6
  readonly configuration: SwaggerGenerationServiceConfiguration;
7
7
  readonly store: QuadStore;
8
8
  constructor(logger: Logger, config: SwaggerGenerationServiceConfiguration, store: QuadStore);
9
- private getProbleemdetailsContent;
10
- private getProbleemdetailsLink;
9
+ private getProblemdetailsContent;
10
+ private getProblemdetailsLink;
11
11
  private getContact;
12
12
  private getLicense;
13
13
  private schemaExists;
@@ -53,23 +53,23 @@ let SwaggerGenerationService = class SwaggerGenerationService {
53
53
  this.configuration = config;
54
54
  this.store = store;
55
55
  }
56
- getProbleemdetailsContent() {
56
+ getProblemdetailsContent() {
57
57
  return {
58
58
  [core_1.OutputFormat.JsonProblem]: {
59
59
  schema: {
60
- $ref: '#/components/schemas/Probleemdetail',
60
+ $ref: '#/components/schemas/Problemdetail',
61
61
  },
62
62
  },
63
63
  };
64
64
  }
65
- getProbleemdetailsLink(label) {
65
+ getProblemdetailsLink(label) {
66
66
  return {
67
- 'Probleemdetail.type': {
67
+ 'Problemdetail.type': {
68
68
  operationId: `${label}GET`,
69
69
  parameters: {
70
70
  type: `$response.body#/type`,
71
71
  },
72
- description: 'De waarde van het attribuut `type` kan gebruikt worden om het gerefereerde object van het type `ProblemDetails` op te halen.',
72
+ description: 'De waarde van het attribuut `type` kan gebruikt worden om het gerefereerde object van het type `Problemdetail` op te halen.',
73
73
  },
74
74
  };
75
75
  }
@@ -164,6 +164,9 @@ let SwaggerGenerationService = class SwaggerGenerationService {
164
164
  for (const classId of this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.owl('Class'))) {
165
165
  if (hasRootClasses && !this.store.isRootClass(classId))
166
166
  continue;
167
+ /* Abstract classes should never be materialized as endpoint */
168
+ if (this.store.isAbstractClass(classId))
169
+ continue;
167
170
  const filteredLinks = {};
168
171
  let label = (_a = (0, core_1.getApplicationProfileLabel)(classId, this.store, this.configuration.language)) === null || _a === void 0 ? void 0 : _a.value;
169
172
  const definition = (_b = (0, core_1.getApplicationProfileDefinition)(classId, this.store, this.configuration.language)) === null || _b === void 0 ? void 0 : _b.value;
@@ -217,48 +220,48 @@ let SwaggerGenerationService = class SwaggerGenerationService {
217
220
  /* Error codes follow the RFC 7807 */
218
221
  400: {
219
222
  description: 'Invalid data supplied.',
220
- content: this.getProbleemdetailsContent(),
221
- links: this.getProbleemdetailsLink(label),
223
+ content: this.getProblemdetailsContent(),
224
+ links: this.getProblemdetailsLink(label),
222
225
  },
223
226
  401: {
224
227
  description: 'Invalid authorization.',
225
- content: this.getProbleemdetailsContent(),
226
- links: this.getProbleemdetailsLink(label),
228
+ content: this.getProblemdetailsContent(),
229
+ links: this.getProblemdetailsLink(label),
227
230
  },
228
231
  403: {
229
232
  description: 'Authentication failed.',
230
- content: this.getProbleemdetailsContent(),
231
- links: this.getProbleemdetailsLink(label),
233
+ content: this.getProblemdetailsContent(),
234
+ links: this.getProblemdetailsLink(label),
232
235
  },
233
236
  404: {
234
237
  description: 'Resource not found.',
235
- content: this.getProbleemdetailsContent(),
236
- links: this.getProbleemdetailsLink(label),
238
+ content: this.getProblemdetailsContent(),
239
+ links: this.getProblemdetailsLink(label),
237
240
  },
238
241
  412: {
239
242
  description: 'Pre-condition failed.',
240
- content: this.getProbleemdetailsContent(),
241
- links: this.getProbleemdetailsLink(label),
243
+ content: this.getProblemdetailsContent(),
244
+ links: this.getProblemdetailsLink(label),
242
245
  },
243
246
  500: {
244
247
  description: 'Unexpected Server Error.',
245
- content: this.getProbleemdetailsContent(),
246
- links: this.getProbleemdetailsLink(label),
248
+ content: this.getProblemdetailsContent(),
249
+ links: this.getProblemdetailsLink(label),
247
250
  },
248
251
  502: {
249
252
  description: 'Bad Gateway.',
250
- content: this.getProbleemdetailsContent(),
251
- links: this.getProbleemdetailsLink(label),
253
+ content: this.getProblemdetailsContent(),
254
+ links: this.getProblemdetailsLink(label),
252
255
  },
253
256
  503: {
254
257
  description: 'Service unavailable.',
255
- content: this.getProbleemdetailsContent(),
256
- links: this.getProbleemdetailsLink(label),
258
+ content: this.getProblemdetailsContent(),
259
+ links: this.getProblemdetailsLink(label),
257
260
  },
258
261
  504: {
259
262
  description: 'Gateway Timeout.',
260
- content: this.getProbleemdetailsContent(),
261
- links: this.getProbleemdetailsLink(label),
263
+ content: this.getProblemdetailsContent(),
264
+ links: this.getProblemdetailsLink(label),
262
265
  },
263
266
  },
264
267
  },
@@ -268,6 +271,32 @@ let SwaggerGenerationService = class SwaggerGenerationService {
268
271
  swagger.components = {
269
272
  schemas: {},
270
273
  };
274
+ /* Add minimal ProblemDetail in case it is not present, but needed for example Swagger */
275
+ swagger.components.schemas['Problemdetail'] = {
276
+ title: 'Problemdetail',
277
+ type: 'object',
278
+ description: 'Meer gedetailleerde beschrijving van de fout in een HTTP response.',
279
+ properties: {
280
+ type: {
281
+ type: 'string',
282
+ format: 'uri',
283
+ },
284
+ title: {
285
+ type: 'string',
286
+ },
287
+ status: {
288
+ type: 'integer',
289
+ format: 'int64',
290
+ },
291
+ detail: {
292
+ type: 'string',
293
+ },
294
+ instance: {
295
+ type: 'string',
296
+ format: 'uri',
297
+ },
298
+ },
299
+ };
271
300
  for (const schemaLabel of Object.keys(schemas))
272
301
  swagger.components.schemas[schemaLabel] = schemas[schemaLabel];
273
302
  return swagger;
@@ -382,9 +411,17 @@ let SwaggerGenerationService = class SwaggerGenerationService {
382
411
  this.logger.error(`Unknown cardinality for attribute ${attributeId.value}`);
383
412
  continue;
384
413
  }
414
+ /* Expanded JSON-LD depends on configuration */
415
+ let expanded = this.configuration.expanded;
416
+ if (this.configuration.excludeClassesExpanded.includes(label)) {
417
+ expanded = false;
418
+ }
419
+ if (this.configuration.excludePropertiesExpanded.includes(`${label}.${attributeLabel}`)) {
420
+ expanded = false;
421
+ }
385
422
  /* Arrays must be introduced into the schema if the max cardinality is 2 or more */
386
423
  const description = `${attributeDefinition}${attributeUsageNote ? ' ' + attributeUsageNote : ''}`;
387
- const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, subclasses, attributeDatatypeAbstract, this.configuration.excludeClasses);
424
+ const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, subclasses, attributeDatatypeAbstract, this.configuration.excludeClasses, expanded);
388
425
  // If mapProperties returns nothing, the property pointed to an excluded class (this.configuration.excludeClasses)
389
426
  if (!properties) {
390
427
  continue;
@@ -397,13 +434,22 @@ let SwaggerGenerationService = class SwaggerGenerationService {
397
434
  if (isPrimitive) {
398
435
  /* Wrap primitive property in its own named schema to avoid naming collisions */
399
436
  const schemaName = `${label}.${attributeLabel}`;
400
- schemas[schemaName] = {
401
- title: schemaName,
402
- type: 'object',
403
- description: description,
404
- properties: properties,
405
- required: requiredProperties,
406
- };
437
+ if (expanded) {
438
+ schemas[schemaName] = {
439
+ title: schemaName,
440
+ type: 'object',
441
+ description: description,
442
+ properties: properties,
443
+ required: requiredProperties,
444
+ };
445
+ }
446
+ else {
447
+ schemas[schemaName] = {
448
+ title: schemaName,
449
+ description: description,
450
+ ...properties,
451
+ };
452
+ }
407
453
  item = { $ref: `#/components/schemas/${schemaName}` };
408
454
  }
409
455
  else {
@@ -537,7 +583,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
537
583
  async writeOutput(outputFormat, obj, outputPath) {
538
584
  const isYaml = outputFormat === core_1.OutputFormat.Yaml;
539
585
  const data = isYaml
540
- ? yaml.dump(JSON.parse(JSON.stringify(obj)), { noRefs: true, lineWidth: -1 })
586
+ ? yaml.dump(JSON.parse(JSON.stringify(obj)), {
587
+ noRefs: true,
588
+ lineWidth: -1,
589
+ })
541
590
  : JSON.stringify(obj, null, 2);
542
591
  const filePath = path.join(this.configuration.output, outputPath);
543
592
  (0, core_1.ensureOutputDirectory)(path.dirname(filePath));
@@ -46,6 +46,21 @@ class SwaggerGenerationServiceRunner extends core_1.AppRunner {
46
46
  describe: 'Disable the creation of links.',
47
47
  default: false,
48
48
  boolean: true,
49
+ })
50
+ .option('expanded', {
51
+ describe: 'Use JSON-LD expanded format instead of default compact format.',
52
+ default: false,
53
+ boolean: true,
54
+ })
55
+ .option('excludeClassesExpanded', {
56
+ describe: 'A list of class names to exclude from expanding their properties with JSON-LD expansion.',
57
+ type: 'string',
58
+ array: true,
59
+ })
60
+ .option('excludePropertiesExpanded', {
61
+ describe: 'A list of property names to exclude from JSON-LD expansion.',
62
+ type: 'string',
63
+ array: true,
49
64
  })
50
65
  .option('silent', {
51
66
  describe: 'All logs are suppressed',
@@ -73,6 +73,18 @@ export declare class SwaggerGenerationServiceConfiguration implements IConfigura
73
73
  * Whether to disable the creation of links
74
74
  */
75
75
  private _disableLinks;
76
+ /**
77
+ * Whether to use expanded JSON-LD format or not
78
+ */
79
+ private _expanded;
80
+ /**
81
+ * An array of class names to be excluded from expansion
82
+ */
83
+ private _excludeClassesExpanded;
84
+ /**
85
+ * An array of property names to be excluded from expansion
86
+ */
87
+ private _excludePropertiesExpanded;
76
88
  createFromCli(params: YargsParams): Promise<void>;
77
89
  get input(): string;
78
90
  get output(): string;
@@ -92,4 +104,7 @@ export declare class SwaggerGenerationServiceConfiguration implements IConfigura
92
104
  get excludeProperties(): string[];
93
105
  get outputFormat(): OutputFormat[];
94
106
  get disableLinks(): boolean;
107
+ get expanded(): boolean;
108
+ get excludeClassesExpanded(): string[];
109
+ get excludePropertiesExpanded(): string[];
95
110
  }
@@ -29,6 +29,9 @@ let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfig
29
29
  this._excludeProperties = params.excludeProperties;
30
30
  this._outputFormat = params.outputFormat;
31
31
  this._disableLinks = params.disableLinks;
32
+ this._expanded = params.expanded;
33
+ this._excludeClassesExpanded = params.excludeClassesExpanded;
34
+ this._excludePropertiesExpanded = (params.excludePropertiesExpanded);
32
35
  }
33
36
  get input() {
34
37
  if (!this._input) {
@@ -108,6 +111,15 @@ let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfig
108
111
  get disableLinks() {
109
112
  return !!this._disableLinks;
110
113
  }
114
+ get expanded() {
115
+ return !!this._expanded;
116
+ }
117
+ get excludeClassesExpanded() {
118
+ return this._excludeClassesExpanded || [];
119
+ }
120
+ get excludePropertiesExpanded() {
121
+ return this._excludePropertiesExpanded || [];
122
+ }
111
123
  };
112
124
  SwaggerGenerationServiceConfiguration = __decorate([
113
125
  (0, inversify_1.injectable)()
@@ -1 +1 @@
1
- export declare const mapProperties: (datatype: string, label: string, subclasses: string[], abstract: boolean, excludeClasses: string[]) => object | undefined;
1
+ export declare const mapProperties: (datatype: string, label: string, subclasses: string[], abstract: boolean, excludeClasses: string[], expanded: boolean) => object | undefined;
@@ -4,7 +4,7 @@ exports.mapProperties = void 0;
4
4
  /* eslint-disable @typescript-eslint/no-loss-of-precision */
5
5
  const core_1 = require("@oslo-flanders/core");
6
6
  /* eslint-disable max-len */
7
- const Properties = new Map([
7
+ const PropertiesExpanded = new Map([
8
8
  [core_1.ns.rdf('langString').value, { '@value': { type: 'string' }, '@language': { type: 'string', pattern: '^nl$' } }],
9
9
  [core_1.ns.rdfs('Literal').value, { '@value': { type: 'string' }, '@type': { type: 'string' } }],
10
10
  [core_1.ns.xsd('string').value, { '@value': { type: 'string' } }],
@@ -32,12 +32,49 @@ const Properties = new Map([
32
32
  [core_1.ns.xsd('decimal').value, { '@value': { type: 'string', pattern: '(+|-)?([0-9]+(.[0-9]*)?|.[0-9]+)' }, '@type': { type: 'string', pattern: '^Decimal$' } }],
33
33
  [core_1.ns.xsd('language').value, { '@value': { type: 'string', pattern: '^[a-z]{2,3}(-[A-Z]{2})?' }, '@type': { type: 'string', pattern: '^Language$' } }],
34
34
  ]);
35
+ /* JSON-LD context provides values for @type and @language for primitive datatypes */
36
+ const PropertiesCompacted = new Map([
37
+ [core_1.ns.rdf('langString').value, { type: 'string' }],
38
+ [core_1.ns.rdfs('Literal').value, { type: 'string' }],
39
+ [core_1.ns.xsd('string').value, { type: 'string' }],
40
+ [core_1.ns.xsd('anyURI').value, { type: 'string', format: 'uri' }],
41
+ [core_1.ns.xsd('dateTime').value, { type: 'string', format: 'date-time' }],
42
+ [core_1.ns.xsd('date').value, { type: 'string', format: 'date' }],
43
+ [core_1.ns.xsd('boolean').value, { type: 'boolean' }],
44
+ [core_1.ns.xsd('integer').value, { type: 'number', format: 'int64' }],
45
+ [core_1.ns.xsd('long').value, { type: 'number', format: 'int64', minimum: -9223372036854776000, maximum: 9223372036854776000 }],
46
+ [core_1.ns.xsd('float').value, { type: 'number', format: 'float' }],
47
+ [core_1.ns.xsd('double').value, { type: 'number', format: 'double' }],
48
+ [core_1.ns.xsd('int').value, { type: 'number', format: 'int32', minimum: -2147483648, maximum: 2147483647 }],
49
+ [core_1.ns.xsd('short').value, { type: 'number', format: 'int32', minimum: -32768, maximum: 32767 }],
50
+ [core_1.ns.xsd('byte').value, { type: 'number', format: 'int32', minimum: -128, maximum: 127 }],
51
+ [core_1.ns.xsd('hexBinary').value, { type: 'string', format: 'binary' }],
52
+ [core_1.ns.xsd('base64Binary').value, { type: 'string', format: 'byte' }],
53
+ [core_1.ns.xsd('nonNegativeInteger').value, { type: 'number', format: 'int64' }],
54
+ [core_1.ns.xsd('nonPositiveInteger').value, { type: 'number', format: 'int64' }],
55
+ [core_1.ns.xsd('negativeInteger').value, { type: 'number', format: 'int64', maximum: 0 }],
56
+ [core_1.ns.xsd('positiveInteger').value, { type: 'number', format: 'int64', minimum: 1 }],
57
+ [core_1.ns.xsd('unsignedLong').value, { type: 'number', format: 'int64', minimum: 0, maximum: 18446744073709552000 }],
58
+ [core_1.ns.xsd('unsignedInt').value, { type: 'number', format: 'int32', minimum: 0, maximum: 4294967295 }],
59
+ [core_1.ns.xsd('unsignedShort').value, { type: 'number', format: 'int32', minimum: 0, maximum: 65535 }],
60
+ [core_1.ns.xsd('unsignedByte').value, { type: 'number', format: 'int32', minimum: 0, maximum: 255 }],
61
+ [core_1.ns.xsd('decimal').value, { type: 'string', pattern: '(+|-)?([0-9]+(.[0-9]*)?|.[0-9]+)' }],
62
+ [core_1.ns.xsd('language').value, { type: 'string', pattern: '^[a-z]{2,3}(-[A-Z]{2})?' }],
63
+ ]);
35
64
  /* eslint-enable max-len*/
36
- const mapProperties = (datatype, label, subclasses, abstract, excludeClasses) => {
65
+ const mapProperties = (datatype, label, subclasses, abstract, excludeClasses, expanded) => {
37
66
  /* Primitive data type conversion from Linked Data to Swagger */
38
- if (Properties.has(datatype)) {
39
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
40
- return Properties.get(datatype);
67
+ if (expanded) {
68
+ if (PropertiesExpanded.has(datatype)) {
69
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
70
+ return PropertiesExpanded.get(datatype);
71
+ }
72
+ }
73
+ else {
74
+ if (PropertiesCompacted.has(datatype)) {
75
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
76
+ return PropertiesCompacted.get(datatype);
77
+ }
41
78
  }
42
79
  const oneOf = [];
43
80
  // Add the superclass to the list if it's not abstract and not excluded
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslo-flanders/swagger-generator",
3
- "version": "1.5.0",
3
+ "version": "2.0.0",
4
4
  "description": "Generate OpenAPI Swagger YAML documentation.",
5
5
  "author": "Digitaal Vlaanderen <https://data.vlaanderen.be/id/organisatie/OVO002949>",
6
6
  "homepage": "https://github.com/informatievlaanderen/OSLO-UML-Transformer/tree/main/packages/oslo-generator-swagger#readme",