@oslo-flanders/swagger-generator 1.0.4 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,12 +3,15 @@
3
3
  > Given an OSLO-compliant RDF file, this tool generates a Swagger API from it.
4
4
 
5
5
  ## Install
6
+
6
7
  ```bash
7
8
  npm install @oslo-flanders/swagger-generator
8
9
  ```
9
10
 
10
11
  ## Global install
12
+
11
13
  To use the service from the command line anywhere, you can install it globally.
14
+
12
15
  ```bash
13
16
  npm install -g @oslo-flanders/swagger-generator
14
17
  ```
@@ -16,25 +19,31 @@ npm install -g @oslo-flanders/swagger-generator
16
19
  ## API
17
20
 
18
21
  The service is executed from the CLI and expects the following parameters:
19
- | Parameter | Description | Required | Possible values |
22
+ | Parameter | Description | Required | Possible values |
20
23
  | ------------------ | ------------------------------------------------------------ | ------------------ | --------------------------- |
21
- | `--input` | The URL or local file path of an OSLO-compliant RDF file | :heavy_check_mark: | |
22
- | `--output` | The name of the output file | :heavy_check_mark: | |
23
- | `--language` | The language in which the Swagger must be generated (labels) | No | |
24
- | `--versionSwagger` | Swagger OpenAPI specification version | :heavy_check_mark: | |
25
- | `--versionAPI` | API version | :heavy_check_mark: | |
26
- | `--title` | Title of the API document | :heavy_check_mark: | |
27
- | `--description` | Description of the API document | :heavy_check_mark: | |
28
- | `--contextURL` | JSON-LD context URL of the datastandard used in the API | :heavy_check_mark: | |
29
- | `--baseURL` | API base URL for endpoints and PURIs | :heavy_check_mark: | |
30
- | `--contactName` | Name of the person or organisation to contact about the API | No | |
31
- | `--contactEmail` | E-mail to contact for questions about the API | No | |
32
- | `--contactURL` | Link to follow as contact about the API | No | |
33
- | `--licenseName` | Name of the license of the API | No | |
34
- | `--licenseURL` | URL of the license of the API | No | |
35
- | `--silent` | Suppress log messages | No | `true` or `false` (default) |
24
+ | `--input` | The URL or local file path of an OSLO-compliant RDF file | :heavy_check_mark: | |
25
+ | `--output` | The name of the output file | :heavy_check_mark: | |
26
+ | `--language` | The language in which the Swagger must be generated (labels) | No | |
27
+ | `--versionSwagger` | Swagger OpenAPI specification version | :heavy_check_mark: | |
28
+ | `--versionAPI` | API version | :heavy_check_mark: | |
29
+ | `--title` | Title of the API document | :heavy_check_mark: | |
30
+ | `--description` | Description of the API document | :heavy_check_mark: | |
31
+ | `--contextURL` | JSON-LD context URL of the datastandard used in the API | :heavy_check_mark: | |
32
+ | `--baseURL` | API base URL for endpoints and PURIs | :heavy_check_mark: | |
33
+ | `--contactName` | Name of the person or organisation to contact about the API | No | |
34
+ | `--contactEmail` | E-mail to contact for questions about the API | No | |
35
+ | `--contactURL` | Link to follow as contact about the API | No | |
36
+ | `--licenseName` | Name of the license of the API | No | |
37
+ | `--licenseURL` | URL of the license of the API | No | |
38
+ | `--excludeClasses` | Classes to exclude from the generated Swagger | No | Persoon Organisatie Test |
39
+ | `--excludeProperties` | Properties to exclude from the generated Swagger | No | voornaam achternaam |
40
+ | `--silent` | Suppress log messages | No | `true` or `false` (default) |
36
41
 
37
42
  ## Usage
43
+
38
44
  ```bash
39
45
  oslo-generator-swagger --input report.jsonld --output swagger.json --language nl --versionSwagger 3.0.4 --versionAPI 1.0.0 --title "Mijn API" --description "Mijn API beschrijving." --contextURL http://example.com/context.jsonld --baseURL http://example.com
46
+ oslo-generator-swagger --input report.jsonld --output swagger.json --language nl --versionSwagger 3.0.4 --versionAPI 1.0.0 --title "Mijn API" --description "Mijn API beschrijving." --contextURL http://example.com/context.jsonld --baseURL http://example.com --excludeClasses Persoon Organisatie
47
+ oslo-generator-swagger --input report.jsonld --output swagger.json --language nl --versionSwagger 3.0.4 --versionAPI 1.0.0 --title "Mijn API" --description "Mijn API beschrijving." --contextURL http://example.com/context.jsonld --baseURL http://example.com --excludeClasses Persoon --excludeProperties Persoon.voornaam
48
+ oslo-generator-swagger --input report.jsonld --output swagger.json --language nl --versionSwagger 3.0.4 --versionAPI 1.0.0 --title "Mijn API" --description "Mijn API beschrijving." --contextURL http://example.com/context.jsonld --baseURL http://example.com --excludeClasses GeregistreerdPersoon --excludeProperties Persoon.voornaam Persoon.achternaam
40
49
  ```
@@ -152,6 +152,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
152
152
  }
153
153
  /* Class labels should be always pascal cased */
154
154
  label = (0, core_1.toPascalCase)(label);
155
+ /* If a class is excluded via configuration, stop here */
156
+ if (this.configuration.excludeClasses.includes(label)) {
157
+ continue;
158
+ }
155
159
  /* Only keep links which are related to the class */
156
160
  for (const key of Object.keys(links)) {
157
161
  if (key.startsWith(`${label}.`))
@@ -294,6 +298,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
294
298
  }
295
299
  /* Class labels should be always pascal cased */
296
300
  label = (0, core_1.toPascalCase)(label);
301
+ /* If a class is excluded via configuration, stop here */
302
+ if (this.configuration.excludeClasses.includes(label)) {
303
+ continue;
304
+ }
297
305
  attributes[label] = [];
298
306
  requiredAttributes[label] = [];
299
307
  /* Find all attributes for object */
@@ -311,6 +319,11 @@ let SwaggerGenerationService = class SwaggerGenerationService {
311
319
  }
312
320
  /* Attribute labels should be always camel cased */
313
321
  attributeLabel = (0, core_1.toCamelCase)(attributeLabel);
322
+ // Addition for the `excludeProperties` flag to remove any reference to an excluded property
323
+ const classNameWithPropertyName = `${label}.${attributeLabel}`;
324
+ if (this.configuration.excludeProperties.includes(classNameWithPropertyName)) {
325
+ continue;
326
+ }
314
327
  if (!attributeRangeId) {
315
328
  this.logger.error(`Unknown range for attribute ${attributeId.value}`);
316
329
  continue;
@@ -344,7 +357,11 @@ let SwaggerGenerationService = class SwaggerGenerationService {
344
357
  }
345
358
  /* Arrays must be introduced into the schema if the max cardinality is 2 or more */
346
359
  const description = `${attributeDefinition}${attributeUsageNote ? ' ' + attributeUsageNote : ''}`;
347
- const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, subclasses, attributeDatatypeAbstract);
360
+ const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, subclasses, attributeDatatypeAbstract, this.configuration.excludeClasses);
361
+ // If mapProperties returns nothing, the property pointed to an excluded class (this.configuration.excludeClasses)
362
+ if (!properties) {
363
+ continue;
364
+ }
348
365
  const requiredProperties = properties
349
366
  ? Object.keys(properties)
350
367
  : undefined;
@@ -437,6 +454,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
437
454
  }
438
455
  /* Class labels should be always pascal cased */
439
456
  label = (0, core_1.toPascalCase)(label);
457
+ /* If a class is excluded via configuration, stop here */
458
+ if (this.configuration.excludeClasses.includes(label)) {
459
+ continue;
460
+ }
440
461
  /* Find all attributes for object */
441
462
  for (const attributeId of attributeIds) {
442
463
  let attributeLabel = (_b = (0, core_1.getApplicationProfileLabel)(attributeId, this.store, this.configuration.language)) === null || _b === void 0 ? void 0 : _b.value;
@@ -447,6 +468,11 @@ let SwaggerGenerationService = class SwaggerGenerationService {
447
468
  }
448
469
  /* Attribute labels should be always camel cased */
449
470
  attributeLabel = (0, core_1.toCamelCase)(attributeLabel);
471
+ // Addition for the `excludeProperties` flag to remove any reference to an excluded property
472
+ const classNameWithPropertyName = `${label}.${attributeLabel}`;
473
+ if (this.configuration.excludeProperties.includes(classNameWithPropertyName)) {
474
+ continue;
475
+ }
450
476
  if (!attributeRangeId) {
451
477
  this.logger.error(`Unknown range for attribute ${attributeId.value}`);
452
478
  continue;
@@ -458,6 +484,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
458
484
  continue;
459
485
  }
460
486
  attributeDatatypeLabel = (0, core_1.toPascalCase)(attributeDatatypeLabel);
487
+ // Addition for the `excludeClasses` flag to remove any reference to an excluded class
488
+ if (this.configuration.excludeClasses.includes(attributeDatatypeLabel)) {
489
+ continue;
490
+ }
461
491
  /* Create all possible links for endpoint */
462
492
  if (!(0, core_1.isStandardDatatype)(attributeDatatypeId)) {
463
493
  links[`${label}.${attributeLabel}`] = {
@@ -32,6 +32,16 @@ class SwaggerGenerationServiceRunner extends core_1.AppRunner {
32
32
  .option('contactURL', { describe: 'API contact URL.' })
33
33
  .option('licenseName', { describe: 'API license name.' })
34
34
  .option('licenseURL', { describe: 'API license URL.' })
35
+ .option('excludeClasses', {
36
+ describe: 'A list of class names to exclude from the output.',
37
+ type: 'string',
38
+ array: true,
39
+ })
40
+ .option('excludeProperties', {
41
+ describe: 'A list of property names to exclude from the output.',
42
+ type: 'string',
43
+ array: true,
44
+ })
35
45
  .option('silent', {
36
46
  describe: 'All logs are suppressed',
37
47
  default: false,
@@ -56,6 +56,14 @@ export declare class SwaggerGenerationServiceConfiguration implements IConfigura
56
56
  * API metadata: license URL
57
57
  */
58
58
  private _licenseURL;
59
+ /**
60
+ * An array of class names to be excluded from the generated output
61
+ */
62
+ private _excludeClasses;
63
+ /**
64
+ * An array of property names to be excluded from the generated output
65
+ */
66
+ private _excludeProperties;
59
67
  createFromCli(params: YargsParams): Promise<void>;
60
68
  get input(): string;
61
69
  get output(): string;
@@ -71,4 +79,6 @@ export declare class SwaggerGenerationServiceConfiguration implements IConfigura
71
79
  get contactEmail(): string | undefined;
72
80
  get licenseName(): string | undefined;
73
81
  get licenseURL(): string | undefined;
82
+ get excludeClasses(): string[];
83
+ get excludeProperties(): string[];
74
84
  }
@@ -24,6 +24,8 @@ let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfig
24
24
  this._contactEmail = params.contactEmail;
25
25
  this._licenseName = params.licenseName;
26
26
  this._licenseURL = params.licenseURL;
27
+ this._excludeClasses = params.excludeClasses;
28
+ this._excludeProperties = params.excludeProperties;
27
29
  }
28
30
  get input() {
29
31
  if (!this._input) {
@@ -91,6 +93,12 @@ let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfig
91
93
  get licenseURL() {
92
94
  return this._licenseURL;
93
95
  }
96
+ get excludeClasses() {
97
+ return this._excludeClasses || [];
98
+ }
99
+ get excludeProperties() {
100
+ return this._excludeProperties || [];
101
+ }
94
102
  };
95
103
  SwaggerGenerationServiceConfiguration = __decorate([
96
104
  (0, inversify_1.injectable)()
@@ -1 +1 @@
1
- export declare const mapProperties: (datatype: string, label: string, subclasses: string[], abstract: boolean) => object;
1
+ export declare const mapProperties: (datatype: string, label: string, subclasses: string[], abstract: boolean, excludeClasses: string[]) => object | undefined;
@@ -32,37 +32,44 @@ 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
  ]);
34
34
  /* eslint-enable max-len*/
35
- const mapProperties = (datatype, label, subclasses, abstract) => {
35
+ const mapProperties = (datatype, label, subclasses, abstract, excludeClasses) => {
36
36
  /* Primitive data type conversion from Linked Data to Swagger */
37
37
  if (Properties.has(datatype)) {
38
38
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39
39
  return Properties.get(datatype);
40
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;
41
+ const oneOf = [];
42
+ // Add the superclass to the list if it's not abstract and not excluded
43
+ if (!abstract && !excludeClasses.includes(label)) {
44
+ oneOf.push({ $ref: `#/components/schemas/${label}` });
45
+ }
46
+ // Add all subclasses that are not excluded
47
+ for (const subclass of subclasses) {
48
+ if (!excludeClasses.includes(subclass)) {
49
+ oneOf.push({ $ref: `#/components/schemas/${subclass}` });
54
50
  }
55
- return {
56
- oneOf,
57
- discriminator: {
58
- propertyName: '@type',
59
- mapping,
60
- },
61
- };
62
51
  }
63
- /* Regular schemas without any subclassing */
52
+ // If no valid classes are left for this property, it should be omitted
53
+ if (oneOf.length === 0) {
54
+ return undefined;
55
+ }
56
+ // If only one class remains, we don't need a discriminator
57
+ if (oneOf.length === 1) {
58
+ return oneOf[0];
59
+ }
60
+ // If multiple classes remain, build the discriminator object
61
+ const mapping = {};
62
+ for (const item of oneOf) {
63
+ const refParts = item.$ref.split('/');
64
+ const className = refParts[refParts.length - 1];
65
+ mapping[className] = item.$ref;
66
+ }
64
67
  return {
65
- $ref: `#/components/schemas/${label}`,
68
+ oneOf,
69
+ discriminator: {
70
+ propertyName: '@type',
71
+ mapping,
72
+ },
66
73
  };
67
74
  };
68
75
  exports.mapProperties = mapProperties;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslo-flanders/swagger-generator",
3
- "version": "1.0.4",
3
+ "version": "1.1.1",
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",
@@ -36,20 +36,20 @@
36
36
  "url": "https://github.com/Informatievlaanderen/OSLO-UML-Transformer/issues"
37
37
  },
38
38
  "devDependencies": {
39
- "@rdfjs/types": "^1.1.0",
39
+ "@rdfjs/types": "^2.0.0",
40
40
  "@types/streamify-array": "^1.0.0"
41
41
  },
42
42
  "dependencies": {
43
- "@oslo-flanders/core": "^1.0.0",
43
+ "@oslo-flanders/core": "^1.1.0",
44
44
  "inversify": "^6.0.1",
45
- "n3": "^1.16.2",
46
- "rdf-data-factory": "^1.1.1",
47
- "rdf-parse": "^2.3.2",
48
- "rdf-serialize": "^2.2.2",
49
- "reflect-metadata": "^0.1.13",
50
- "streamify-array": "^1.0.1",
45
+ "n3": "^2.0.0",
46
+ "rdf-data-factory": "^2.0.0",
47
+ "rdf-parse": "^5.0.0",
48
+ "rdf-serialize": "^5.1.0",
49
+ "reflect-metadata": "^0.2.1",
50
+ "streamify-array": "^2.0.0",
51
51
  "streamify-string": "^1.0.1",
52
- "yargs": "^17.6.0"
52
+ "yargs": "^18.0.0"
53
53
  },
54
54
  "gitHead": "beaa3821b72a7df104ff61af49fed6c1140fadd8"
55
55
  }