Skip to content

Commit

Permalink
feat(reference): add OpenAPI 2.0 resolve strategy
Browse files Browse the repository at this point in the history
Refs #3101
  • Loading branch information
char0n committed Nov 28, 2023
1 parent 222e3f0 commit 413ec46
Show file tree
Hide file tree
Showing 89 changed files with 1,510 additions and 2 deletions.
20 changes: 20 additions & 0 deletions packages/apidom-reference/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,21 @@ Supported media types:
'application/vnd.aai.asyncapi+yaml;version=2.6.0',
]
```

##### [openapi-2](https://github.com/swagger-api/apidom/tree/main/packages/apidom-reference/src/resolve/strategies/openapi-2)

External resolution strategy for understanding and resolving external dependencies of [OpenApi 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md) definitions.

Supported media types:

```js
[
'application/vnd.oai.openapi;version=2.0',
'application/vnd.oai.openapi+json;version=2.0',
'application/vnd.oai.openapi+yaml;version=2.0',
]
```

##### [openapi-3-0](https://github.com/swagger-api/apidom/tree/main/packages/apidom-reference/src/resolve/strategies/openapi-3-0)

External resolution strategy for understanding and resolving external dependencies of [OpenApi 3.0.x](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md) definitions.
Expand Down Expand Up @@ -1088,6 +1103,7 @@ returns `true` or until entire list of strategies is exhausted (throws error).

```js
[
OpenApi2ResolveStrategy(),
OpenApi3_0ResolveStrategy(),
OpenApi3_1ResolveStrategy(),
AsyncApi2ResolveStrategy(),
Expand All @@ -1100,10 +1116,12 @@ It's possible to **change** strategies **order globally** by mutating global `re
```js
import { options } from '@swagger-api/apidom-reference';
import AsyncApi2ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/asyncapi-2';
import OpenApi2ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/openapi-2';
import OpenApi3_0ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/openapi-3-0';
import OpenApi3_1ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/openapi-3-1';

options.resolve.strategies = [
OpenApi2ResolveStrategy(),
OpenApi3_0ResolveStrategy(),
OpenApi3_1ResolveStrategy(),
AsyncApi2ResolveStrategy(),
Expand All @@ -1115,6 +1133,7 @@ To **change** the strategies **order** on ad-hoc basis:
```js
import { resolve } from '@swagger-api/apidom-reference';
import AsyncApi2ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/asyncapi-2';
import OpenApi2ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/openapi-2';
import OpenApi3_0ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/openapi-3-0';
import OpenApi3_1ResolveStrategy from '@swagger-api/apidom-reference/resolve/strategies/openapi-3-1';

Expand All @@ -1126,6 +1145,7 @@ await resolve('/home/user/oas.json', {
resolve: {
strategies: [
AsyncApi2ResolveStrategy(),
OpenApi2ResolveStrategy(),
OpenApi3_0ResolveStrategy(),
OpenApi3_1ResolveStrategy(),
]
Expand Down
5 changes: 5 additions & 0 deletions packages/apidom-reference/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@
"require": "./cjs/resolve/strategies/asyncapi-2/index.cjs",
"types": "./types/resolve/strategies/asyncapi-2/index.d.ts"
},
"./resolve/strategies/openapi-2": {
"import": "./es/resolve/strategies/openapi-2/index.mjs",
"require": "./cjs/resolve/strategies/openapi-2/index.cjs",
"types": "./types/resolve/strategies/openapi-2/index.d.ts"
},
"./resolve/strategies/openapi-3-0": {
"import": "./es/resolve/strategies/openapi-3-0/index.mjs",
"require": "./cjs/resolve/strategies/openapi-3-0/index.cjs",
Expand Down
2 changes: 2 additions & 0 deletions packages/apidom-reference/src/configuration/saturated.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import FileResolver from '../resolve/resolvers/file/index-node';
import HttpResolverAxios from '../resolve/resolvers/http-axios';
import OpenApi2ResolveStrategy from '../resolve/strategies/openapi-2';
import OpenApi3_0ResolveStrategy from '../resolve/strategies/openapi-3-0';
import OpenApi3_1ResolveStrategy from '../resolve/strategies/openapi-3-1';
import AsyncApi2ResolveStrategy from '../resolve/strategies/asyncapi-2';
Expand Down Expand Up @@ -44,6 +45,7 @@ options.resolve.resolvers = [
];

options.resolve.strategies = [
OpenApi2ResolveStrategy(),
OpenApi3_0ResolveStrategy(),
OpenApi3_1ResolveStrategy(),
AsyncApi2ResolveStrategy(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import stampit from 'stampit';
import { createNamespace, visit } from '@swagger-api/apidom-core';
import openapi2Namespace, {
getNodeType,
isSwaggerElement,
keyMap,
mediaTypes,
} from '@swagger-api/apidom-ns-openapi-2';

import ResolveStrategy from '../ResolveStrategy';
import {
File as IFile,
ReferenceOptions as IReferenceOptions,
ResolveStrategy as IResolveStrategy,
} from '../../../types';
import ReferenceSet from '../../../ReferenceSet';
import Reference from '../../../Reference';
import OpenApi2ResolveVisitor from './visitor';

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

const OpenApi2ResolveStrategy: stampit.Stamp<IResolveStrategy> = stampit(ResolveStrategy, {
init() {
this.name = 'openapi-2';
},
methods: {
canResolve(file: IFile) {
// assert by media type
if (file.mediaType !== 'text/plain') {
return mediaTypes.includes(file.mediaType);
}

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

async resolve(file: IFile, options: IReferenceOptions) {
const namespace = createNamespace(openapi2Namespace);
const reference = Reference({ uri: file.uri, value: file.parseResult });
const visitor = OpenApi2ResolveVisitor({ reference, namespace, options });
const refSet = ReferenceSet();
refSet.add(reference);

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

return refSet;
},
},
});

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

import OpenApi2DereferenceVisitor from '../../../dereference/strategies/openapi-2/visitor';

const OpenApi2ResolveVisitor = stampit(OpenApi2DereferenceVisitor);

export default OpenApi2ResolveVisitor;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import stampit from 'stampit';
import { createNamespace, visit } from '@swagger-api/apidom-core';
import asyncApi2Namespace, {
import openapi3_0Namespace, {
getNodeType,
isOpenApi3_0Element,
keyMap,
Expand Down Expand Up @@ -37,7 +37,7 @@ const OpenApi3_0ResolveStrategy: stampit.Stamp<IResolveStrategy> = stampit(Resol
},

async resolve(file: IFile, options: IReferenceOptions) {
const namespace = createNamespace(asyncApi2Namespace);
const namespace = createNamespace(openapi3_0Namespace);
const reference = Reference({ uri: file.uri, value: file.parseResult });
const visitor = OpenApi3_0ResolveVisitor({ reference, namespace, options });
const refSet = ReferenceSet();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"definitions": {
"externalSchema": {
"$ref": "./root.json#/definitions/schema"
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"swagger": "2.0",
"definitions": {
"schema": {
"$ref": "./ex.json#/definitions/externalSchema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"swagger": "2.0",
"definitions": {
"schema": {
"$ref": "#/definitions/schema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"definitions": {
"externalSchema1": {
"$ref": "./root.json#/definitions/schema2"
},
"externalSchema2": {
"$ref": "./root.json#/definitions/schema2"
},
"externalSchema3": {
"type": "string",
"description": "externalSchema3 description"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"swagger": "2.0",
"definitions": {
"schema1": {
"$ref": "./ex.json#/definitions/externalSchema1"
},
"schema2": {
"type": "object",
"description": "schema2 description"
},
"schema3": {
"$ref": "./ex.json#/definitions/externalSchema3"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"definitions": {
"indirection": {
"$ref": "./ex2.json#/definitions/indirection"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"definitions": {
"indirection": {
"$ref": "./ex3.json#/definitions/externalSchema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"definitions": {
"externalSchema": {
"type": "object",
"description": "external schema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"swagger": "2.0",
"definitions": {
"schema": {
"$ref": "./ex1.json#/definitions/indirection"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"definitions": {
"externalSchema": {
"type": "object",
"description": "external schema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"swagger": "2.0",
"definitions": {
"schema": {
"$ref": "./ex.json#/definitions/externalSchema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"one": {
"$ref": "#/two"
},
"two": {
"a": {
"$ref": "#/three"
}
},
"three": {
"b": {
"$ref": "#/two"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"swagger": "2.0",
"definitions": {
"schema": {
"$ref": "./ex.json#/one"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"definitions": {
"externalSchema": {
"type": "number",
"description": "external schema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"swagger": "2.0",
"definitions": {
"schema1": {
"$ref": "#/definitions/schema2"
},
"schema2": {
"$ref": "#/definitions/schema3"
},
"schema3": {
"$ref": "#/definitions/schema4"
},
"schema4": {
"type": "number",
"description": "schema4 description"
},
"schema5": {
"$ref": "./ex.json#/definitions/externalSchema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"definitions": {
"indirection": {
"$ref": "./ex2.json#/definitions/indirection"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"definitions": {
"indirection": {
"$ref": "./ex3.json#/definitions/indirection"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"definitions": {
"indirection": {
"$ref": "./root.json#/definitions/schema"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"swagger": "2.0",
"definitions": {
"schema": {
"$ref": "./ex1.json#/definitions/indirection"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"swagger": "2.0",
"definitions": {
"schema1": {
"$ref": "#/definitions/schema2"
},
"schema2": {
"$ref": "#/definitions/schema3"
},
"schema3": {
"$ref": "#/definitions/schema4"
},
"schema4": {
"$ref": "#/definitions/schema1"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"definitions": {
"externalSchema": {
"type": "string",
"description": "external schema"
}
}
}
Loading

0 comments on commit 413ec46

Please sign in to comment.