@oslo-flanders/swagger-generator 2.0.0 → 3.0.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
@@ -24,6 +24,7 @@ The service is executed from the CLI and expects the following parameters:
24
24
  | `--input` | The URL or local file path of an OSLO-compliant RDF file | :heavy_check_mark: | |
25
25
  | `--output` | The name of the output file | :heavy_check_mark: | |
26
26
  | `--language` | The language in which the Swagger must be generated (labels) | No | |
27
+ | `--primaryLanguage` | The primary language of the API. Output files for this language keep their original name, while other languages get a `_{language}` suffix | No | `nl` (default) |
27
28
  | `--versionSwagger` | Swagger OpenAPI specification version | :heavy_check_mark: | |
28
29
  | `--versionAPI` | API version | :heavy_check_mark: | |
29
30
  | `--title` | Title of the API document | :heavy_check_mark: | |
@@ -17,4 +17,12 @@ export declare class SwaggerGenerationService implements IService {
17
17
  createSchemas(): Object;
18
18
  createLinks(): Object;
19
19
  writeOutput(outputFormat: OutputFormat, obj: Object, outputPath: string): Promise<void>;
20
+ /**
21
+ * Create a self-contained copy of the components object where all `$ref`
22
+ * pointers to `#/components/schemas/<name>` are replaced by the actual
23
+ * schema definition inline. Resolves recursively so that nested `$ref`
24
+ * references are also inlined. Circular references are preserved as `$ref`
25
+ * to avoid infinite recursion.
26
+ */
27
+ private resolveRefs;
20
28
  }
@@ -128,16 +128,23 @@ let SwaggerGenerationService = class SwaggerGenerationService {
128
128
  ...(Object.keys(links).length > 0 ? { links } : {}),
129
129
  },
130
130
  };
131
+ /* Create embedded (self-contained) variant with all $ref resolved inline */
132
+ const embeddedComponents = this.resolveRefs(components, schemas);
131
133
  /* Create Swagger endpoint paths as example */
132
134
  const swagger = this.createSwagger(schemas, links);
135
+ /* Only append the language suffix when the generated language differs from the primary language */
136
+ const languageSuffix = this.configuration.language === this.configuration.primaryLanguage
137
+ ? ''
138
+ : `_${this.configuration.language}`;
133
139
  for (const format of this.configuration.outputFormat) {
134
140
  const ext = (_a = FILE_EXTENSIONS[format]) !== null && _a !== void 0 ? _a : '.json';
135
141
  for (const label of Object.keys(schemas))
136
- await this.writeOutput(format, schemas[label], `swagger/components/schemas/${label}${ext}`);
142
+ await this.writeOutput(format, schemas[label], `swagger/components/schemas/${label}${languageSuffix}${ext}`);
137
143
  for (const label of Object.keys(links))
138
- await this.writeOutput(format, links[label], `swagger/components/links/${label}${ext}`);
139
- await this.writeOutput(format, components, `swagger/components${ext}`);
140
- await this.writeOutput(format, swagger, `swagger/example${ext}`);
144
+ await this.writeOutput(format, links[label], `swagger/components/links/${label}${languageSuffix}${ext}`);
145
+ await this.writeOutput(format, components, `swagger/components${languageSuffix}${ext}`);
146
+ await this.writeOutput(format, embeddedComponents, `swagger/_embedded${languageSuffix}${ext}`);
147
+ await this.writeOutput(format, swagger, `swagger/example${languageSuffix}${ext}`);
141
148
  }
142
149
  }
143
150
  createSwagger(schemas, links = {}) {
@@ -592,6 +599,71 @@ let SwaggerGenerationService = class SwaggerGenerationService {
592
599
  (0, core_1.ensureOutputDirectory)(path.dirname(filePath));
593
600
  await (0, promises_1.writeFile)(filePath, data);
594
601
  }
602
+ /**
603
+ * Create a self-contained copy of the components object where all `$ref`
604
+ * pointers to `#/components/schemas/<name>` are replaced by the actual
605
+ * schema definition inline. Resolves recursively so that nested `$ref`
606
+ * references are also inlined. Circular references are preserved as `$ref`
607
+ * to avoid infinite recursion.
608
+ */
609
+ resolveRefs(components, schemas) {
610
+ const embedded = JSON.parse(JSON.stringify(components));
611
+ const resolving = new Set();
612
+ function walk(obj) {
613
+ if (!obj || typeof obj !== 'object') {
614
+ return;
615
+ }
616
+ if (Array.isArray(obj)) {
617
+ for (let i = 0; i < obj.length; i++) {
618
+ if (obj[i] !== null && typeof obj[i] === 'object' && obj[i].$ref) {
619
+ const match = obj[i].$ref.match(/^#\/components\/schemas\/(.+)$/);
620
+ if (match && schemas[match[1]]) {
621
+ if (resolving.has(match[1])) {
622
+ // Circular reference – keep the $ref as-is
623
+ continue;
624
+ }
625
+ resolving.add(match[1]);
626
+ obj[i] = JSON.parse(JSON.stringify(schemas[match[1]]));
627
+ walk(obj[i]);
628
+ resolving.delete(match[1]);
629
+ }
630
+ }
631
+ else {
632
+ walk(obj[i]);
633
+ }
634
+ }
635
+ }
636
+ else {
637
+ for (const key of Object.keys(obj)) {
638
+ if (key === '$ref' &&
639
+ typeof obj[key] === 'string' &&
640
+ obj.$ref.startsWith('#/components/schemas/')) {
641
+ continue;
642
+ }
643
+ if (obj[key] !== null &&
644
+ typeof obj[key] === 'object' &&
645
+ obj[key].$ref) {
646
+ const match = obj[key].$ref.match(/^#\/components\/schemas\/(.+)$/);
647
+ if (match && schemas[match[1]]) {
648
+ if (resolving.has(match[1])) {
649
+ // Circular reference – keep the $ref as-is
650
+ continue;
651
+ }
652
+ resolving.add(match[1]);
653
+ obj[key] = JSON.parse(JSON.stringify(schemas[match[1]]));
654
+ walk(obj[key]);
655
+ resolving.delete(match[1]);
656
+ }
657
+ }
658
+ else {
659
+ walk(obj[key]);
660
+ }
661
+ }
662
+ }
663
+ }
664
+ walk(embedded);
665
+ return embedded;
666
+ }
595
667
  };
596
668
  SwaggerGenerationService = __decorate([
597
669
  (0, inversify_1.injectable)(),
@@ -19,6 +19,10 @@ class SwaggerGenerationServiceRunner extends core_1.AppRunner {
19
19
  })
20
20
  .option('versionAPI', { describe: 'API version.' })
21
21
  .option('language', { describe: 'API language tag.', default: 'nl' })
22
+ .option('primaryLanguage', {
23
+ describe: 'The primary language of the API. Output files for this language keep their original name, while other languages get a `_{language}` suffix.',
24
+ default: 'nl',
25
+ })
22
26
  .option('title', {
23
27
  describe: 'API title.',
24
28
  type: 'string',
@@ -81,6 +85,7 @@ class SwaggerGenerationServiceRunner extends core_1.AppRunner {
81
85
  'title',
82
86
  'contextURL',
83
87
  'baseURL',
88
+ 'language'
84
89
  ])
85
90
  .help('h')
86
91
  .alias('h', 'help');
@@ -13,6 +13,11 @@ export declare class SwaggerGenerationServiceConfiguration implements IConfigura
13
13
  * The language of the labels that are used in the context
14
14
  */
15
15
  private _language;
16
+ /**
17
+ * The primary language of the API. Output files for this language keep their
18
+ * original name, while files for other languages get a `_{language}` suffix.
19
+ */
20
+ private _primaryLanguage;
16
21
  /**
17
22
  * Swagger version
18
23
  */
@@ -89,6 +94,7 @@ export declare class SwaggerGenerationServiceConfiguration implements IConfigura
89
94
  get input(): string;
90
95
  get output(): string;
91
96
  get language(): string;
97
+ get primaryLanguage(): string;
92
98
  get versionSwagger(): string;
93
99
  get versionAPI(): string;
94
100
  get title(): string;
@@ -14,6 +14,7 @@ let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfig
14
14
  this._input = params.input;
15
15
  this._output = params.output;
16
16
  this._language = params.language;
17
+ this._primaryLanguage = params.primaryLanguage;
17
18
  this._versionSwagger = params.versionSwagger;
18
19
  this._versionAPI = params.versionAPI;
19
20
  this._title = params.title;
@@ -51,6 +52,10 @@ let SwaggerGenerationServiceConfiguration = class SwaggerGenerationServiceConfig
51
52
  }
52
53
  return this._language;
53
54
  }
55
+ get primaryLanguage() {
56
+ /* Default to Dutch, which is the primary language of the OSLO standards */
57
+ return this._primaryLanguage || 'nl';
58
+ }
54
59
  get versionSwagger() {
55
60
  if (!this._versionSwagger) {
56
61
  throw new Error(`Trying to access property "versionSwagger" before it was set.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslo-flanders/swagger-generator",
3
- "version": "2.0.0",
3
+ "version": "3.0.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",