diff --git a/apidom/packages/apidom-ls/src/parser-factory.ts b/apidom/packages/apidom-ls/src/parser-factory.ts index 842e772943..2abee3fe09 100644 --- a/apidom/packages/apidom-ls/src/parser-factory.ts +++ b/apidom/packages/apidom-ls/src/parser-factory.ts @@ -10,15 +10,8 @@ import * as openapi3_1Adapter_Yaml from 'apidom-parser-adapter-openapi-yaml-3-1' // @ts-ignore import * as asyncapi2_0Adapter_Yaml from 'apidom-parser-adapter-asyncapi-yaml-2-0'; -// @ts-ignore -import { ParseResultElement } from 'apidom'; - import { TextDocument } from 'vscode-languageserver-textdocument'; -export interface Parser { - parse(source: string, options: ParserOptions): PromiseLike; -} - export interface ParserOptions { sourceMap?: boolean; specObj?: string; @@ -58,7 +51,7 @@ export function isJsonDoc(document: TextDocument | string): boolean { return jsonStart != null && JSON_ENDS[jsonStart[0]].test(text); } -export function getParser(document: TextDocument): Parser { +export function getParser(document: TextDocument): ApiDOMParser { const async = isAsyncDoc(document); const json = isJsonDoc(document); if (async && json) { diff --git a/apidom/packages/apidom-ls/test/openapi-json.ts b/apidom/packages/apidom-ls/test/openapi-json.ts index de6ba6bcd0..a0c8a49ddf 100644 --- a/apidom/packages/apidom-ls/test/openapi-json.ts +++ b/apidom/packages/apidom-ls/test/openapi-json.ts @@ -230,8 +230,13 @@ describe('apidom-ls', function () { // parser.use(asyncapi2_0Adapter); // eslint-disable-next-line @typescript-eslint/no-unused-vars const parseResult = await parser.parse(value, { sourceMap: true }); - addMetadataMapping(parseResult.api); - assert.deepEqual(parseResult.api.meta.get('metadataMap').toValue(), metadataMap); + if (parseResult.api !== undefined) { + addMetadataMapping(parseResult.api); + + assert.deepEqual(parseResult.api.meta.get('metadataMap').toValue(), metadataMap); + } else { + assert.fail('parserResult.api should return OpenApi Element'); + } }); }); diff --git a/apidom/packages/apidom-parser/src/parser.ts b/apidom/packages/apidom-parser/src/parser.ts index e0d4954c07..b7511311e6 100644 --- a/apidom/packages/apidom-parser/src/parser.ts +++ b/apidom/packages/apidom-parser/src/parser.ts @@ -3,12 +3,12 @@ import { head } from 'ramda'; import { isArray, isFunction, isString, isUndefined } from 'ramda-adjunct'; import { ParseResultElement, Namespace } from 'apidom'; -interface ParserOptions { +interface ParserOptions extends Record { mediaType?: string; } type Detect = (source: string) => boolean; -type Parse = (source: string, options: ParserOptions) => ParseResultElement; +type Parse = (source: string, options: ParserOptions) => Promise; interface ApiDOMParserAdapter { detect?: Detect; @@ -17,7 +17,13 @@ interface ApiDOMParserAdapter { namespace: Namespace; } -const ApiDOMParser = stampit().init(function ApiDOMParser() { +interface ApiDOMParser { + use(adapter: ApiDOMParserAdapter): ApiDOMParser; + findNamespace(source: string, options?: ParserOptions): Namespace; + parse(source: string, options?: ParserOptions): Promise; +} + +const ApiDOMParser: stampit.Stamp = stampit().init(function ApiDOMParser() { const adapters: ApiDOMParserAdapter[] = []; const detectAdapterCandidates = (source: string) => { @@ -45,7 +51,7 @@ const ApiDOMParser = stampit().init(function ApiDOMParser() { return this; }; - this.namespace = function namespace(source: string, options: ParserOptions = {}) { + this.findNamespace = function findNamespace(source: string, options: ParserOptions = {}) { const adapter = findAdapter(source, options.mediaType); return adapter?.namespace; diff --git a/experiments/apidom-playground/src/features/app/file-importer/components/FileImporter.jsx b/experiments/apidom-playground/src/features/app/file-importer/components/FileImporter.jsx index 4d41a50fa5..ba4362e352 100644 --- a/experiments/apidom-playground/src/features/app/file-importer/components/FileImporter.jsx +++ b/experiments/apidom-playground/src/features/app/file-importer/components/FileImporter.jsx @@ -7,7 +7,7 @@ import SpeedDialAction from '@material-ui/lab/SpeedDialAction'; import DescriptionIcon from '@material-ui/icons/Description'; import AttachFileIcon from '@material-ui/icons/AttachFile'; import ImportExportIcon from '@material-ui/icons/ImportExport'; -import { setSource } from 'features/app/slice'; +import { setSource, setBaseURI } from 'features/app/slice'; import UrlImportDialog from 'features/app/file-importer/url-import-dialog/components/UrlImportDialog'; const useStyles = makeStyles((theme) => ({ @@ -46,6 +46,7 @@ const FileImporter = () => { const reader = new FileReader(); const onloadend = (onloadendEvent) => { const source = onloadendEvent.target.result; + dispatch(setBaseURI(window.location.href)); dispatch(setSource(source)); }; diff --git a/experiments/apidom-playground/src/features/app/left-pane/editor-controls/components/EditorControls.jsx b/experiments/apidom-playground/src/features/app/left-pane/editor-controls/components/EditorControls.jsx index dc087aa5fa..483d04c46d 100644 --- a/experiments/apidom-playground/src/features/app/left-pane/editor-controls/components/EditorControls.jsx +++ b/experiments/apidom-playground/src/features/app/left-pane/editor-controls/components/EditorControls.jsx @@ -63,7 +63,7 @@ const EditorControls = () => { dispatch(parseSource({ source, mediaType })); }; const handleApiDOMResolve = () => { - dispatch(resolveApiDOM({ apiDOM, mediaType, baseURI })); + dispatch(resolveApiDOM({ source, apiDOM, mediaType, baseURI })); }; return ( diff --git a/experiments/apidom-playground/src/features/app/slice.js b/experiments/apidom-playground/src/features/app/slice.js index eee672c86d..f805bfa382 100644 --- a/experiments/apidom-playground/src/features/app/slice.js +++ b/experiments/apidom-playground/src/features/app/slice.js @@ -67,7 +67,7 @@ export const importURL = createAsyncThunk('importURLStatus', async (url) => { }); export const parseSource = createAsyncThunk('parseSourceStatus', async ({ source, mediaType }) => { - const namespace = parser.namespace(source, { sourceMap: true, mediaType }); + const namespace = parser.findNamespace(source, { sourceMap: true, mediaType }); const parseResult = await parser.parse(source, { sourceMap: true, mediaType }); const refract = dehydrate(parseResult, namespace); @@ -76,8 +76,8 @@ export const parseSource = createAsyncThunk('parseSourceStatus', async ({ source export const resolveApiDOM = createAsyncThunk( 'resolveApiDOMStatus', - async ({ apiDOM, mediaType, baseURI }) => { - const namespace = parser.namespace('', { mediaType }); + async ({ source, apiDOM, mediaType, baseURI }) => { + const namespace = parser.findNamespace(source, { mediaType }); const parseResult = from(apiDOM, namespace); return resolveApiDOMReferences(parseResult, { parse: { mediaType }, resolve: { baseURI } });