Skip to content

Commit f954835

Browse files
authored
refactor(openapi): unify how we work with media types (#1146)
Refs #1130
1 parent 90a76fd commit f954835

File tree

31 files changed

+316
-268
lines changed

31 files changed

+316
-268
lines changed

packages/apidom-core/test/traversal/findAtOffset.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { assert } from 'chai';
22
import ApiDOMParser from '@swagger-api/apidom-parser';
3+
import { mediaTypes } from '@swagger-api/apidom-ns-openapi-3-1';
34
import * as openapi3_1Adapter from '@swagger-api/apidom-parser-adapter-openapi-json-3-1';
45

56
import { findAtOffset } from '../../src';
@@ -14,7 +15,7 @@ describe('traversal', function () {
1415
beforeEach(async function () {
1516
parseResult = await parser.parse('{"prop": "val"}', {
1617
sourceMap: true,
17-
mediaType: 'application/vnd.oai.openapi+json;version=3.1.0',
18+
mediaType: mediaTypes.latest('json'),
1819
});
1920
});
2021

packages/apidom-ns-openapi-3-1/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, OpenAPIMediaTypes } from './media-types';
17+
1618
// eslint-disable-next-line no-restricted-exports
1719
export { default } from './namespace';
1820

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

packages/apidom-parser-adapter-openapi-json-3-1/src/adapter.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +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 openApiNamespace, { OpenApi3_1Element } from '@swagger-api/apidom-ns-openapi-3-1';
5+
import openApiNamespace, {
6+
OpenApi3_1Element,
7+
mediaTypes,
8+
OpenAPIMediaTypes,
9+
} from '@swagger-api/apidom-ns-openapi-3-1';
610

7-
export const mediaTypes = [
8-
'application/vnd.oai.openapi;version=3.1.0',
9-
'application/vnd.oai.openapi+json;version=3.1.0',
10-
];
11+
const jsonMediaTypes = new OpenAPIMediaTypes(
12+
...mediaTypes.forFormat('generic'),
13+
...mediaTypes.forFormat('json'),
14+
);
15+
16+
export { jsonMediaTypes as mediaTypes };
1117

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

packages/apidom-parser-adapter-openapi-yaml-3-1/src/adapter.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +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 parseYaml } from '@swagger-api/apidom-parser-adapter-yaml-1-2';
5-
import openApiNamespace, { OpenApi3_1Element } from '@swagger-api/apidom-ns-openapi-3-1';
5+
import openApiNamespace, {
6+
OpenApi3_1Element,
7+
mediaTypes,
8+
OpenAPIMediaTypes,
9+
} from '@swagger-api/apidom-ns-openapi-3-1';
610

7-
export const mediaTypes = [
8-
'application/vnd.oai.openapi;version=3.1.0',
9-
'application/vnd.oai.openapi+yaml;version=3.1.0',
10-
];
11+
const yamlMediaTypes = new OpenAPIMediaTypes(
12+
...mediaTypes.forFormat('generic'),
13+
...mediaTypes.forFormat('yaml'),
14+
);
15+
16+
export { yamlMediaTypes as mediaTypes };
1117

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

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,6 @@ const EditorControls = () => {
9595
<MenuItem value="application/json">application/json</MenuItem>
9696
<MenuItem value="application/yaml">application/yaml</MenuItem>
9797
<MenuItem value="text/yaml">text/yaml</MenuItem>
98-
<MenuItem value="application/vnd.oai.openapi;version=3.1.0">
99-
application/vnd.oai.openapi;version=3.1.0
100-
</MenuItem>
101-
<MenuItem value="application/vnd.oai.openapi+json;version=3.1.0">
102-
application/vnd.oai.openapi+json;version=3.1.0
103-
</MenuItem>
104-
<MenuItem value="application/vnd.oai.openapi+yaml;version=3.1.0">
105-
application/vnd.oai.openapi+yaml;version=3.1.0
106-
</MenuItem>
10798
{mediaTypes.map((medType) => (
10899
<MenuItem key={medType} value={medType}>
109100
{medType}

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { createSelector } from 'swagger-adjust';
22
import { isEmptyString, isNonEmptyString, isNull } from 'ramda-adjunct';
33
import { from, traverse, createNamespace, sexprs, toValue } from '@swagger-api/apidom-core';
44
/* eslint-disable camelcase */
5-
import openApi3_1NsPlugin from '@swagger-api/apidom-ns-openapi-3-1';
6-
/* eslint-enable */
5+
import openApi3_1NsPlugin, {
6+
mediaTypes as openApi3_1MediaTypes,
7+
} from '@swagger-api/apidom-ns-openapi-3-1';
78
import asyncApi2NsPlugin, {
89
mediaTypes as asyncApi2MediaTypes,
910
} from '@swagger-api/apidom-ns-asyncapi-2';
@@ -30,7 +31,7 @@ export const selectApiDOMNamespace = createSelector(selectMediaType, (mediaType)
3031
if (isEmptyString(mediaType)) {
3132
return null;
3233
}
33-
if (mediaType.includes('vnd.oai.openapi')) {
34+
if (openApi3_1MediaTypes.includes(mediaType)) {
3435
return createNamespace(openApi3_1NsPlugin);
3536
}
3637
if (asyncApi2MediaTypes.includes(mediaType)) {
@@ -103,6 +104,7 @@ export const selectCanDereference = createSelector(
103104
);
104105

105106
export const selectMediaTypes = (() => {
106-
const allMediaTypes = [...asyncApi2MediaTypes];
107+
const allMediaTypes = [...openApi3_1MediaTypes, ...asyncApi2MediaTypes];
107108
return () => allMediaTypes;
108109
})();
110+
/* eslint-enable */

packages/apidom-reference/src/dereference/strategies/openapi-3-1/index.ts

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

1011
import DereferenceStrategy from '../DereferenceStrategy';
@@ -31,11 +32,7 @@ const OpenApi3_1DereferenceStrategy: stampit.Stamp<IDereferenceStrategy> = stamp
3132
canDereference(file: IFile): boolean {
3233
// assert by media type
3334
if (file.mediaType !== 'text/plain') {
34-
return [
35-
'application/vnd.oai.openapi;version=3.1.0',
36-
'application/vnd.oai.openapi+json;version=3.1.0',
37-
'application/vnd.oai.openapi+yaml;version=3.1.0',
38-
].includes(file.mediaType);
35+
return mediaTypes.includes(file.mediaType);
3936
}
4037

4138
// assert by inspecting ApiDOM

packages/apidom-reference/src/resolve/strategies/openapi-3-1/index.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import openApi3_1Namespace, {
44
getNodeType,
55
isOpenApi3_1Element,
66
keyMap,
7+
mediaTypes,
78
} from '@swagger-api/apidom-ns-openapi-3-1';
89

910
import ResolveStrategy from '../ResolveStrategy';
@@ -28,11 +29,7 @@ const OpenApi3_1ResolveStrategy: stampit.Stamp<IResolveStrategy> = stampit(Resol
2829
canResolve(file: IFile) {
2930
// assert by media type
3031
if (file.mediaType !== 'text/plain') {
31-
return [
32-
'application/vnd.oai.openapi;version=3.1.0',
33-
'application/vnd.oai.openapi+json;version=3.1.0',
34-
'application/vnd.oai.openapi+yaml;version=3.1.0',
35-
].includes(file.mediaType);
32+
return mediaTypes.includes(file.mediaType);
3633
}
3734

3835
// assert by inspecting ApiDOM

packages/apidom-reference/test/dereference/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { assert } from 'chai';
22
import path from 'path';
33
import { toValue } from '@swagger-api/apidom-core';
4+
import { mediaTypes } from '@swagger-api/apidom-ns-openapi-3-1';
45

56
import { dereference, dereferenceApiDOM, parse } from '../../src';
67
import { loadJsonFile } from '../helpers';
@@ -21,7 +22,7 @@ describe('dereference', function () {
2122
context('dereference', function () {
2223
specify('should dereference a file', async function () {
2324
const actual = await dereference(rootFilePath, {
24-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
25+
parse: { mediaType: mediaTypes.latest('json') },
2526
});
2627

2728
assert.deepEqual(toValue(actual), expected);
@@ -43,7 +44,7 @@ describe('dereference', function () {
4344

4445
specify('should dereference an ApiDOM fragment using CWD as baseURI', async function () {
4546
const fragment = await parse(rootFilePath, {
46-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
47+
parse: { mediaType: mediaTypes.latest('json') },
4748
});
4849
const actual = await dereferenceApiDOM(fragment);
4950

@@ -54,7 +55,7 @@ describe('dereference', function () {
5455
context('given fragment is instance of ParseResultElement', function () {
5556
specify('should dereference an ApiDOM fragment', async function () {
5657
const fragment = await parse(rootFilePath, {
57-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
58+
parse: { mediaType: mediaTypes.latest('json') },
5859
});
5960
const actual = await dereferenceApiDOM(fragment, { resolve: { baseURI: rootFilePath } });
6061

@@ -65,7 +66,7 @@ describe('dereference', function () {
6566
context("given fragment isn't instance of ParseResultElement", function () {
6667
specify('should dereference an ApiDOM fragment', async function () {
6768
const { api } = await parse(rootFilePath, {
68-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
69+
parse: { mediaType: mediaTypes.latest('json') },
6970
});
7071

7172
// @ts-ignore

packages/apidom-reference/test/dereference/strategies/openapi-3-1/callback-object/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path from 'path';
22
import { assert } from 'chai';
33
import { toValue } from '@swagger-api/apidom-core';
4+
import { mediaTypes } from '@swagger-api/apidom-ns-openapi-3-1';
45

56
import { loadJsonFile } from '../../../../helpers';
67
import { dereference } from '../../../../../src';
@@ -17,7 +18,7 @@ describe('dereference', function () {
1718
specify('should dereference', async function () {
1819
const rootFilePath = path.join(fixturePath, 'root.json');
1920
const actual = await dereference(rootFilePath, {
20-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
21+
parse: { mediaType: mediaTypes.latest('json') },
2122
});
2223
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
2324

@@ -31,7 +32,7 @@ describe('dereference', function () {
3132
specify('should dereference', async function () {
3233
const rootFilePath = path.join(fixturePath, 'root.json');
3334
const actual = await dereference(rootFilePath, {
34-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
35+
parse: { mediaType: mediaTypes.latest('json') },
3536
});
3637
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
3738

packages/apidom-reference/test/dereference/strategies/openapi-3-1/example-object/index.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path from 'path';
22
import { assert } from 'chai';
33
import { toValue } from '@swagger-api/apidom-core';
4+
import { mediaTypes } from '@swagger-api/apidom-ns-openapi-3-1';
45

56
import { loadJsonFile } from '../../../../helpers';
67
import { dereference } from '../../../../../src';
@@ -18,7 +19,7 @@ describe('dereference', function () {
1819
specify('should dereference', async function () {
1920
const rootFilePath = path.join(fixturePath, 'root.json');
2021
const actual = await dereference(rootFilePath, {
21-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
22+
parse: { mediaType: mediaTypes.latest('json') },
2223
});
2324
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
2425

@@ -32,7 +33,7 @@ describe('dereference', function () {
3233
specify('should dereference', async function () {
3334
const rootFilePath = path.join(fixturePath, 'root.json');
3435
const actual = await dereference(rootFilePath, {
35-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
36+
parse: { mediaType: mediaTypes.latest('json') },
3637
});
3738
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
3839

@@ -46,7 +47,7 @@ describe('dereference', function () {
4647
specify('should dereference', async function () {
4748
const rootFilePath = path.join(fixturePath, 'root.json');
4849
const actual = await dereference(rootFilePath, {
49-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
50+
parse: { mediaType: mediaTypes.latest('json') },
5051
});
5152
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
5253

@@ -61,7 +62,7 @@ describe('dereference', function () {
6162
specify('should dereference', async function () {
6263
const rootFilePath = path.join(fixturePath, 'root.json');
6364
const actual = await dereference(rootFilePath, {
64-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
65+
parse: { mediaType: mediaTypes.latest('json') },
6566
});
6667
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
6768

@@ -75,7 +76,7 @@ describe('dereference', function () {
7576
specify('should dereference', async function () {
7677
const rootFilePath = path.join(fixturePath, 'root.json');
7778
const actual = await dereference(rootFilePath, {
78-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
79+
parse: { mediaType: mediaTypes.latest('json') },
7980
});
8081
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
8182

@@ -89,7 +90,7 @@ describe('dereference', function () {
8990
specify('should dereference', async function () {
9091
const rootFilePath = path.join(fixturePath, 'root.json');
9192
const actual = await dereference(rootFilePath, {
92-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
93+
parse: { mediaType: mediaTypes.latest('json') },
9394
});
9495
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
9596

@@ -103,7 +104,7 @@ describe('dereference', function () {
103104
specify('should dereference', async function () {
104105
const rootFilePath = path.join(fixturePath, 'root.json');
105106
const actual = await dereference(rootFilePath, {
106-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
107+
parse: { mediaType: mediaTypes.latest('json') },
107108
});
108109
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
109110

@@ -117,7 +118,7 @@ describe('dereference', function () {
117118
specify('should dereference', async function () {
118119
const rootFilePath = path.join(fixturePath, 'root.json');
119120
const actual = await dereference(rootFilePath, {
120-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
121+
parse: { mediaType: mediaTypes.latest('json') },
121122
});
122123
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
123124

@@ -133,7 +134,7 @@ describe('dereference', function () {
133134

134135
try {
135136
await dereference(rootFilePath, {
136-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
137+
parse: { mediaType: mediaTypes.latest('json') },
137138
});
138139
assert.fail('should throw DereferenceError');
139140
} catch (e) {
@@ -148,7 +149,7 @@ describe('dereference', function () {
148149
specify('should not dereference', async function () {
149150
const rootFilePath = path.join(fixturePath, 'root.json');
150151
const actual = await dereference(rootFilePath, {
151-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
152+
parse: { mediaType: mediaTypes.latest('json') },
152153
resolve: { external: false },
153154
});
154155
const expected = loadJsonFile(path.join(fixturePath, 'dereferenced.json'));
@@ -165,7 +166,7 @@ describe('dereference', function () {
165166

166167
try {
167168
await dereference(rootFilePath, {
168-
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
169+
parse: { mediaType: mediaTypes.latest('json') },
169170
});
170171
assert.fail('should throw DereferenceError');
171172
} catch (error: any) {

0 commit comments

Comments
 (0)