@speclynx/apidom-overlay 5.2.7 → 6.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speclynx/apidom-overlay",
3
- "version": "5.2.7",
3
+ "version": "6.0.1",
4
4
  "description": "Apply Overlay 1.x.y documents to API definitions.",
5
5
  "keywords": [
6
6
  "apidom",
@@ -53,12 +53,12 @@
53
53
  "license": "Apache-2.0",
54
54
  "dependencies": {
55
55
  "@babel/runtime-corejs3": "^8.0.5",
56
- "@speclynx/apidom-core": "5.2.7",
57
- "@speclynx/apidom-datamodel": "5.2.7",
58
- "@speclynx/apidom-error": "5.2.7",
59
- "@speclynx/apidom-json-path": "5.2.7",
60
- "@speclynx/apidom-ns-overlay-1": "5.2.7",
61
- "@speclynx/apidom-reference": "5.2.7",
56
+ "@speclynx/apidom-core": "6.0.1",
57
+ "@speclynx/apidom-datamodel": "6.0.1",
58
+ "@speclynx/apidom-error": "6.0.1",
59
+ "@speclynx/apidom-json-path": "6.0.1",
60
+ "@speclynx/apidom-ns-overlay-1": "6.0.1",
61
+ "@speclynx/apidom-reference": "6.0.1",
62
62
  "type-fest": "^5.10.0"
63
63
  },
64
64
  "files": [
@@ -71,5 +71,5 @@
71
71
  "README.md",
72
72
  "CHANGELOG.md"
73
73
  ],
74
- "gitHead": "e99285824ceb947024c97a13c7827843efdaa9e0"
74
+ "gitHead": "d2ea4f01cac54a0d5e1030386e3b0b60664c9619"
75
75
  }
@@ -9,6 +9,7 @@ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
9
9
  var _apidomCore = require("@speclynx/apidom-core");
10
10
  var _apidomJsonPath = require("@speclynx/apidom-json-path");
11
11
  var _apidomNsOverlay = require("@speclynx/apidom-ns-overlay-1");
12
+ var _apidomReference = require("@speclynx/apidom-reference");
12
13
  var _OverlayError = _interopRequireDefault(require("../../errors/OverlayError.cjs"));
13
14
  var _validate = require("../../validate.cjs");
14
15
  var _TraceBuilder = _interopRequireDefault(require("../trace/TraceBuilder.cjs"));
@@ -16,6 +17,10 @@ var _TraceBuilder = _interopRequireDefault(require("../trace/TraceBuilder.cjs"))
16
17
  * @public
17
18
  */
18
19
 
20
+ /**
21
+ * @public
22
+ */
23
+
19
24
  /**
20
25
  * Internal options that carry the tracer instance.
21
26
  */
@@ -342,14 +347,44 @@ const applyAction = (actionElement, targetElement, options = defaultApplyOptions
342
347
  * Under `immutable: false` the caller's parse result is updated in place
343
348
  * instead, with its result element replaced by the new tree.
344
349
  *
350
+ * The overlay is dereferenced first (`options.reference` configures
351
+ * `@speclynx/apidom-reference`), so Reusable Action References are applied as
352
+ * the Action Objects they resolve to. The overlay itself is never mutated.
353
+ *
345
354
  * @public
346
355
  */
347
356
  exports.applyAction = applyAction;
348
- const applyOverlay = (overlayElement, targetElement, options = defaultApplyOptions) => {
357
+ const applyOverlay = async (overlayElement, targetElement, options = defaultApplyOptions) => {
349
358
  const overlay = overlayElement instanceof _apidomDatamodel.ParseResultElement ? overlayElement.api : overlayElement;
350
359
  if (!(0, _apidomNsOverlay.isOverlay1Element)(overlay)) {
351
360
  throw new _OverlayError.default('First argument must be an Overlay 1.x document');
352
361
  }
362
+
363
+ /**
364
+ * References (Overlay 1.2.0) are resolved by dereferencing before the target is
365
+ * touched, so an unresolvable reference fails the overlay without applying any action.
366
+ */
367
+ let dereferencedOverlay;
368
+ try {
369
+ // always immutable: dereferencing must never modify the caller's overlay
370
+ dereferencedOverlay = await (0, _apidomReference.dereferenceApiDOM)(overlay, {
371
+ ...options.reference,
372
+ dereference: {
373
+ ...options.reference?.dereference,
374
+ immutable: true
375
+ }
376
+ });
377
+ } catch (error) {
378
+ throw new _OverlayError.default(error.message, {
379
+ cause: error
380
+ });
381
+ }
382
+
383
+ // references left in place (`continueOnError`, `resolve.internal: false`) cannot be applied
384
+ const unresolvedReference = (0, _apidomDatamodel.isArrayElement)(dereferencedOverlay.actions) ? dereferencedOverlay.actions.content.find(_apidomNsOverlay.isReusableActionReferenceElement) : undefined;
385
+ if ((0, _apidomNsOverlay.isReusableActionReferenceElement)(unresolvedReference)) {
386
+ throw new _OverlayError.default(`Overlay contains unresolved Reusable Action Reference "${(0, _apidomCore.toValue)(unresolvedReference.$ref)}"`);
387
+ }
353
388
  const opts = withDefaults(options);
354
389
  let parseResult;
355
390
  let resultElement;
@@ -387,8 +422,8 @@ const applyOverlay = (overlayElement, targetElement, options = defaultApplyOptio
387
422
  ...internalOptions,
388
423
  immutable: false
389
424
  };
390
- if ((0, _apidomDatamodel.isArrayElement)(overlay.actions)) {
391
- for (const action of overlay.actions) {
425
+ if ((0, _apidomDatamodel.isArrayElement)(dereferencedOverlay.actions)) {
426
+ for (const action of dereferencedOverlay.actions) {
392
427
  target = applyAction(action, target, mutatingOptions);
393
428
  }
394
429
  }
@@ -1,10 +1,14 @@
1
1
  import { isObjectElement, isArrayElement, includesClasses, cloneDeep, cloneShallow, ParseResultElement } from '@speclynx/apidom-datamodel';
2
2
  import { deepmerge, toValue } from '@speclynx/apidom-core';
3
3
  import { evaluate, NormalizedPath } from '@speclynx/apidom-json-path';
4
- import { isOverlay1Element } from '@speclynx/apidom-ns-overlay-1';
4
+ import { isOverlay1Element, isReusableActionReferenceElement } from '@speclynx/apidom-ns-overlay-1';
5
+ import { dereferenceApiDOM } from '@speclynx/apidom-reference';
5
6
  import OverlayError from "../../errors/OverlayError.mjs";
6
7
  import { validateAction, validateTargetNodes } from "../../validate.mjs";
7
8
  import TraceBuilder from "../trace/TraceBuilder.mjs";
9
+ /**
10
+ * @public
11
+ */
8
12
  /**
9
13
  * @public
10
14
  */
@@ -330,13 +334,43 @@ export const applyAction = (actionElement, targetElement, options = defaultApply
330
334
  * Under `immutable: false` the caller's parse result is updated in place
331
335
  * instead, with its result element replaced by the new tree.
332
336
  *
337
+ * The overlay is dereferenced first (`options.reference` configures
338
+ * `@speclynx/apidom-reference`), so Reusable Action References are applied as
339
+ * the Action Objects they resolve to. The overlay itself is never mutated.
340
+ *
333
341
  * @public
334
342
  */
335
- export const applyOverlay = (overlayElement, targetElement, options = defaultApplyOptions) => {
343
+ export const applyOverlay = async (overlayElement, targetElement, options = defaultApplyOptions) => {
336
344
  const overlay = overlayElement instanceof ParseResultElement ? overlayElement.api : overlayElement;
337
345
  if (!isOverlay1Element(overlay)) {
338
346
  throw new OverlayError('First argument must be an Overlay 1.x document');
339
347
  }
348
+
349
+ /**
350
+ * References (Overlay 1.2.0) are resolved by dereferencing before the target is
351
+ * touched, so an unresolvable reference fails the overlay without applying any action.
352
+ */
353
+ let dereferencedOverlay;
354
+ try {
355
+ // always immutable: dereferencing must never modify the caller's overlay
356
+ dereferencedOverlay = await dereferenceApiDOM(overlay, {
357
+ ...options.reference,
358
+ dereference: {
359
+ ...options.reference?.dereference,
360
+ immutable: true
361
+ }
362
+ });
363
+ } catch (error) {
364
+ throw new OverlayError(error.message, {
365
+ cause: error
366
+ });
367
+ }
368
+
369
+ // references left in place (`continueOnError`, `resolve.internal: false`) cannot be applied
370
+ const unresolvedReference = isArrayElement(dereferencedOverlay.actions) ? dereferencedOverlay.actions.content.find(isReusableActionReferenceElement) : undefined;
371
+ if (isReusableActionReferenceElement(unresolvedReference)) {
372
+ throw new OverlayError(`Overlay contains unresolved Reusable Action Reference "${toValue(unresolvedReference.$ref)}"`);
373
+ }
340
374
  const opts = withDefaults(options);
341
375
  let parseResult;
342
376
  let resultElement;
@@ -374,8 +408,8 @@ export const applyOverlay = (overlayElement, targetElement, options = defaultApp
374
408
  ...internalOptions,
375
409
  immutable: false
376
410
  };
377
- if (isArrayElement(overlay.actions)) {
378
- for (const action of overlay.actions) {
411
+ if (isArrayElement(dereferencedOverlay.actions)) {
412
+ for (const action of dereferencedOverlay.actions) {
379
413
  target = applyAction(action, target, mutatingOptions);
380
414
  }
381
415
  }
@@ -30,7 +30,7 @@ const applyAction = (action, target, options) => (0, _apidomCore.toValue)((0, _a
30
30
  * @public
31
31
  */
32
32
  exports.applyAction = applyAction;
33
- const applyOverlay = (overlay, target, options) => (0, _apidomCore.toValue)((0, _apidom.applyOverlay)((0, _apidomNsOverlay.refractOverlay1)(overlay), (0, _apidomDatamodel.refract)(target), {
33
+ const applyOverlay = async (overlay, target, options) => (0, _apidomCore.toValue)(await (0, _apidom.applyOverlay)((0, _apidomNsOverlay.refractOverlay1)(overlay), (0, _apidomDatamodel.refract)(target), {
34
34
  ...options,
35
35
  immutable: false
36
36
  }));
@@ -23,7 +23,7 @@ export const applyAction = (action, target, options) => toValue(applyActionApiDO
23
23
  *
24
24
  * @public
25
25
  */
26
- export const applyOverlay = (overlay, target, options) => toValue(applyOverlayApiDOM(refractOverlay1(overlay), refract(target), {
26
+ export const applyOverlay = async (overlay, target, options) => toValue(await applyOverlayApiDOM(refractOverlay1(overlay), refract(target), {
27
27
  ...options,
28
28
  immutable: false
29
29
  }));
@@ -10,10 +10,6 @@ var _apidomNsOverlay = require("@speclynx/apidom-ns-overlay-1");
10
10
  var _apidomReference = require("@speclynx/apidom-reference");
11
11
  var _apidom = require("./apidom.cjs");
12
12
  var _OverlayError = _interopRequireDefault(require("../../errors/OverlayError.cjs"));
13
- /**
14
- * @public
15
- */
16
-
17
13
  const defaultReferenceOptions = {
18
14
  parse: {
19
15
  parserOpts: {
@@ -84,7 +80,15 @@ const applyOverlay = async (overlayURI, targetURI, options = defaultOptions) =>
84
80
  // apply overlay actions to the target (mutable by default: targetParseResult with result replaced)
85
81
  return (0, _apidom.applyOverlay)(overlayParseResult, targetParseResult, {
86
82
  ...options,
87
- immutable: options.immutable ?? defaultOptions.immutable
83
+ immutable: options.immutable ?? defaultOptions.immutable,
84
+ reference: {
85
+ ...options.reference,
86
+ // same normalization `parse` applies, so reference errors report the parsed document's URI
87
+ resolve: {
88
+ ...options.reference?.resolve,
89
+ baseURI: _apidomReference.url.sanitize(_apidomReference.url.stripHash(overlayURI))
90
+ }
91
+ }
88
92
  });
89
93
  };
90
94
  var _default = exports.default = applyOverlay;
@@ -1,11 +1,8 @@
1
1
  import { isParseResultElement } from '@speclynx/apidom-datamodel';
2
2
  import { isOverlay1Element } from '@speclynx/apidom-ns-overlay-1';
3
- import { parse, mergeOptions } from '@speclynx/apidom-reference';
3
+ import { parse, mergeOptions, url } from '@speclynx/apidom-reference';
4
4
  import { applyOverlay as applyOverlayApiDOM } from "./apidom.mjs";
5
5
  import OverlayError from "../../errors/OverlayError.mjs";
6
- /**
7
- * @public
8
- */
9
6
  const defaultReferenceOptions = {
10
7
  parse: {
11
8
  parserOpts: {
@@ -76,7 +73,15 @@ const applyOverlay = async (overlayURI, targetURI, options = defaultOptions) =>
76
73
  // apply overlay actions to the target (mutable by default: targetParseResult with result replaced)
77
74
  return applyOverlayApiDOM(overlayParseResult, targetParseResult, {
78
75
  ...options,
79
- immutable: options.immutable ?? defaultOptions.immutable
76
+ immutable: options.immutable ?? defaultOptions.immutable,
77
+ reference: {
78
+ ...options.reference,
79
+ // same normalization `parse` applies, so reference errors report the parsed document's URI
80
+ resolve: {
81
+ ...options.reference?.resolve,
82
+ baseURI: url.sanitize(url.stripHash(overlayURI))
83
+ }
84
+ }
80
85
  });
81
86
  };
82
87
  export default applyOverlay;
@@ -14,7 +14,7 @@ var _OverlayError = _interopRequireDefault(require("../../errors/OverlayError.cj
14
14
  */
15
15
 
16
16
  const defaultDiffOptions = {
17
- overlay: '1.1.0',
17
+ overlay: '1.2.0',
18
18
  info: {
19
19
  title: 'API diff',
20
20
  version: '0.0.0'
@@ -143,7 +143,7 @@ const diffArrays = (left, right, segments, actions) => {
143
143
  * Produces an {@link Overlay1Element} that, when applied to `leftElement`, yields `rightElement`.
144
144
  *
145
145
  * Known limitations:
146
- * - Identical documents produce an overlay with an empty `actions` array. Overlay 1.1.0 §3
146
+ * - Identical documents produce an overlay with an empty `actions` array. Overlay 1.x §3
147
147
  * requires `actions` to be non-empty; callers should guard against the no-diff case.
148
148
  * - Root-level structural type change (e.g. object root → array root) throws {@link OverlayError}
149
149
  * because Overlay has no mechanism to replace the root node.
@@ -6,7 +6,7 @@ import OverlayError from "../../errors/OverlayError.mjs";
6
6
  * @public
7
7
  */
8
8
  const defaultDiffOptions = {
9
- overlay: '1.1.0',
9
+ overlay: '1.2.0',
10
10
  info: {
11
11
  title: 'API diff',
12
12
  version: '0.0.0'
@@ -135,7 +135,7 @@ const diffArrays = (left, right, segments, actions) => {
135
135
  * Produces an {@link Overlay1Element} that, when applied to `leftElement`, yields `rightElement`.
136
136
  *
137
137
  * Known limitations:
138
- * - Identical documents produce an overlay with an empty `actions` array. Overlay 1.1.0 §3
138
+ * - Identical documents produce an overlay with an empty `actions` array. Overlay 1.x §3
139
139
  * requires `actions` to be non-empty; callers should guard against the no-diff case.
140
140
  * - Root-level structural type change (e.g. object root → array root) throws {@link OverlayError}
141
141
  * because Overlay has no mechanism to replace the root node.
@@ -96,9 +96,13 @@ export declare const applyOverlay: (overlayURI: string, targetURI?: string, opti
96
96
  * Under `immutable: false` the caller's parse result is updated in place
97
97
  * instead, with its result element replaced by the new tree.
98
98
  *
99
+ * The overlay is dereferenced first (`options.reference` configures
100
+ * `@speclynx/apidom-reference`), so Reusable Action References are applied as
101
+ * the Action Objects they resolve to. The overlay itself is never mutated.
102
+ *
99
103
  * @public
100
104
  */
101
- export declare const applyOverlayApiDOM: <T extends Element_2 | ParseResultElement>(overlayElement: Overlay1Element | ParseResultElement, targetElement: T, options?: ApplyOptions) => T;
105
+ export declare const applyOverlayApiDOM: <T extends Element_2 | ParseResultElement>(overlayElement: Overlay1Element | ParseResultElement, targetElement: T, options?: ApplyOverlayOptions) => Promise<T>;
102
106
 
103
107
  /**
104
108
  * @public
@@ -115,7 +119,7 @@ export declare interface ApplyOverlayOptions extends ApplyOptions {
115
119
  *
116
120
  * @public
117
121
  */
118
- export declare const applyOverlayPOJO: (overlay: Record<string, unknown>, target: Record<string, unknown>, options?: ApplyOptions) => unknown;
122
+ export declare const applyOverlayPOJO: (overlay: Record<string, unknown>, target: Record<string, unknown>, options?: ApplyOverlayOptions) => Promise<unknown>;
119
123
 
120
124
  /**
121
125
  * @public
@@ -131,7 +135,7 @@ export declare const defaultDiffOverlayOptions: DiffOverlayOptions;
131
135
  * Produces an {@link Overlay1Element} that, when applied to `leftElement`, yields `rightElement`.
132
136
  *
133
137
  * Known limitations:
134
- * - Identical documents produce an overlay with an empty `actions` array. Overlay 1.1.0 §3
138
+ * - Identical documents produce an overlay with an empty `actions` array. Overlay 1.x §3
135
139
  * requires `actions` to be non-empty; callers should guard against the no-diff case.
136
140
  * - Root-level structural type change (e.g. object root → array root) throws {@link OverlayError}
137
141
  * because Overlay has no mechanism to replace the root node.