Skip to content

Commit 7af536a

Browse files
authored
fix(reference): use spec compliant JSON Pointer implementation (#4904)
Refs #4870
1 parent 90f9a02 commit 7af536a

File tree

30 files changed

+345
-347
lines changed

30 files changed

+345
-347
lines changed

packages/apidom-reference/src/dereference/strategies/apidom/visitor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
visit,
1414
cloneDeep,
1515
} from '@swagger-api/apidom-core';
16-
import { uriToPointer as uriToElementID } from '@swagger-api/apidom-json-pointer';
16+
import { URIFragmentIdentifier } from '@swagger-api/apidom-json-pointer/modern';
1717

1818
import MaximumResolveDepthError from '../../../errors/MaximumResolveDepthError.ts';
1919
import * as url from '../../../util/url.ts';
@@ -130,7 +130,7 @@ class ApiDOMDereferenceVisitor {
130130

131131
const reference = await this.toReference(refNormalizedURI);
132132
const refBaseURI = url.resolve(retrievalURI, refNormalizedURI);
133-
const elementID = uriToElementID(refBaseURI);
133+
const elementID = URIFragmentIdentifier.fromURIReference(refBaseURI);
134134
let referencedElement: unknown | Element | undefined = evaluate(
135135
elementID,
136136
reference.value.result as Element,

packages/apidom-reference/src/dereference/strategies/asyncapi-2/visitor.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
RefElement,
1616
} from '@swagger-api/apidom-core';
1717
import { ApiDOMError } from '@swagger-api/apidom-error';
18-
import { evaluate, uriToPointer } from '@swagger-api/apidom-json-pointer';
18+
import { evaluate, URIFragmentIdentifier } from '@swagger-api/apidom-json-pointer/modern';
1919
import {
2020
ChannelItemElement,
2121
getNodeType,
@@ -197,10 +197,10 @@ class AsyncAPI2DereferenceVisitor {
197197

198198
this.indirections.push(referencingElement);
199199

200-
const jsonPointer = uriToPointer($refBaseURI);
200+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
201201

202202
// possibly non-semantic fragment
203-
let referencedElement = evaluate(jsonPointer, reference.value.result as Element);
203+
let referencedElement = evaluate<Element>(reference.value.result, jsonPointer);
204204
referencedElement.id = identityManager.identify(referencedElement);
205205

206206
/**
@@ -391,10 +391,10 @@ class AsyncAPI2DereferenceVisitor {
391391

392392
this.indirections.push(referencingElement);
393393

394-
const jsonPointer = uriToPointer($refBaseURI);
394+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
395395

396396
// possibly non-semantic referenced element
397-
let referencedElement = evaluate(jsonPointer, reference.value.result as Element);
397+
let referencedElement = evaluate<Element>(reference.value.result, jsonPointer);
398398
referencedElement.id = identityManager.identify(referencedElement);
399399

400400
/**

packages/apidom-reference/src/dereference/strategies/openapi-2/visitor.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
Namespace,
1515
} from '@swagger-api/apidom-core';
1616
import { ApiDOMError } from '@swagger-api/apidom-error';
17-
import { evaluate, uriToPointer } from '@swagger-api/apidom-json-pointer';
17+
import { evaluate, URIFragmentIdentifier } from '@swagger-api/apidom-json-pointer/modern';
1818
import {
1919
getNodeType,
2020
isReferenceElement,
@@ -199,10 +199,10 @@ class OpenAPI2DereferenceVisitor {
199199

200200
this.indirections.push(referencingElement);
201201

202-
const jsonPointer = uriToPointer($refBaseURI);
202+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
203203

204204
// possibly non-semantic fragment
205-
let referencedElement = evaluate(jsonPointer, reference.value.result as Element);
205+
let referencedElement = evaluate<Element>(reference.value.result, jsonPointer);
206206
referencedElement.id = identityManager.identify(referencedElement);
207207

208208
/**
@@ -372,10 +372,10 @@ class OpenAPI2DereferenceVisitor {
372372

373373
this.indirections.push(referencingElement);
374374

375-
const jsonPointer = uriToPointer($refBaseURI);
375+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
376376

377377
// possibly non-semantic referenced element
378-
let referencedElement = evaluate(jsonPointer, reference.value.result as Element);
378+
let referencedElement = evaluate<Element>(reference.value.result, jsonPointer);
379379
referencedElement.id = identityManager.identify(referencedElement);
380380

381381
/**
@@ -544,10 +544,10 @@ class OpenAPI2DereferenceVisitor {
544544

545545
this.indirections.push(referencingElement);
546546

547-
const jsonPointer = uriToPointer($refBaseURI);
547+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
548548

549549
// possibly non-semantic fragment
550-
let referencedElement = evaluate(jsonPointer, reference.value.result as Element);
550+
let referencedElement = evaluate<Element>(reference.value.result, jsonPointer);
551551
referencedElement.id = identityManager.identify(referencedElement);
552552

553553
/**

packages/apidom-reference/src/dereference/strategies/openapi-3-0/visitor.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
Namespace,
1717
} from '@swagger-api/apidom-core';
1818
import { ApiDOMError } from '@swagger-api/apidom-error';
19-
import { evaluate, uriToPointer } from '@swagger-api/apidom-json-pointer';
19+
import { evaluate, URIFragmentIdentifier } from '@swagger-api/apidom-json-pointer/modern';
2020
import {
2121
getNodeType,
2222
keyMap,
@@ -201,10 +201,10 @@ class OpenAPI3_0DereferenceVisitor {
201201

202202
this.indirections.push(referencingElement);
203203

204-
const jsonPointer = uriToPointer($refBaseURI);
204+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
205205

206206
// possibly non-semantic fragment
207-
let referencedElement = evaluate(jsonPointer, reference.value.result as Element);
207+
let referencedElement = evaluate<Element>(reference.value.result, jsonPointer);
208208
referencedElement.id = identityManager.identify(referencedElement);
209209

210210
/**
@@ -373,10 +373,10 @@ class OpenAPI3_0DereferenceVisitor {
373373

374374
this.indirections.push(referencingElement);
375375

376-
const jsonPointer = uriToPointer($refBaseURI);
376+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
377377

378378
// possibly non-semantic referenced element
379-
let referencedElement = evaluate(jsonPointer, reference.value.result as Element);
379+
let referencedElement = evaluate<Element>(reference.value.result, jsonPointer);
380380
referencedElement.id = identityManager.identify(referencedElement);
381381

382382
/**
@@ -536,7 +536,7 @@ class OpenAPI3_0DereferenceVisitor {
536536

537537
if (isStringElement(linkElement.operationRef)) {
538538
// possibly non-semantic referenced element
539-
const jsonPointer = uriToPointer(toValue(linkElement.operationRef));
539+
const jsonPointer = URIFragmentIdentifier.fromURIReference(toValue(linkElement.operationRef));
540540
const retrievalURI = this.toBaseURI(toValue(linkElement.operationRef));
541541
const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
542542
const isExternalReference = !isInternalReference;
@@ -554,7 +554,7 @@ class OpenAPI3_0DereferenceVisitor {
554554

555555
const reference = await this.toReference(toValue(linkElement.operationRef));
556556

557-
operationElement = evaluate(jsonPointer, reference.value.result as Element);
557+
operationElement = evaluate<Element>(reference.value.result, jsonPointer);
558558
// applying semantics to a referenced element
559559
if (isPrimitiveElement(operationElement)) {
560560
const cacheKey = `operation-${toValue(identityManager.identify(operationElement))}`;

packages/apidom-reference/src/dereference/strategies/openapi-3-1/selectors/uri.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { isUndefined } from 'ramda-adjunct';
22
import { Element, filter } from '@swagger-api/apidom-core';
33
import { isSchemaElement, SchemaElement } from '@swagger-api/apidom-ns-openapi-3-1';
4-
import { uriToPointer, evaluate as jsonPointerEvaluate } from '@swagger-api/apidom-json-pointer';
4+
import {
5+
URIFragmentIdentifier,
6+
evaluate as jsonPointerEvaluate,
7+
} from '@swagger-api/apidom-json-pointer/modern';
58

69
import * as url from '../../../../util/url.ts';
710
import EvaluationJsonSchemaUriError from '../../../../errors/EvaluationJsonSchemaUriError.ts';
@@ -33,20 +36,12 @@ export const evaluate = <T extends Element>(uri: string, element: T): Element |
3336
throw new EvaluationJsonSchemaUriError(`Evaluation failed on URI: "${uri}"`);
3437
}
3538

36-
let fragmentEvaluate;
37-
let selector;
3839
if (isAnchor(uriToAnchor(uri))) {
3940
// we're dealing with JSON Schema $anchor here
40-
fragmentEvaluate = $anchorEvaluate;
41-
selector = uriToAnchor(uri);
42-
} else {
43-
// we're assuming here that we're dealing with JSON Pointer here
44-
fragmentEvaluate = jsonPointerEvaluate;
45-
selector = uriToPointer(uri);
41+
return $anchorEvaluate(uriToAnchor(uri), result);
4642
}
4743

48-
// @ts-ignore
49-
return fragmentEvaluate(selector, result);
44+
return jsonPointerEvaluate(result, URIFragmentIdentifier.fromURIReference(uri));
5045
};
5146
evaluate.cache = new WeakMap();
5247

packages/apidom-reference/src/dereference/strategies/openapi-3-1/visitor.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ import {
1818
Namespace,
1919
} from '@swagger-api/apidom-core';
2020
import { ApiDOMError } from '@swagger-api/apidom-error';
21-
import { evaluate as jsonPointerEvaluate, uriToPointer } from '@swagger-api/apidom-json-pointer';
21+
import {
22+
evaluate as jsonPointerEvaluate,
23+
URIFragmentIdentifier,
24+
} from '@swagger-api/apidom-json-pointer/modern';
2225
import {
2326
getNodeType,
2427
isReferenceLikeElement,
@@ -212,10 +215,10 @@ class OpenAPI3_1DereferenceVisitor {
212215

213216
this.indirections.push(referencingElement);
214217

215-
const jsonPointer = uriToPointer($refBaseURI);
218+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
216219

217220
// possibly non-semantic fragment
218-
let referencedElement = jsonPointerEvaluate(jsonPointer, reference.value.result as Element);
221+
let referencedElement = jsonPointerEvaluate<Element>(reference.value.result, jsonPointer);
219222
referencedElement.id = identityManager.identify(referencedElement);
220223

221224
// applying semantics to a fragment
@@ -398,10 +401,10 @@ class OpenAPI3_1DereferenceVisitor {
398401

399402
this.indirections.push(referencingElement);
400403

401-
const jsonPointer = uriToPointer($refBaseURI);
404+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
402405

403406
// possibly non-semantic referenced element
404-
let referencedElement = jsonPointerEvaluate(jsonPointer, reference.value.result as Element);
407+
let referencedElement = jsonPointerEvaluate<Element>(reference.value.result, jsonPointer);
405408
referencedElement.id = identityManager.identify(referencedElement);
406409

407410
/**
@@ -561,7 +564,7 @@ class OpenAPI3_1DereferenceVisitor {
561564

562565
if (isStringElement(linkElement.operationRef)) {
563566
// possibly non-semantic referenced element
564-
const jsonPointer = uriToPointer(toValue(linkElement.operationRef));
567+
const jsonPointer = URIFragmentIdentifier.fromURIReference(toValue(linkElement.operationRef));
565568
const retrievalURI = this.toBaseURI(toValue(linkElement.operationRef));
566569
const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
567570
const isExternalReference = !isInternalReference;
@@ -579,7 +582,7 @@ class OpenAPI3_1DereferenceVisitor {
579582

580583
const reference = await this.toReference(toValue(linkElement.operationRef));
581584

582-
operationElement = jsonPointerEvaluate(jsonPointer, reference.value.result as Element);
585+
operationElement = jsonPointerEvaluate<OperationElement>(reference.value.result, jsonPointer);
583586
// applying semantics to a referenced element
584587
if (isPrimitiveElement(operationElement)) {
585588
const cacheKey = `operation-${toValue(identityManager.identify(operationElement))}`;
@@ -770,9 +773,9 @@ class OpenAPI3_1DereferenceVisitor {
770773
}
771774

772775
reference = await this.toReference(url.unsanitize($refBaseURI));
773-
const selector = uriToPointer($refBaseURI);
776+
const selector = URIFragmentIdentifier.fromURIReference($refBaseURI);
774777
const referenceAsSchema = maybeRefractToSchemaElement(reference.value.result as Element);
775-
referencedElement = jsonPointerEvaluate(selector, referenceAsSchema);
778+
referencedElement = jsonPointerEvaluate(referenceAsSchema, selector);
776779
referencedElement = maybeRefractToSchemaElement(referencedElement);
777780
referencedElement.id = identityManager.identify(referencedElement);
778781
}
@@ -822,9 +825,9 @@ class OpenAPI3_1DereferenceVisitor {
822825
}
823826

824827
reference = await this.toReference(url.unsanitize($refBaseURI));
825-
const selector = uriToPointer($refBaseURI);
828+
const selector = URIFragmentIdentifier.fromURIReference($refBaseURI);
826829
const referenceAsSchema = maybeRefractToSchemaElement(reference.value.result as Element);
827-
referencedElement = jsonPointerEvaluate(selector, referenceAsSchema);
830+
referencedElement = jsonPointerEvaluate(referenceAsSchema, selector);
828831
referencedElement = maybeRefractToSchemaElement(referencedElement);
829832
referencedElement.id = identityManager.identify(referencedElement);
830833
}

packages/apidom-reference/test/dereference/strategies/asyncapi-2/channel-item-object/dereference-apidom.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { assert } from 'chai';
33
import {
44
mediaTypes,
55
isChannelItemElement,
6-
AsyncApi2Element,
6+
ChannelItemElement,
77
} from '@swagger-api/apidom-ns-asyncapi-2';
88
import { toValue } from '@swagger-api/apidom-core';
9-
import { evaluate } from '@swagger-api/apidom-json-pointer';
9+
import { evaluate } from '@swagger-api/apidom-json-pointer/modern';
1010
import { fileURLToPath } from 'node:url';
1111

1212
import { parse, dereferenceApiDOM } from '../../../../../src/index.ts';
@@ -24,9 +24,9 @@ describe('dereference', function () {
2424
const parseResult = await parse(fixturePath, {
2525
parse: { mediaType: mediaTypes.latest('json') },
2626
});
27-
const channelItemElement = evaluate(
27+
const channelItemElement = evaluate<ChannelItemElement>(
28+
parseResult.api,
2829
'/channels/channelItem1',
29-
parseResult.api as AsyncApi2Element,
3030
);
3131
const dereferenced = await dereferenceApiDOM(channelItemElement, {
3232
parse: { mediaType: mediaTypes.latest('json') },
@@ -40,9 +40,9 @@ describe('dereference', function () {
4040
const parseResult = await parse(fixturePath, {
4141
parse: { mediaType: mediaTypes.latest('json') },
4242
});
43-
const channelItemElement = evaluate(
43+
const channelItemElement = evaluate<ChannelItemElement>(
44+
parseResult.api,
4445
'/channels/channelItem1',
45-
parseResult.api as AsyncApi2Element,
4646
);
4747
const dereferenced = await dereferenceApiDOM(channelItemElement, {
4848
parse: { mediaType: mediaTypes.latest('json') },

0 commit comments

Comments
 (0)