@oslo-flanders/swagger-generator 1.1.0 → 1.2.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 +25 -16
- package/lib/SwaggerGenerationService.d.ts +1 -0
- package/lib/SwaggerGenerationService.js +46 -3
- 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 +31 -23
- package/lib/types/Swagger.d.ts +3 -0
- package/package.json +2 -2
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
|
```
|
|
@@ -10,6 +10,7 @@ export declare class SwaggerGenerationService implements IService {
|
|
|
10
10
|
private getProbleemdetailsLink;
|
|
11
11
|
private getContact;
|
|
12
12
|
private getLicense;
|
|
13
|
+
private schemaExists;
|
|
13
14
|
init(): Promise<void>;
|
|
14
15
|
run(): Promise<void>;
|
|
15
16
|
createSwagger(schemas: any, links: any): Object;
|
|
@@ -89,6 +89,15 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
89
89
|
url: this.configuration.licenseURL,
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
|
+
/* The schema already exists in the model. This would mean that there are identical labels, which isn't ideal
|
|
93
|
+
https://vlaamseoverheid.atlassian.net/browse/DATAST-2249?atlOrigin=eyJpIjoiMWYyZjVmOTFhMWExNDc4MmIwMGQxNjhkMjJmN2NhZGUiLCJwIjoiaiJ9
|
|
94
|
+
*/
|
|
95
|
+
schemaExists(schema, label) {
|
|
96
|
+
if (schema[label]) {
|
|
97
|
+
this.logger.warn(`[SwaggerGenerationService]: Schema already exists for the label (${label}) and will be overwritten.`);
|
|
98
|
+
}
|
|
99
|
+
return !!schema[label];
|
|
100
|
+
}
|
|
92
101
|
async init() {
|
|
93
102
|
return this.store.addQuadsFromFile(this.configuration.input);
|
|
94
103
|
}
|
|
@@ -152,6 +161,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
152
161
|
}
|
|
153
162
|
/* Class labels should be always pascal cased */
|
|
154
163
|
label = (0, core_1.toPascalCase)(label);
|
|
164
|
+
/* If a class is excluded via configuration, stop here */
|
|
165
|
+
if (this.configuration.excludeClasses.includes(label)) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
155
168
|
/* Only keep links which are related to the class */
|
|
156
169
|
for (const key of Object.keys(links)) {
|
|
157
170
|
if (key.startsWith(`${label}.`))
|
|
@@ -248,7 +261,7 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
248
261
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
249
262
|
const schemas = {};
|
|
250
263
|
/* Create schema for each enumeration */
|
|
251
|
-
for (const enumId of this.store.
|
|
264
|
+
for (const enumId of this.store.getEnumerations()) {
|
|
252
265
|
let label = (_a = (0, core_1.getApplicationProfileLabel)(enumId, this.store, this.configuration.language)) === null || _a === void 0 ? void 0 : _a.value;
|
|
253
266
|
if (!label) {
|
|
254
267
|
this.logger.error(`Unknown enum label for ${enumId.value}`);
|
|
@@ -256,6 +269,7 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
256
269
|
}
|
|
257
270
|
/* Class labels should be always pascal cased */
|
|
258
271
|
label = (0, core_1.toPascalCase)(label);
|
|
272
|
+
this.schemaExists(schemas, label);
|
|
259
273
|
schemas[label] = {
|
|
260
274
|
title: label,
|
|
261
275
|
type: 'object',
|
|
@@ -273,7 +287,9 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
273
287
|
for (const classId of [
|
|
274
288
|
...this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.owl('Class')),
|
|
275
289
|
...this.store.findSubjects(core_1.ns.rdf('type'), core_1.ns.rdfs('Datatype')),
|
|
276
|
-
]
|
|
290
|
+
]
|
|
291
|
+
// Extra filter to exclude all the enumerations since these are mentioned twice in the intermedairy format under enums and classes
|
|
292
|
+
.filter((val) => !(0, core_1.isEnumeration)(this.store, val))) {
|
|
277
293
|
const assignedUri = this.store.getAssignedUri(classId);
|
|
278
294
|
/* Primitive datatypes may not be generated */
|
|
279
295
|
if (assignedUri && [...core_1.DataTypes.values()].includes(assignedUri.value))
|
|
@@ -294,6 +310,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
294
310
|
}
|
|
295
311
|
/* Class labels should be always pascal cased */
|
|
296
312
|
label = (0, core_1.toPascalCase)(label);
|
|
313
|
+
/* If a class is excluded via configuration, stop here */
|
|
314
|
+
if (this.configuration.excludeClasses.includes(label)) {
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
297
317
|
attributes[label] = [];
|
|
298
318
|
requiredAttributes[label] = [];
|
|
299
319
|
/* Find all attributes for object */
|
|
@@ -311,6 +331,11 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
311
331
|
}
|
|
312
332
|
/* Attribute labels should be always camel cased */
|
|
313
333
|
attributeLabel = (0, core_1.toCamelCase)(attributeLabel);
|
|
334
|
+
// Addition for the `excludeProperties` flag to remove any reference to an excluded property
|
|
335
|
+
const classNameWithPropertyName = `${label}.${attributeLabel}`;
|
|
336
|
+
if (this.configuration.excludeProperties.includes(classNameWithPropertyName)) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
314
339
|
if (!attributeRangeId) {
|
|
315
340
|
this.logger.error(`Unknown range for attribute ${attributeId.value}`);
|
|
316
341
|
continue;
|
|
@@ -344,7 +369,11 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
344
369
|
}
|
|
345
370
|
/* Arrays must be introduced into the schema if the max cardinality is 2 or more */
|
|
346
371
|
const description = `${attributeDefinition}${attributeUsageNote ? ' ' + attributeUsageNote : ''}`;
|
|
347
|
-
const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, subclasses, attributeDatatypeAbstract);
|
|
372
|
+
const properties = (0, Properties_1.mapProperties)(attributeDatatypeId, attributeDatatypeLabel, subclasses, attributeDatatypeAbstract, this.configuration.excludeClasses);
|
|
373
|
+
// If mapProperties returns nothing, the property pointed to an excluded class (this.configuration.excludeClasses)
|
|
374
|
+
if (!properties) {
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
348
377
|
const requiredProperties = properties
|
|
349
378
|
? Object.keys(properties)
|
|
350
379
|
: undefined;
|
|
@@ -395,6 +424,7 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
395
424
|
},
|
|
396
425
|
};
|
|
397
426
|
}
|
|
427
|
+
this.schemaExists(schemas, label);
|
|
398
428
|
/* Create components for each schema */
|
|
399
429
|
schemas[label] = {
|
|
400
430
|
title: label,
|
|
@@ -437,6 +467,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
437
467
|
}
|
|
438
468
|
/* Class labels should be always pascal cased */
|
|
439
469
|
label = (0, core_1.toPascalCase)(label);
|
|
470
|
+
/* If a class is excluded via configuration, stop here */
|
|
471
|
+
if (this.configuration.excludeClasses.includes(label)) {
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
440
474
|
/* Find all attributes for object */
|
|
441
475
|
for (const attributeId of attributeIds) {
|
|
442
476
|
let attributeLabel = (_b = (0, core_1.getApplicationProfileLabel)(attributeId, this.store, this.configuration.language)) === null || _b === void 0 ? void 0 : _b.value;
|
|
@@ -447,6 +481,11 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
447
481
|
}
|
|
448
482
|
/* Attribute labels should be always camel cased */
|
|
449
483
|
attributeLabel = (0, core_1.toCamelCase)(attributeLabel);
|
|
484
|
+
// Addition for the `excludeProperties` flag to remove any reference to an excluded property
|
|
485
|
+
const classNameWithPropertyName = `${label}.${attributeLabel}`;
|
|
486
|
+
if (this.configuration.excludeProperties.includes(classNameWithPropertyName)) {
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
450
489
|
if (!attributeRangeId) {
|
|
451
490
|
this.logger.error(`Unknown range for attribute ${attributeId.value}`);
|
|
452
491
|
continue;
|
|
@@ -458,6 +497,10 @@ let SwaggerGenerationService = class SwaggerGenerationService {
|
|
|
458
497
|
continue;
|
|
459
498
|
}
|
|
460
499
|
attributeDatatypeLabel = (0, core_1.toPascalCase)(attributeDatatypeLabel);
|
|
500
|
+
// Addition for the `excludeClasses` flag to remove any reference to an excluded class
|
|
501
|
+
if (this.configuration.excludeClasses.includes(attributeDatatypeLabel)) {
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
461
504
|
/* Create all possible links for endpoint */
|
|
462
505
|
if (!(0, core_1.isStandardDatatype)(attributeDatatypeId)) {
|
|
463
506
|
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
|
@@ -30,39 +30,47 @@ const Properties = new Map([
|
|
|
30
30
|
[core_1.ns.xsd('unsignedShort').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 65535 }, '@type': { type: 'string', pattern: '^UnsignedShort$' } }],
|
|
31
31
|
[core_1.ns.xsd('unsignedByte').value, { '@value': { type: 'number', format: 'int32', minimum: 0, maximum: 255 }, '@type': { type: 'string', pattern: '^UnsignedByte$' } }],
|
|
32
32
|
[core_1.ns.xsd('decimal').value, { '@value': { type: 'string', pattern: '(+|-)?([0-9]+(.[0-9]*)?|.[0-9]+)' }, '@type': { type: 'string', pattern: '^Decimal$' } }],
|
|
33
|
+
[core_1.ns.xsd('language').value, { '@value': { type: 'string', pattern: '^[a-z]{2,3}(-[A-Z]{2})?' }, '@type': { type: 'string', pattern: '^Language$' } }],
|
|
33
34
|
]);
|
|
34
35
|
/* eslint-enable max-len*/
|
|
35
|
-
const mapProperties = (datatype, label, subclasses, abstract) => {
|
|
36
|
+
const mapProperties = (datatype, label, subclasses, abstract, excludeClasses) => {
|
|
36
37
|
/* Primitive data type conversion from Linked Data to Swagger */
|
|
37
38
|
if (Properties.has(datatype)) {
|
|
38
39
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
39
40
|
return Properties.get(datatype);
|
|
40
41
|
}
|
|
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;
|
|
42
|
+
const oneOf = [];
|
|
43
|
+
// Add the superclass to the list if it's not abstract and not excluded
|
|
44
|
+
if (!abstract && !excludeClasses.includes(label)) {
|
|
45
|
+
oneOf.push({ $ref: `#/components/schemas/${label}` });
|
|
46
|
+
}
|
|
47
|
+
// Add all subclasses that are not excluded
|
|
48
|
+
for (const subclass of subclasses) {
|
|
49
|
+
if (!excludeClasses.includes(subclass)) {
|
|
50
|
+
oneOf.push({ $ref: `#/components/schemas/${subclass}` });
|
|
54
51
|
}
|
|
55
|
-
return {
|
|
56
|
-
oneOf,
|
|
57
|
-
discriminator: {
|
|
58
|
-
propertyName: '@type',
|
|
59
|
-
mapping,
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
52
|
}
|
|
63
|
-
|
|
53
|
+
// If no valid classes are left for this property, it should be omitted
|
|
54
|
+
if (oneOf.length === 0) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
// If only one class remains, we don't need a discriminator
|
|
58
|
+
if (oneOf.length === 1) {
|
|
59
|
+
return oneOf[0];
|
|
60
|
+
}
|
|
61
|
+
// If multiple classes remain, build the discriminator object
|
|
62
|
+
const mapping = {};
|
|
63
|
+
for (const item of oneOf) {
|
|
64
|
+
const refParts = item.$ref.split('/');
|
|
65
|
+
const className = refParts[refParts.length - 1];
|
|
66
|
+
mapping[className] = item.$ref;
|
|
67
|
+
}
|
|
64
68
|
return {
|
|
65
|
-
|
|
69
|
+
oneOf,
|
|
70
|
+
discriminator: {
|
|
71
|
+
propertyName: '@type',
|
|
72
|
+
mapping,
|
|
73
|
+
},
|
|
66
74
|
};
|
|
67
75
|
};
|
|
68
76
|
exports.mapProperties = mapProperties;
|
package/lib/types/Swagger.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oslo-flanders/swagger-generator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.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",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@types/streamify-array": "^1.0.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@oslo-flanders/core": "^1.
|
|
43
|
+
"@oslo-flanders/core": "^1.2.0",
|
|
44
44
|
"inversify": "^6.0.1",
|
|
45
45
|
"n3": "^2.0.0",
|
|
46
46
|
"rdf-data-factory": "^2.0.0",
|