@speclynx/apidom-overlay 4.4.0 → 4.6.0
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 +12 -0
- package/README.md +95 -10
- package/dist/apidom-overlay.browser.js +262 -109
- package/dist/apidom-overlay.browser.min.js +1 -1
- package/package.json +8 -8
- package/src/{apply.cjs → apply/realms/apidom.cjs} +72 -10
- package/src/{apply.mjs → apply/realms/apidom.mjs} +69 -8
- package/src/apply/realms/pojo.cjs +23 -0
- package/src/apply/realms/pojo.mjs +17 -0
- package/src/{apply-uri.cjs → apply/realms/uri.cjs} +3 -3
- package/src/{apply-uri.mjs → apply/realms/uri.mjs} +2 -2
- package/src/apply/trace/TraceBuilder.cjs +45 -0
- package/src/apply/trace/TraceBuilder.mjs +41 -0
- package/src/apply/trace/index.cjs +7 -0
- package/src/apply/trace/index.mjs +1 -0
- package/src/apply/trace/types.cjs +3 -0
- package/src/apply/trace/types.mjs +1 -0
- package/src/index.cjs +10 -7
- package/src/index.mjs +4 -3
- package/types/apidom-overlay.d.ts +49 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [4.6.0](https://github.com/speclynx/apidom/compare/v4.5.0...v4.6.0) (2026-04-12)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **overlay:** add tracing and restructure into realms ([#234](https://github.com/speclynx/apidom/issues/234)) ([3ae47c6](https://github.com/speclynx/apidom/commit/3ae47c6f8916b70db15704ade73af63210813c8c))
|
|
11
|
+
|
|
12
|
+
# [4.5.0](https://github.com/speclynx/apidom/compare/v4.4.0...v4.5.0) (2026-04-12)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
- **overlay:** add support for POJO ([#233](https://github.com/speclynx/apidom/issues/233)) ([810b8e4](https://github.com/speclynx/apidom/commit/810b8e4b10787f9982e449915fbc0c4d58c65e1d))
|
|
17
|
+
|
|
6
18
|
# [4.4.0](https://github.com/speclynx/apidom/compare/v4.3.1...v4.4.0) (2026-04-12)
|
|
7
19
|
|
|
8
20
|
### Features
|
package/README.md
CHANGED
|
@@ -19,11 +19,11 @@ This package provides three levels of API for applying overlays:
|
|
|
19
19
|
|
|
20
20
|
### Applying from file/URL
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
`applyOverlay` parses an overlay document, resolves the target (from `targetURI` or the overlay's `extends` field),
|
|
23
23
|
and applies all actions. The target is parsed with style preservation for round-trip fidelity.
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
|
-
import applyOverlay from '@speclynx/apidom-overlay';
|
|
26
|
+
import { applyOverlay } from '@speclynx/apidom-overlay';
|
|
27
27
|
import { toYAML } from '@speclynx/apidom-core';
|
|
28
28
|
|
|
29
29
|
// target from extends field
|
|
@@ -62,14 +62,12 @@ const target = refract({
|
|
|
62
62
|
const result = applyOverlayApiDOM(overlay, target);
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`applyAction` applies a single overlay action. Useful for programmatic, step-by-step application.
|
|
65
|
+
`applyActionApiDOM` applies a single overlay action. Useful for programmatic, step-by-step application.
|
|
68
66
|
|
|
69
67
|
```js
|
|
70
68
|
import { refract } from '@speclynx/apidom-datamodel';
|
|
71
69
|
import { refractAction } from '@speclynx/apidom-ns-overlay-1';
|
|
72
|
-
import {
|
|
70
|
+
import { applyActionApiDOM } from '@speclynx/apidom-overlay';
|
|
73
71
|
|
|
74
72
|
const action = refractAction({
|
|
75
73
|
target: '$.info.title',
|
|
@@ -77,7 +75,38 @@ const action = refractAction({
|
|
|
77
75
|
});
|
|
78
76
|
const target = refract({ info: { title: 'Old Title', version: '1.0.0' } });
|
|
79
77
|
|
|
80
|
-
const result =
|
|
78
|
+
const result = applyActionApiDOM(action, target);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Applying to plain JavaScript objects (POJO)
|
|
82
|
+
|
|
83
|
+
`applyOverlayPOJO` and `applyActionPOJO` accept and return plain JavaScript objects —
|
|
84
|
+
no need to manually refract or serialize.
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
import { applyOverlayPOJO, applyActionPOJO } from '@speclynx/apidom-overlay';
|
|
88
|
+
|
|
89
|
+
// full overlay
|
|
90
|
+
const result = applyOverlayPOJO(
|
|
91
|
+
{
|
|
92
|
+
overlay: '1.1.0',
|
|
93
|
+
info: { title: 'My overlay', version: '1.0.0' },
|
|
94
|
+
actions: [
|
|
95
|
+
{ target: '$.info.title', update: 'Renamed API' },
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
openapi: '3.1.0',
|
|
100
|
+
info: { title: 'Original', version: '1.0.0' },
|
|
101
|
+
},
|
|
102
|
+
);
|
|
103
|
+
// result is a plain object: { openapi: '3.1.0', info: { title: 'Renamed API', version: '1.0.0' } }
|
|
104
|
+
|
|
105
|
+
// single action
|
|
106
|
+
const updated = applyActionPOJO(
|
|
107
|
+
{ target: '$.info.title', update: 'New Title' },
|
|
108
|
+
{ info: { title: 'Old Title' } },
|
|
109
|
+
);
|
|
81
110
|
```
|
|
82
111
|
|
|
83
112
|
## Overlay spec semantics
|
|
@@ -95,17 +124,73 @@ The implementation follows [Overlay 1.1.0](https://spec.openapis.org/overlay/v1.
|
|
|
95
124
|
| `remove: true` | Removes matched nodes; when combined with `update`, the update has no effect |
|
|
96
125
|
| Action ordering | Applied sequentially — each action modifies the result of the previous |
|
|
97
126
|
|
|
127
|
+
## Tracing
|
|
128
|
+
|
|
129
|
+
Overlay application supports tracing to inspect what each action did during application.
|
|
130
|
+
Pass a trace object via the `trace` option — it will be populated in place with step-by-step
|
|
131
|
+
information about every action applied.
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
import { applyOverlayApiDOM } from '@speclynx/apidom-overlay';
|
|
135
|
+
|
|
136
|
+
const trace = {};
|
|
137
|
+
const result = applyOverlayApiDOM(overlay, target, { trace });
|
|
138
|
+
|
|
139
|
+
console.log(trace.failed); // false
|
|
140
|
+
console.log(trace.message); // 'Overlay was successfully applied'
|
|
141
|
+
|
|
142
|
+
for (const action of trace.actions) {
|
|
143
|
+
console.log(action.target); // '$.info.title'
|
|
144
|
+
console.log(action.type); // 'update' | 'copy' | 'remove' | 'noop'
|
|
145
|
+
console.log(action.matchCount); // 1
|
|
146
|
+
console.log(action.normalizedPaths); // ["$['info']['title']"]
|
|
147
|
+
console.log(action.success); // true
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
When an action fails, the trace captures the error before it is re-thrown:
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
const trace = {};
|
|
155
|
+
try {
|
|
156
|
+
applyOverlayApiDOM(overlay, target, { trace });
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.log(trace.failed); // true
|
|
159
|
+
console.log(trace.failedAt); // index of the failed action
|
|
160
|
+
console.log(trace.message); // error message
|
|
161
|
+
console.log(trace.actions[trace.failedAt].error); // the OverlayError instance
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Tracing works across all API levels — ApiDOM elements, file/URL, and POJO:
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
// single action (ApiDOM)
|
|
169
|
+
const trace = {};
|
|
170
|
+
applyActionApiDOM(action, target, { trace });
|
|
171
|
+
console.log(trace.actions[0].type); // 'update'
|
|
172
|
+
|
|
173
|
+
// file/URL
|
|
174
|
+
const trace = {};
|
|
175
|
+
await applyOverlay('/path/to/overlay.yaml', undefined, { trace });
|
|
176
|
+
|
|
177
|
+
// POJO
|
|
178
|
+
const trace = {};
|
|
179
|
+
applyOverlayPOJO(overlay, target, { trace });
|
|
180
|
+
```
|
|
181
|
+
|
|
98
182
|
## Options
|
|
99
183
|
|
|
100
184
|
### ApplyOptions
|
|
101
185
|
|
|
102
|
-
Passed to `
|
|
186
|
+
Passed to `applyActionApiDOM`, `applyOverlayApiDOM`, and `applyOverlay`:
|
|
103
187
|
|
|
104
188
|
| Option | Type | Default | Description |
|
|
105
189
|
|---|---|---|---|
|
|
106
190
|
| `deepmerge` | `DeepMergeUserOptions` | `{}` | Custom [deepmerge options](https://github.com/speclynx/apidom/blob/main/packages/apidom-core/src/merge/deepmerge.ts) from `@speclynx/apidom-core`. Default `customMerge` enforces Overlay spec type compatibility. |
|
|
107
191
|
| `strict` | `boolean` | `false` | When `true`, throws `OverlayError` if any action's target JSONPath matches zero nodes. |
|
|
108
192
|
| `immutable` | `boolean` | `true` | When `true` (default), returns a new element without mutating the input. Set to `false` for in-place mutation. |
|
|
193
|
+
| `trace` | `OverlayTrace` | — | When provided, populated in place with action-by-action trace data. See [Tracing](#tracing). |
|
|
109
194
|
|
|
110
195
|
### ApplyOverlayOptions
|
|
111
196
|
|
|
@@ -136,10 +221,10 @@ All errors thrown by this package are instances of `OverlayError`, which extends
|
|
|
136
221
|
Errors carry structured context for diagnostics:
|
|
137
222
|
|
|
138
223
|
```js
|
|
139
|
-
import {
|
|
224
|
+
import { applyActionApiDOM, OverlayError } from '@speclynx/apidom-overlay';
|
|
140
225
|
|
|
141
226
|
try {
|
|
142
|
-
|
|
227
|
+
applyActionApiDOM(action, target);
|
|
143
228
|
} catch (error) {
|
|
144
229
|
if (error instanceof OverlayError) {
|
|
145
230
|
console.error(error.message);
|
|
@@ -11,99 +11,7 @@
|
|
|
11
11
|
return /******/ (() => { // webpackBootstrap
|
|
12
12
|
/******/ var __webpack_modules__ = ({
|
|
13
13
|
|
|
14
|
-
/***/
|
|
15
|
-
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
16
|
-
|
|
17
|
-
"use strict";
|
|
18
|
-
__webpack_require__.r(__webpack_exports__);
|
|
19
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
20
|
-
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
21
|
-
/* harmony export */ });
|
|
22
|
-
/* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(96911);
|
|
23
|
-
/* harmony import */ var _speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26432);
|
|
24
|
-
/* harmony import */ var _speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29807);
|
|
25
|
-
/* harmony import */ var _apply_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3138);
|
|
26
|
-
/* harmony import */ var _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(18436);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @public
|
|
35
|
-
*/
|
|
36
|
-
|
|
37
|
-
const defaultOptions = {
|
|
38
|
-
parse: {
|
|
39
|
-
parserOpts: {
|
|
40
|
-
strict: false,
|
|
41
|
-
style: true,
|
|
42
|
-
'overlay-json-1': {
|
|
43
|
-
sourceMap: true,
|
|
44
|
-
style: false,
|
|
45
|
-
extends: true
|
|
46
|
-
},
|
|
47
|
-
'overlay-yaml-1': {
|
|
48
|
-
sourceMap: true,
|
|
49
|
-
style: false,
|
|
50
|
-
extends: true
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
resolve: {
|
|
55
|
-
resolverOpts: {
|
|
56
|
-
fileAllowList: ['*']
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Applies an overlay document from a file/URL to its target document.
|
|
63
|
-
*
|
|
64
|
-
* Parses the overlay, resolves the target from `targetURI` or the overlay's
|
|
65
|
-
* `extends` field, parses the target with style preservation for round-trip fidelity,
|
|
66
|
-
* and applies all overlay actions.
|
|
67
|
-
*
|
|
68
|
-
* @param overlayURI - URI to the overlay document (file path or URL)
|
|
69
|
-
* @param targetURI - URI to the target document; if omitted, uses the overlay's `extends` field
|
|
70
|
-
* @param options - apidom-reference options + overlay merge options
|
|
71
|
-
* @returns ParseResultElement with the modified target document
|
|
72
|
-
*
|
|
73
|
-
* @public
|
|
74
|
-
*/
|
|
75
|
-
const applyOverlay = async (overlayURI, targetURI, options = {
|
|
76
|
-
immutable: false,
|
|
77
|
-
strict: false
|
|
78
|
-
}) => {
|
|
79
|
-
const mergedOptions = (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.mergeOptions)(defaultOptions, options);
|
|
80
|
-
|
|
81
|
-
// parse the overlay document along with document attached to `extends` field (if present)
|
|
82
|
-
const overlayParseResult = await (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.parse)(overlayURI, mergedOptions);
|
|
83
|
-
const overlayElement = overlayParseResult.api;
|
|
84
|
-
if (!(0,_speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_1__.isOverlay1Element)(overlayElement)) {
|
|
85
|
-
throw new _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__["default"](`Failed to parse overlay document "${overlayURI}"`);
|
|
86
|
-
}
|
|
87
|
-
let targetParseResult;
|
|
88
|
-
if (targetURI) {
|
|
89
|
-
const targetOptions = (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.mergeOptions)(defaultOptions, options);
|
|
90
|
-
targetParseResult = await (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.parse)(targetURI, targetOptions);
|
|
91
|
-
} else {
|
|
92
|
-
const extendsElement = overlayElement.get('extends');
|
|
93
|
-
targetParseResult = extendsElement?.meta?.get('parseResult');
|
|
94
|
-
}
|
|
95
|
-
if (!(0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__.isParseResultElement)(targetParseResult)) {
|
|
96
|
-
throw new _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__["default"]('No target specified: provide targetURI or set the "extends" field in the overlay document');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// apply overlay actions to the target (returns targetParseResult with result replaced)
|
|
100
|
-
return (0,_apply_ts__WEBPACK_IMPORTED_MODULE_3__.applyOverlayApiDOM)(overlayParseResult, targetParseResult, options);
|
|
101
|
-
};
|
|
102
|
-
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (applyOverlay);
|
|
103
|
-
|
|
104
|
-
/***/ },
|
|
105
|
-
|
|
106
|
-
/***/ 3138
|
|
14
|
+
/***/ 28216
|
|
107
15
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
108
16
|
|
|
109
17
|
"use strict";
|
|
@@ -111,7 +19,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
111
19
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
112
20
|
/* harmony export */ applyAction: () => (/* binding */ applyAction),
|
|
113
21
|
/* harmony export */ applyCopyAction: () => (/* binding */ applyCopyAction),
|
|
114
|
-
/* harmony export */
|
|
22
|
+
/* harmony export */ applyOverlay: () => (/* binding */ applyOverlay),
|
|
115
23
|
/* harmony export */ applyRemoveAction: () => (/* binding */ applyRemoveAction),
|
|
116
24
|
/* harmony export */ applyUpdateAction: () => (/* binding */ applyUpdateAction)
|
|
117
25
|
/* harmony export */ });
|
|
@@ -125,6 +33,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
125
33
|
/* harmony import */ var _speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(26432);
|
|
126
34
|
/* harmony import */ var _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(18436);
|
|
127
35
|
/* harmony import */ var _validate_ts__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(24338);
|
|
36
|
+
/* harmony import */ var _trace_TraceBuilder_ts__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(90563);
|
|
37
|
+
|
|
128
38
|
|
|
129
39
|
|
|
130
40
|
|
|
@@ -136,6 +46,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
136
46
|
* @public
|
|
137
47
|
*/
|
|
138
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Internal options that carry the tracer instance.
|
|
51
|
+
*/
|
|
52
|
+
|
|
139
53
|
const defaultApplyOptions = {
|
|
140
54
|
immutable: true,
|
|
141
55
|
strict: false
|
|
@@ -277,6 +191,8 @@ const applyRemoveAction = (normalizedPaths, targetElement, options = defaultAppl
|
|
|
277
191
|
* @public
|
|
278
192
|
*/
|
|
279
193
|
const applyAction = (actionElement, targetElement, options = defaultApplyOptions) => {
|
|
194
|
+
const internalOpts = options;
|
|
195
|
+
const tracer = internalOpts.tracer ?? (options.trace ? new _trace_TraceBuilder_ts__WEBPACK_IMPORTED_MODULE_10__["default"](options.trace) : undefined);
|
|
280
196
|
const actionValidation = (0,_validate_ts__WEBPACK_IMPORTED_MODULE_9__.validateAction)(actionElement);
|
|
281
197
|
if (!actionValidation.valid) throw actionValidation.error;
|
|
282
198
|
const targetExpression = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__["default"])(actionElement.target);
|
|
@@ -290,24 +206,53 @@ const applyAction = (actionElement, targetElement, options = defaultApplyOptions
|
|
|
290
206
|
});
|
|
291
207
|
if (matches.length === 0) {
|
|
292
208
|
if (options.strict) {
|
|
293
|
-
|
|
209
|
+
const error = new _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_8__["default"](`Action target "${targetExpression}" matched zero nodes (strict mode)`, {
|
|
294
210
|
action: actionElement
|
|
295
211
|
});
|
|
212
|
+
tracer?.action({
|
|
213
|
+
target: targetExpression,
|
|
214
|
+
type: 'noop',
|
|
215
|
+
matchCount: 0,
|
|
216
|
+
normalizedPaths: [],
|
|
217
|
+
success: false,
|
|
218
|
+
error
|
|
219
|
+
});
|
|
220
|
+
throw error;
|
|
296
221
|
}
|
|
222
|
+
tracer?.action({
|
|
223
|
+
target: targetExpression,
|
|
224
|
+
type: 'noop',
|
|
225
|
+
matchCount: 0,
|
|
226
|
+
normalizedPaths: []
|
|
227
|
+
});
|
|
297
228
|
return targetElement;
|
|
298
229
|
}
|
|
299
230
|
try {
|
|
300
231
|
// remove action
|
|
301
232
|
const removeValue = actionElement.removeField;
|
|
302
233
|
if (removeValue !== undefined && (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__["default"])(removeValue) === true) {
|
|
303
|
-
|
|
234
|
+
const result = applyRemoveAction(normalizedPaths, targetElement, options);
|
|
235
|
+
tracer?.action({
|
|
236
|
+
target: targetExpression,
|
|
237
|
+
type: 'remove',
|
|
238
|
+
matchCount: matches.length,
|
|
239
|
+
normalizedPaths
|
|
240
|
+
});
|
|
241
|
+
return result;
|
|
304
242
|
}
|
|
305
243
|
|
|
306
244
|
// update action
|
|
307
245
|
if (actionElement.update !== undefined) {
|
|
308
246
|
const nodesValidation = (0,_validate_ts__WEBPACK_IMPORTED_MODULE_9__.validateTargetNodes)(matches);
|
|
309
247
|
if (!nodesValidation.valid) throw nodesValidation.error;
|
|
310
|
-
|
|
248
|
+
const result = applyUpdateAction(normalizedPaths, actionElement.update, targetElement, options);
|
|
249
|
+
tracer?.action({
|
|
250
|
+
target: targetExpression,
|
|
251
|
+
type: 'update',
|
|
252
|
+
matchCount: matches.length,
|
|
253
|
+
normalizedPaths
|
|
254
|
+
});
|
|
255
|
+
return result;
|
|
311
256
|
}
|
|
312
257
|
|
|
313
258
|
// copy action
|
|
@@ -315,14 +260,35 @@ const applyAction = (actionElement, targetElement, options = defaultApplyOptions
|
|
|
315
260
|
const nodesValidation = (0,_validate_ts__WEBPACK_IMPORTED_MODULE_9__.validateTargetNodes)(matches);
|
|
316
261
|
if (!nodesValidation.valid) throw nodesValidation.error;
|
|
317
262
|
const copyExpression = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__["default"])(actionElement.copy);
|
|
318
|
-
|
|
263
|
+
const result = applyCopyAction(normalizedPaths, copyExpression, targetElement, options);
|
|
264
|
+
tracer?.action({
|
|
265
|
+
target: targetExpression,
|
|
266
|
+
type: 'copy',
|
|
267
|
+
matchCount: matches.length,
|
|
268
|
+
normalizedPaths
|
|
269
|
+
});
|
|
270
|
+
return result;
|
|
319
271
|
}
|
|
272
|
+
tracer?.action({
|
|
273
|
+
target: targetExpression,
|
|
274
|
+
type: 'noop',
|
|
275
|
+
matchCount: matches.length,
|
|
276
|
+
normalizedPaths
|
|
277
|
+
});
|
|
320
278
|
return targetElement;
|
|
321
279
|
} catch (error) {
|
|
322
280
|
// enrich OverlayError with action context, preserving original stack
|
|
323
281
|
if (error instanceof _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_8__["default"] && !error.action) {
|
|
324
282
|
error.action = actionElement;
|
|
325
283
|
}
|
|
284
|
+
tracer?.action({
|
|
285
|
+
target: targetExpression,
|
|
286
|
+
type: 'noop',
|
|
287
|
+
matchCount: matches.length,
|
|
288
|
+
normalizedPaths,
|
|
289
|
+
success: false,
|
|
290
|
+
error: error instanceof _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_8__["default"] ? error : undefined
|
|
291
|
+
});
|
|
326
292
|
throw error;
|
|
327
293
|
}
|
|
328
294
|
};
|
|
@@ -333,7 +299,7 @@ const applyAction = (actionElement, targetElement, options = defaultApplyOptions
|
|
|
333
299
|
*
|
|
334
300
|
* @public
|
|
335
301
|
*/
|
|
336
|
-
const
|
|
302
|
+
const applyOverlay = (overlayElement, targetElement, options = defaultApplyOptions) => {
|
|
337
303
|
const overlay = overlayElement instanceof _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__["default"] ? overlayElement.api : overlayElement;
|
|
338
304
|
if (!(0,_speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_7__.isOverlay1Element)(overlay)) {
|
|
339
305
|
throw new _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_8__["default"]('First argument must be an Overlay 1.x document');
|
|
@@ -350,8 +316,13 @@ const applyOverlayApiDOM = (overlayElement, targetElement, options = defaultAppl
|
|
|
350
316
|
if (!(0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__.isArrayElement)(overlay.actions)) {
|
|
351
317
|
return targetElement;
|
|
352
318
|
}
|
|
319
|
+
const tracer = options.trace ? new _trace_TraceBuilder_ts__WEBPACK_IMPORTED_MODULE_10__["default"](options.trace) : undefined;
|
|
320
|
+
const internalOptions = tracer ? {
|
|
321
|
+
...options,
|
|
322
|
+
tracer
|
|
323
|
+
} : options;
|
|
353
324
|
for (const action of overlay.actions) {
|
|
354
|
-
target = applyAction(action, target,
|
|
325
|
+
target = applyAction(action, target, internalOptions);
|
|
355
326
|
}
|
|
356
327
|
if (targetElement instanceof _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__["default"]) {
|
|
357
328
|
targetElement.replaceResult(target);
|
|
@@ -362,6 +333,184 @@ const applyOverlayApiDOM = (overlayElement, targetElement, options = defaultAppl
|
|
|
362
333
|
|
|
363
334
|
/***/ },
|
|
364
335
|
|
|
336
|
+
/***/ 83942
|
|
337
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
338
|
+
|
|
339
|
+
"use strict";
|
|
340
|
+
__webpack_require__.r(__webpack_exports__);
|
|
341
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
342
|
+
/* harmony export */ applyAction: () => (/* binding */ applyAction),
|
|
343
|
+
/* harmony export */ applyOverlay: () => (/* binding */ applyOverlay)
|
|
344
|
+
/* harmony export */ });
|
|
345
|
+
/* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10404);
|
|
346
|
+
/* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(44673);
|
|
347
|
+
/* harmony import */ var _speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(35957);
|
|
348
|
+
/* harmony import */ var _apidom_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(28216);
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Applies a single overlay action (POJO) to a target (POJO).
|
|
356
|
+
*
|
|
357
|
+
* @public
|
|
358
|
+
*/
|
|
359
|
+
const applyAction = (action, target, options) => (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_1__["default"])((0,_apidom_ts__WEBPACK_IMPORTED_MODULE_3__.applyAction)((0,_speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_2__.refractAction)(action), (0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__.refract)(target), options));
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Applies an entire overlay document (POJO) to a target (POJO).
|
|
363
|
+
*
|
|
364
|
+
* @public
|
|
365
|
+
*/
|
|
366
|
+
const applyOverlay = (overlay, target, options) => (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_1__["default"])((0,_apidom_ts__WEBPACK_IMPORTED_MODULE_3__.applyOverlay)((0,_speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_2__.refractOverlay1)(overlay), (0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__.refract)(target), options));
|
|
367
|
+
|
|
368
|
+
/***/ },
|
|
369
|
+
|
|
370
|
+
/***/ 42768
|
|
371
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
372
|
+
|
|
373
|
+
"use strict";
|
|
374
|
+
__webpack_require__.r(__webpack_exports__);
|
|
375
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
376
|
+
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
377
|
+
/* harmony export */ });
|
|
378
|
+
/* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(96911);
|
|
379
|
+
/* harmony import */ var _speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26432);
|
|
380
|
+
/* harmony import */ var _speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(29807);
|
|
381
|
+
/* harmony import */ var _apidom_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(28216);
|
|
382
|
+
/* harmony import */ var _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(18436);
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* @public
|
|
391
|
+
*/
|
|
392
|
+
|
|
393
|
+
const defaultOptions = {
|
|
394
|
+
parse: {
|
|
395
|
+
parserOpts: {
|
|
396
|
+
strict: false,
|
|
397
|
+
style: true,
|
|
398
|
+
'overlay-json-1': {
|
|
399
|
+
sourceMap: true,
|
|
400
|
+
style: false,
|
|
401
|
+
extends: true
|
|
402
|
+
},
|
|
403
|
+
'overlay-yaml-1': {
|
|
404
|
+
sourceMap: true,
|
|
405
|
+
style: false,
|
|
406
|
+
extends: true
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
resolve: {
|
|
411
|
+
resolverOpts: {
|
|
412
|
+
fileAllowList: ['*']
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Applies an overlay document from a file/URL to its target document.
|
|
419
|
+
*
|
|
420
|
+
* Parses the overlay, resolves the target from `targetURI` or the overlay's
|
|
421
|
+
* `extends` field, parses the target with style preservation for round-trip fidelity,
|
|
422
|
+
* and applies all overlay actions.
|
|
423
|
+
*
|
|
424
|
+
* @param overlayURI - URI to the overlay document (file path or URL)
|
|
425
|
+
* @param targetURI - URI to the target document; if omitted, uses the overlay's `extends` field
|
|
426
|
+
* @param options - apidom-reference options + overlay merge options
|
|
427
|
+
* @returns ParseResultElement with the modified target document
|
|
428
|
+
*
|
|
429
|
+
* @public
|
|
430
|
+
*/
|
|
431
|
+
const applyOverlay = async (overlayURI, targetURI, options = {
|
|
432
|
+
immutable: false,
|
|
433
|
+
strict: false
|
|
434
|
+
}) => {
|
|
435
|
+
const mergedOptions = (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.mergeOptions)(defaultOptions, options);
|
|
436
|
+
|
|
437
|
+
// parse the overlay document along with document attached to `extends` field (if present)
|
|
438
|
+
const overlayParseResult = await (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.parse)(overlayURI, mergedOptions);
|
|
439
|
+
const overlayElement = overlayParseResult.api;
|
|
440
|
+
if (!(0,_speclynx_apidom_ns_overlay_1__WEBPACK_IMPORTED_MODULE_1__.isOverlay1Element)(overlayElement)) {
|
|
441
|
+
throw new _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__["default"](`Failed to parse overlay document "${overlayURI}"`);
|
|
442
|
+
}
|
|
443
|
+
let targetParseResult;
|
|
444
|
+
if (targetURI) {
|
|
445
|
+
const targetOptions = (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.mergeOptions)(defaultOptions, options);
|
|
446
|
+
targetParseResult = await (0,_speclynx_apidom_reference__WEBPACK_IMPORTED_MODULE_2__.parse)(targetURI, targetOptions);
|
|
447
|
+
} else {
|
|
448
|
+
const extendsElement = overlayElement.get('extends');
|
|
449
|
+
targetParseResult = extendsElement?.meta?.get('parseResult');
|
|
450
|
+
}
|
|
451
|
+
if (!(0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_0__.isParseResultElement)(targetParseResult)) {
|
|
452
|
+
throw new _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__["default"]('No target specified: provide targetURI or set the "extends" field in the overlay document');
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// apply overlay actions to the target (returns targetParseResult with result replaced)
|
|
456
|
+
return (0,_apidom_ts__WEBPACK_IMPORTED_MODULE_3__.applyOverlay)(overlayParseResult, targetParseResult, options);
|
|
457
|
+
};
|
|
458
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (applyOverlay);
|
|
459
|
+
|
|
460
|
+
/***/ },
|
|
461
|
+
|
|
462
|
+
/***/ 90563
|
|
463
|
+
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
464
|
+
|
|
465
|
+
"use strict";
|
|
466
|
+
__webpack_require__.r(__webpack_exports__);
|
|
467
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
468
|
+
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
469
|
+
/* harmony export */ });
|
|
470
|
+
/**
|
|
471
|
+
* Collects trace entries during overlay application.
|
|
472
|
+
* Instantiated internally when `options.trace` is provided.
|
|
473
|
+
*/
|
|
474
|
+
class TraceBuilder {
|
|
475
|
+
#trace;
|
|
476
|
+
constructor(trace) {
|
|
477
|
+
this.#trace = trace;
|
|
478
|
+
this.#trace.actions = [];
|
|
479
|
+
this.#trace.failed = false;
|
|
480
|
+
this.#trace.failedAt = -1;
|
|
481
|
+
this.#trace.message = 'Overlay was successfully applied';
|
|
482
|
+
}
|
|
483
|
+
action(step) {
|
|
484
|
+
const {
|
|
485
|
+
target,
|
|
486
|
+
type,
|
|
487
|
+
matchCount,
|
|
488
|
+
normalizedPaths,
|
|
489
|
+
success = true,
|
|
490
|
+
error
|
|
491
|
+
} = step;
|
|
492
|
+
const position = this.#trace.actions.length;
|
|
493
|
+
this.#trace.actions.push({
|
|
494
|
+
target,
|
|
495
|
+
type,
|
|
496
|
+
matchCount,
|
|
497
|
+
normalizedPaths,
|
|
498
|
+
success,
|
|
499
|
+
...(error !== undefined ? {
|
|
500
|
+
error
|
|
501
|
+
} : {})
|
|
502
|
+
});
|
|
503
|
+
if (!success) {
|
|
504
|
+
this.#trace.failed = true;
|
|
505
|
+
this.#trace.failedAt = position;
|
|
506
|
+
this.#trace.message = error?.message ?? 'Action failed';
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (TraceBuilder);
|
|
511
|
+
|
|
512
|
+
/***/ },
|
|
513
|
+
|
|
365
514
|
/***/ 18436
|
|
366
515
|
(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
|
|
367
516
|
|
|
@@ -100862,16 +101011,20 @@ var __webpack_exports__ = {};
|
|
|
100862
101011
|
"use strict";
|
|
100863
101012
|
__webpack_require__.r(__webpack_exports__);
|
|
100864
101013
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
100865
|
-
/* harmony export */ OverlayError: () => (/* reexport safe */
|
|
100866
|
-
/* harmony export */
|
|
100867
|
-
/* harmony export */
|
|
100868
|
-
/* harmony export */
|
|
100869
|
-
/* harmony export */
|
|
101014
|
+
/* harmony export */ OverlayError: () => (/* reexport safe */ _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__["default"]),
|
|
101015
|
+
/* harmony export */ applyActionApiDOM: () => (/* reexport safe */ _apply_realms_apidom_ts__WEBPACK_IMPORTED_MODULE_0__.applyAction),
|
|
101016
|
+
/* harmony export */ applyActionPOJO: () => (/* reexport safe */ _apply_realms_pojo_ts__WEBPACK_IMPORTED_MODULE_2__.applyAction),
|
|
101017
|
+
/* harmony export */ applyOverlay: () => (/* reexport safe */ _apply_realms_uri_ts__WEBPACK_IMPORTED_MODULE_1__["default"]),
|
|
101018
|
+
/* harmony export */ applyOverlayApiDOM: () => (/* reexport safe */ _apply_realms_apidom_ts__WEBPACK_IMPORTED_MODULE_0__.applyOverlay),
|
|
101019
|
+
/* harmony export */ applyOverlayPOJO: () => (/* reexport safe */ _apply_realms_pojo_ts__WEBPACK_IMPORTED_MODULE_2__.applyOverlay),
|
|
101020
|
+
/* harmony export */ validateAction: () => (/* reexport safe */ _validate_ts__WEBPACK_IMPORTED_MODULE_3__.validateAction)
|
|
100870
101021
|
/* harmony export */ });
|
|
100871
|
-
/* harmony import */ var
|
|
100872
|
-
/* harmony import */ var
|
|
100873
|
-
/* harmony import */ var
|
|
100874
|
-
/* harmony import */ var
|
|
101022
|
+
/* harmony import */ var _apply_realms_apidom_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28216);
|
|
101023
|
+
/* harmony import */ var _apply_realms_uri_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42768);
|
|
101024
|
+
/* harmony import */ var _apply_realms_pojo_ts__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(83942);
|
|
101025
|
+
/* harmony import */ var _validate_ts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(24338);
|
|
101026
|
+
/* harmony import */ var _errors_OverlayError_ts__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(18436);
|
|
101027
|
+
|
|
100875
101028
|
|
|
100876
101029
|
|
|
100877
101030
|
|