@oslo-flanders/swagger-generator 1.0.3 → 1.0.4

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.
@@ -1,19 +1,19 @@
1
1
  import type { IService } from '@oslo-flanders/core';
2
2
  import { QuadStore, Logger } from '@oslo-flanders/core';
3
- import type * as RDF from '@rdfjs/types';
4
- import { DataFactory } from 'rdf-data-factory';
5
3
  import { SwaggerGenerationServiceConfiguration } from './config/SwaggerGenerationServiceConfiguration';
6
4
  export declare class SwaggerGenerationService implements IService {
7
5
  readonly logger: Logger;
8
6
  readonly configuration: SwaggerGenerationServiceConfiguration;
9
- readonly dataFactory: DataFactory<RDF.Quad>;
10
7
  readonly store: QuadStore;
11
8
  constructor(logger: Logger, config: SwaggerGenerationServiceConfiguration, store: QuadStore);
9
+ private getProbleemdetailsContent;
10
+ private getProbleemdetailsLink;
12
11
  private getContact;
13
12
  private getLicense;
14
- private getTag;
15
13
  init(): Promise<void>;
16
14
  run(): Promise<void>;
17
- createSwagger(): Object;
18
- writeSwagger(swagger: Object): Promise<void>;
15
+ createSwagger(schemas: any, links: any): Object;
16
+ createSchemas(): Object;
17
+ createLinks(): Object;
18
+ writeJSON(json: Object, outputPath: string): Promise<void>;
19
19
  }
@@ -1,10 +1,33 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
21
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
22
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
23
  };
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
8
31
  var __metadata = (this && this.__metadata) || function (k, v) {
9
32
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
33
  };
@@ -14,20 +37,37 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
14
37
  Object.defineProperty(exports, "__esModule", { value: true });
15
38
  exports.SwaggerGenerationService = void 0;
16
39
  const core_1 = require("@oslo-flanders/core");
40
+ const path = __importStar(require("path"));
17
41
  const promises_1 = require("fs/promises");
18
42
  const inversify_1 = require("inversify");
19
- const rdf_data_factory_1 = require("rdf-data-factory");
20
43
  const SwaggerGenerationServiceConfiguration_1 = require("./config/SwaggerGenerationServiceConfiguration");
21
44
  const Properties_1 = require("./enums/Properties");
22
- const swaggerUtils_1 = require("./utils/swaggerUtils");
23
- const Swagger_1 = require("./constants/Swagger");
24
45
  let SwaggerGenerationService = class SwaggerGenerationService {
25
46
  constructor(logger, config, store) {
26
- this.dataFactory = new rdf_data_factory_1.DataFactory();
27
47
  this.logger = logger;
28
48
  this.configuration = config;
29
49
  this.store = store;
30
50
  }
51
+ getProbleemdetailsContent() {
52
+ return {
53
+ [core_1.OutputFormat.JsonProblem]: {
54
+ schema: {
55
+ $ref: '#/components/schemas/Probleemdetail',
56
+ },
57
+ },
58
+ };
59
+ }
60
+ getProbleemdetailsLink(label) {
61
+ return {
62
+ 'Probleemdetail.type': {
63
+ operationId: `${label}GET`,
64
+ parameters: {
65
+ type: `$response.body#/type`,
66
+ },
67
+ description: 'De waarde van het attribuut `type` kan gebruikt worden om het gerefereerde object van het type `ProblemDetails` op te halen.',
68
+ },
69
+ };
70
+ }
31
71
  getContact() {
32
72
  /* If no contact information is provided, the whole block may not appear */
33
73
  if (!this.configuration.contactName &&
@@ -49,25 +89,37 @@ let SwaggerGenerationService = class SwaggerGenerationService {
49
89
  url: this.configuration.licenseURL,
50
90
  };
51
91
  }
52
- getTag(subject) {
53
- var _a;
54
- if ((_a = this.store
55
- .getAssignedUri(subject)) === null || _a === void 0 ? void 0 : _a.value.startsWith(this.configuration.baseURL)) {
56
- return 'OSLO datastandaarden';
57
- }
58
- return 'Externe datastandaarden';
59
- }
60
92
  async init() {
61
93
  return this.store.addQuadsFromFile(this.configuration.input);
62
94
  }
63
95
  async run() {
64
- /* Create Swagger as JSON */
65
- const swagger = this.createSwagger();
66
- /* Write Swagger to file */
67
- await this.writeSwagger(swagger);
96
+ /* Create Swagger schemas */
97
+ const schemas = this.createSchemas();
98
+ for (const label of Object.keys(schemas))
99
+ await this.writeJSON(schemas[label], `swagger/components/schemas/${label}.json`);
100
+ /* Create Swagger links */
101
+ const links = this.createLinks();
102
+ for (const label of Object.keys(links))
103
+ await this.writeJSON(links[label], `swagger/components/links/${label}.json`);
104
+ /* Create self-standing referenceable components */
105
+ const components = {
106
+ openapi: this.configuration.versionSwagger,
107
+ info: {
108
+ title: `Components of ${this.configuration.title}`,
109
+ description: this.configuration.description,
110
+ contact: this.getContact(),
111
+ license: this.getLicense(),
112
+ version: this.configuration.versionAPI,
113
+ },
114
+ components: { schemas, links },
115
+ };
116
+ await this.writeJSON(components, `swagger/components.json`);
117
+ /* Create Swagger endpoint paths as example */
118
+ const swagger = this.createSwagger(schemas, links);
119
+ await this.writeJSON(swagger, 'swagger/example.json');
68
120
  }
69
- createSwagger() {
70
- var _a, _b, _c, _d, _e, _f, _g, _h;
121
+ createSwagger(schemas, links) {
122
+ var _a, _b, _c;
71
123
  const swagger = {
72
124
  openapi: this.configuration.versionSwagger,
73
125
  info: {
@@ -84,16 +136,153 @@ let SwaggerGenerationService = class SwaggerGenerationService {
84
136
  },
85
137
  ],
86
138
  paths: {},
87
- components: {
88
- schemas: {},
89
- },
90
139
  };
91
- /* Create endpoint for each Class */
92
- let links = {};
140
+ const hasRootClasses = this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.oslo('RootClass')).length > 0;
141
+ /* Create endpoint for each Class which is marked as RootClass, if none, generate all */
93
142
  for (const classId of this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.owl('Class'))) {
143
+ if (hasRootClasses && !this.store.isRootClass(classId))
144
+ continue;
145
+ const filteredLinks = {};
94
146
  let label = (_a = (0, core_1.getApplicationProfileLabel)(classId, this.store, this.configuration.language)) === null || _a === void 0 ? void 0 : _a.value;
95
147
  const definition = (_b = (0, core_1.getApplicationProfileDefinition)(classId, this.store, this.configuration.language)) === null || _b === void 0 ? void 0 : _b.value;
96
- const usageNote = (_c = (0, core_1.getApplicationProfileDefinition)(classId, this.store, this.configuration.language)) === null || _c === void 0 ? void 0 : _c.value;
148
+ const usageNote = (_c = (0, core_1.getApplicationProfileUsageNote)(classId, this.store, this.configuration.language)) === null || _c === void 0 ? void 0 : _c.value;
149
+ if (!label) {
150
+ this.logger.error(`Unknown class label for ${classId.value}`);
151
+ continue;
152
+ }
153
+ /* Class labels should be always pascal cased */
154
+ label = (0, core_1.toPascalCase)(label);
155
+ /* Only keep links which are related to the class */
156
+ for (const key of Object.keys(links)) {
157
+ if (key.startsWith(`${label}.`))
158
+ filteredLinks[key] = links[key];
159
+ }
160
+ /* Create an endpoint for each object to have PURIs for each object */
161
+ swagger.paths[`/id/${label}/{id}`] = {
162
+ get: {
163
+ summary: definition,
164
+ description: usageNote,
165
+ operationId: `${label}GET`,
166
+ parameters: [
167
+ {
168
+ name: 'id',
169
+ required: true,
170
+ in: 'path',
171
+ description: `Identificator van een ${label} object.`,
172
+ schema: {
173
+ type: 'string',
174
+ },
175
+ },
176
+ ],
177
+ responses: {
178
+ 200: {
179
+ description: `${label} object gevonden.`,
180
+ content: {
181
+ [core_1.OutputFormat.JsonLd]: {
182
+ schema: {
183
+ $ref: `#/components/schemas/${label}`,
184
+ },
185
+ },
186
+ },
187
+ links: filteredLinks,
188
+ },
189
+ /* Error codes follow the RFC 7807 */
190
+ 400: {
191
+ description: 'Invalid data supplied.',
192
+ content: this.getProbleemdetailsContent(),
193
+ links: this.getProbleemdetailsLink(label),
194
+ },
195
+ 401: {
196
+ description: 'Invalid authorization.',
197
+ content: this.getProbleemdetailsContent(),
198
+ links: this.getProbleemdetailsLink(label),
199
+ },
200
+ 403: {
201
+ description: 'Authentication failed.',
202
+ content: this.getProbleemdetailsContent(),
203
+ links: this.getProbleemdetailsLink(label),
204
+ },
205
+ 404: {
206
+ description: 'Resource not found.',
207
+ content: this.getProbleemdetailsContent(),
208
+ links: this.getProbleemdetailsLink(label),
209
+ },
210
+ 412: {
211
+ description: 'Pre-condition failed.',
212
+ content: this.getProbleemdetailsContent(),
213
+ links: this.getProbleemdetailsLink(label),
214
+ },
215
+ 500: {
216
+ description: 'Unexpected Server Error.',
217
+ content: this.getProbleemdetailsContent(),
218
+ links: this.getProbleemdetailsLink(label),
219
+ },
220
+ 502: {
221
+ description: 'Bad Gateway.',
222
+ content: this.getProbleemdetailsContent(),
223
+ links: this.getProbleemdetailsLink(label),
224
+ },
225
+ 503: {
226
+ description: 'Service unavailable.',
227
+ content: this.getProbleemdetailsContent(),
228
+ links: this.getProbleemdetailsLink(label),
229
+ },
230
+ 504: {
231
+ description: 'Gateway Timeout.',
232
+ content: this.getProbleemdetailsContent(),
233
+ links: this.getProbleemdetailsLink(label),
234
+ },
235
+ },
236
+ },
237
+ };
238
+ }
239
+ /* Inline schemas */
240
+ swagger.components = {
241
+ schemas: {},
242
+ };
243
+ for (const schemaLabel of Object.keys(schemas))
244
+ swagger.components.schemas[schemaLabel] = schemas[schemaLabel];
245
+ return swagger;
246
+ }
247
+ createSchemas() {
248
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
249
+ const schemas = {};
250
+ /* Create schema for each enumeration */
251
+ for (const enumId of this.store.findSubjects(core_1.ns.oslo('assignedURI'), core_1.ns.skos('Concept'))) {
252
+ let label = (_a = (0, core_1.getApplicationProfileLabel)(enumId, this.store, this.configuration.language)) === null || _a === void 0 ? void 0 : _a.value;
253
+ if (!label) {
254
+ this.logger.error(`Unknown enum label for ${enumId.value}`);
255
+ continue;
256
+ }
257
+ /* Class labels should be always pascal cased */
258
+ label = (0, core_1.toPascalCase)(label);
259
+ schemas[label] = {
260
+ title: label,
261
+ type: 'object',
262
+ description: `Enumeratie van ${label}`,
263
+ properties: {
264
+ '@id': {
265
+ type: 'string',
266
+ format: 'uri',
267
+ },
268
+ },
269
+ required: ['@id'],
270
+ };
271
+ }
272
+ /* Create schema for each Class and Datatype */
273
+ for (const classId of [
274
+ ...this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.owl('Class')),
275
+ ...this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.rdfs('Datatype')),
276
+ ]) {
277
+ const assignedUri = this.store.getAssignedUri(classId);
278
+ /* Primitive datatypes may not be generated */
279
+ if (assignedUri && [...core_1.DataTypes.values()].includes(assignedUri.value))
280
+ continue;
281
+ /* Abstract classes may not be generated to avoid that they are instantiated */
282
+ if (this.store.isAbstractClass(classId))
283
+ continue;
284
+ let label = (_b = (0, core_1.getApplicationProfileLabel)(classId, this.store, this.configuration.language)) === null || _b === void 0 ? void 0 : _b.value;
285
+ const definition = (_c = (0, core_1.getApplicationProfileDefinition)(classId, this.store, this.configuration.language)) === null || _c === void 0 ? void 0 : _c.value;
97
286
  let attributes = {};
98
287
  let requiredAttributes = {};
99
288
  /* Get all attributes in a recursive manner for inheritance */
@@ -104,16 +293,16 @@ let SwaggerGenerationService = class SwaggerGenerationService {
104
293
  continue;
105
294
  }
106
295
  /* Class labels should be always pascal cased */
107
- label = (0, swaggerUtils_1.toPascalCase)(label);
296
+ label = (0, core_1.toPascalCase)(label);
108
297
  attributes[label] = [];
109
298
  requiredAttributes[label] = [];
110
- links[label] = {};
111
299
  /* Find all attributes for object */
112
300
  for (const attributeId of attributeIds) {
113
301
  let attributeLabel = (_d = (0, core_1.getApplicationProfileLabel)(attributeId, this.store, this.configuration.language)) === null || _d === void 0 ? void 0 : _d.value;
114
302
  const attributeMinCount = (0, core_1.getMinCount)(attributeId, this.store);
115
303
  const attributeMaxCount = (0, core_1.getMaxCount)(attributeId, this.store);
116
304
  const attributeRangeId = this.store.getRange(attributeId);
305
+ const attributeDomainId = this.store.getDomain(attributeId);
117
306
  const attributeDefinition = (_e = (0, core_1.getApplicationProfileDefinition)(attributeId, this.store, this.configuration.language)) === null || _e === void 0 ? void 0 : _e.value;
118
307
  const attributeUsageNote = (_f = (0, core_1.getApplicationProfileUsageNote)(attributeId, this.store, this.configuration.language)) === null || _f === void 0 ? void 0 : _f.value;
119
308
  if (!attributeLabel) {
@@ -121,39 +310,65 @@ let SwaggerGenerationService = class SwaggerGenerationService {
121
310
  continue;
122
311
  }
123
312
  /* Attribute labels should be always camel cased */
124
- attributeLabel = (0, swaggerUtils_1.toCamelCase)(attributeLabel);
313
+ attributeLabel = (0, core_1.toCamelCase)(attributeLabel);
125
314
  if (!attributeRangeId) {
126
315
  this.logger.error(`Unknown range for attribute ${attributeId.value}`);
127
316
  continue;
128
317
  }
318
+ if (!attributeDomainId) {
319
+ this.logger.error(`Unknown domain for attribute ${attributeId.value}`);
320
+ continue;
321
+ }
129
322
  const attributeDatatypeId = (_g = this.store.getAssignedUri(attributeRangeId)) === null || _g === void 0 ? void 0 : _g.value;
130
- const attributeDatatypeLabel = (_h = (0, core_1.getApplicationProfileLabel)(attributeRangeId, this.store, this.configuration.language)) === null || _h === void 0 ? void 0 : _h.value;
323
+ let attributeDatatypeLabel = (_h = (0, core_1.getApplicationProfileLabel)(attributeRangeId, this.store, this.configuration.language)) === null || _h === void 0 ? void 0 : _h.value;
131
324
  if (!attributeDatatypeId || !attributeDatatypeLabel) {
132
325
  this.logger.error(`Unknown datatype for attribute ${attributeId.value}`);
133
326
  continue;
134
327
  }
328
+ attributeDatatypeLabel = (0, core_1.toPascalCase)(attributeDatatypeLabel);
329
+ const attributeDatatypeAbstract = this.store.isAbstractClass(attributeRangeId);
330
+ /* Attribute datatypes may have a super class assigned, but any subclass of this super class must be allowed */
331
+ const subclasses = [];
332
+ for (const subclassId of this.store.findSubjects(core_1.ns.rdfs('subClassOf'), attributeRangeId)) {
333
+ const subclassLabel = (_j = (0, core_1.getApplicationProfileLabel)(subclassId, this.store, this.configuration.language)) === null || _j === void 0 ? void 0 : _j.value;
334
+ if (!subclassLabel) {
335
+ console.error(`Unable to retrieve subclass label of ${subclassId}`);
336
+ continue;
337
+ }
338
+ subclasses.push((0, core_1.toPascalCase)(subclassLabel));
339
+ }
340
+ /* Cardinality */
135
341
  if (!attributeMinCount || !attributeMaxCount) {
136
342
  this.logger.error(`Unknown cardinality for attribute ${attributeId.value}`);
137
343
  continue;
138
344
  }
139
345
  /* Arrays must be introduced into the schema if the max cardinality is 2 or more */
140
- const type = 'object';
141
346
  const description = `${attributeDefinition}${attributeUsageNote ? ' ' + attributeUsageNote : ''}`;
142
- const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, this.configuration.baseURL);
347
+ const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, subclasses, attributeDatatypeAbstract);
143
348
  const requiredProperties = properties
144
349
  ? Object.keys(properties)
145
350
  : undefined;
351
+ /* Primitive datatypes are objects with properties */
352
+ let item = {};
353
+ if ([...core_1.DataTypes.values()].includes(attributeDatatypeId)) {
354
+ item = {
355
+ type: 'object',
356
+ description: description,
357
+ properties: properties,
358
+ required: requiredProperties,
359
+ };
360
+ /* Schema references are $ref, not objects */
361
+ }
362
+ else {
363
+ item = properties;
364
+ }
146
365
  if (attributeMaxCount != '0' && attributeMaxCount != '1') {
147
- attributes[label][`${label}.${attributeLabel}`] = {
366
+ /* minItems must be 1, empty arrays are removed by not including the attribute, even if minCount == 0 */
367
+ attributes[label][attributeLabel] = {
148
368
  type: 'array',
149
369
  description: `Lijst van ${attributeDatatypeLabel} items.`,
150
- items: {
151
- type: type,
152
- description: description,
153
- properties: properties,
154
- required: requiredProperties,
155
- },
156
- minItems: parseInt(attributeMinCount),
370
+ items: item,
371
+ minItems: Math.max(parseInt(attributeMinCount), 1),
157
372
  maxItems: attributeMaxCount == '*'
158
373
  ? undefined
159
374
  : parseInt(attributeMaxCount),
@@ -161,102 +376,108 @@ let SwaggerGenerationService = class SwaggerGenerationService {
161
376
  /* Regular property with a cardinality of [0..0], [0..1], [1..1] */
162
377
  }
163
378
  else {
164
- attributes[label][`${label}.${attributeLabel}`] = {
165
- type: type,
166
- description: description,
167
- properties: properties,
168
- required: requiredProperties,
169
- };
379
+ attributes[label][attributeLabel] = item;
170
380
  }
171
381
  /* Only require properties which are not arrays since those have their own cardinality checks */
172
382
  if (attributeMinCount == '1')
173
- requiredAttributes[label].push(`${label}.${attributeLabel}`);
174
- /* Create all possible links for endpoint */
175
- if (!(0, core_1.isStandardDatatype)(attributeDatatypeId)) {
176
- links[label][`${attributeDatatypeLabel}GET`] = {
177
- operationId: `${attributeDatatypeLabel}GET`,
178
- parameters: {
179
- /* Referring to response body always starts with the same prefix */
180
- id: `$response.body#/${label}.${attributeLabel}/@id`,
181
- },
182
- description: `Het \`@id\` attribuut van de waarde van \`${label}.${attributeLabel}\` kan gebruikt worden om het gerefereerde object van het type \`${attributeDatatypeLabel}\` op te halen.`,
183
- };
184
- }
383
+ requiredAttributes[label].push(attributeLabel);
185
384
  }
186
- /* Create an endpoint for each object to have PURIs for each object */
187
- swagger.paths[`/id/${label}/{id}`] = {
188
- get: {
189
- summary: definition,
190
- description: usageNote,
191
- operationId: `${label}GET`,
192
- tags: [this.getTag(classId)],
193
- parameters: [
194
- {
195
- name: 'id',
196
- required: true,
197
- in: 'path',
198
- description: `Identificator van een ${label} object.`,
199
- schema: {
200
- type: 'string',
201
- },
202
- },
203
- ],
204
- responses: {
205
- 200: {
206
- description: `${label} object gevonden.`,
207
- content: {
208
- [core_1.OutputFormat.JsonLd]: {
209
- schema: {
210
- $ref: `#/components/schemas/${label}`,
211
- },
212
- },
213
- },
214
- links: links[label],
215
- },
216
- 400: {
217
- description: `Ontbrekende informatie bij het opvragen een ${label} object.`,
218
- },
219
- 404: {
220
- description: `${label} object met gegeven ID niet gevonden.`,
221
- },
385
+ /* Remove duplicates in requiredAttributes list which may be introduced due to redefine/subsetting in inheritance */
386
+ requiredAttributes[label] = [...new Set(requiredAttributes[label])];
387
+ /* Root classes require a @context property, add it here if needed */
388
+ let context = {};
389
+ if (this.store.isRootClass(classId)) {
390
+ context = {
391
+ '@context': {
392
+ type: 'string',
393
+ description: 'URI of the JSON-LD versioned context file for this response.',
394
+ pattern: `^${this.configuration.contextURL}$`.replace(/\//g, '\\/'),
222
395
  },
223
- },
224
- };
396
+ };
397
+ }
225
398
  /* Create components for each schema */
226
- swagger.components.schemas[label] = {
399
+ schemas[label] = {
400
+ title: label,
227
401
  type: 'object',
228
402
  description: definition,
229
403
  properties: {
230
- '@context': {
231
- type: 'string',
232
- format: 'uri',
233
- enum: [this.configuration.contextURL],
234
- },
235
404
  '@id': {
236
405
  type: 'string',
237
406
  format: 'uri',
238
- pattern: `^${this.configuration.baseURL.replace(Swagger_1.RE_SLASH, '\\/').replace(Swagger_1.RE_DOT, '\\.')}id\\/${label}\\/\\d`,
239
407
  },
408
+ /* Do not allow double typing for strict validation and problems with Swagger tooling (discriminator keyword) */
240
409
  '@type': {
241
- type: 'array',
242
- description: 'Lijst van object types (klasse)',
243
- items: {
244
- type: 'string',
245
- description: `${label} type`,
246
- /* enum validation breaks codegen, see https://vlaamseoverheid.atlassian.net/browse/DATAST-46 */
247
- },
248
- minItems: 1,
410
+ type: 'string',
411
+ description: `Object type (klasse ${label})`,
412
+ pattern: `^${label}\$`,
249
413
  },
250
414
  ...attributes[label],
415
+ ...context,
251
416
  },
252
- required: ['@context', '@id', '@type', ...requiredAttributes[label]],
417
+ required: ['@type', ...requiredAttributes[label]],
253
418
  };
254
419
  }
255
- return swagger;
420
+ return schemas;
421
+ }
422
+ createLinks() {
423
+ var _a, _b, _c, _d;
424
+ let links = {};
425
+ /* Create link for each Class, datatypes are always nested. */
426
+ for (const classId of this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.owl('Class'))) {
427
+ let label = (_a = (0, core_1.getApplicationProfileLabel)(classId, this.store, this.configuration.language)) === null || _a === void 0 ? void 0 : _a.value;
428
+ /* Abstract classes may not be instantiated so they cannot have links */
429
+ if (this.store.isAbstractClass(classId))
430
+ continue;
431
+ /* Get all attributes in a recursive manner for inheritance */
432
+ let attributeIds = [];
433
+ attributeIds = (0, core_1.findAllAttributes)(classId, attributeIds, this.store, this.logger);
434
+ if (!label) {
435
+ this.logger.error(`Unknown class label for ${classId.value}`);
436
+ continue;
437
+ }
438
+ /* Class labels should be always pascal cased */
439
+ label = (0, core_1.toPascalCase)(label);
440
+ /* Find all attributes for object */
441
+ for (const attributeId of attributeIds) {
442
+ let attributeLabel = (_b = (0, core_1.getApplicationProfileLabel)(attributeId, this.store, this.configuration.language)) === null || _b === void 0 ? void 0 : _b.value;
443
+ const attributeRangeId = this.store.getRange(attributeId);
444
+ if (!attributeLabel) {
445
+ this.logger.error(`Unknown label for attribute ${attributeId.value}`);
446
+ continue;
447
+ }
448
+ /* Attribute labels should be always camel cased */
449
+ attributeLabel = (0, core_1.toCamelCase)(attributeLabel);
450
+ if (!attributeRangeId) {
451
+ this.logger.error(`Unknown range for attribute ${attributeId.value}`);
452
+ continue;
453
+ }
454
+ const attributeDatatypeId = (_c = this.store.getAssignedUri(attributeRangeId)) === null || _c === void 0 ? void 0 : _c.value;
455
+ let attributeDatatypeLabel = (_d = (0, core_1.getApplicationProfileLabel)(attributeRangeId, this.store, this.configuration.language)) === null || _d === void 0 ? void 0 : _d.value;
456
+ if (!attributeDatatypeId || !attributeDatatypeLabel) {
457
+ this.logger.error(`Unknown datatype for attribute ${attributeId.value}`);
458
+ continue;
459
+ }
460
+ attributeDatatypeLabel = (0, core_1.toPascalCase)(attributeDatatypeLabel);
461
+ /* Create all possible links for endpoint */
462
+ if (!(0, core_1.isStandardDatatype)(attributeDatatypeId)) {
463
+ links[`${label}.${attributeLabel}`] = {
464
+ operationId: `${label}GET`,
465
+ parameters: {
466
+ /* Referring to response body always starts with the same prefix */
467
+ id: `$response.body#/${label}.${attributeLabel}/@id`,
468
+ },
469
+ description: `De waarde van het attribuut \`@id\` kan gebruikt worden om het gerefereerde object van het type \`${attributeDatatypeLabel}\` op te halen.`,
470
+ };
471
+ }
472
+ }
473
+ }
474
+ return links;
256
475
  }
257
- async writeSwagger(swagger) {
258
- const data = JSON.stringify(swagger, null, 2);
259
- await (0, promises_1.writeFile)(this.configuration.output, data);
476
+ async writeJSON(json, outputPath) {
477
+ const data = JSON.stringify(json, null, 2);
478
+ const filePath = path.join(this.configuration.output, outputPath);
479
+ (0, core_1.ensureOutputDirectory)(path.dirname(filePath));
480
+ await (0, promises_1.writeFile)(filePath, data);
260
481
  }
261
482
  };
262
483
  SwaggerGenerationService = __decorate([
@@ -10,7 +10,6 @@ exports.SwaggerGenerationServiceConfiguration = void 0;
10
10
  const inversify_1 = require("inversify");
11
11
  let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfiguration {
12
12
  async createFromCli(params) {
13
- console.log(params.title);
14
13
  this._input = params.input;
15
14
  this._output = params.output;
16
15
  this._language = params.language;
@@ -67,13 +66,13 @@ let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfig
67
66
  }
68
67
  get contextURL() {
69
68
  if (!this._contextURL) {
70
- throw new Error(`Trying access property "contextURL" before it was set.`);
69
+ throw new Error(`Trying to access property "contextURL" before it was set.`);
71
70
  }
72
71
  return this._contextURL;
73
72
  }
74
73
  get baseURL() {
75
74
  if (!this._baseURL) {
76
- throw new Error(`Trying access property "baseURL" before it was set.`);
75
+ throw new Error(`Trying to access property "baseURL" before it was set.`);
77
76
  }
78
77
  return this._baseURL;
79
78
  }
@@ -1,2 +1,5 @@
1
- export declare const RE_DOT: RegExp;
2
- export declare const RE_SLASH: RegExp;
1
+ export declare const ERROR_RESPONSES: {
2
+ code: string;
3
+ description: string;
4
+ }[];
5
+ export declare const PROBLEEM_DETAILS_SCHEMA_REF = "#/components/schemas/ProbleemDetails";
@@ -1,7 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RE_SLASH = exports.RE_DOT = void 0;
4
- /* Regex for escaping URIs when using patterns in OpenAPI JSON */
5
- exports.RE_DOT = /\./gi;
6
- exports.RE_SLASH = /\//gi;
3
+ exports.PROBLEEM_DETAILS_SCHEMA_REF = exports.ERROR_RESPONSES = void 0;
4
+ exports.ERROR_RESPONSES = [
5
+ { code: '400', description: 'Invalid data supplied.' },
6
+ { code: '401', description: 'Invalid authorization.' },
7
+ { code: '403', description: 'Authentication failed.' },
8
+ { code: '404', description: 'Resource not found.' },
9
+ { code: '412', description: 'Pre-condition failed.' },
10
+ { code: '500', description: 'Unexpected Server Error.' },
11
+ { code: '502', description: 'Bad Gateway.' },
12
+ { code: '503', description: 'Service unavailable.' },
13
+ { code: '504', description: 'Gateway Timeout.' },
14
+ ];
15
+ exports.PROBLEEM_DETAILS_SCHEMA_REF = '#/components/schemas/ProbleemDetails';
7
16
  //# sourceMappingURL=Swagger.js.map
@@ -1 +1 @@
1
- export declare const mapProperties: (datatype: string, label: string, baseURI: string) => object;
1
+ export declare const mapProperties: (datatype: string, label: string, subclasses: string[], abstract: boolean) => object;
@@ -1,47 +1,70 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.mapProperties = void 0;
4
+ /* eslint-disable @typescript-eslint/no-loss-of-precision */
4
5
  const core_1 = require("@oslo-flanders/core");
5
- const Swagger_1 = require("../constants/Swagger");
6
- /* eslint-disable */
6
+ /* eslint-disable max-len */
7
7
  const Properties = new Map([
8
- [core_1.ns.rdf('langString').value, { '@value': { type: 'string' }, '@language': { type: 'string', enum: ['nl'] } }],
8
+ [core_1.ns.rdf('langString').value, { '@value': { type: 'string' }, '@language': { type: 'string', pattern: '^nl$' } }],
9
+ [core_1.ns.rdfs('Literal').value, { '@value': { type: 'string' } }],
9
10
  [core_1.ns.xsd('string').value, { '@value': { type: 'string' } }],
10
11
  [core_1.ns.xsd('anyURI').value, { '@id': { type: 'string', format: 'uri' } }],
11
- [core_1.ns.xsd('dateTime').value, { '@value': { type: 'string', format: 'date-time' }, '@type': { type: 'string', enum: ['DateTime'] } }],
12
- [core_1.ns.xsd('date').value, { '@value': { type: 'string', format: 'date' }, '@type': { type: 'string', enum: ['Date'] } }],
13
- [core_1.ns.xsd('boolean').value, { '@value': { type: 'boolean' }, '@type': { type: 'string', enum: ['Boolean'] } }],
14
- [core_1.ns.xsd('integer').value, { '@value': { type: 'number', format: 'int64' }, '@type': { type: 'string', enum: ['Integer'] } }],
15
- [core_1.ns.xsd('long').value, { '@value': { type: 'number', format: 'int64', minimum: -9223372036854775808, maximum: 9223372036854775807 }, '@type': { type: 'string', enum: ['Long'] } }],
16
- [core_1.ns.xsd('float').value, { '@value': { type: 'number', format: 'float' }, '@type': { type: 'string', enum: ['Float'] } }],
17
- [core_1.ns.xsd('double').value, { '@value': { type: 'number', format: 'double' }, '@type': { type: 'string', enum: ['Double'] } }],
18
- [core_1.ns.xsd('int').value, { '@value': { type: 'number', format: 'int32', minimum: -2147483648, maximum: 2147483647 }, '@type': { type: 'string', enum: ['Int'] } }],
19
- [core_1.ns.xsd('short').value, { '@value': { type: 'number', format: 'int32', minimum: -32768, maximum: 32767 }, '@type': { type: 'string', enum: ['Short'] } }],
20
- [core_1.ns.xsd('byte').value, { '@value': { type: 'number', format: 'int32', minimum: -128, maximum: 127 }, '@type': { type: 'string', enum: ['Byte'] } }],
21
- [core_1.ns.xsd('hexBinary').value, { '@value': { type: 'string', format: 'binary' }, '@type': { type: 'string', enum: ['HexBinary'] } }],
22
- [core_1.ns.xsd('base64Binary').value, { '@value': { type: 'string', format: 'byte' }, '@type': { type: 'string', enum: ['Base64Binary'] } }],
23
- [core_1.ns.xsd('nonNegativeInteger').value, { '@value': { type: 'number', format: 'int64' }, '@type': { type: 'string', enum: ['NonNegativeInteger'] } }],
24
- [core_1.ns.xsd('nonPositiveInteger').value, { '@value': { type: 'number', format: 'int64' }, '@type': { type: 'string', enum: ['NonPositiveInteger'] } }],
25
- [core_1.ns.xsd('negativeInteger').value, { '@value': { type: 'number', format: 'int64', maximum: 0 }, '@type': { type: 'string', enum: ['NegativeInteger'] } }],
26
- [core_1.ns.xsd('positiveInteger').value, { '@value': { type: 'number', format: 'int64', minimum: 1 }, '@type': { type: 'string', enum: ['PositiveInteger'] } }],
27
- [core_1.ns.xsd('unsignedLong').value, { '@value': { type: 'number', format: 'int64', minimum: 0, maximum: 18446744073709551615 }, '@type': { type: 'string', enum: ['UnsignedLong'] } }],
28
- [core_1.ns.xsd('unsignedInt').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 4294967295 }, '@type': { type: 'string', enum: ['UnsignedInt'] } }],
29
- [core_1.ns.xsd('unsignedShort').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 65535 }, '@type': { type: 'string', enum: ['UnsignedShort'] } }],
30
- [core_1.ns.xsd('unsignedByte').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 255 }, '@type': { type: 'string', enum: ['UnsignedByte'] } }],
31
- [core_1.ns.xsd('decimal').value, { '@value': { type: 'string', pattern: '(+|-)?([0-9]+(.[0-9]*)?|.[0-9]+)' }, '@type': { type: 'string', enum: ['Decimal'] } }],
12
+ [core_1.ns.xsd('dateTime').value, { '@value': { type: 'string', format: 'date-time' }, '@type': { type: 'string', pattern: '^DateTime$' } }],
13
+ [core_1.ns.xsd('date').value, { '@value': { type: 'string', format: 'date' }, '@type': { type: 'string', pattern: '^Date$' } }],
14
+ [core_1.ns.xsd('boolean').value, { '@value': { type: 'boolean' }, '@type': { type: 'string', pattern: '^Boolean$' } }],
15
+ [core_1.ns.xsd('integer').value, { '@value': { type: 'number', format: 'int64' }, '@type': { type: 'string', pattern: '^Integer$' } }],
16
+ [core_1.ns.xsd('long').value, { '@value': { type: 'number', format: 'int64', minimum: -9223372036854776000, maximum: 9223372036854776000 }, '@type': { type: 'string', pattern: '^Long$' } }],
17
+ [core_1.ns.xsd('float').value, { '@value': { type: 'number', format: 'float' }, '@type': { type: 'string', pattern: '^Float$' } }],
18
+ [core_1.ns.xsd('double').value, { '@value': { type: 'number', format: 'double' }, '@type': { type: 'string', pattern: '^Double$' } }],
19
+ [core_1.ns.xsd('int').value, { '@value': { type: 'number', format: 'int32', minimum: -2147483648, maximum: 2147483647 }, '@type': { type: 'string', pattern: '^Int$' } }],
20
+ [core_1.ns.xsd('short').value, { '@value': { type: 'number', format: 'int32', minimum: -32768, maximum: 32767 }, '@type': { type: 'string', pattern: '^Short$' } }],
21
+ [core_1.ns.xsd('byte').value, { '@value': { type: 'number', format: 'int32', minimum: -128, maximum: 127 }, '@type': { type: 'string', pattern: '^Byte$' } }],
22
+ [core_1.ns.xsd('hexBinary').value, { '@value': { type: 'string', format: 'binary' }, '@type': { type: 'string', pattern: '^HexBinary$' } }],
23
+ [core_1.ns.xsd('base64Binary').value, { '@value': { type: 'string', format: 'byte' }, '@type': { type: 'string', pattern: '^Base64Binary$' } }],
24
+ [core_1.ns.xsd('nonNegativeInteger').value, { '@value': { type: 'number', format: 'int64' }, '@type': { type: 'string', pattern: '^NonNegativeInteger$' } }],
25
+ [core_1.ns.xsd('nonPositiveInteger').value, { '@value': { type: 'number', format: 'int64' }, '@type': { type: 'string', pattern: '^NonPositiveInteger$' } }],
26
+ [core_1.ns.xsd('negativeInteger').value, { '@value': { type: 'number', format: 'int64', maximum: 0 }, '@type': { type: 'string', pattern: '^NegativeInteger$' } }],
27
+ [core_1.ns.xsd('positiveInteger').value, { '@value': { type: 'number', format: 'int64', minimum: 1 }, '@type': { type: 'string', pattern: '^PositiveInteger$' } }],
28
+ [core_1.ns.xsd('unsignedLong').value, { '@value': { type: 'number', format: 'int64', minimum: 0, maximum: 18446744073709552000 }, '@type': { type: 'string', pattern: '^UnsignedLong$' } }],
29
+ [core_1.ns.xsd('unsignedInt').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 4294967295 }, '@type': { type: 'string', pattern: '^UnsignedInt$' } }],
30
+ [core_1.ns.xsd('unsignedShort').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 65535 }, '@type': { type: 'string', pattern: '^UnsignedShort$' } }],
31
+ [core_1.ns.xsd('unsignedByte').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 255 }, '@type': { type: 'string', pattern: '^UnsignedByte$' } }],
32
+ [core_1.ns.xsd('decimal').value, { '@value': { type: 'string', pattern: '(+|-)?([0-9]+(.[0-9]*)?|.[0-9]+)' }, '@type': { type: 'string', pattern: '^Decimal$' } }],
32
33
  ]);
33
- /* eslint-enable */
34
- const mapProperties = (datatype, label, baseURI) => {
34
+ /* eslint-enable max-len*/
35
+ const mapProperties = (datatype, label, subclasses, abstract) => {
36
+ /* Primitive data type conversion from Linked Data to Swagger */
35
37
  if (Properties.has(datatype)) {
38
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
36
39
  return Properties.get(datatype);
37
40
  }
41
+ /* Multiple subclasses requires a discriminator to link both the superclass and subclasses as schemas */
42
+ if (subclasses.length > 0) {
43
+ const mapping = {};
44
+ const oneOf = [];
45
+ /* Only allow super class if it is not abstract */
46
+ if (!abstract) {
47
+ mapping[label] = `#/components/schemas/${label}`;
48
+ oneOf.push({ $ref: `#/components/schemas/${label}` });
49
+ }
50
+ for (const subclass of subclasses) {
51
+ const ref = `#/components/schemas/${subclass}`;
52
+ oneOf.push({ $ref: ref });
53
+ mapping[subclass] = ref;
54
+ }
55
+ return {
56
+ oneOf,
57
+ discriminator: {
58
+ propertyName: '@type',
59
+ mapping,
60
+ },
61
+ };
62
+ }
63
+ /* Regular schemas without any subclassing */
38
64
  return {
39
- '@id': {
40
- type: 'string',
41
- format: 'uri',
42
- pattern: `^${baseURI.replace(Swagger_1.RE_SLASH, '\\/').replace(Swagger_1.RE_DOT, '\\.')}id\\/${label}\\/\\d`,
43
- },
65
+ $ref: `#/components/schemas/${label}`,
44
66
  };
45
67
  };
46
68
  exports.mapProperties = mapProperties;
69
+ /* eslint-enable */
47
70
  //# sourceMappingURL=Properties.js.map
@@ -2,8 +2,8 @@ export interface SwaggerRoot {
2
2
  openapi: string;
3
3
  info: SwaggerInfo;
4
4
  servers: SwaggerServer[];
5
- paths: SwaggerPaths;
6
- components: SwaggerComponents;
5
+ paths: Record<string, SwaggerPath>;
6
+ components?: SwaggerComponents;
7
7
  }
8
8
  export interface SwaggerInfo {
9
9
  title: string;
@@ -25,68 +25,69 @@ export interface SwaggerServer {
25
25
  url: string;
26
26
  description?: string;
27
27
  }
28
- export type SwaggerPaths = Record<string, SwaggerPathsOperations>;
29
- export interface SwaggerPathsOperations {
30
- get?: SwaggerPathsOperation;
31
- post?: SwaggerPathsOperation;
32
- put?: SwaggerPathsOperation;
33
- delete?: SwaggerPathsOperation;
34
- patch?: SwaggerPathsOperation;
28
+ export interface SwaggerComponents {
29
+ schemas: Record<string, SwaggerSchema>;
30
+ links?: Record<string, SwaggerLink>;
31
+ }
32
+ export interface SwaggerPath {
33
+ get?: SwaggerPathOperation;
34
+ post?: SwaggerPathOperation;
35
+ put?: SwaggerPathOperation;
36
+ delete?: SwaggerPathOperation;
37
+ patch?: SwaggerPathOperation;
35
38
  }
36
- export interface SwaggerPathsOperation {
39
+ export interface SwaggerPathOperation {
37
40
  tags?: string[];
38
41
  summary?: string;
39
42
  description?: string;
40
43
  operationId?: string;
41
- parameters?: SwaggerPathsOperationParameter[];
42
- requestBody?: SwaggerPathsOperationRequestBody;
43
- responses?: SwaggerPathsOperationResponses;
44
+ parameters?: SwaggerParameter[];
45
+ requestBody?: SwaggerRequestBody;
46
+ responses: Record<string, SwaggerResponse>;
44
47
  }
45
- export interface SwaggerPathsOperationParameter {
46
- name?: string;
48
+ export interface SwaggerParameter {
49
+ name: string;
47
50
  description?: string;
48
51
  in: string;
49
52
  required: boolean;
50
- schema: SwaggerPathsOperationParameterSchema;
51
- }
52
- export interface SwaggerPathsOperationParameterSchema {
53
- type: string;
53
+ schema: {
54
+ type: string;
55
+ };
54
56
  }
55
- export interface SwaggerPathsOperationRequestBody {
57
+ export interface SwaggerRequestBody {
56
58
  description?: string;
57
- content: SwaggerPathsOperationRequestBodyContent;
58
- }
59
- export type SwaggerPathsOperationRequestBodyContent = Record<string, SwaggerPathsOperationRequestBodyContentValue>;
60
- export interface SwaggerPathsOperationRequestBodyContentValue {
61
- schema: SwaggerPathsOperationRequestBodyContentValueSchema;
62
- example?: SwaggerPathsOperationRequestBodyContentValueExample;
63
- }
64
- export interface SwaggerPathsOperationRequestBodyContentValueSchema {
59
+ content: Record<string, {
60
+ schema: SwaggerSchema | SchemaRef;
61
+ example?: Record<string, string>;
62
+ }>;
63
+ }
64
+ export interface SwaggerResponse {
65
+ description: string;
66
+ content?: Record<string, {
67
+ schema: SchemaRef;
68
+ }>;
69
+ links?: Record<string, SwaggerLink>;
70
+ }
71
+ export interface SwaggerSchema {
72
+ title?: string;
65
73
  type: string;
66
- }
67
- export type SwaggerPathsOperationRequestBodyContentValueExample = Record<string, string>;
68
- export interface SwaggerPathsOperationResponses {
69
- }
70
- export interface SwaggerComponents {
71
- schemas: SwaggerComponentsSchemas;
72
- }
73
- export type SwaggerComponentsSchemas = Record<string, SwaggerComponentsSchemasValue>;
74
- export interface SwaggerComponentsSchemasValue {
75
- type?: string;
76
74
  description?: string;
77
- properties?: SwaggerComponentsValueProperties;
75
+ pattern?: string;
76
+ format?: string;
77
+ minimum?: number;
78
+ maximum?: number;
79
+ minItems?: number;
80
+ maxItems?: number;
81
+ enum?: string[];
82
+ items?: SwaggerSchema | SchemaRef;
83
+ properties?: Record<string, SwaggerSchema | SchemaRef>;
78
84
  required?: string[];
79
85
  }
80
- export type SwaggerComponentsValueProperties = Record<string, SwaggerComponentsValuePropertiesValue>;
81
- export interface SwaggerComponentsValuePropertiesValue {
82
- type: string;
83
- description?: string;
84
- enum?: string[];
85
- items?: SwaggerComponentsValuePropertiesValueItems;
86
+ export interface SchemaRef {
87
+ $ref: string;
86
88
  }
87
- export interface SwaggerComponentsValuePropertiesValueItems {
88
- type: string;
89
- description?: string;
90
- properties?: SwaggerComponentsValueProperties;
91
- required?: string[];
89
+ export interface SwaggerLink {
90
+ operationId: string;
91
+ parameters: Record<string, string>;
92
+ description: string;
92
93
  }
@@ -1,5 +1,5 @@
1
- import type { QuadStore } from '@oslo-flanders/core';
2
- import type * as RDF from '@rdfjs/types';
3
- export declare function findAllAttributes(subject: RDF.Term, attributeIds: RDF.Term[], store: QuadStore): RDF.Term[];
4
- export declare function toPascalCase(text: string): string;
5
- export declare function toCamelCase(text: string): string;
1
+ import type { SwaggerLink, SwaggerResponse, SwaggerInfoContact, SwaggerInfoLicense } from '../types/Swagger';
2
+ export declare function getContact(contactName?: string, contactURL?: string, contactEmail?: string): SwaggerInfoContact | undefined;
3
+ export declare function getLicense(licenseName?: string, licenseURL?: string): SwaggerInfoLicense | undefined;
4
+ export declare function buildErrorResponses(label: string): Record<string, SwaggerResponse>;
5
+ export declare function filterLinksByClass(links: Record<string, SwaggerLink>, classLabel: string): Record<string, SwaggerLink>;
@@ -1,32 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toCamelCase = exports.toPascalCase = exports.findAllAttributes = void 0;
4
- const core_1 = require("@oslo-flanders/core");
5
- function findAllAttributes(subject, attributeIds, store) {
6
- const parentIds = store.findObjects(subject, core_1.ns.rdfs('subClassOf'));
7
- attributeIds = [
8
- ...attributeIds,
9
- ...store.findSubjects(core_1.ns.rdfs('domain'), subject),
10
- ];
11
- for (const parentId of parentIds) {
12
- attributeIds = findAllAttributes(parentId, attributeIds, store);
13
- }
14
- return attributeIds;
3
+ exports.filterLinksByClass = exports.buildErrorResponses = exports.getLicense = exports.getContact = void 0;
4
+ /* eslint-disable max-len */
5
+ const OutputFormat_1 = require("@oslo-flanders/core/lib/enums/OutputFormat");
6
+ const Swagger_1 = require("../constants/Swagger");
7
+ function getProbleemdetailsContent() {
8
+ return {
9
+ [OutputFormat_1.OutputFormat.JsonProblem]: {
10
+ schema: { $ref: Swagger_1.PROBLEEM_DETAILS_SCHEMA_REF },
11
+ },
12
+ };
13
+ }
14
+ function getProbleemdetailsLink(label) {
15
+ return {
16
+ 'ProbleemDetails.type': {
17
+ operationId: `${label}GET`,
18
+ parameters: { type: '$response.body#/type' },
19
+ description: 'De waarde van het attribuut `type` kan gebruikt worden om het gerefereerde object van het type `ProblemDetails` op te halen.',
20
+ },
21
+ };
15
22
  }
16
- exports.findAllAttributes = findAllAttributes;
17
- function removeCaret(text) {
18
- return text.replace(/^\^/u, '');
23
+ function getContact(contactName, contactURL, contactEmail) {
24
+ if (!contactName && !contactURL && !contactEmail)
25
+ return undefined;
26
+ return { name: contactName, url: contactURL, email: contactEmail };
19
27
  }
20
- function toPascalCase(text) {
21
- return removeCaret(text)
22
- .replace(/(?:^\w|[A-Z]|\b\w)/gu, (word, index) => word.toUpperCase())
23
- .replace(/\s+/gu, '');
28
+ exports.getContact = getContact;
29
+ function getLicense(licenseName, licenseURL) {
30
+ if (!licenseName && !licenseURL)
31
+ return undefined;
32
+ return { name: licenseName, url: licenseURL };
33
+ }
34
+ exports.getLicense = getLicense;
35
+ function buildErrorResponses(label) {
36
+ const responses = {};
37
+ for (const { code, description } of Swagger_1.ERROR_RESPONSES) {
38
+ responses[code] = {
39
+ description,
40
+ content: getProbleemdetailsContent(),
41
+ links: getProbleemdetailsLink(label),
42
+ };
43
+ }
44
+ return responses;
24
45
  }
25
- exports.toPascalCase = toPascalCase;
26
- function toCamelCase(text) {
27
- return removeCaret(text)
28
- .replace(/(?:^\w|[A-Z]|\b\w)/gu, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase())
29
- .replace(/\s+/gu, '');
46
+ exports.buildErrorResponses = buildErrorResponses;
47
+ function filterLinksByClass(links, classLabel) {
48
+ const prefix = `${classLabel}.`;
49
+ return Object.fromEntries(Object.entries(links).filter(([key]) => key.startsWith(prefix)));
30
50
  }
31
- exports.toCamelCase = toCamelCase;
51
+ exports.filterLinksByClass = filterLinksByClass;
52
+ /* eslint-enable*/
32
53
  //# sourceMappingURL=swaggerUtils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslo-flanders/swagger-generator",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
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",