Skip to content

Commit

Permalink
feat(reference): apply dereferencing architecture 2.0 to OpenAPI 2.0 (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
char0n committed Mar 14, 2024
1 parent bbb9a25 commit 63a41d4
Show file tree
Hide file tree
Showing 8 changed files with 523 additions and 269 deletions.
@@ -1,5 +1,4 @@
import stampit from 'stampit';
import { propEq } from 'ramda';
import { Element, isElement, cloneDeep, visit } from '@swagger-api/apidom-core';

import DereferenceStrategy from '../DereferenceStrategy';
Expand Down Expand Up @@ -38,7 +37,7 @@ const ApiDOMDereferenceStrategy: stampit.Stamp<IDereferenceStrategy> = stampit(
refSet.add(reference);
} else {
// pre-computed refSet was provided as configuration option
reference = refSet.find(propEq(file.uri, 'uri'));
reference = refSet.find((ref) => ref.uri === file.uri);
}

/**
Expand Down
@@ -1,6 +1,5 @@
import stampit from 'stampit';
import { defaultTo, propEq } from 'ramda';
import { createNamespace, visit, Element } from '@swagger-api/apidom-core';
import { createNamespace, visit, Element, cloneDeep } from '@swagger-api/apidom-core';
import openApi2Namespace, {
getNodeType,
isSwaggerElement,
Expand Down Expand Up @@ -40,15 +39,39 @@ const OpenApi2DereferenceStrategy: stampit.Stamp<IDereferenceStrategy> = stampit

async dereference(file: IFile, options: IReferenceOptions): Promise<Element> {
const namespace = createNamespace(openApi2Namespace);
const refSet = defaultTo(ReferenceSet(), options.dereference.refSet);
const refSet = options.dereference.refSet ?? ReferenceSet();
let reference;

if (!refSet.has(file.uri)) {
reference = Reference({ uri: file.uri, value: file.parseResult });
refSet.add(reference);
} else {
// pre-computed refSet was provided as configuration option
reference = refSet.find(propEq(file.uri, 'uri'));
reference = refSet.find((ref) => ref.uri === file.uri);
}

/**
* Clone refSet due the dereferencing process being mutable.
* We don't want to mutate the original refSet and the references.
*/
if (options.dereference.immutable) {
const immutableRefs = refSet.refs.map((ref) =>
Reference({
...ref,
uri: `immutable://${ref.uri}`,
}),
);
const mutableRefs = refSet.refs.map((ref) =>
Reference({
...ref,
value: cloneDeep(ref.value),
}),
);

refSet.clean();
mutableRefs.forEach((ref) => refSet.add(ref));
immutableRefs.forEach((ref) => refSet.add(ref));
reference = refSet.find((ref) => ref.uri === file.uri);
}

const visitor = OpenApi2DereferenceVisitor({ reference, namespace, options });
Expand All @@ -57,12 +80,27 @@ const OpenApi2DereferenceStrategy: stampit.Stamp<IDereferenceStrategy> = stampit
nodeTypeGetter: getNodeType,
});

/**
* Release all memory if this refSet was not provided as an configuration option.
* If provided as configuration option, then provider is responsible for cleanup.
*/
if (options.dereference.refSet === null) {
/**
* Release all memory if this refSet was not provided as a configuration option.
* If provided as configuration option, then provider is responsible for cleanup.
*/
refSet.clean();
} else if (options.dereference.immutable) {
/**
* If immutable option is set, then we need to remove mutable refs from the refSet.
*/
const immutableRefs = refSet.refs
.filter((ref) => ref.uri.startsWith('immutable://'))
.map((ref) =>
Reference({
...ref,
uri: ref.uri.replace(/^immutable:\/\//, ''),
}),
);

refSet.clean();
immutableRefs.forEach((ref) => refSet.add(ref));
}

return dereferencedElement;
Expand Down

0 comments on commit 63a41d4

Please sign in to comment.