@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 +25 -16
- package/lib/SwaggerGenerationService.js +31 -1
- package/lib/SwaggerGenerationServiceRunner.js +10 -0
- package/lib/config/SwaggerGenerationServiceConfiguration.d.ts +10 -0
- package/lib/config/SwaggerGenerationServiceConfiguration.js +8 -0
- package/lib/enums/Properties.d.ts +1 -1
- package/lib/enums/Properties.js +30 -23
- package/package.json +10 -10
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
|
|
22
|
+
| Parameter | Description | Required | Possible values |
|
|
20
23
|
| ------------------ | ------------------------------------------------------------ | ------------------ | --------------------------- |
|
|
21
|
-
| `--input`
|
|
22
|
-
| `--output`
|
|
23
|
-
| `--language`
|
|
24
|
-
| `--versionSwagger` | Swagger OpenAPI specification version
|
|
25
|
-
| `--versionAPI`
|
|
26
|
-
| `--title`
|
|
27
|
-
| `--description`
|
|
28
|
-
| `--contextURL`
|
|
29
|
-
| `--baseURL`
|
|
30
|
-
| `--contactName`
|
|
31
|
-
| `--contactEmail`
|
|
32
|
-
| `--contactURL`
|
|
33
|
-
| `--licenseName`
|
|
34
|
-
| `--licenseURL`
|
|
35
|
-
| `--
|
|
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;
|
package/lib/enums/Properties.js
CHANGED
|
@@ -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
|
-
|
|
42
|
-
if
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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": "^
|
|
39
|
+
"@rdfjs/types": "^2.0.0",
|
|
40
40
|
"@types/streamify-array": "^1.0.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@oslo-flanders/core": "^1.
|
|
43
|
+
"@oslo-flanders/core": "^1.1.0",
|
|
44
44
|
"inversify": "^6.0.1",
|
|
45
|
-
"n3": "^
|
|
46
|
-
"rdf-data-factory": "^
|
|
47
|
-
"rdf-parse": "^
|
|
48
|
-
"rdf-serialize": "^
|
|
49
|
-
"reflect-metadata": "^0.1
|
|
50
|
-
"streamify-array": "^
|
|
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": "^
|
|
52
|
+
"yargs": "^18.0.0"
|
|
53
53
|
},
|
|
54
54
|
"gitHead": "beaa3821b72a7df104ff61af49fed6c1140fadd8"
|
|
55
55
|
}
|