Skip to content

Commit ae11834

Browse files
committed
fix(asyncapi): allow replace Schema for Reference in Message.payload
Refs #427
1 parent 8e82645 commit ae11834

File tree

6 files changed

+125
-8
lines changed

6 files changed

+125
-8
lines changed

apidom/packages/apidom-ns-asyncapi-2-0/src/refractor/visitors/async-api-2-0/message/index.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ObjectElement, isObjectElement, Element } from 'apidom';
55
import MessageElement from '../../../../elements/Message';
66
import FallbackVisitor from '../../FallbackVisitor';
77
import FixedFieldsVisitor from '../../generics/FixedFieldsVisitor';
8+
import { isReferenceLikeElement } from '../../../predicates';
89

910
const MessageVisitor = stampit(FixedFieldsVisitor, FallbackVisitor, {
1011
props: {
@@ -31,14 +32,22 @@ const MessageVisitor = stampit(FixedFieldsVisitor, FallbackVisitor, {
3132
ObjectElement(objectElement: ObjectElement) {
3233
// @ts-ignore
3334
const result = FixedFieldsVisitor.compose.methods.ObjectElement.call(this, objectElement);
34-
35-
// refract payload according to `schemaFormat`
36-
const schemaFormat = defaultTo(
37-
'application/vnd.aai.asyncapi;version=2.0.0',
38-
objectElement.get('schemaFormat')?.toValue(),
39-
);
4035
const payload = this.element.get('payload');
41-
this.refractPayload(schemaFormat, payload);
36+
37+
if (isReferenceLikeElement(payload)) {
38+
// refract to ReferenceElement
39+
this.element.payload = this.toRefractedElement(
40+
['document', 'objects', 'Reference'],
41+
payload,
42+
);
43+
} else {
44+
// refract payload according to `schemaFormat`
45+
const schemaFormat = defaultTo(
46+
'application/vnd.aai.asyncapi;version=2.0.0',
47+
objectElement.get('schemaFormat')?.toValue(),
48+
);
49+
this.refractPayload(schemaFormat, payload);
50+
}
4251

4352
return result;
4453
},

apidom/packages/apidom-ns-asyncapi-2-0/test/refractor/elements/Message/__snapshots__/index.ts.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,16 @@ exports[`refractor elements given payload field of other type should refract to
9393
(BooleanElement)))
9494
`;
9595

96+
exports[`refractor elements given payload field of type ReferenceElement should refract to semantic ApiDOM tree 1`] = `
97+
(MessageElement
98+
(MemberElement
99+
(StringElement)
100+
(ReferenceElement
101+
(MemberElement
102+
(StringElement)
103+
(StringElement)))))
104+
`;
105+
96106
exports[`refractor elements given payload field of type SchemaElement should refract to semantic ApiDOM tree 1`] = `
97107
(MessageElement
98108
(MemberElement

apidom/packages/apidom-ns-asyncapi-2-0/test/refractor/elements/Message/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ describe('refractor', function () {
5555
});
5656
});
5757

58+
context('given payload field of type ReferenceElement', function () {
59+
specify('should refract to semantic ApiDOM tree', function () {
60+
const messageElement = MessageElement.refract({
61+
payload: {
62+
$ref: '#/json-pointer',
63+
},
64+
});
65+
66+
expect(sexprs(messageElement)).toMatchSnapshot();
67+
});
68+
});
69+
5870
context('given payload field of other type', function () {
5971
specify('should refract to semantic ApiDOM tree', function () {
6072
const messageElement = MessageElement.refract({
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[
2+
{
3+
"asyncapi": "2.0.0",
4+
"components": {
5+
"messages": {
6+
"UserSignedUp": {
7+
"name": "userSignedUp",
8+
"title": "User signed up event",
9+
"summary": "Inform about a new user",
10+
"contentType": "application/json",
11+
"payload": {
12+
"type": "object",
13+
"title": "User signed up event",
14+
"summary": "Inform about a new user",
15+
"contentType": "application/json",
16+
"properties": {
17+
"firstName": {
18+
"type": "string",
19+
"description": "foo"
20+
}
21+
}
22+
}
23+
}
24+
},
25+
"schemas": {
26+
"userSignedUpPayload": {
27+
"type": "object",
28+
"title": "User signed up event",
29+
"summary": "Inform about a new user",
30+
"contentType": "application/json",
31+
"properties": {
32+
"firstName": {
33+
"type": "string",
34+
"description": "foo"
35+
}
36+
}
37+
}
38+
}
39+
}
40+
}
41+
]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"asyncapi": "2.0.0",
3+
"components": {
4+
"messages": {
5+
"UserSignedUp": {
6+
"name": "userSignedUp",
7+
"title": "User signed up event",
8+
"summary": "Inform about a new user",
9+
"contentType": "application/json",
10+
"payload": {
11+
"$ref": "#/components/schemas/userSignedUpPayload"
12+
}
13+
}
14+
},
15+
"schemas": {
16+
"userSignedUpPayload": {
17+
"type": "object",
18+
"title": "User signed up event",
19+
"summary": "Inform about a new user",
20+
"contentType": "application/json",
21+
"properties": {
22+
"firstName": {
23+
"type": "string",
24+
"description": "foo"
25+
}
26+
}
27+
}
28+
}
29+
}
30+
}

apidom/packages/apidom-reference/test/dereference/strategies/asyncapi-2-0/reference-object/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from 'path';
22
import { assert } from 'chai';
3-
import { toValue } from 'apidom';
3+
import { toValue, sexprs } from 'apidom';
44
import { isParameterElement } from 'apidom-ns-asyncapi-2-0';
55

66
import { loadJsonFile } from '../../../../helpers';
@@ -261,6 +261,21 @@ describe('dereference', function () {
261261
});
262262
});
263263

264+
context('given Reference Objects referencing Schema Object', function () {
265+
const fixturePath = path.join(rootFixturePath, 'referencing-schema-object');
266+
267+
specify('should dereference', async function () {
268+
const rootFilePath = path.join(fixturePath, 'root.json');
269+
const actual = await dereference(rootFilePath, {
270+
parse: { mediaType: 'application/vnd.aai.asyncapi+json;version=2.0.0' },
271+
});
272+
console.dir(sexprs(actual));
273+
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
274+
275+
assert.deepEqual(toValue(actual), expected);
276+
});
277+
});
278+
264279
context('given Reference Objects and maxDepth of dereference', function () {
265280
const fixturePath = path.join(rootFixturePath, 'max-depth');
266281

0 commit comments

Comments
 (0)