Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const parse = async (

if (isNotUndefined(firstResultElement)) {
const asyncApiElement = AsyncApi2_0Element.refract(firstResultElement, refractorOpts);
asyncApiElement.classes.push('result');
parseResultElement = transclude(firstResultElement, asyncApiElement, parseResultElement);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const parse = async (

if (isNotUndefined(firstResultElement)) {
const asyncApiElement = AsyncApi2_0Element.refract(firstResultElement, refractorOpts);
asyncApiElement.classes.push('result');
parseResultElement = transclude(firstResultElement, asyncApiElement, parseResultElement);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const parse = async (

if (isNotUndefined(firstResultElement)) {
const openApiElement = OpenApi3_1Element.refract(firstResultElement, refractorOpts);
openApiElement.classes.push('result');
parseResultElement = transclude(firstResultElement, openApiElement, parseResultElement);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const parse = async (

if (isNotUndefined(firstResultElement)) {
const openApiElement = OpenApi3_1Element.refract(firstResultElement, refractorOpts);
openApiElement.classes.push('result');
parseResultElement = transclude(firstResultElement, openApiElement, parseResultElement);
}

Expand Down
8 changes: 8 additions & 0 deletions apidom/packages/apidom-reference/src/ReferenceSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ const ReferenceSet: stampit.Stamp<IReferenceSet> = stampit({
*values() {
yield* this.refs;
},

clean() {
this.refs.forEach((ref: IReference) => {
// eslint-disable-next-line no-param-reassign
ref.refSet = null;
});
this.refs = [];
},
},
});

Expand Down
130 changes: 0 additions & 130 deletions apidom/packages/apidom-reference/src/dereference.ts

This file was deleted.

57 changes: 57 additions & 0 deletions apidom/packages/apidom-reference/src/dereference/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { isEmpty } from 'ramda';
import { Element, ParseResultElement } from 'apidom';

import File from '../util/File';
import * as plugins from '../util/plugins';
import { UnmatchedResolveStrategyError } from '../util/errors';
import DereferenceError from '../util/errors/DereferenceError';
import { ReferenceOptions as IReferenceOptions } from '../types';
import parse from '../parse';
import { merge as mergeOptions } from '../options/util';

/**
* Dereferences ApiDOM with all it's external references.
*/
export const dereferenceApiDOM = async <T extends Element>(
element: T,
options: IReferenceOptions,
): Promise<T> => {
const file = File({
uri: options.resolve.baseURI,
parseResult: element,
mediaType: options.parse.mediaType,
});

const dereferenceStrategies = plugins.filter(
'canDereference',
file,
options.dereference.strategies,
);

// we couldn't find any dereference for this File
if (isEmpty(dereferenceStrategies)) {
throw new UnmatchedResolveStrategyError(file.uri);
}

try {
const { result } = await plugins.run('dereference', [file, options], dereferenceStrategies);
return result;
} catch (error) {
throw new DereferenceError(`Error while dereferencing file "${file.uri}"`, error);
}
};

/**
* Dereferences a file with all it's external references.
*/
const dereference = async (
uri: string,
options: IReferenceOptions,
): Promise<ParseResultElement> => {
const parseResult = await parse(uri, options);
const mergedOptions = mergeOptions(options, { resolve: { baseURI: uri } });

return dereferenceApiDOM(parseResult, mergedOptions);
};

export default dereference;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import stampit from 'stampit';

import { DereferenceStrategy as IDereferenceStrategy } from '../../types';
import { NotImplementedError } from '../../util/errors';

const DereferenceStrategy: stampit.Stamp<IDereferenceStrategy> = stampit({
methods: {
canDereference() {
return false;
},

async dereference(): Promise<never> {
throw new NotImplementedError();
},
},
});

export default DereferenceStrategy;
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import stampit from 'stampit';
import { createNamespace, visit, Element } from 'apidom';
import openApi3_1Namespace, {
getNodeType,
isOpenApi3_1Element,
keyMap,
} from 'apidom-ns-openapi-3-1';

import DereferenceStrategy from '../DereferenceStrategy';
import {
DereferenceStrategy as IDereferenceStrategy,
File as IFile,
ReferenceOptions as IReferenceOptions,
} from '../../../types';
import Reference from '../../../Reference';
import ReferenceSet from '../../../ReferenceSet';
import OpenApi3_1DereferenceVisitor from './visitor';

// @ts-ignore
const visitAsync = visit[Symbol.for('nodejs.util.promisify.custom')];

const OpenApi3_1DereferenceStrategy: stampit.Stamp<IDereferenceStrategy> = stampit(
DereferenceStrategy,
{
methods: {
canDereference(file: IFile): boolean {
// assert by media type
if (file.mediaType !== 'text/plain') {
return [
'application/vnd.oai.openapi;version=3.1.0',
'application/vnd.oai.openapi+json;version=3.1.0',
'application/vnd.oai.openapi+yaml;version=3.1.0',
].includes(file.mediaType);
}

// assert by inspecting ApiDOM
return isOpenApi3_1Element(file.parseResult?.api);
},

async dereference(file: IFile, options: IReferenceOptions): Promise<Element> {
const namespace = createNamespace(openApi3_1Namespace);
const reference = Reference({ uri: file.uri, value: file.parseResult });
const visitor = OpenApi3_1DereferenceVisitor({ reference, namespace, options });
const refSet = ReferenceSet();
refSet.add(reference);

const dereferencedElement = await visitAsync(refSet.rootRef.value, visitor, {
keyMap,
nodeTypeGetter: getNodeType,
});

// release all memory
refSet.clean();

return dereferencedElement;
},
},
},
);

export default OpenApi3_1DereferenceStrategy;
Loading