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
@@ -1,5 +1,5 @@
import stampit from 'stampit';
import { hasIn, pathSatisfies, propEq, reduceRight } from 'ramda';
import { hasIn, pathSatisfies, propEq } from 'ramda';
import { isNotUndefined } from 'ramda-adjunct';
import { isPrimitiveElement, isStringElement, visit, Element } from 'apidom';
import {
Expand All @@ -19,42 +19,14 @@ import { MaximumDereferenceDepthError, MaximumResolverDepthError } from '../../.
import * as url from '../../../util/url';
import parse from '../../../parse';
import Reference from '../../../Reference';
import {
resolveInherited$id,
refractToSchemaElement,
} from '../../../resolve/strategies/openapi-3-1/util';

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

/**
* Cached version of SchemaElement.refract.
*/
export const refractToSchemaElement = <T extends Element>(element: T) => {
if (refractToSchemaElement.cache.has(element)) {
return refractToSchemaElement.cache.get(element);
}

const refracted = SchemaElement.refract(element);
refractToSchemaElement.cache.set(element, refracted);
return refracted;
};
refractToSchemaElement.cache = new WeakMap();

/**
* Folding of inherited$id list from right to left using
* URL resolving mechanism.
*/
export const resolveInherited$id = (schemaElement: SchemaElement) =>
reduceRight(
($id: string, acc: string): string => {
const uriWithoutHash = url.stripHash($id);
const sanitizedURI = url.isFileSystemPath(uriWithoutHash)
? url.fromFileSystemPath(uriWithoutHash)
: uriWithoutHash;

return url.resolve(sanitizedURI, acc);
},
schemaElement.$ref?.toValue(),
schemaElement.meta.get('inherited$id').toValue(),
);

const OpenApi3_1DereferenceVisitor = stampit({
props: {
indirections: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { reduceRight } from 'ramda';
import { Element } from 'apidom';
import { SchemaElement } from 'apidom-ns-openapi-3-1';

import * as url from '../../../util/url';

/**
* Folding of inherited$id list from right to left using
* URL resolving mechanism.
*/
export const resolveInherited$id = (schemaElement: SchemaElement) =>
reduceRight(
($id: string, acc: string): string => {
const uriWithoutHash = url.stripHash($id);
const sanitizedURI = url.isFileSystemPath(uriWithoutHash)
? url.fromFileSystemPath(uriWithoutHash)
: uriWithoutHash;

return url.resolve(sanitizedURI, acc);
},
schemaElement.$ref?.toValue(),
schemaElement.meta.get('inherited$id').toValue(),
);

/**
* Cached version of SchemaElement.refract.
*/
export const refractToSchemaElement = <T extends Element>(element: T) => {
if (refractToSchemaElement.cache.has(element)) {
return refractToSchemaElement.cache.get(element);
}

const refracted = SchemaElement.refract(element);
refractToSchemaElement.cache.set(element, refracted);
return refracted;
};
refractToSchemaElement.cache = new WeakMap();
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ import * as url from '../../../util/url';
import parse from '../../../parse';
import Reference from '../../../Reference';
import { evaluate as jsonPointerEvaluate, uriToPointer } from '../../../selectors/json-pointer';
import {
refractToSchemaElement,
resolveInherited$id,
} from '../../../dereference/strategies/openapi-3-1/visitor';
import { refractToSchemaElement, resolveInherited$id } from './util';
import {
evaluate as $anchorEvaluate,
isAnchor,
Expand Down Expand Up @@ -78,7 +75,10 @@ const OpenApi3_1ResolveVisitor = stampit({
return refSet.find(propEq('uri', baseURI));
}

const parseResult = await parse(baseURI, this.options);
const parseResult = await parse(baseURI, {
...this.options,
parse: { ...this.options.parse, mediaType: 'text/plain' },
});

// register new Reference with ReferenceSet
const reference = Reference({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { dereference } from '../../../../../src';
import {
DereferenceError,
MaximumDereferenceDepthError,
MaximumResolverDepthError,
ResolverError,
} from '../../../../../src/util/errors';
import { loadJsonFile } from '../../../../helpers';
Expand Down Expand Up @@ -472,6 +473,26 @@ describe('dereference', function () {
});
});

context('given Reference Objects and maxDepth of resolution', function () {
const fixturePath = path.join(rootFixturePath, 'max-depth');

specify('should throw error', async function () {
const rootFilePath = path.join(fixturePath, 'root.json');

try {
await dereference(rootFilePath, {
parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.0' },
resolve: { maxDepth: 2 },
});
assert.fail('should throw MaximumResolverDepthError');
} catch (error) {
assert.instanceOf(error, DereferenceError);
assert.instanceOf(error.cause.cause, MaximumResolverDepthError);
assert.match(error.cause.cause.message, /fixtures\/max-depth\/ex2.json"$/);
}
});
});

context('given Schema Objects with unresolvable reference', function () {
const fixturePath = path.join(rootFixturePath, 'unresolvable-reference');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import path from 'path';
import { assert } from 'chai';

import { resolve } from '../../../../../src';
import { MaximumResolverDepthError, ResolverError } from '../../../../../src/util/errors';
import { dereference, resolve } from '../../../../../src';
import {
DereferenceError,
MaximumDereferenceDepthError,
MaximumResolverDepthError,
ResolverError,
} from '../../../../../src/util/errors';

const rootFixturePath = path.join(__dirname, 'fixtures');

Expand Down Expand Up @@ -179,6 +184,26 @@ describe('resolve', function () {
});
});

context('given Reference Objects and maxDepth of dereference', function () {
const fixturePath = path.join(rootFixturePath, 'max-depth');

specify('should throw error', async function () {
const rootFilePath = path.join(fixturePath, 'root.json');

try {
await dereference(rootFilePath, {
parse: { mediaType: 'application/vnd.aai.asyncapi+json;version=2.0.0' },
dereference: { maxDepth: 2 },
});
assert.fail('should throw MaximumDereferenceDepthError');
} catch (error) {
assert.instanceOf(error, DereferenceError);
assert.instanceOf(error.cause.cause, MaximumDereferenceDepthError);
assert.match(error.cause.cause.message, /fixtures\/max-depth\/ex2.json"$/);
}
});
});

context('given Reference Objects and maxDepth of resolution', function () {
const fixturePath = path.join(rootFixturePath, 'max-depth');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import path from 'path';
import { assert } from 'chai';

import { resolve } from '../../../../../src';
import { MaximumResolverDepthError, ResolverError } from '../../../../../src/util/errors';
import { dereference, resolve } from '../../../../../src';
import {
MaximumResolverDepthError,
MaximumDereferenceDepthError,
ResolverError,
DereferenceError,
} from '../../../../../src/util/errors';

const rootFixturePath = path.join(__dirname, 'fixtures');

Expand Down Expand Up @@ -179,6 +184,26 @@ describe('resolve', function () {
});
});

context('given Reference Objects and maxDepth of dereference', function () {
const fixturePath = path.join(rootFixturePath, 'max-depth');

specify('should throw error', async function () {
const rootFilePath = path.join(fixturePath, 'root.json');

try {
await dereference(rootFilePath, {
parse: { mediaType: 'application/vnd.aai.asyncapi+json;version=2.0.0' },
dereference: { maxDepth: 2 },
});
assert.fail('should throw MaximumDereferenceDepthError');
} catch (error) {
assert.instanceOf(error, DereferenceError);
assert.instanceOf(error.cause.cause, MaximumDereferenceDepthError);
assert.match(error.cause.cause.message, /fixtures\/max-depth\/ex2.json"$/);
}
});
});

context('given Reference Objects and maxDepth of resolution', function () {
const fixturePath = path.join(rootFixturePath, 'max-depth');

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$defs": {
"UserProfile": {
"$anchor": "user-profile",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"openapi": "3.1.0",
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"login": {
"type": "string"
},
"password": {
"type": "string"
},
"profile": {
"$ref": "./ex.json#user-profile"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"openapi": "3.1.0",
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"login": {
"type": "string"
},
"password": {
"type": "string"
},
"profile": {
"$ref": "#user-profile"
}
}
},
"UserProfile": {
"$anchor": "user-profile",
"properties": {
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"openapi": "3.1.0",
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"login": {
"type": "string"
},
"password": {
"type": "string"
},
"profile": {
"$ref": "#user-profile"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"openapi": "3.1.0",
"components": {
"schemas": {
"User": {
"$id": "./schemas/",
"type": "object",
"properties": {
"login": {
"type": "string"
},
"password": {
"type": "string"
},
"profile": {
"$id": "./nested/",
"$ref": "./ex.json"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "object",
"properties": {
"avatar": {
"type": "string"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"openapi": "3.1.0",
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"login": {
"type": "string"
},
"password": {
"type": "string"
},
"profile": {
"$id": "./nested/",
"$ref": "./ex.json"
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "object",
"properties": {
"avatar": {
"type": "string"
}
}
}
Loading