Skip to content

Commit 37bd666

Browse files
Mark FejesGaetano Guerriero
authored andcommitted
fix: add support for external refs
1 parent 571cd8c commit 37bd666

File tree

6 files changed

+76
-4
lines changed

6 files changed

+76
-4
lines changed

package-lock.json

Lines changed: 25 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"ajv-formats": "^2.0.0"
3939
},
4040
"dependencies": {
41+
"@apidevtools/json-schema-ref-parser": "^9.0.9",
4142
"@openapi-contrib/openapi-schema-to-json-schema": "^3.0.4",
4243
"ajv": "^8.0.0",
4344
"ajv-formats": "^2.0.0",

src/parse-schema.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import jsYaml from 'js-yaml'
22
import { JSONSchema } from 'json-schema-to-typescript';
3+
import $RefParser from '@apidevtools/json-schema-ref-parser';
34
import { readFileSync } from 'fs';
5+
import { dirname } from 'path';
46

57
const toJsonSchema = require('@openapi-contrib/openapi-schema-to-json-schema');
68

@@ -12,7 +14,7 @@ export interface ParsedSchema {
1214
whitelistedDecoders: string[] | undefined;
1315
}
1416

15-
export function parseSchema(inputFilePath: string, schemaType: SchemaType): ParsedSchema {
17+
export async function parseSchema(inputFilePath: string, schemaType: SchemaType): Promise<ParsedSchema> {
1618
switch (schemaType) {
1719
case 'json':
1820
case 'yaml':
@@ -22,7 +24,7 @@ export function parseSchema(inputFilePath: string, schemaType: SchemaType): Pars
2224
}
2325
}
2426

25-
function parseOpenApiSchema(inputFilePath: string, schemaType: 'yaml' | 'json'): ParsedSchema {
27+
async function parseOpenApiSchema(inputFilePath: string, schemaType: 'yaml' | 'json'): Promise<ParsedSchema> {
2628
let schema: any;
2729

2830
const inputFileContent = readFileSync(inputFilePath, 'utf8');
@@ -33,6 +35,14 @@ function parseOpenApiSchema(inputFilePath: string, schemaType: 'yaml' | 'json'):
3335
schema = JSON.parse(inputFileContent);
3436
}
3537

38+
// need to change to input file base directory, so relative ref paths can be resolved
39+
const originalDirectory = process.cwd();
40+
process.chdir(dirname(inputFilePath));
41+
// resolve external references to original schema
42+
schema = await $RefParser.bundle(schema)
43+
// change back to original directory
44+
process.chdir(originalDirectory);
45+
3646
const properties: Record<string, any> = {};
3747
const definitions: Record<string, JSONSchema> = {};
3848

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
components:
2+
schemas:
3+
UserList:
4+
type: array
5+
items:
6+
$ref: './user.yaml#/definitions/User'

tests/schemas/user.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
definitions:
2+
User:
3+
type: object
4+
properties:
5+
id:
6+
type: string
7+
name:
8+
type: string
9+
required: ['id']
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import path from "path";
2+
import fs from "fs";
3+
import { generate } from "openapi-typescript-validator";
4+
5+
describe("schema-with-external-ref", () => {
6+
const name = "schema-with-external-ref";
7+
const generatedDir = path.join(__dirname, "../generated", name);
8+
const schemaDir = path.join(__dirname, "../schemas");
9+
10+
beforeAll(async () => {
11+
if (fs.existsSync(generatedDir))
12+
fs.rmdirSync(generatedDir, { recursive: true });
13+
});
14+
15+
test('schema with external ref', async () => {
16+
await generate({
17+
schemaFile: path.join(schemaDir, "schema-with-external-ref.yaml"),
18+
schemaType: "yaml",
19+
directory: generatedDir
20+
});
21+
});
22+
23+
});

0 commit comments

Comments
 (0)