@speclynx/apidom-reference 5.2.5 → 5.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +7 -3
- package/dist/apidom-reference.browser.js +119 -88
- package/dist/apidom-reference.browser.min.js +1 -1
- package/package.json +29 -29
- package/src/dereference/strategies/arazzo-1/index.cjs +11 -10
- package/src/dereference/strategies/arazzo-1/index.mjs +11 -10
- package/src/dereference/strategies/arazzo-1/source-descriptions.cjs +65 -42
- package/src/dereference/strategies/arazzo-1/source-descriptions.mjs +64 -42
- package/src/dereference/strategies/arazzo-1/visitor.cjs +30 -26
- package/src/dereference/strategies/arazzo-1/visitor.mjs +30 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speclynx/apidom-reference",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.6",
|
|
4
4
|
"description": "Advanced algorithms for semantic ApiDOM manipulations like dereferencing or resolution.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apidom",
|
|
@@ -298,33 +298,33 @@
|
|
|
298
298
|
"author": "Vladimir Gorej",
|
|
299
299
|
"license": "Apache-2.0",
|
|
300
300
|
"dependencies": {
|
|
301
|
-
"@babel/runtime-corejs3": "^8.0.
|
|
302
|
-
"@speclynx/apidom-core": "5.2.
|
|
303
|
-
"@speclynx/apidom-datamodel": "5.2.
|
|
304
|
-
"@speclynx/apidom-error": "5.2.
|
|
305
|
-
"@speclynx/apidom-json-pointer": "5.2.
|
|
306
|
-
"@speclynx/apidom-ns-arazzo-1": "5.2.
|
|
307
|
-
"@speclynx/apidom-ns-asyncapi-2": "5.2.
|
|
308
|
-
"@speclynx/apidom-ns-json-schema-2020-12": "5.2.
|
|
309
|
-
"@speclynx/apidom-ns-openapi-2": "5.2.
|
|
310
|
-
"@speclynx/apidom-ns-openapi-3-0": "5.2.
|
|
311
|
-
"@speclynx/apidom-ns-openapi-3-1": "5.2.
|
|
312
|
-
"@speclynx/apidom-ns-overlay-1": "5.2.
|
|
313
|
-
"@speclynx/apidom-parser-adapter-arazzo-json-1": "5.2.
|
|
314
|
-
"@speclynx/apidom-parser-adapter-arazzo-yaml-1": "5.2.
|
|
315
|
-
"@speclynx/apidom-parser-adapter-asyncapi-json-2": "5.2.
|
|
316
|
-
"@speclynx/apidom-parser-adapter-asyncapi-yaml-2": "5.2.
|
|
317
|
-
"@speclynx/apidom-parser-adapter-json": "5.2.
|
|
318
|
-
"@speclynx/apidom-parser-adapter-openapi-json-2": "5.2.
|
|
319
|
-
"@speclynx/apidom-parser-adapter-openapi-json-3-0": "5.2.
|
|
320
|
-
"@speclynx/apidom-parser-adapter-openapi-json-3-1": "5.2.
|
|
321
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-2": "5.2.
|
|
322
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-3-0": "5.2.
|
|
323
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-3-1": "5.2.
|
|
324
|
-
"@speclynx/apidom-parser-adapter-overlay-json-1": "5.2.
|
|
325
|
-
"@speclynx/apidom-parser-adapter-overlay-yaml-1": "5.2.
|
|
326
|
-
"@speclynx/apidom-parser-adapter-yaml-1-2": "5.2.
|
|
327
|
-
"@speclynx/apidom-traverse": "5.2.
|
|
301
|
+
"@babel/runtime-corejs3": "^8.0.5",
|
|
302
|
+
"@speclynx/apidom-core": "5.2.6",
|
|
303
|
+
"@speclynx/apidom-datamodel": "5.2.6",
|
|
304
|
+
"@speclynx/apidom-error": "5.2.6",
|
|
305
|
+
"@speclynx/apidom-json-pointer": "5.2.6",
|
|
306
|
+
"@speclynx/apidom-ns-arazzo-1": "5.2.6",
|
|
307
|
+
"@speclynx/apidom-ns-asyncapi-2": "5.2.6",
|
|
308
|
+
"@speclynx/apidom-ns-json-schema-2020-12": "5.2.6",
|
|
309
|
+
"@speclynx/apidom-ns-openapi-2": "5.2.6",
|
|
310
|
+
"@speclynx/apidom-ns-openapi-3-0": "5.2.6",
|
|
311
|
+
"@speclynx/apidom-ns-openapi-3-1": "5.2.6",
|
|
312
|
+
"@speclynx/apidom-ns-overlay-1": "5.2.6",
|
|
313
|
+
"@speclynx/apidom-parser-adapter-arazzo-json-1": "5.2.6",
|
|
314
|
+
"@speclynx/apidom-parser-adapter-arazzo-yaml-1": "5.2.6",
|
|
315
|
+
"@speclynx/apidom-parser-adapter-asyncapi-json-2": "5.2.6",
|
|
316
|
+
"@speclynx/apidom-parser-adapter-asyncapi-yaml-2": "5.2.6",
|
|
317
|
+
"@speclynx/apidom-parser-adapter-json": "5.2.6",
|
|
318
|
+
"@speclynx/apidom-parser-adapter-openapi-json-2": "5.2.6",
|
|
319
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-0": "5.2.6",
|
|
320
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-1": "5.2.6",
|
|
321
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-2": "5.2.6",
|
|
322
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-0": "5.2.6",
|
|
323
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-1": "5.2.6",
|
|
324
|
+
"@speclynx/apidom-parser-adapter-overlay-json-1": "5.2.6",
|
|
325
|
+
"@speclynx/apidom-parser-adapter-overlay-yaml-1": "5.2.6",
|
|
326
|
+
"@speclynx/apidom-parser-adapter-yaml-1-2": "5.2.6",
|
|
327
|
+
"@speclynx/apidom-traverse": "5.2.6",
|
|
328
328
|
"@swaggerexpert/arazzo-runtime-expression": "^3.2.0",
|
|
329
329
|
"axios": "^1.20.0",
|
|
330
330
|
"picomatch": "^4.0.7",
|
|
@@ -346,5 +346,5 @@
|
|
|
346
346
|
"README.md",
|
|
347
347
|
"CHANGELOG.md"
|
|
348
348
|
],
|
|
349
|
-
"gitHead": "
|
|
349
|
+
"gitHead": "c78f4a79e2b91b9ad099dff6dff5dc35236ae75b"
|
|
350
350
|
}
|
|
@@ -121,6 +121,17 @@ class Arazzo1DereferenceStrategy extends _DereferenceStrategy.default {
|
|
|
121
121
|
})
|
|
122
122
|
});
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
* If immutable option is set, replay refs from the refSet.
|
|
126
|
+
* Replayed before source descriptions are dereferenced, so they can reuse the refs.
|
|
127
|
+
*/
|
|
128
|
+
if (options.dereference.immutable) {
|
|
129
|
+
mutableRefSet.refs.filter(ref => ref.uri.startsWith('immutable://')).map(ref => new _Reference.default({
|
|
130
|
+
...ref,
|
|
131
|
+
uri: ref.uri.replace(/^immutable:\/\//, '')
|
|
132
|
+
})).forEach(ref => immutableRefSet.add(ref));
|
|
133
|
+
}
|
|
134
|
+
|
|
124
135
|
/**
|
|
125
136
|
* Dereference source descriptions if option is enabled.
|
|
126
137
|
*/
|
|
@@ -135,16 +146,6 @@ class Arazzo1DereferenceStrategy extends _DereferenceStrategy.default {
|
|
|
135
146
|
parseResult.push(...sourceDescriptions);
|
|
136
147
|
}
|
|
137
148
|
|
|
138
|
-
/**
|
|
139
|
-
* If immutable option is set, replay refs from the refSet.
|
|
140
|
-
*/
|
|
141
|
-
if (options.dereference.immutable) {
|
|
142
|
-
mutableRefSet.refs.filter(ref => ref.uri.startsWith('immutable://')).map(ref => new _Reference.default({
|
|
143
|
-
...ref,
|
|
144
|
-
uri: ref.uri.replace(/^immutable:\/\//, '')
|
|
145
|
-
})).forEach(ref => immutableRefSet.add(ref));
|
|
146
|
-
}
|
|
147
|
-
|
|
148
149
|
/**
|
|
149
150
|
* Release all memory if this refSet was not provided as a configuration option.
|
|
150
151
|
* If provided as configuration option, then provider is responsible for cleanup.
|
|
@@ -70,6 +70,17 @@ class Arazzo1DereferenceStrategy extends DereferenceStrategy {
|
|
|
70
70
|
})
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* If immutable option is set, replay refs from the refSet.
|
|
75
|
+
* Replayed before source descriptions are dereferenced, so they can reuse the refs.
|
|
76
|
+
*/
|
|
77
|
+
if (options.dereference.immutable) {
|
|
78
|
+
mutableRefSet.refs.filter(ref => ref.uri.startsWith('immutable://')).map(ref => new Reference({
|
|
79
|
+
...ref,
|
|
80
|
+
uri: ref.uri.replace(/^immutable:\/\//, '')
|
|
81
|
+
})).forEach(ref => immutableRefSet.add(ref));
|
|
82
|
+
}
|
|
83
|
+
|
|
73
84
|
/**
|
|
74
85
|
* Dereference source descriptions if option is enabled.
|
|
75
86
|
*/
|
|
@@ -84,16 +95,6 @@ class Arazzo1DereferenceStrategy extends DereferenceStrategy {
|
|
|
84
95
|
parseResult.push(...sourceDescriptions);
|
|
85
96
|
}
|
|
86
97
|
|
|
87
|
-
/**
|
|
88
|
-
* If immutable option is set, replay refs from the refSet.
|
|
89
|
-
*/
|
|
90
|
-
if (options.dereference.immutable) {
|
|
91
|
-
mutableRefSet.refs.filter(ref => ref.uri.startsWith('immutable://')).map(ref => new Reference({
|
|
92
|
-
...ref,
|
|
93
|
-
uri: ref.uri.replace(/^immutable:\/\//, '')
|
|
94
|
-
})).forEach(ref => immutableRefSet.add(ref));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
98
|
/**
|
|
98
99
|
* Release all memory if this refSet was not provided as a configuration option.
|
|
99
100
|
* If provided as configuration option, then provider is responsible for cleanup.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
|
|
3
4
|
var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
@@ -8,9 +9,13 @@ exports.dereferenceSourceDescriptions = dereferenceSourceDescriptions;
|
|
|
8
9
|
var _apidomDatamodel = require("@speclynx/apidom-datamodel");
|
|
9
10
|
var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
|
|
10
11
|
var _apidomCore = require("@speclynx/apidom-core");
|
|
12
|
+
var _ramda = require("ramda");
|
|
11
13
|
var url = _interopRequireWildcard(require("../../../util/url.cjs"));
|
|
14
|
+
var _Reference = _interopRequireDefault(require("../../../Reference.cjs"));
|
|
15
|
+
var _ReferenceSet = _interopRequireDefault(require("../../../ReferenceSet.cjs"));
|
|
12
16
|
var _util = require("../../../options/util.cjs");
|
|
13
|
-
var _index =
|
|
17
|
+
var _index = _interopRequireDefault(require("../../../parse/index.cjs"));
|
|
18
|
+
var _index2 = require("../../index.cjs");
|
|
14
19
|
var _util2 = require("./util.cjs");
|
|
15
20
|
/**
|
|
16
21
|
* Dereferences a single source description element.
|
|
@@ -63,53 +68,64 @@ async function dereferenceSourceDescription(sourceDescription, ctx) {
|
|
|
63
68
|
|
|
64
69
|
// check if source description was already parsed (e.g., during parse phase with sourceDescriptions: true)
|
|
65
70
|
const existingParseResult = sourceDescription.meta.get('parseResult');
|
|
71
|
+
const parentRefSet = ctx.options.dereference.refSet;
|
|
72
|
+
let refSet = null;
|
|
66
73
|
try {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
dereference: {
|
|
78
|
-
strategyOpts: {
|
|
79
|
-
// nested documents should dereference all their source descriptions
|
|
80
|
-
// (parent's name filter doesn't apply to nested documents)
|
|
81
|
-
// set at strategy-specific level to override any inherited filters
|
|
82
|
-
[ctx.strategyName]: {
|
|
83
|
-
sourceDescriptions: true,
|
|
84
|
-
sourceDescriptionsDepth: ctx.currentDepth + 1,
|
|
85
|
-
sourceDescriptionsAncestors: ctx.ancestors,
|
|
86
|
-
sourceDescriptionsDereferenced: ctx.dereferenced
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}));
|
|
74
|
+
// source description document comes from, in order of preference:
|
|
75
|
+
// caller-supplied refSet, parse phase, or is fetched and parsed now
|
|
76
|
+
const cachedReference = parentRefSet?.find(ref => ref.uri === retrievalURI);
|
|
77
|
+
let sourceDescriptionParseResult;
|
|
78
|
+
let isFreshlyParsed = false;
|
|
79
|
+
if (cachedReference !== undefined) {
|
|
80
|
+
sourceDescriptionParseResult = cachedReference.value;
|
|
81
|
+
} else if ((0, _apidomDatamodel.isParseResultElement)(existingParseResult)) {
|
|
82
|
+
sourceDescriptionParseResult = existingParseResult;
|
|
91
83
|
} else {
|
|
92
|
-
|
|
93
|
-
sourceDescriptionDereferenced = await (0, _index.default)(retrievalURI, (0, _util.merge)(ctx.options, {
|
|
84
|
+
sourceDescriptionParseResult = await (0, _index.default)(retrievalURI, (0, _util.merge)(ctx.options, {
|
|
94
85
|
parse: {
|
|
95
|
-
mediaType: 'text/plain'
|
|
96
|
-
}
|
|
97
|
-
dereference: {
|
|
98
|
-
strategyOpts: {
|
|
99
|
-
// nested documents should dereference all their source descriptions
|
|
100
|
-
// (parent's name filter doesn't apply to nested documents)
|
|
101
|
-
// set at strategy-specific level to override any inherited filters
|
|
102
|
-
[ctx.strategyName]: {
|
|
103
|
-
sourceDescriptions: true,
|
|
104
|
-
sourceDescriptionsDepth: ctx.currentDepth + 1,
|
|
105
|
-
sourceDescriptionsAncestors: ctx.ancestors,
|
|
106
|
-
sourceDescriptionsDereferenced: ctx.dereferenced
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
86
|
+
mediaType: 'text/plain'
|
|
87
|
+
} // allow parser plugin detection
|
|
110
88
|
}));
|
|
89
|
+
isFreshlyParsed = true;
|
|
111
90
|
}
|
|
112
91
|
|
|
92
|
+
// caller-supplied refSet is rooted at the entry document, but strategies dereference
|
|
93
|
+
// the root of the refSet; re-root its references at the source description
|
|
94
|
+
if (parentRefSet !== null) {
|
|
95
|
+
refSet = new _ReferenceSet.default({
|
|
96
|
+
refs: [new _Reference.default({
|
|
97
|
+
uri: retrievalURI,
|
|
98
|
+
value: sourceDescriptionParseResult
|
|
99
|
+
}), ...parentRefSet.refs.map(ref => new _Reference.default({
|
|
100
|
+
...ref,
|
|
101
|
+
refSet: undefined
|
|
102
|
+
}))]
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const sourceDescriptionDereferenced = await (0, _index2.dereferenceApiDOM)(sourceDescriptionParseResult, (0, _util.merge)((0, _ramda.assocPath)(['dereference', 'refSet'], refSet, ctx.options), {
|
|
106
|
+
parse: {
|
|
107
|
+
mediaType: 'text/plain' // allow dereference strategy detection via ApiDOM inspection
|
|
108
|
+
},
|
|
109
|
+
resolve: {
|
|
110
|
+
baseURI: retrievalURI
|
|
111
|
+
},
|
|
112
|
+
dereference: {
|
|
113
|
+
// freshly parsed document not reported to any refSet can be dereferenced in mutable mode
|
|
114
|
+
immutable: ctx.options.dereference.immutable && !(isFreshlyParsed && parentRefSet === null),
|
|
115
|
+
strategyOpts: {
|
|
116
|
+
// nested documents should dereference all their source descriptions
|
|
117
|
+
// (parent's name filter doesn't apply to nested documents)
|
|
118
|
+
// set at strategy-specific level to override any inherited filters
|
|
119
|
+
[ctx.strategyName]: {
|
|
120
|
+
sourceDescriptions: true,
|
|
121
|
+
sourceDescriptionsDepth: ctx.currentDepth + 1,
|
|
122
|
+
sourceDescriptionsAncestors: ctx.ancestors,
|
|
123
|
+
sourceDescriptionsDereferenced: ctx.dereferenced
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}));
|
|
128
|
+
|
|
113
129
|
// merge dereferenced result into our parse result
|
|
114
130
|
for (const item of sourceDescriptionDereferenced) {
|
|
115
131
|
parseResult.push(item);
|
|
@@ -121,6 +137,13 @@ async function dereferenceSourceDescription(sourceDescription, ctx) {
|
|
|
121
137
|
annotation.classes.push('error');
|
|
122
138
|
parseResult.push(annotation);
|
|
123
139
|
return parseResult;
|
|
140
|
+
} finally {
|
|
141
|
+
// report documents reached through the source description to the caller-supplied refSet,
|
|
142
|
+
// even when dereferencing it failed
|
|
143
|
+
if (parentRefSet !== null && refSet !== null) {
|
|
144
|
+
parentRefSet.merge(refSet);
|
|
145
|
+
parentRefSet.circular ||= refSet.circular;
|
|
146
|
+
}
|
|
124
147
|
}
|
|
125
148
|
|
|
126
149
|
// register dereferenced document for later references to it
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { ParseResultElement, AnnotationElement, isArrayElement, isStringElement, isParseResultElement } from '@speclynx/apidom-datamodel';
|
|
2
2
|
import { isArazzoSpecification1Element, isSourceDescriptionElement } from '@speclynx/apidom-ns-arazzo-1';
|
|
3
3
|
import { toValue } from '@speclynx/apidom-core';
|
|
4
|
+
import { assocPath } from 'ramda';
|
|
4
5
|
import * as url from "../../../util/url.mjs";
|
|
6
|
+
import Reference from "../../../Reference.mjs";
|
|
7
|
+
import ReferenceSet from "../../../ReferenceSet.mjs";
|
|
5
8
|
import { merge as mergeOptions } from "../../../options/util.mjs";
|
|
6
|
-
import
|
|
9
|
+
import parse from "../../../parse/index.mjs";
|
|
10
|
+
import { dereferenceApiDOM } from "../../index.mjs";
|
|
7
11
|
import { arazzoDocumentURIs, resolveArazzo$selfField, validateSourceDescriptionAPI } from "./util.mjs";
|
|
8
12
|
/**
|
|
9
13
|
* Dereferences a single source description element.
|
|
@@ -56,53 +60,64 @@ async function dereferenceSourceDescription(sourceDescription, ctx) {
|
|
|
56
60
|
|
|
57
61
|
// check if source description was already parsed (e.g., during parse phase with sourceDescriptions: true)
|
|
58
62
|
const existingParseResult = sourceDescription.meta.get('parseResult');
|
|
63
|
+
const parentRefSet = ctx.options.dereference.refSet;
|
|
64
|
+
let refSet = null;
|
|
59
65
|
try {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
},
|
|
70
|
-
dereference: {
|
|
71
|
-
strategyOpts: {
|
|
72
|
-
// nested documents should dereference all their source descriptions
|
|
73
|
-
// (parent's name filter doesn't apply to nested documents)
|
|
74
|
-
// set at strategy-specific level to override any inherited filters
|
|
75
|
-
[ctx.strategyName]: {
|
|
76
|
-
sourceDescriptions: true,
|
|
77
|
-
sourceDescriptionsDepth: ctx.currentDepth + 1,
|
|
78
|
-
sourceDescriptionsAncestors: ctx.ancestors,
|
|
79
|
-
sourceDescriptionsDereferenced: ctx.dereferenced
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}));
|
|
66
|
+
// source description document comes from, in order of preference:
|
|
67
|
+
// caller-supplied refSet, parse phase, or is fetched and parsed now
|
|
68
|
+
const cachedReference = parentRefSet?.find(ref => ref.uri === retrievalURI);
|
|
69
|
+
let sourceDescriptionParseResult;
|
|
70
|
+
let isFreshlyParsed = false;
|
|
71
|
+
if (cachedReference !== undefined) {
|
|
72
|
+
sourceDescriptionParseResult = cachedReference.value;
|
|
73
|
+
} else if (isParseResultElement(existingParseResult)) {
|
|
74
|
+
sourceDescriptionParseResult = existingParseResult;
|
|
84
75
|
} else {
|
|
85
|
-
|
|
86
|
-
sourceDescriptionDereferenced = await dereference(retrievalURI, mergeOptions(ctx.options, {
|
|
76
|
+
sourceDescriptionParseResult = await parse(retrievalURI, mergeOptions(ctx.options, {
|
|
87
77
|
parse: {
|
|
88
|
-
mediaType: 'text/plain'
|
|
89
|
-
}
|
|
90
|
-
dereference: {
|
|
91
|
-
strategyOpts: {
|
|
92
|
-
// nested documents should dereference all their source descriptions
|
|
93
|
-
// (parent's name filter doesn't apply to nested documents)
|
|
94
|
-
// set at strategy-specific level to override any inherited filters
|
|
95
|
-
[ctx.strategyName]: {
|
|
96
|
-
sourceDescriptions: true,
|
|
97
|
-
sourceDescriptionsDepth: ctx.currentDepth + 1,
|
|
98
|
-
sourceDescriptionsAncestors: ctx.ancestors,
|
|
99
|
-
sourceDescriptionsDereferenced: ctx.dereferenced
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
78
|
+
mediaType: 'text/plain'
|
|
79
|
+
} // allow parser plugin detection
|
|
103
80
|
}));
|
|
81
|
+
isFreshlyParsed = true;
|
|
104
82
|
}
|
|
105
83
|
|
|
84
|
+
// caller-supplied refSet is rooted at the entry document, but strategies dereference
|
|
85
|
+
// the root of the refSet; re-root its references at the source description
|
|
86
|
+
if (parentRefSet !== null) {
|
|
87
|
+
refSet = new ReferenceSet({
|
|
88
|
+
refs: [new Reference({
|
|
89
|
+
uri: retrievalURI,
|
|
90
|
+
value: sourceDescriptionParseResult
|
|
91
|
+
}), ...parentRefSet.refs.map(ref => new Reference({
|
|
92
|
+
...ref,
|
|
93
|
+
refSet: undefined
|
|
94
|
+
}))]
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
const sourceDescriptionDereferenced = await dereferenceApiDOM(sourceDescriptionParseResult, mergeOptions(assocPath(['dereference', 'refSet'], refSet, ctx.options), {
|
|
98
|
+
parse: {
|
|
99
|
+
mediaType: 'text/plain' // allow dereference strategy detection via ApiDOM inspection
|
|
100
|
+
},
|
|
101
|
+
resolve: {
|
|
102
|
+
baseURI: retrievalURI
|
|
103
|
+
},
|
|
104
|
+
dereference: {
|
|
105
|
+
// freshly parsed document not reported to any refSet can be dereferenced in mutable mode
|
|
106
|
+
immutable: ctx.options.dereference.immutable && !(isFreshlyParsed && parentRefSet === null),
|
|
107
|
+
strategyOpts: {
|
|
108
|
+
// nested documents should dereference all their source descriptions
|
|
109
|
+
// (parent's name filter doesn't apply to nested documents)
|
|
110
|
+
// set at strategy-specific level to override any inherited filters
|
|
111
|
+
[ctx.strategyName]: {
|
|
112
|
+
sourceDescriptions: true,
|
|
113
|
+
sourceDescriptionsDepth: ctx.currentDepth + 1,
|
|
114
|
+
sourceDescriptionsAncestors: ctx.ancestors,
|
|
115
|
+
sourceDescriptionsDereferenced: ctx.dereferenced
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}));
|
|
120
|
+
|
|
106
121
|
// merge dereferenced result into our parse result
|
|
107
122
|
for (const item of sourceDescriptionDereferenced) {
|
|
108
123
|
parseResult.push(item);
|
|
@@ -114,6 +129,13 @@ async function dereferenceSourceDescription(sourceDescription, ctx) {
|
|
|
114
129
|
annotation.classes.push('error');
|
|
115
130
|
parseResult.push(annotation);
|
|
116
131
|
return parseResult;
|
|
132
|
+
} finally {
|
|
133
|
+
// report documents reached through the source description to the caller-supplied refSet,
|
|
134
|
+
// even when dereferencing it failed
|
|
135
|
+
if (parentRefSet !== null && refSet !== null) {
|
|
136
|
+
parentRefSet.merge(refSet);
|
|
137
|
+
parentRefSet.circular ||= refSet.circular;
|
|
138
|
+
}
|
|
117
139
|
}
|
|
118
140
|
|
|
119
141
|
// register dereferenced document for later references to it
|
|
@@ -252,34 +252,38 @@ class Arazzo1DereferenceVisitor {
|
|
|
252
252
|
return;
|
|
253
253
|
}
|
|
254
254
|
const runtimeExpression = (0, _apidomCore.toValue)(referencingElement.reference);
|
|
255
|
-
|
|
256
|
-
// parse the runtime expression
|
|
257
|
-
const {
|
|
258
|
-
result,
|
|
259
|
-
tree
|
|
260
|
-
} = (0, _arazzoRuntimeExpression.parse)(runtimeExpression);
|
|
261
|
-
if (!result.success) {
|
|
262
|
-
throw new _apidomError.ApiDOMStructuredError(`Invalid Reusable Object reference format: "${runtimeExpression}"`, {
|
|
263
|
-
runtimeExpression
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// ReusableElement can only reference components
|
|
268
|
-
if (tree.type !== 'ComponentsExpression') {
|
|
269
|
-
throw new _apidomError.ApiDOMStructuredError(`Reusable Object reference "${runtimeExpression}" must be a components expression`, {
|
|
270
|
-
runtimeExpression
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// evaluate runtime expression as JSON Pointer to get the referenced element
|
|
275
|
-
const jsonPointer = (0, _apidomJsonPointer.compile)(['components', tree.componentType, tree.componentName]);
|
|
276
255
|
let referencedElement;
|
|
277
256
|
try {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
});
|
|
257
|
+
// parse the runtime expression
|
|
258
|
+
const {
|
|
259
|
+
result,
|
|
260
|
+
tree
|
|
261
|
+
} = (0, _arazzoRuntimeExpression.parse)(runtimeExpression);
|
|
262
|
+
if (!result.success) {
|
|
263
|
+
throw new _apidomError.ApiDOMStructuredError(`Invalid Reusable Object reference format: "${runtimeExpression}"`, {
|
|
264
|
+
runtimeExpression
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// ReusableElement can only reference components
|
|
269
|
+
if (tree.type !== 'ComponentsExpression') {
|
|
270
|
+
throw new _apidomError.ApiDOMStructuredError(`Reusable Object reference "${runtimeExpression}" must be a components expression`, {
|
|
271
|
+
runtimeExpression
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// evaluate runtime expression as JSON Pointer to get the referenced element
|
|
276
|
+
const jsonPointer = (0, _apidomJsonPointer.compile)(['components', tree.componentType, tree.componentName]);
|
|
277
|
+
try {
|
|
278
|
+
referencedElement = (0, _apidomJsonPointer.evaluate)(this.reference.value.result, jsonPointer);
|
|
279
|
+
} catch {
|
|
280
|
+
throw new _apidomError.ApiDOMStructuredError(`Reusable Object reference "${runtimeExpression}" cannot be resolved`, {
|
|
281
|
+
runtimeExpression
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
} catch (error) {
|
|
285
|
+
this.handleError(`Error while dereferencing Reusable Object. Cannot resolve reference "${runtimeExpression}": ${error.message}`, error, referencingElement, 'reference', runtimeExpression, path);
|
|
286
|
+
return;
|
|
283
287
|
}
|
|
284
288
|
|
|
285
289
|
/**
|
|
@@ -243,34 +243,38 @@ class Arazzo1DereferenceVisitor {
|
|
|
243
243
|
return;
|
|
244
244
|
}
|
|
245
245
|
const runtimeExpression = toValue(referencingElement.reference);
|
|
246
|
-
|
|
247
|
-
// parse the runtime expression
|
|
248
|
-
const {
|
|
249
|
-
result,
|
|
250
|
-
tree
|
|
251
|
-
} = parseRuntimeExpression(runtimeExpression);
|
|
252
|
-
if (!result.success) {
|
|
253
|
-
throw new ApiDOMStructuredError(`Invalid Reusable Object reference format: "${runtimeExpression}"`, {
|
|
254
|
-
runtimeExpression
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// ReusableElement can only reference components
|
|
259
|
-
if (tree.type !== 'ComponentsExpression') {
|
|
260
|
-
throw new ApiDOMStructuredError(`Reusable Object reference "${runtimeExpression}" must be a components expression`, {
|
|
261
|
-
runtimeExpression
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// evaluate runtime expression as JSON Pointer to get the referenced element
|
|
266
|
-
const jsonPointer = jsonPointerCompile(['components', tree.componentType, tree.componentName]);
|
|
267
246
|
let referencedElement;
|
|
268
247
|
try {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
});
|
|
248
|
+
// parse the runtime expression
|
|
249
|
+
const {
|
|
250
|
+
result,
|
|
251
|
+
tree
|
|
252
|
+
} = parseRuntimeExpression(runtimeExpression);
|
|
253
|
+
if (!result.success) {
|
|
254
|
+
throw new ApiDOMStructuredError(`Invalid Reusable Object reference format: "${runtimeExpression}"`, {
|
|
255
|
+
runtimeExpression
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// ReusableElement can only reference components
|
|
260
|
+
if (tree.type !== 'ComponentsExpression') {
|
|
261
|
+
throw new ApiDOMStructuredError(`Reusable Object reference "${runtimeExpression}" must be a components expression`, {
|
|
262
|
+
runtimeExpression
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// evaluate runtime expression as JSON Pointer to get the referenced element
|
|
267
|
+
const jsonPointer = jsonPointerCompile(['components', tree.componentType, tree.componentName]);
|
|
268
|
+
try {
|
|
269
|
+
referencedElement = jsonPointerEvaluate(this.reference.value.result, jsonPointer);
|
|
270
|
+
} catch {
|
|
271
|
+
throw new ApiDOMStructuredError(`Reusable Object reference "${runtimeExpression}" cannot be resolved`, {
|
|
272
|
+
runtimeExpression
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
} catch (error) {
|
|
276
|
+
this.handleError(`Error while dereferencing Reusable Object. Cannot resolve reference "${runtimeExpression}": ${error.message}`, error, referencingElement, 'reference', runtimeExpression, path);
|
|
277
|
+
return;
|
|
274
278
|
}
|
|
275
279
|
|
|
276
280
|
/**
|