Skip to content

Commit d1c29f3

Browse files
committed
fix(parser): fix sync/async inconsistencies
Closes #310
1 parent d5d444f commit d1c29f3

File tree

4 files changed

+25
-18
lines changed

4 files changed

+25
-18
lines changed

apidom/packages/apidom-parser/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const parser = ApiDOMParser();
4343
parser.use(jsonParserAdapter);
4444
parser.use(yamlParserAdapter);
4545

46-
const namespace = parser.findNamespace('{"prop", "value"}', { mediaType: 'application/json' });
46+
const namespace = await parser.findNamespace('{"prop", "value"}', { mediaType: 'application/json' });
4747
```
4848

4949
## Parsing

apidom/packages/apidom-parser/src/parser.ts

+18-11
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,20 @@ interface ApiDOMParser {
2626
const ApiDOMParser: stampit.Stamp<ApiDOMParser> = stampit().init(function ApiDOMParser() {
2727
const adapters: ApiDOMParserAdapter[] = [];
2828

29-
const detectAdapterCandidates = (source: string) => {
30-
return adapters.filter((adapter) => {
31-
if (!isFunction(adapter.detect)) return false;
29+
const detectAdapterCandidates = async (source: string) => {
30+
const candidates = [];
31+
32+
for (const adapter of adapters) {
33+
// eslint-disable-next-line no-await-in-loop
34+
if (isFunction(adapter.detect) && (await adapter.detect(source))) {
35+
candidates.push(adapter);
36+
}
37+
}
3238

33-
return adapter.detect(source);
34-
});
39+
return candidates;
3540
};
3641

37-
const findAdapter = (source: string, mediaType: string | undefined) => {
42+
const findAdapter = async (source: string, mediaType: string | undefined) => {
3843
if (isString(mediaType)) {
3944
return adapters.find((adapter) => {
4045
if (!isArray(adapter.mediaTypes)) return false;
@@ -43,25 +48,27 @@ const ApiDOMParser: stampit.Stamp<ApiDOMParser> = stampit().init(function ApiDOM
4348
});
4449
}
4550

46-
return head(detectAdapterCandidates(source));
51+
const candidates = await detectAdapterCandidates(source);
52+
53+
return head(candidates);
4754
};
4855

4956
this.use = function use(adapter: ApiDOMParserAdapter) {
5057
adapters.push(adapter);
5158
return this;
5259
};
5360

54-
this.findNamespace = function findNamespace(source: string, options: ParserOptions = {}) {
55-
const adapter = findAdapter(source, options.mediaType);
61+
this.findNamespace = async function findNamespace(source: string, options: ParserOptions = {}) {
62+
const adapter = await findAdapter(source, options.mediaType);
5663

5764
return adapter?.namespace;
5865
};
5966

6067
this.parse = async function parse(source: string, options: ParserOptions = {}) {
61-
const adapter = findAdapter(source, options.mediaType);
68+
const adapter = await findAdapter(source, options.mediaType);
6269

6370
if (isUndefined(adapter)) {
64-
return Promise.reject(new Error('Document did not match any registered parsers'));
71+
throw new Error('Document did not match any registered parsers');
6572
}
6673

6774
return adapter.parse(source, options);

experiments/apidom-playground/src/features/app/apidom.worker.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const parser = ApiDOMParser()
2525
/* eslint-disable */
2626
const service = {
2727
async parse(source, { mediaType }) {
28-
const namespace = parser.findNamespace(source, { sourceMap: true, mediaType });
28+
const namespace = await parser.findNamespace(source, { sourceMap: true, mediaType });
2929
const parseResult = await parser.parse(source, { sourceMap: true, mediaType });
3030
const refract = dehydrate(parseResult, namespace);
3131

@@ -38,14 +38,14 @@ const service = {
3838
},
3939

4040
async resolveApiDOM(apiDOM, { source, mediaType, baseURI }) {
41-
const namespace = parser.findNamespace(source, { mediaType });
41+
const namespace = await parser.findNamespace(source, { mediaType });
4242
const parseResult = from(apiDOM, namespace);
4343

4444
return resolveApiDOMReferences(parseResult, { parse: { mediaType }, resolve: { baseURI } });
4545
},
4646

4747
async dereferenceApiDOM(apiDOM, { source, mediaType, baseURI }) {
48-
const namespace = parser.findNamespace(source, { mediaType });
48+
const namespace = await parser.findNamespace(source, { mediaType });
4949
const parseResult = from(apiDOM, namespace);
5050
const dereferenced = await derefereceApiDOMReferences(parseResult.api, {
5151
parse: { mediaType },
@@ -56,8 +56,8 @@ const service = {
5656
return JSON.stringify(refract, undefined, 2);
5757
},
5858

59-
humanizeDereferenced(dereferenced, { source, mediaType }) {
60-
const namespace = parser.findNamespace(source, { mediaType });
59+
async humanizeDereferenced(dereferenced, { source, mediaType }) {
60+
const namespace = await parser.findNamespace(source, { mediaType });
6161
const element = from(dereferenced, namespace);
6262
const pojo = toValue(element, namespace);
6363

experiments/apidom-playground/src/features/app/slice.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export const dereferenceApiDOM = createAsyncThunk(
142142

143143
export const humanizeDereferencedApiDOM = createAsyncThunk(
144144
'humanizeDereferencedApiDOMStatus',
145-
({ source, mediaType, dereferenced }, { extra: { apiDOMService } }) => {
145+
async ({ source, mediaType, dereferenced }, { extra: { apiDOMService } }) => {
146146
return apiDOMService.humanizeDereferenced(dereferenced, { source, mediaType });
147147
}
148148
);

0 commit comments

Comments
 (0)