Skip to content

Commit 90a76fd

Browse files
authored
refactor(asyncapi): unify how we work with media types (#1145)
Refs #1130
1 parent 9fd4583 commit 90a76fd

File tree

23 files changed

+196
-192
lines changed

23 files changed

+196
-192
lines changed

packages/apidom-core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import defaultNamespaceInstance from './namespace';
77

88
export { default as refractorPluginElementIdentity } from './refractor/plugins/element-identity';
99
export { default as refractorPluginSemanticElementIdentity } from './refractor/plugins/semantic-element-identity';
10+
export { default as MediaTypes } from './media-types';
1011

1112
export {
1213
Element,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class MediaTypes<T> extends Array<T> {
2+
// eslint-disable-next-line class-methods-use-this
3+
forFormat() {
4+
throw new Error('Not implemented!');
5+
}
6+
7+
// eslint-disable-next-line class-methods-use-this
8+
latest() {
9+
throw new Error('Not implemented!');
10+
}
11+
}
12+
13+
export default MediaTypes;

packages/apidom-ns-asyncapi-2/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export {
1313
isStringElement,
1414
} from '@swagger-api/apidom-core';
1515

16+
export { default as mediaTypes, AsyncAPIMediaTypes } from './media-types';
17+
1618
// eslint-disable-next-line no-restricted-exports
1719
export { default } from './namespace';
1820

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { MediaTypes } from '@swagger-api/apidom-core';
2+
3+
export class AsyncAPIMediaTypes extends MediaTypes<string> {
4+
forFormat(format = 'generic') {
5+
const effectiveFormat = format === 'generic' ? 'asyncapi;version' : format;
6+
return this.filter((mediaType) => mediaType.includes(effectiveFormat));
7+
}
8+
9+
latest(format = 'generic') {
10+
if (format === 'json') {
11+
return this[7];
12+
}
13+
if (format === 'yaml') {
14+
return this[8];
15+
}
16+
17+
return this[6];
18+
}
19+
}
20+
21+
const mediaTypes = new AsyncAPIMediaTypes(
22+
'application/vnd.aai.asyncapi;version=2.0.0',
23+
'application/vnd.aai.asyncapi+json;version=2.0.0',
24+
'application/vnd.aai.asyncapi+yaml;version=2.0.0',
25+
'application/vnd.aai.asyncapi;version=2.1.0',
26+
'application/vnd.aai.asyncapi+json;version=2.1.0',
27+
'application/vnd.aai.asyncapi+yaml;version=2.1.0',
28+
'application/vnd.aai.asyncapi;version=2.2.0',
29+
'application/vnd.aai.asyncapi+json;version=2.2.0',
30+
'application/vnd.aai.asyncapi+yaml;version=2.2.0',
31+
);
32+
33+
export default mediaTypes;

packages/apidom-ns-asyncapi-2/src/refractor/plugins/replace-empty-element.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
isArrayElement,
1010
} from '@swagger-api/apidom-core';
1111

12+
import mediaTypes from '../../media-types';
1213
/**
1314
* AsyncApi 2.0.0 | 2.1.0 | 2.2.0 specification elements.
1415
*/
@@ -261,23 +262,9 @@ const schema = {
261262
payload(...args: any[]) {
262263
// @ts-ignore
263264
const { context: messageElement } = this;
264-
const supportedSchemaFormats = [
265-
'application/vnd.aai.asyncapi;version=2.0.0',
266-
'application/vnd.aai.asyncapi+json;version=2.0.0',
267-
'application/vnd.aai.asyncapi+yaml;version=2.0.0',
268-
'application/vnd.aai.asyncapi;version=2.1.0',
269-
'application/vnd.aai.asyncapi+json;version=2.1.0',
270-
'application/vnd.aai.asyncapi+yaml;version=2.1.0',
271-
'application/vnd.aai.asyncapi;version=2.2.0',
272-
'application/vnd.aai.asyncapi+json;version=2.2.0',
273-
'application/vnd.aai.asyncapi+yaml;version=2.2.0',
274-
];
275-
const schemaFormat = defaultTo(
276-
'application/vnd.aai.asyncapi;version=2.2.0',
277-
messageElement.schemaFormat?.toValue(),
278-
);
265+
const schemaFormat = defaultTo(mediaTypes.latest(), messageElement.schemaFormat?.toValue());
279266

280-
if (supportedSchemaFormats.includes(schemaFormat)) {
267+
if (mediaTypes.includes(schemaFormat)) {
281268
return new SchemaElement(...args);
282269
}
283270

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

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import stampit from 'stampit';
22
import { always, defaultTo } from 'ramda';
33
import { ObjectElement, isObjectElement, Element } from '@swagger-api/apidom-core';
44

5+
import mediaTypes from '../../../../media-types';
56
import MessageElement from '../../../../elements/Message';
67
import FallbackVisitor from '../../FallbackVisitor';
78
import FixedFieldsVisitor from '../../generics/FixedFieldsVisitor';
@@ -17,20 +18,7 @@ const MessageVisitor = stampit(FixedFieldsVisitor, FallbackVisitor, {
1718
},
1819
methods: {
1920
refractPayload(schemaFormat: string, payload: Element) {
20-
if (
21-
[
22-
'application/vnd.aai.asyncapi;version=2.0.0',
23-
'application/vnd.aai.asyncapi+json;version=2.0.0',
24-
'application/vnd.aai.asyncapi+yaml;version=2.0.0',
25-
'application/vnd.aai.asyncapi;version=2.1.0',
26-
'application/vnd.aai.asyncapi+json;version=2.1.0',
27-
'application/vnd.aai.asyncapi+yaml;version=2.1.0',
28-
'application/vnd.aai.asyncapi;version=2.2.0',
29-
'application/vnd.aai.asyncapi+json;version=2.2.0',
30-
'application/vnd.aai.asyncapi+yaml;version=2.2.0',
31-
].includes(schemaFormat) &&
32-
isObjectElement(payload)
33-
) {
21+
if (isObjectElement(payload) && mediaTypes.includes(schemaFormat)) {
3422
this.element.payload = this.toRefractedElement(['document', 'objects', 'Schema'], payload);
3523
}
3624
},
@@ -49,7 +37,7 @@ const MessageVisitor = stampit(FixedFieldsVisitor, FallbackVisitor, {
4937
} else {
5038
// refract payload according to `schemaFormat`
5139
const schemaFormat = defaultTo(
52-
'application/vnd.aai.asyncapi;version=2.2.0',
40+
mediaTypes.latest(),
5341
objectElement.get('schemaFormat')?.toValue(),
5442
);
5543
this.refractPayload(schemaFormat, payload);

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11497,7 +11497,7 @@ exports[`refractor given generic ApiDOM object in AsyncApi 2.1.0 shape should re
1149711497
},
1149811498
"value": {
1149911499
"element": "string",
11500-
"content": "application/vnd.aai.asyncapi;version=2.0.0"
11500+
"content": "application/vnd.aai.asyncapi;version=2.1.0"
1150111501
}
1150211502
}
1150311503
},
@@ -12397,7 +12397,7 @@ exports[`refractor given generic ApiDOM object in AsyncApi 2.1.0 shape should re
1239712397
},
1239812398
"value": {
1239912399
"element": "string",
12400-
"content": "application/vnd.aai.asyncapi;version=2.0.0"
12400+
"content": "application/vnd.aai.asyncapi;version=2.1.0"
1240112401
}
1240212402
}
1240312403
},
@@ -19647,7 +19647,7 @@ exports[`refractor given generic ApiDOM object in AsyncApi 2.2.0 shape should re
1964719647
},
1964819648
"value": {
1964919649
"element": "string",
19650-
"content": "application/vnd.aai.asyncapi;version=2.0.0"
19650+
"content": "application/vnd.aai.asyncapi;version=2.2.0"
1965119651
}
1965219652
}
1965319653
},
@@ -20630,7 +20630,7 @@ exports[`refractor given generic ApiDOM object in AsyncApi 2.2.0 shape should re
2063020630
},
2063120631
"value": {
2063220632
"element": "string",
20633-
"content": "application/vnd.aai.asyncapi;version=2.0.0"
20633+
"content": "application/vnd.aai.asyncapi;version=2.2.0"
2063420634
}
2063520635
}
2063620636
},

packages/apidom-ns-asyncapi-2/test/refractor/fixtures/asyncapi-2-1-0.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
"description": "correlation id description",
128128
"location": "http://asyncapi.com/"
129129
},
130-
"schemaFormat": "application/vnd.aai.asyncapi;version=2.0.0",
130+
"schemaFormat": "application/vnd.aai.asyncapi;version=2.1.0",
131131
"contentType": "application/json",
132132
"name": "name of the message",
133133
"title": "title of the message",
@@ -176,7 +176,7 @@
176176
"description": "correlation id description",
177177
"location": "http://asyncapi.com/"
178178
},
179-
"schemaFormat": "application/vnd.aai.asyncapi;version=2.0.0",
179+
"schemaFormat": "application/vnd.aai.asyncapi;version=2.1.0",
180180
"contentType": "application/json",
181181
"name": "name of the message trait",
182182
"title": "title of the message trait",

packages/apidom-ns-asyncapi-2/test/refractor/fixtures/asyncapi-2-2-0.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130
"description": "correlation id description",
131131
"location": "http://asyncapi.com/"
132132
},
133-
"schemaFormat": "application/vnd.aai.asyncapi;version=2.0.0",
133+
"schemaFormat": "application/vnd.aai.asyncapi;version=2.2.0",
134134
"contentType": "application/json",
135135
"name": "name of the message",
136136
"title": "title of the message",
@@ -183,7 +183,7 @@
183183
"description": "correlation id description",
184184
"location": "http://asyncapi.com/"
185185
},
186-
"schemaFormat": "application/vnd.aai.asyncapi;version=2.0.0",
186+
"schemaFormat": "application/vnd.aai.asyncapi;version=2.2.0",
187187
"contentType": "application/json",
188188
"name": "name of the message trait",
189189
"title": "title of the message trait",

packages/apidom-parser-adapter-asyncapi-json-2/src/adapter.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import { propOr, omit } from 'ramda';
22
import { isNotUndefined } from 'ramda-adjunct';
33
import { ParseResultElement, createNamespace } from '@swagger-api/apidom-core';
44
import { parse as parseJson } from '@swagger-api/apidom-parser-adapter-json';
5-
import asyncApiNamespace, { AsyncApi2Element } from '@swagger-api/apidom-ns-asyncapi-2';
5+
import asyncApiNamespace, {
6+
AsyncApi2Element,
7+
mediaTypes,
8+
AsyncAPIMediaTypes,
9+
} from '@swagger-api/apidom-ns-asyncapi-2';
610

7-
export const mediaTypes = [
8-
'application/vnd.aai.asyncapi;version=2.0.0',
9-
'application/vnd.aai.asyncapi+json;version=2.0.0',
10-
'application/vnd.aai.asyncapi;version=2.1.0',
11-
'application/vnd.aai.asyncapi+json;version=2.1.0',
12-
'application/vnd.aai.asyncapi;version=2.2.0',
13-
'application/vnd.aai.asyncapi+json;version=2.2.0',
14-
];
11+
const jsonMediaTypes = new AsyncAPIMediaTypes(
12+
...mediaTypes.forFormat('generic'),
13+
...mediaTypes.forFormat('json'),
14+
);
15+
16+
export { jsonMediaTypes as mediaTypes };
1517

1618
export const detect = (source: string): boolean =>
1719
!!source.match(/(["']?)asyncapi\1\s*:\s*(["']?)2\.\d+\.\d+\2/g);

packages/apidom-parser-adapter-asyncapi-yaml-2/src/adapter.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import { omit, propOr } from 'ramda';
22
import { isNotUndefined } from 'ramda-adjunct';
33
import { ParseResultElement, createNamespace } from '@swagger-api/apidom-core';
44
import { parse as parseYaml } from '@swagger-api/apidom-parser-adapter-yaml-1-2';
5-
import asyncApiNamespace, { AsyncApi2Element } from '@swagger-api/apidom-ns-asyncapi-2';
5+
import asyncApiNamespace, {
6+
AsyncApi2Element,
7+
mediaTypes,
8+
AsyncAPIMediaTypes,
9+
} from '@swagger-api/apidom-ns-asyncapi-2';
610

7-
export const mediaTypes = [
8-
'application/vnd.aai.asyncapi;version=2.0.0',
9-
'application/vnd.aai.asyncapi+yaml;version=2.0.0',
10-
'application/vnd.aai.asyncapi;version=2.1.0',
11-
'application/vnd.aai.asyncapi+yaml;version=2.1.0',
12-
'application/vnd.aai.asyncapi;version=2.2.0',
13-
'application/vnd.aai.asyncapi+yaml;version=2.2.0',
14-
];
11+
const yamlMediaTypes = new AsyncAPIMediaTypes(
12+
...mediaTypes.forFormat('generic'),
13+
...mediaTypes.forFormat('yaml'),
14+
);
15+
16+
export { yamlMediaTypes as mediaTypes };
1517

1618
export const detect = (source: string): boolean =>
1719
!!source.match(/(["']?)asyncapi\1\s*:\s*(["']?)2\.\d+\.\d+\2/g);

packages/apidom-playground/src/playground/components/left-pane/EditorControls.jsx

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const EditorControls = () => {
3333
const canDereference = useSystemSelector('playground', 'selectCanDereference');
3434
const source = useSystemSelector('playground', 'selectSource');
3535
const apiDOM = useSystemSelector('playground', 'selectApiDOM');
36+
const mediaTypes = useSystemSelector('playground', 'selectMediaTypes');
3637
const setMediaType = useSystemActionCreatorBound('playground', 'setMediaType');
3738
const setBaseURI = useSystemActionCreatorBound('playground', 'setBaseURI');
3839
const parseSource = useSystemActionCreatorBound('playground', 'parseSource');
@@ -103,33 +104,11 @@ const EditorControls = () => {
103104
<MenuItem value="application/vnd.oai.openapi+yaml;version=3.1.0">
104105
application/vnd.oai.openapi+yaml;version=3.1.0
105106
</MenuItem>
106-
<MenuItem value="application/vnd.aai.asyncapi;version=2.0.0">
107-
application/vnd.aai.asyncapi;version=2.0.0
108-
</MenuItem>
109-
<MenuItem value="application/vnd.aai.asyncapi+json;version=2.0.0">
110-
application/vnd.aai.asyncapi+json;version=2.0.0
111-
</MenuItem>
112-
<MenuItem value="application/vnd.aai.asyncapi+yaml;version=2.0.0">
113-
application/vnd.aai.asyncapi+yaml;version=2.0.0
114-
</MenuItem>
115-
<MenuItem value="application/vnd.aai.asyncapi;version=2.1.0">
116-
application/vnd.aai.asyncapi;version=2.1.0
117-
</MenuItem>
118-
<MenuItem value="application/vnd.aai.asyncapi+json;version=2.1.0">
119-
application/vnd.aai.asyncapi+json;version=2.1.0
120-
</MenuItem>
121-
<MenuItem value="application/vnd.aai.asyncapi+yaml;version=2.1.0">
122-
application/vnd.aai.asyncapi+yaml;version=2.1.0
123-
</MenuItem>
124-
<MenuItem value="application/vnd.aai.asyncapi;version=2.1.0">
125-
application/vnd.aai.asyncapi;version=2.2.0
126-
</MenuItem>
127-
<MenuItem value="application/vnd.aai.asyncapi+json;version=2.1.0">
128-
application/vnd.aai.asyncapi+json;version=2.2.0
129-
</MenuItem>
130-
<MenuItem value="application/vnd.aai.asyncapi+yaml;version=2.1.0">
131-
application/vnd.aai.asyncapi+yaml;version=2.2.0
132-
</MenuItem>
107+
{mediaTypes.map((medType) => (
108+
<MenuItem key={medType} value={medType}>
109+
{medType}
110+
</MenuItem>
111+
))}
133112
</Select>
134113
</FormControl>
135114
</Grid>

packages/apidom-playground/src/playground/plugin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
selectCanParse,
2929
selectCanResolve,
3030
selectCanDereference,
31+
selectMediaTypes,
3132
} from './selectors.js';
3233
import AppBar from './components/AppBar.jsx';
3334
import Backdrop from './components/Backdrop.jsx';
@@ -97,6 +98,7 @@ const ApiDOMPlaygroundPlugin = () => ({
9798
selectCanParse,
9899
selectCanResolve,
99100
selectCanDereference,
101+
selectMediaTypes,
100102
},
101103
},
102104
},

packages/apidom-playground/src/playground/selectors.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { from, traverse, createNamespace, sexprs, toValue } from '@swagger-api/a
44
/* eslint-disable camelcase */
55
import openApi3_1NsPlugin from '@swagger-api/apidom-ns-openapi-3-1';
66
/* eslint-enable */
7-
import asyncApi2NsPlugin from '@swagger-api/apidom-ns-asyncapi-2';
7+
import asyncApi2NsPlugin, {
8+
mediaTypes as asyncApi2MediaTypes,
9+
} from '@swagger-api/apidom-ns-asyncapi-2';
810

911
export const selectSource = (state) => state.source;
1012

@@ -31,7 +33,7 @@ export const selectApiDOMNamespace = createSelector(selectMediaType, (mediaType)
3133
if (mediaType.includes('vnd.oai.openapi')) {
3234
return createNamespace(openApi3_1NsPlugin);
3335
}
34-
if (mediaType.includes('vnd.aai.asyncapi')) {
36+
if (asyncApi2MediaTypes.includes(mediaType)) {
3537
return createNamespace(asyncApi2NsPlugin);
3638
}
3739
return createNamespace();
@@ -99,3 +101,8 @@ export const selectCanDereference = createSelector(
99101
(baseURI, apiDOM, mediaType) =>
100102
isNonEmptyString(baseURI) && isNonEmptyString(apiDOM) && isNonEmptyString(mediaType)
101103
);
104+
105+
export const selectMediaTypes = (() => {
106+
const allMediaTypes = [...asyncApi2MediaTypes];
107+
return () => allMediaTypes;
108+
})();

packages/apidom-reference/src/dereference/strategies/asyncapi-2/index.ts

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import asyncApi2Namespace, {
55
getNodeType,
66
isAsyncApi2Element,
77
keyMap,
8+
mediaTypes,
89
} from '@swagger-api/apidom-ns-asyncapi-2';
910

1011
import DereferenceStrategy from '../DereferenceStrategy';
@@ -30,17 +31,7 @@ const AsyncApi2DereferenceStrategy: stampit.Stamp<IDereferenceStrategy> = stampi
3031
canDereference(file: IFile): boolean {
3132
// assert by media type
3233
if (file.mediaType !== 'text/plain') {
33-
return [
34-
'application/vnd.aai.asyncapi;version=2.0.0',
35-
'application/vnd.aai.asyncapi+json;version=2.0.0',
36-
'application/vnd.aai.asyncapi+yaml;version=2.0.0',
37-
'application/vnd.aai.asyncapi;version=2.1.0',
38-
'application/vnd.aai.asyncapi+json;version=2.1.0',
39-
'application/vnd.aai.asyncapi+yaml;version=2.1.0',
40-
'application/vnd.aai.asyncapi;version=2.2.0',
41-
'application/vnd.aai.asyncapi+json;version=2.2.0',
42-
'application/vnd.aai.asyncapi+yaml;version=2.2.0',
43-
].includes(file.mediaType);
34+
return mediaTypes.includes(file.mediaType);
4435
}
4536

4637
// assert by inspecting ApiDOM

0 commit comments

Comments
 (0)