Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@ export async function parse(
options: BundlerOptions = {}
) {
/* eslint-disable indent */

let circular: boolean | 'ignore' = false;
if (options.dereference === 'ignore-circular') {
circular = 'ignore';
}

// It is assumed that there will be major Spec versions 4, 5 and on.
switch (specVersion) {
case 2:
RefParserOptions = {
dereference: {
circular: false,
circular,
// prettier-ignore
excludedPathMatcher: (path: string): any => { // eslint-disable-line
return;
Expand All @@ -39,7 +45,7 @@ export async function parse(
case 3:
RefParserOptions = {
dereference: {
circular: false,
circular,
excludedPathMatcher: (path: string): any => {
return (
// prettier-ignore
Expand Down Expand Up @@ -69,5 +75,9 @@ export async function parse(
);
}

return await $RefParser.dereference(JSONSchema, RefParserOptions) as AsyncAPIObject;
let bundled = JSONSchema;
if (circular !== false) {
bundled = await $RefParser.bundle(bundled, RefParserOptions);
}
return await $RefParser.dereference(bundled, RefParserOptions) as AsyncAPIObject;
}
1 change: 1 addition & 0 deletions src/spec-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,5 @@ export interface Options {
base?: string;
baseDir?: string;
xOrigin?: boolean;
dereference?: string;
}
20 changes: 20 additions & 0 deletions tests/circular.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
asyncapi: 3.0.0
info:
title: Test model
version: 1.0.0
components:
messages:
btree:
payload:
type: object
properties:
root:
$ref: '#/components/messages/node'
node:
payload:
type: object
properties:
left:
$ref: '#/components/messages/node'
right:
$ref: '#/components/messages/node'
10 changes: 10 additions & 0 deletions tests/circular/asyncapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
asyncapi: 3.0.0
info:
title: Test model
version: 1.0.0
components:
messages:
btree:
title: BTree
payload:
$ref: "./btree.yml"
6 changes: 6 additions & 0 deletions tests/circular/btree.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$schema: "https://json-schema.org/draft-07/schema#"
title: BTree
type: object
properties:
root:
$ref: "./node.yml"
8 changes: 8 additions & 0 deletions tests/circular/node.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$schema: "https://json-schema.org/draft-07/schema#"
title: Node
type: object
properties:
left:
$ref: "#"
right:
$ref: "#"
82 changes: 82 additions & 0 deletions tests/lib/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,88 @@ describe('[integration testing] bundler should ', () => {

expect(document.json()).toMatchObject(resultingObject);
});

test('should throw if circular `$ref` exists and derefrence for circular references is disabled for single file', async () => {
const files = ['circular.yml'];

await expect(async () => {
await bundle(files, {
xOrigin: true,
baseDir: path.resolve(process.cwd(), './tests'),
dereference: 'strict',
})
}).rejects.toThrow(Error);
});

test('should not throw if circular `$ref` exists and derefrence for circular references is ignored for single file', async () => {
const files = ['circular.yml'];

const response = await bundle(files, {
xOrigin: true,
baseDir: path.resolve(process.cwd(), './tests'),
dereference: 'ignore-circular',
});
expect(response).resolves;
});

test('should throw if circular `$ref` exists and derefrence for circular references is disabled for multiple files', async () => {
const files = ['asyncapi.yaml'];

await expect(async () => {
await bundle(files, {
xOrigin: true,
baseDir: path.resolve(process.cwd(), './tests/circular'),
dereference: 'strict',
})
}).rejects.toThrow(Error);
});

test('should not throw if circular `$ref` exists and derefrence for circular references is ignored for multiple files', async () => {
const resultingObject = {
asyncapi: '3.0.0',
info: {
title: 'Test model',
version: '1.0.0',
},
components: {
messages: {
btree: {
title: 'BTree',
payload: {
$schema: 'https://json-schema.org/draft-07/schema#',
title: 'BTree',
type: 'object',
properties: {
root: {
$schema: 'https://json-schema.org/draft-07/schema#',
title: 'Node',
type: 'object',
properties: {
left: {
$ref: '#/components/messages/btree/payload/properties/root'
},
right: {
$ref: '#/components/messages/btree/payload/properties/root'
},
},
},
},
},
},
},
},
};

const files = ['asyncapi.yaml'];

const response = await bundle(files, {
xOrigin: true,
baseDir: path.resolve(process.cwd(), './tests/circular'),
dereference: 'ignore-circular',
});

expect(response.json()).toMatchObject(resultingObject);
});
});

describe('[unit testing]', () => {
Expand Down